Set of changes updating version 8.2 to the level of 8.1, since 8.2
development had been halted since it was first created back in April. Version 8.2 is now the official development version, with the first development push to create a Cairo graphics interface.
This commit is contained in:
parent
d97fff5b08
commit
088fc759c4
4
README
4
README
|
|
@ -23,7 +23,9 @@
|
|||
---------------------------------
|
||||
|
||||
As of the release of version 8.2, Version 8.1 is now the new stable
|
||||
distribution, and 8.2 is the development distribution.
|
||||
distribution, and 8.2 is the development distribution. First
|
||||
development push over 8.1 is to add a Cairo (2D hardware-accelerated
|
||||
graphics) interface ("magic -d CAIRO" or "magic -d XR").
|
||||
|
||||
4. Version 8.1 Release Notes:
|
||||
---------------------------------
|
||||
|
|
|
|||
|
|
@ -971,19 +971,24 @@ gdsCopyPaintFunc(tile, gdsCopyRec)
|
|||
GDSCopyRec *gdsCopyRec;
|
||||
{
|
||||
int pNum;
|
||||
TileType dinfo;
|
||||
Rect sourceRect, targetRect;
|
||||
Transform *trans = gdsCopyRec->trans;
|
||||
Plane *plane = gdsCopyRec->plane;
|
||||
|
||||
dinfo = TiGetTypeExact(tile);
|
||||
|
||||
if (trans)
|
||||
{
|
||||
TiToRect(tile, &sourceRect);
|
||||
GeoTransRect(trans, &sourceRect, &targetRect);
|
||||
if (IsSplit(tile))
|
||||
dinfo = DBTransformDiagonal(TiGetTypeExact(tile), trans);
|
||||
}
|
||||
else
|
||||
TiToRect(tile, &targetRect);
|
||||
|
||||
DBNMPaintPlane(plane, TiGetTypeExact(tile), &targetRect, CIFPaintTable,
|
||||
DBNMPaintPlane(plane, dinfo, &targetRect, CIFPaintTable,
|
||||
(PaintUndoInfo *)NULL);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -851,8 +851,7 @@ calmaElementText()
|
|||
break;
|
||||
}
|
||||
|
||||
if (layer >= 0 && (cifCurReadStyle->crs_layers[layer]->crl_flags
|
||||
& CIFR_TEXTLABELS))
|
||||
if (layer >= 0 && cifCurReadStyle->crs_labelSticky[layer])
|
||||
flags = LABEL_STICKY;
|
||||
else if (cifCurReadStyle->crs_flags & CRF_NO_RECONNECT_LABELS)
|
||||
flags = LABEL_STICKY;
|
||||
|
|
|
|||
|
|
@ -459,8 +459,10 @@ calmaProcessDef(def, outf)
|
|||
|
||||
DBPropGet(def->cd_parents->cu_parent, "GDS_FILE", &isReadOnly);
|
||||
if (!isReadOnly)
|
||||
TxError("Calma output error: Can't find GDS file for vendor cell."
|
||||
" Using magic's internal definition\n");
|
||||
TxError("Calma output error: Can't find GDS file \"%s\" "
|
||||
"for vendor cell \"%s\". Using magic's "
|
||||
"internal definition\n", filename,
|
||||
def->cd_name);
|
||||
else
|
||||
def->cd_flags |= CDVENDORGDS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -515,19 +515,24 @@ cifCopyPaintFunc(tile, cifCopyRec)
|
|||
CIFCopyRec *cifCopyRec;
|
||||
{
|
||||
int pNum;
|
||||
TileType dinfo;
|
||||
Rect sourceRect, targetRect;
|
||||
Transform *trans = cifCopyRec->trans;
|
||||
Plane *plane = cifCopyRec->plane;
|
||||
|
||||
dinfo = TiGetTypeExact(tile);
|
||||
|
||||
if (trans)
|
||||
{
|
||||
TiToRect(tile, &sourceRect);
|
||||
GeoTransRect(trans, &sourceRect, &targetRect);
|
||||
if (IsSplit(tile))
|
||||
dinfo = DBTransformDiagonal(TiGetTypeExact(tile), trans);
|
||||
}
|
||||
else
|
||||
TiToRect(tile, &targetRect);
|
||||
|
||||
DBNMPaintPlane(plane, TiGetTypeExact(tile), &targetRect, CIFPaintTable,
|
||||
DBNMPaintPlane(plane, dinfo, &targetRect, CIFPaintTable,
|
||||
(PaintUndoInfo *)NULL);
|
||||
|
||||
return 0;
|
||||
|
|
@ -612,8 +617,12 @@ CIFPaintCurrent()
|
|||
{
|
||||
CIFCopyRec cifCopyRec;
|
||||
|
||||
newplane = DBNewPlane((ClientData) TT_SPACE);
|
||||
DBClearPaintPlane(newplane);
|
||||
newplane = parray[pNum];
|
||||
if (newplane == NULL)
|
||||
{
|
||||
newplane = DBNewPlane((ClientData) TT_SPACE);
|
||||
DBClearPaintPlane(newplane);
|
||||
}
|
||||
|
||||
cifCopyRec.plane = newplane;
|
||||
cifCopyRec.trans = NULL;
|
||||
|
|
@ -1064,8 +1073,7 @@ cifParseUser94()
|
|||
}
|
||||
if (type >=0 )
|
||||
{
|
||||
if (layer >= 0 && (cifCurReadStyle->crs_layers[layer]->crl_flags
|
||||
& CIFR_TEXTLABELS))
|
||||
if (layer >= 0 && cifCurReadStyle->crs_labelSticky[layer])
|
||||
flags = LABEL_STICKY;
|
||||
else
|
||||
flags = 0;
|
||||
|
|
@ -1179,8 +1187,7 @@ cifParseUser95()
|
|||
if (type >=0 )
|
||||
{
|
||||
int flags;
|
||||
if (layer >= 0 && (cifCurReadStyle->crs_layers[layer]->crl_flags
|
||||
& CIFR_TEXTLABELS))
|
||||
if (layer >= 0 && cifCurReadStyle->crs_labelSticky[layer])
|
||||
flags = LABEL_STICKY;
|
||||
else
|
||||
flags = 0;
|
||||
|
|
|
|||
|
|
@ -365,6 +365,7 @@ cifReadStyleInit()
|
|||
for (i = 0; i < MAXCIFRLAYERS; i++)
|
||||
{
|
||||
cifCurReadStyle->crs_labelLayer[i] = TT_SPACE;
|
||||
cifCurReadStyle->crs_labelSticky[i] = FALSE;
|
||||
cifCurReadStyle->crs_layers[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -861,7 +862,7 @@ CIFReadTechLine(sectionName, argc, argv)
|
|||
cifCurReadStyle->crs_labelLayer[i]
|
||||
= cifCurReadLayer->crl_magicType;
|
||||
if (argc == 3)
|
||||
cifCurReadStyle->crs_layers[i]->crl_flags |= CIFR_TEXTLABELS;
|
||||
cifCurReadStyle->crs_labelSticky[i] = TRUE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -52,13 +52,10 @@ typedef struct
|
|||
* a single OR operation, so it can be handled specially.
|
||||
* CIFR_TEMPLAYER: Means this layer is a temporary CIF layer, and that
|
||||
* the "crl_magicType" should be interpreted as a CIF layer.
|
||||
* CIFR_TEXTLABELS: Means this layer is used for text-only layers, not to
|
||||
* be moved or electrically connected to any other layer.
|
||||
*/
|
||||
|
||||
#define CIFR_SIMPLE 1
|
||||
#define CIFR_TEMPLAYER 2
|
||||
#define CIFR_TEXTLABELS 4
|
||||
|
||||
/* The following structure defines a complete CIF read-in style.
|
||||
* The constant MAXCIFRLAYERS must be less than TT_MAXTYPES, and
|
||||
|
|
@ -107,6 +104,8 @@ typedef struct cifrstyle
|
|||
/* Gives the Magic layer to use for labels
|
||||
* on each possible CIF layer.
|
||||
*/
|
||||
bool crs_labelSticky[MAXCIFRLAYERS];
|
||||
/* Marker if label layer makes sticky labels */
|
||||
CIFReadLayer *crs_layers[MAXCIFRLAYERS];
|
||||
HashTable cifCalmaToCif; /* Table mapping from Calma layer numbers to
|
||||
* CIF layers
|
||||
|
|
|
|||
|
|
@ -1868,7 +1868,7 @@ CmdFlatten(w, cmd)
|
|||
TxCommand *cmd;
|
||||
{
|
||||
int rval, xMask;
|
||||
bool dolabels;
|
||||
bool dolabels, toplabels, invert;
|
||||
char *destname;
|
||||
CellDef *newdef;
|
||||
CellUse *newuse;
|
||||
|
|
@ -1878,6 +1878,7 @@ CmdFlatten(w, cmd)
|
|||
destname = cmd->tx_argv[cmd->tx_argc - 1];
|
||||
xMask = CU_DESCEND_ALL;
|
||||
dolabels = TRUE;
|
||||
toplabels = FALSE;
|
||||
|
||||
rval = 0;
|
||||
if (cmd->tx_argc > 2)
|
||||
|
|
@ -1885,26 +1886,39 @@ CmdFlatten(w, cmd)
|
|||
int i;
|
||||
for (i = 1; i < (cmd->tx_argc - 1); i++)
|
||||
{
|
||||
if (strncmp(cmd->tx_argv[i], "-no", 3))
|
||||
if (!strncmp(cmd->tx_argv[i], "-no", 3))
|
||||
{
|
||||
invert = TRUE;
|
||||
}
|
||||
else if (!strncmp(cmd->tx_argv[i], "-do", 3))
|
||||
{
|
||||
invert = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
rval = -1;
|
||||
break;
|
||||
}
|
||||
else if (strlen(cmd->tx_argv[i]) > 3)
|
||||
|
||||
if (strlen(cmd->tx_argv[i]) > 3)
|
||||
{
|
||||
switch(cmd->tx_argv[1][3])
|
||||
switch(cmd->tx_argv[i][3])
|
||||
{
|
||||
case 'l':
|
||||
dolabels = FALSE;
|
||||
dolabels = (invert) ? FALSE : TRUE;
|
||||
break;
|
||||
case 't':
|
||||
toplabels = (invert) ? FALSE : TRUE;
|
||||
break;
|
||||
case 's':
|
||||
xMask = CU_DESCEND_NO_SUBCKT;
|
||||
xMask = (invert) ? CU_DESCEND_NO_SUBCKT : CU_DESCEND_ALL;
|
||||
break;
|
||||
case 'v':
|
||||
xMask = CU_DESCEND_NO_VENDOR;
|
||||
xMask = (invert) ? CU_DESCEND_NO_VENDOR : CU_DESCEND_ALL;
|
||||
break;
|
||||
default:
|
||||
TxError("options are: -nolabels, -nosubcircuits -novendor\n");
|
||||
TxError("options are: -nolabels, -nosubcircuits "
|
||||
"-novendor, -dotoplabels\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1945,6 +1959,13 @@ CmdFlatten(w, cmd)
|
|||
DBCellCopyAllPaint(&scx, &DBAllButSpaceAndDRCBits, xMask, flatDestUse);
|
||||
if (dolabels)
|
||||
FlatCopyAllLabels(&scx, &DBAllTypeBits, xMask, flatDestUse);
|
||||
else if (toplabels)
|
||||
{
|
||||
int savemask = scx.scx_use->cu_expandMask;
|
||||
scx.scx_use->cu_expandMask = CU_DESCEND_SPECIAL;
|
||||
DBCellCopyAllLabels(&scx, &DBAllTypeBits, CU_DESCEND_SPECIAL, flatDestUse);
|
||||
scx.scx_use->cu_expandMask = savemask;
|
||||
}
|
||||
|
||||
if (xMask != CU_DESCEND_ALL)
|
||||
DBCellCopyAllCells(&scx, xMask, flatDestUse, (Rect *)NULL);
|
||||
|
|
|
|||
|
|
@ -532,8 +532,43 @@ DBTreeSrLabels(scx, mask, xMask, tpath, flags, func, cdarg)
|
|||
{
|
||||
if (SigInterruptPending) break;
|
||||
is_touching = FALSE;
|
||||
|
||||
if ((lab->lab_font < 0) || (flags & TF_LABEL_ATTACH))
|
||||
is_touching = GEO_TOUCH(&lab->lab_rect, r);
|
||||
{
|
||||
/* For non-manhattan searches, label must be in or */
|
||||
/* touch the triangle. (to-do: needs a proper */
|
||||
/* insideness test) */
|
||||
|
||||
if (flags & TF_LABEL_ATTACH_CORNER)
|
||||
{
|
||||
Rect r1 = *r;
|
||||
Rect r2 = *r;
|
||||
if (flags & TF_LABEL_ATTACH_NOT_NE)
|
||||
{
|
||||
r1.r_ytop = r->r_ybot;
|
||||
r2.r_xtop = r->r_xbot;
|
||||
}
|
||||
else if (flags & TF_LABEL_ATTACH_NOT_NW)
|
||||
{
|
||||
r1.r_ytop = r->r_ybot;
|
||||
r2.r_xbot = r->r_xtop;
|
||||
}
|
||||
else if (flags & TF_LABEL_ATTACH_NOT_SE)
|
||||
{
|
||||
r1.r_ybot = r->r_ytop;
|
||||
r2.r_xtop = r->r_xbot;
|
||||
}
|
||||
else if (flags & TF_LABEL_ATTACH_NOT_SW)
|
||||
{
|
||||
r1.r_ybot = r->r_ytop;
|
||||
r2.r_xbot = r->r_xtop;
|
||||
}
|
||||
is_touching = GEO_TOUCH(&lab->lab_bbox, &r1) ||
|
||||
GEO_TOUCH(&lab->lab_bbox, &r2);
|
||||
}
|
||||
else
|
||||
is_touching = GEO_TOUCH(&lab->lab_rect, r);
|
||||
}
|
||||
if (!is_touching && (flags & TF_LABEL_DISPLAY) && (lab->lab_font >= 0))
|
||||
is_touching = GEO_TOUCH(&lab->lab_bbox, r);
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ DBDescendSubcell(use, xMask)
|
|||
|
||||
case CU_DESCEND_NO_VENDOR:
|
||||
return (use->cu_def->cd_flags & CDVENDORGDS) ? FALSE : TRUE;
|
||||
|
||||
case CU_DESCEND_NONE:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE; /* in case CU_DESCEND_ALL is not defined as 0 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -296,6 +296,77 @@ dbSrConnectStartFunc(tile, pTile)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Function similar to DBSrConnect but which does the first pass only */
|
||||
/* and leaves the marked tiles intact. Tiles must be cleared by the */
|
||||
/* caller. */
|
||||
|
||||
int
|
||||
DBSrConnectOnePass(def, startArea, mask, connect, bounds, func, clientData)
|
||||
CellDef *def; /* Cell definition in which to carry out
|
||||
* the connectivity search. Only paint
|
||||
* in this definition is considered.
|
||||
*/
|
||||
Rect *startArea; /* Area to search for an initial tile. Only
|
||||
* tiles OVERLAPPING the area are considered.
|
||||
* This area should have positive x and y
|
||||
* dimensions.
|
||||
*/
|
||||
TileTypeBitMask *mask; /* Only tiles of one of these types are used
|
||||
* as initial tiles.
|
||||
*/
|
||||
TileTypeBitMask *connect; /* Pointer to a table indicating what tile
|
||||
* types connect to what other tile types.
|
||||
* Each entry gives a mask of types that
|
||||
* connect to tiles of a given type.
|
||||
*/
|
||||
Rect *bounds; /* Area, in coords of scx->scx_use->cu_def,
|
||||
* that limits the search: only tiles
|
||||
* overalapping this area will be returned.
|
||||
* Use TiPlaneRect to search everywhere.
|
||||
*/
|
||||
int (*func)(); /* Function to apply at each connected tile. */
|
||||
ClientData clientData; /* Client data for above function. */
|
||||
|
||||
{
|
||||
struct conSrArg csa;
|
||||
int startPlane, result;
|
||||
Tile *startTile; /* Starting tile for search. */
|
||||
extern int dbSrConnectFunc(); /* Forward declaration. */
|
||||
extern int dbSrConnectStartFunc();
|
||||
|
||||
result = 0;
|
||||
csa.csa_def = def;
|
||||
csa.csa_bounds = *bounds;
|
||||
|
||||
/* Find a starting tile (if there are many tiles underneath the
|
||||
* starting area, pick any one). The search function just saves
|
||||
* the tile address and returns.
|
||||
*/
|
||||
|
||||
startTile = NULL;
|
||||
for (startPlane = PL_TECHDEPBASE; startPlane < DBNumPlanes; startPlane++)
|
||||
{
|
||||
if (DBSrPaintArea((Tile *) NULL,
|
||||
def->cd_planes[startPlane], startArea, mask,
|
||||
dbSrConnectStartFunc, (ClientData) &startTile) != 0) break;
|
||||
}
|
||||
if (startTile == NULL) return 0;
|
||||
/* The following lets us call DBSrConnect recursively */
|
||||
else if (startTile->ti_client == (ClientData)1) return 0;
|
||||
|
||||
|
||||
/* Pass 1. During this pass the client function gets called. */
|
||||
|
||||
csa.csa_clientFunc = func;
|
||||
csa.csa_clientData = clientData;
|
||||
csa.csa_clear = FALSE;
|
||||
csa.csa_connect = connect;
|
||||
csa.csa_plane = startPlane;
|
||||
if (dbSrConnectFunc(startTile, &csa) != 0) result = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -402,6 +473,8 @@ dbSrConnectFunc(tile, csa)
|
|||
if (t2->ti_client == (ClientData) CLIENTDEFAULT) continue;
|
||||
}
|
||||
else if (t2->ti_client != (ClientData) CLIENTDEFAULT) continue;
|
||||
if (IsSplit(t2))
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body | TT_SIDE)); /* bit set */
|
||||
if (dbSrConnectFunc(t2, csa) != 0) return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -427,6 +500,13 @@ bottomside:
|
|||
if (t2->ti_client == (ClientData) CLIENTDEFAULT) continue;
|
||||
}
|
||||
else if (t2->ti_client != (ClientData) CLIENTDEFAULT) continue;
|
||||
if (IsSplit(t2))
|
||||
{
|
||||
if (SplitDirection(t2))
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body | TT_SIDE)); /* bit set */
|
||||
else
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body & ~TT_SIDE)); /* bit clear */
|
||||
}
|
||||
if (dbSrConnectFunc(t2, csa) != 0) return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -451,6 +531,8 @@ rightside:
|
|||
if (t2->ti_client == (ClientData) CLIENTDEFAULT) goto nextRight;
|
||||
}
|
||||
else if (t2->ti_client != (ClientData) CLIENTDEFAULT) goto nextRight;
|
||||
if (IsSplit(t2))
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body & ~TT_SIDE)); /* bit clear */
|
||||
if (dbSrConnectFunc(t2, csa) != 0) return 1;
|
||||
}
|
||||
nextRight: if (BOTTOM(t2) <= tileArea.r_ybot) break;
|
||||
|
|
@ -476,6 +558,13 @@ topside:
|
|||
if (t2->ti_client == (ClientData) CLIENTDEFAULT) goto nextTop;
|
||||
}
|
||||
else if (t2->ti_client != (ClientData) CLIENTDEFAULT) goto nextTop;
|
||||
if (IsSplit(t2))
|
||||
{
|
||||
if (SplitDirection(t2))
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body & ~TT_SIDE)); /* bit clear */
|
||||
else
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body | TT_SIDE)); /* bit set */
|
||||
}
|
||||
if (dbSrConnectFunc(t2, csa) != 0) return 1;
|
||||
}
|
||||
nextTop: if (LEFT(t2) <= tileArea.r_xbot) break;
|
||||
|
|
@ -606,8 +695,16 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
|
|||
SearchContext scx2 = *csa2->csa2_topscx;
|
||||
TileTypeBitMask mask;
|
||||
|
||||
// Do NOT go searching on labels connected to space!
|
||||
if (slab->lab_type == TT_SPACE) continue;
|
||||
TTMaskSetOnlyType(&mask, slab->lab_type);
|
||||
GeoTransRect(&scx->scx_trans, &slab->lab_rect, &scx2.scx_area);
|
||||
|
||||
// Expand search area by 1 to capture edge and point labels.
|
||||
scx2.scx_area.r_xbot--;
|
||||
scx2.scx_area.r_xtop++;
|
||||
scx2.scx_area.r_ybot--;
|
||||
scx2.scx_area.r_ytop++;
|
||||
DBTreeSrTiles(&scx2, &mask, csa2->csa2_xMask,
|
||||
dbcConnectFunc, (ClientData) csa2);
|
||||
}
|
||||
|
|
@ -657,6 +754,7 @@ dbcConnectFunc(tile, cx)
|
|||
TileType loctype = TiGetTypeExact(tile);
|
||||
TileType dinfo = 0;
|
||||
int pNum = cx->tc_plane;
|
||||
unsigned char searchtype;
|
||||
CellDef *def;
|
||||
|
||||
TiToRect(tile, &tileArea);
|
||||
|
|
@ -767,8 +865,30 @@ dbcConnectFunc(tile, cx)
|
|||
/* Check the source def for any labels belonging to this */
|
||||
/* tile area and plane, and add them to the destination. */
|
||||
|
||||
searchtype = TF_LABEL_ATTACH;
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
/* If the tile is split, then labels attached to the */
|
||||
/* opposite point of the triangle are NOT connected. */
|
||||
|
||||
if (SplitSide(tile))
|
||||
{
|
||||
if (SplitDirection(tile))
|
||||
searchtype |= TF_LABEL_ATTACH_NOT_SW;
|
||||
else
|
||||
searchtype |= TF_LABEL_ATTACH_NOT_NW;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SplitDirection(tile))
|
||||
searchtype |= TF_LABEL_ATTACH_NOT_NE;
|
||||
else
|
||||
searchtype |= TF_LABEL_ATTACH_NOT_SE;
|
||||
}
|
||||
}
|
||||
|
||||
DBTreeSrLabels(&scx2, connectMask, csa2->csa2_xMask, NULL,
|
||||
TF_LABEL_ATTACH, dbcConnectLabelFunc,
|
||||
searchtype, dbcConnectLabelFunc,
|
||||
(ClientData) csa2);
|
||||
|
||||
/* Since the whole area of this tile hasn't been recorded,
|
||||
|
|
|
|||
|
|
@ -1811,7 +1811,7 @@ dbReadLabels(cellDef, line, len, f, scalen, scaled)
|
|||
TxError("Skipping bad \"port\" line: %s", line);
|
||||
goto nextlabel;
|
||||
}
|
||||
lab->lab_flags &= ~LABEL_STICKY;
|
||||
/* lab->lab_flags &= ~LABEL_STICKY; */
|
||||
lab->lab_flags |= idx;
|
||||
for (pptr = &ppos[0]; *pptr != '\0'; pptr++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -592,9 +592,10 @@ DBTechPrintTypes(mask, dolist)
|
|||
*/
|
||||
|
||||
PlaneMask
|
||||
DBTechNoisyNameMask(layers, mask)
|
||||
DBTechNameMask0(layers, mask, noisy)
|
||||
char *layers; /* String to be parsed. */
|
||||
TileTypeBitMask *mask; /* Where to store the layer mask. */
|
||||
bool noisy; /* Whether or not to output errors */
|
||||
{
|
||||
char *p, *p2, c;
|
||||
TileTypeBitMask m2; /* Each time around the loop, we will
|
||||
|
|
@ -652,7 +653,7 @@ DBTechNoisyNameMask(layers, mask)
|
|||
}
|
||||
save = *p2;
|
||||
*p2 = 0;
|
||||
planemask |= DBTechNoisyNameMask(p, &m2);
|
||||
planemask |= DBTechNameMask0(p, &m2, noisy);
|
||||
*p2 = save;
|
||||
if (save == ')') p = p2 + 1;
|
||||
else p = p2;
|
||||
|
|
@ -700,7 +701,10 @@ DBTechNoisyNameMask(layers, mask)
|
|||
p++;
|
||||
}
|
||||
|
||||
t = DBTechNoisyNameType(p);
|
||||
if (noisy)
|
||||
t = DBTechNoisyNameType(p);
|
||||
else
|
||||
t = DBTechNameType(p);
|
||||
if (t >= 0)
|
||||
m2 = DBLayerTypeMaskTbl[t];
|
||||
|
||||
|
|
@ -743,7 +747,10 @@ DBTechNoisyNameMask(layers, mask)
|
|||
while ((*p2 != 0) && (*p2 != ',')) p2 += 1;
|
||||
save = *p2;
|
||||
*p2 = 0;
|
||||
plane = DBTechNoisyNamePlane(p+1);
|
||||
if (noisy)
|
||||
plane = DBTechNoisyNamePlane(p+1);
|
||||
else
|
||||
plane = DBTechNamePlane(p+1);
|
||||
*p2 = save;
|
||||
p = p2;
|
||||
if (plane > 0)
|
||||
|
|
@ -775,3 +782,20 @@ DBTechNoisyNameMask(layers, mask)
|
|||
return planemask;
|
||||
}
|
||||
|
||||
/* Wrappers for DBTechNameMask0() */
|
||||
|
||||
PlaneMask
|
||||
DBTechNoisyNameMask(layers, mask)
|
||||
char *layers; /* String to be parsed. */
|
||||
TileTypeBitMask *mask; /* Where to store the layer mask. */
|
||||
{
|
||||
return DBTechNameMask0(layers, mask, TRUE);
|
||||
}
|
||||
|
||||
PlaneMask
|
||||
DBTechNameMask(layers, mask)
|
||||
char *layers; /* String to be parsed. */
|
||||
TileTypeBitMask *mask; /* Where to store the layer mask. */
|
||||
{
|
||||
return DBTechNameMask0(layers, mask, FALSE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,9 +147,12 @@ DBFixMismatch()
|
|||
* the uses.
|
||||
*/
|
||||
|
||||
cellDef->cd_bbox.r_xtop = cellDef->cd_bbox.r_xbot - 1;
|
||||
cellDef->cd_extended.r_xtop = cellDef->cd_extended.r_xbot - 1;
|
||||
DBReComputeBbox(cellDef);
|
||||
if (!(cellDef->cd_flags & CDFIXEDBBOX))
|
||||
{
|
||||
cellDef->cd_bbox.r_xtop = cellDef->cd_bbox.r_xbot - 1;
|
||||
cellDef->cd_extended.r_xtop = cellDef->cd_extended.r_xbot - 1;
|
||||
DBReComputeBbox(cellDef);
|
||||
}
|
||||
|
||||
/* Now, for each parent, recheck the parent in both the
|
||||
* old area of the child and the new area.
|
||||
|
|
|
|||
|
|
@ -519,6 +519,7 @@ typedef struct celluse
|
|||
#define CU_DESCEND_NO_SUBCKT 0x0005 /* Descend no subcircuits */
|
||||
#define CU_DESCEND_NO_VENDOR 0x0006 /* Descend no vendor-GDS subcells */
|
||||
#define CU_DESCEND_NO_LOCK 0x0007 /* Descend unlocked subcells only */
|
||||
#define CU_DESCEND_NONE 0x0009 /* Descend no subcells */
|
||||
|
||||
/*
|
||||
* All subcells used by a cell are part of another tile plane,
|
||||
|
|
@ -635,6 +636,11 @@ typedef struct treeFilter
|
|||
* of paint to which the label is
|
||||
* attached
|
||||
*/
|
||||
#define TF_LABEL_ATTACH_NOT_NE 0x04 /* Same as above, ignore tile NE corner */
|
||||
#define TF_LABEL_ATTACH_NOT_NW 0x08 /* Same as above, ignore tile NW corner */
|
||||
#define TF_LABEL_ATTACH_NOT_SE 0x10 /* Same as above, ignore tile SE corner */
|
||||
#define TF_LABEL_ATTACH_NOT_SW 0x20 /* Same as above, ignore tile SW corner */
|
||||
#define TF_LABEL_ATTACH_CORNER 0x3C /* Mask of the four types above */
|
||||
|
||||
/* -------------- Undo information passed to DBPaintPlane ------------- */
|
||||
|
||||
|
|
@ -729,7 +735,7 @@ extern bool DBTechAddContact();
|
|||
extern bool DBTechAddCompose();
|
||||
extern TileType DBTechNameType(), DBTechNoisyNameType();
|
||||
extern int DBTechNamePlane(), DBTechNoisyNamePlane();
|
||||
extern PlaneMask DBTechNoisyNameMask();
|
||||
extern PlaneMask DBTechNameMask(), DBTechNoisyNameMask();
|
||||
extern PlaneMask DBTechTypesToPlanes();
|
||||
extern bool DBTechTypesOnPlane();
|
||||
extern void DBTechInitPlane();
|
||||
|
|
|
|||
16
defs.mak
16
defs.mak
|
|
@ -50,7 +50,7 @@ AR = ar
|
|||
ARFLAGS = crv
|
||||
LINK = ld -r
|
||||
LD = /bin/ld
|
||||
M4 = /bin/m4
|
||||
M4 = @M4@
|
||||
RANLIB = ranlib
|
||||
SHDLIB_EXT = .so
|
||||
LDDL_FLAGS = ${LDFLAGS} -shared -Wl,-soname,$@ -Wl,--version-script=${MAGICDIR}/magic/symbol.map
|
||||
|
|
@ -58,15 +58,15 @@ LD_RUN_PATH =
|
|||
LIB_SPECS = -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6
|
||||
WISH_EXE = /usr/bin/wish
|
||||
TCL_LIB_DIR = /usr/lib
|
||||
MAGIC_VERSION = 8.1
|
||||
MAGIC_REVISION = 151
|
||||
MAGIC_VERSION = 8.2
|
||||
MAGIC_REVISION = 0
|
||||
|
||||
CC = gcc
|
||||
CPP = gcc -E -x c
|
||||
CPP = /scripts/preproc.py
|
||||
CXX = g++
|
||||
|
||||
CPPFLAGS = -I. -I${MAGICDIR}
|
||||
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.1\" -DMAGIC_REVISION=\"151\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DX11_BACKING_STORE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DNDEBUG -DGCORE=\"/bin/gcore\"
|
||||
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"0\" -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DX11_BACKING_STORE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DNDEBUG -DGCORE=\"/bin/gcore\"
|
||||
DFLAGS += -DSHDLIB_EXT=\".so\"
|
||||
CFLAGS = -g -m64 -fPIC -Wimplicit-int -fPIC
|
||||
|
||||
|
|
@ -78,9 +78,9 @@ DEPEND_FLAG = -MM
|
|||
EXEEXT =
|
||||
|
||||
GR_CFLAGS =
|
||||
GR_DFLAGS = -DX11 -DXLIB -DOGL -DNDEBUG
|
||||
GR_LIBS = -lX11 -lGL -lGLU -lXi -lXmu -lXext -lm -lstdc++ ${X11_LDFLAGS}
|
||||
GR_SRCS = ${TK_SRCS} ${TOGL_SRCS} ${TKCOMMON_SRCS}
|
||||
GR_DFLAGS = -DX11 -DXLIB -DOGL -DCAIRO -DNDEBUG
|
||||
GR_LIBS = -lX11 -lGL -lGLU -lXi -lXmu -lXext -lm -lcairo -lfontconfig -lfreetype -lstdc++ ${X11_LDFLAGS}
|
||||
GR_SRCS = ${TK_SRCS} ${TOGL_SRCS} ${TOGL_SRCS} ${TKCOMMON_SRCS}
|
||||
GR_HELPER_SRCS =
|
||||
GR_HELPER_PROG =
|
||||
|
||||
|
|
|
|||
|
|
@ -1073,7 +1073,7 @@ drcExtend(argc, argv)
|
|||
DRCCookie *dp, *dpnew, *dptrig;
|
||||
TileType i, j;
|
||||
int plane, plane2;
|
||||
TileTypeBitMask set2, setZ, setN;
|
||||
TileTypeBitMask set2, setZ, setN, setM;
|
||||
PlaneMask pMask1, pMask2, pset, ptest;
|
||||
bool exact = FALSE;
|
||||
|
||||
|
|
@ -1094,7 +1094,6 @@ drcExtend(argc, argv)
|
|||
"the same plane\n");
|
||||
return (0);
|
||||
}
|
||||
TTMaskCom2(&setN, &set1);
|
||||
|
||||
ptest = DBTechNoisyNameMask(layers2, &set2);
|
||||
pMask2 = CoincidentPlanes(&set2, ptest);
|
||||
|
|
@ -1105,6 +1104,13 @@ drcExtend(argc, argv)
|
|||
"the same plane\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* setM is the union of set1 and set2 */
|
||||
TTMaskZero(&setM);
|
||||
TTMaskSetMask3(&setM, &set1, &set2);
|
||||
|
||||
/* setN is the inverse of set1, and setC is the inverse of set2 */
|
||||
TTMaskCom2(&setN, &set1);
|
||||
TTMaskCom2(&setC, &set2);
|
||||
|
||||
/* Zero mask */
|
||||
|
|
@ -1130,14 +1136,14 @@ drcExtend(argc, argv)
|
|||
/* find bucket preceding the new one we wish to insert */
|
||||
dp = drcFindBucket(i, j, distance);
|
||||
dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie));
|
||||
drcAssign(dpnew, distance, dp->drcc_next, &set1, &setZ, why,
|
||||
drcAssign(dpnew, distance, dp->drcc_next, &setM, &setZ, why,
|
||||
0, DRC_FORWARD, plane, plane);
|
||||
|
||||
dp->drcc_next = dpnew;
|
||||
|
||||
dp = drcFindBucket(j, i, distance);
|
||||
dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie));
|
||||
drcAssign(dpnew, distance, dp->drcc_next, &set1, &setZ, why,
|
||||
drcAssign(dpnew, distance, dp->drcc_next, &setM, &setZ, why,
|
||||
0, DRC_REVERSE, plane, plane);
|
||||
|
||||
dp->drcc_next = dpnew;
|
||||
|
|
@ -1171,7 +1177,7 @@ drcExtend(argc, argv)
|
|||
/* find bucket preceding the new one we wish to insert */
|
||||
dp = drcFindBucket(i, j, distance);
|
||||
dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie));
|
||||
drcAssign(dpnew, distance, dp->drcc_next, &set1, &setZ, why,
|
||||
drcAssign(dpnew, distance, dp->drcc_next, &setM, &setZ, why,
|
||||
0, DRC_FORWARD, plane2, plane);
|
||||
dptrig = (DRCCookie *)mallocMagic(sizeof(DRCCookie));
|
||||
drcAssign(dptrig, 1, dpnew, &setN, &setZ, why,
|
||||
|
|
@ -1180,7 +1186,7 @@ drcExtend(argc, argv)
|
|||
|
||||
dp = drcFindBucket(j, i, distance);
|
||||
dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie));
|
||||
drcAssign(dpnew, distance, dp->drcc_next, &set1, &setZ, why,
|
||||
drcAssign(dpnew, distance, dp->drcc_next, &setM, &setZ, why,
|
||||
0, DRC_REVERSE, plane2, plane);
|
||||
dptrig = (DRCCookie *)mallocMagic(sizeof(DRCCookie));
|
||||
drcAssign(dptrig, 1, dpnew, &setN, &setZ, why,
|
||||
|
|
|
|||
|
|
@ -399,16 +399,29 @@ subcktHierVisit(use, hierName, is_top)
|
|||
{
|
||||
Def *def = use->use_def;
|
||||
EFNode *snode;
|
||||
EFNodeName *nodeName;
|
||||
bool hasports = FALSE;
|
||||
|
||||
/* Avoid generating records for circuits that have no ports. */
|
||||
/* These are already absorbed into the parent. All other */
|
||||
/* subcircuits have at least one port marked by the EF_PORT flag. */
|
||||
/* Do not count the substrate port, as it exists even on cells */
|
||||
/* with no other ports. */
|
||||
|
||||
for (snode = (EFNode *) def->def_firstn.efnode_next;
|
||||
snode != &def->def_firstn;
|
||||
snode = (EFNode *) snode->efnode_next)
|
||||
if (snode->efnode_flags & (EF_PORT | EF_SUBS_PORT))
|
||||
if (snode->efnode_flags & EF_PORT)
|
||||
{
|
||||
for (nodeName = snode->efnode_name; nodeName != NULL;
|
||||
nodeName = nodeName->efnn_next)
|
||||
if (nodeName->efnn_port >= 0)
|
||||
{
|
||||
hasports = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (snode->efnode_flags & EF_SUBS_PORT)
|
||||
{
|
||||
hasports = TRUE;
|
||||
break;
|
||||
|
|
@ -1714,6 +1727,7 @@ esHierVisit(hc, cdata)
|
|||
DefFlagsData *dfd;
|
||||
int flags;
|
||||
int locDoSubckt = esDoSubckt;
|
||||
bool doStub;
|
||||
|
||||
dfd = (DefFlagsData *)cdata;
|
||||
topdef = dfd->def;
|
||||
|
|
@ -1756,57 +1770,69 @@ esHierVisit(hc, cdata)
|
|||
hcf = EFFlatBuildOneLevel(hc->hc_use->use_def, flags);
|
||||
|
||||
/* If definition has been marked as having no devices, then this */
|
||||
/* def is not to be output unless it is the top level. */
|
||||
/* def is not to be output unless it is the top level. However, if */
|
||||
/* this subcircuit is an abstract view, then create a subcircuit */
|
||||
/* stub entry for it (declares port names and order but no devices) */
|
||||
|
||||
if ((def != topdef) && (hc->hc_use->use_def->def_flags & DEF_NODEVICES))
|
||||
doStub = ((hc->hc_use->use_def->def_flags & DEF_ABSTRACT) && esDoBlackBox) ?
|
||||
TRUE : FALSE;
|
||||
|
||||
if ((def != topdef) && (hc->hc_use->use_def->def_flags & DEF_NODEVICES) &&
|
||||
(!doStub))
|
||||
{
|
||||
EFFlatDone();
|
||||
return 0;
|
||||
}
|
||||
else if (doStub)
|
||||
fprintf(esSpiceF, "* Black-box entry subcircuit for %s abstract view\n",
|
||||
def->def_name);
|
||||
|
||||
/* Generate subcircuit header */
|
||||
if ((def != topdef) || (def->def_flags & DEF_SUBCIRCUIT))
|
||||
topVisit(def);
|
||||
topVisit(def, doStub);
|
||||
else
|
||||
fprintf(esSpiceF, "\n* Top level circuit %s\n\n", topdef->def_name);
|
||||
|
||||
/* Output subcircuit calls */
|
||||
EFHierVisitSubcircuits(hcf, subcktHierVisit, (ClientData)NULL);
|
||||
|
||||
/* Merge devices */
|
||||
if (esMergeDevsA || esMergeDevsC)
|
||||
if (!doStub) /* By definition, stubs have no internal components */
|
||||
{
|
||||
devMerge *p;
|
||||
/* Output subcircuit calls */
|
||||
EFHierVisitSubcircuits(hcf, subcktHierVisit, (ClientData)NULL);
|
||||
|
||||
EFHierVisitDevs(hcf, spcdevHierMergeVisit, (ClientData)NULL);
|
||||
TxPrintf("Devs merged: %d\n", esSpiceDevsMerged);
|
||||
esFMIndex = 0;
|
||||
for (p = devMergeList; p != NULL; p = p->next)
|
||||
freeMagic(p);
|
||||
devMergeList = NULL;
|
||||
}
|
||||
/* Merge devices */
|
||||
if (esMergeDevsA || esMergeDevsC)
|
||||
{
|
||||
devMerge *p;
|
||||
|
||||
/* Output devices */
|
||||
EFHierVisitDevs(hcf, spcdevHierVisit, (ClientData)NULL);
|
||||
EFHierVisitDevs(hcf, spcdevHierMergeVisit, (ClientData)NULL);
|
||||
TxPrintf("Devs merged: %d\n", esSpiceDevsMerged);
|
||||
esFMIndex = 0;
|
||||
for (p = devMergeList; p != NULL; p = p->next)
|
||||
freeMagic(p);
|
||||
devMergeList = NULL;
|
||||
}
|
||||
|
||||
/* Output lumped parasitic resistors */
|
||||
EFHierVisitResists(hcf, spcresistHierVisit, (ClientData)NULL);
|
||||
/* Output devices */
|
||||
EFHierVisitDevs(hcf, spcdevHierVisit, (ClientData)NULL);
|
||||
|
||||
/* Output coupling capacitances */
|
||||
sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n", esCapAccuracy);
|
||||
EFHierVisitCaps(hcf, spccapHierVisit, (ClientData)NULL);
|
||||
/* Output lumped parasitic resistors */
|
||||
EFHierVisitResists(hcf, spcresistHierVisit, (ClientData)NULL);
|
||||
|
||||
if (EFCompat == FALSE)
|
||||
{
|
||||
/* Find the substrate node */
|
||||
EFHierVisitNodes(hcf, spcsubHierVisit, (ClientData)&resstr);
|
||||
if (resstr == NULL) resstr = StrDup((char **)NULL, "0");
|
||||
/* Output coupling capacitances */
|
||||
sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n", esCapAccuracy);
|
||||
EFHierVisitCaps(hcf, spccapHierVisit, (ClientData)NULL);
|
||||
|
||||
/* Output lumped capacitance and resistance to substrate */
|
||||
sprintf( esSpiceCapFormat, "C%%d %%s %s %%.%dlffF%%s\n",
|
||||
if (EFCompat == FALSE)
|
||||
{
|
||||
/* Find the substrate node */
|
||||
EFHierVisitNodes(hcf, spcsubHierVisit, (ClientData)&resstr);
|
||||
if (resstr == NULL) resstr = StrDup((char **)NULL, "0");
|
||||
|
||||
/* Output lumped capacitance and resistance to substrate */
|
||||
sprintf( esSpiceCapFormat, "C%%d %%s %s %%.%dlffF%%s\n",
|
||||
resstr, esCapAccuracy);
|
||||
EFHierVisitNodes(hcf, spcnodeHierVisit, (ClientData) NULL);
|
||||
freeMagic(resstr);
|
||||
EFHierVisitNodes(hcf, spcnodeHierVisit, (ClientData) NULL);
|
||||
freeMagic(resstr);
|
||||
}
|
||||
}
|
||||
|
||||
if ((def != topdef) || (def->def_flags & DEF_SUBCIRCUIT))
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
bool esDoExtResis = FALSE;
|
||||
bool esDoPorts = TRUE;
|
||||
bool esDoHierarchy = FALSE;
|
||||
bool esDoBlackBox = FALSE;
|
||||
bool esDoRenumber = FALSE;
|
||||
bool esDoResistorTee = FALSE;
|
||||
int esDoSubckt = AUTO;
|
||||
|
|
@ -207,9 +208,10 @@ Exttospice_Init(interp)
|
|||
#define EXTTOSPC_SCALE 8
|
||||
#define EXTTOSPC_SUBCIRCUITS 9
|
||||
#define EXTTOSPC_HIERARCHY 10
|
||||
#define EXTTOSPC_RENUMBER 11
|
||||
#define EXTTOSPC_MERGENAMES 12
|
||||
#define EXTTOSPC_HELP 13
|
||||
#define EXTTOSPC_BLACKBOX 11
|
||||
#define EXTTOSPC_RENUMBER 12
|
||||
#define EXTTOSPC_MERGENAMES 13
|
||||
#define EXTTOSPC_HELP 14
|
||||
|
||||
void
|
||||
CmdExtToSpice(w, cmd)
|
||||
|
|
@ -256,6 +258,7 @@ CmdExtToSpice(w, cmd)
|
|||
"scale [on|off] use .option card for scaling",
|
||||
"subcircuits [on|off] standard cells become subcircuit calls",
|
||||
"hierarchy [on|off] output hierarchical spice for LVS",
|
||||
"blackbox [on|off] output abstract views as black-box entries",
|
||||
"renumber [on|off] on = number instances X1, X2, etc.\n"
|
||||
" off = keep instance ID names",
|
||||
"global [on|off] on = merge unconnected global nets by name",
|
||||
|
|
@ -373,6 +376,20 @@ CmdExtToSpice(w, cmd)
|
|||
esDoHierarchy = FALSE;
|
||||
break;
|
||||
|
||||
case EXTTOSPC_BLACKBOX:
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
Tcl_SetResult(magicinterp, (esDoBlackBox) ? "on" : "off", NULL);
|
||||
return;
|
||||
}
|
||||
idx = Lookup(cmd->tx_argv[2], yesno);
|
||||
if (idx < 0) goto usage;
|
||||
else if (idx < 3) /* yes */
|
||||
esDoBlackBox = TRUE;
|
||||
else /* no */
|
||||
esDoBlackBox = FALSE;
|
||||
break;
|
||||
|
||||
case EXTTOSPC_RENUMBER:
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
|
|
@ -828,7 +845,13 @@ runexttospice:
|
|||
locDoSubckt = FALSE;
|
||||
if (esDoHierarchy)
|
||||
{
|
||||
if ((esDoSubckt == TRUE) || (locDoSubckt == TRUE))
|
||||
topVisit(efFlatRootDef, FALSE);
|
||||
|
||||
ESGenerateHierarchy(inName, flatFlags);
|
||||
|
||||
if ((esDoSubckt == TRUE) || (locDoSubckt == TRUE))
|
||||
fprintf(esSpiceF, ".ends\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -840,7 +863,7 @@ runexttospice:
|
|||
locDoSubckt = TRUE;
|
||||
}
|
||||
if ((esDoSubckt == TRUE) || (locDoSubckt == TRUE))
|
||||
topVisit(efFlatRootDef);
|
||||
topVisit(efFlatRootDef, FALSE);
|
||||
|
||||
/* When generating subcircuits, remove the subcircuit */
|
||||
/* flag from the top level cell. Other than being */
|
||||
|
|
@ -1016,7 +1039,7 @@ main(argc, argv)
|
|||
locDoSubckt = TRUE;
|
||||
}
|
||||
if ((esDoSubckt == TRUE) || (locDoSubckt == TRUE))
|
||||
topVisit(efFlatRootDef);
|
||||
topVisit(efFlatRootDef, FALSE);
|
||||
|
||||
/* If we don't want to write subcircuit calls, remove the */
|
||||
/* subcircuit flag from all cells at this time. */
|
||||
|
|
@ -1466,6 +1489,14 @@ subcktVisit(use, hierName, is_top)
|
|||
}
|
||||
}
|
||||
|
||||
/* SPICE subcircuit names must begin with A-Z. This will also be */
|
||||
/* enforced when writing X subcircuit calls. */
|
||||
subcktname = def->def_name;
|
||||
while (!isalpha(*subcktname)) subcktname++;
|
||||
|
||||
if (tchars > 80) fprintf(esSpiceF, "\n+");
|
||||
fprintf(esSpiceF, " %s", subcktname); /* subcircuit model name */
|
||||
|
||||
// Check for a "device parameter" defined with the name of the cell.
|
||||
// This contains a list of parameter strings to be passed to the
|
||||
// cell instance.
|
||||
|
|
@ -1484,14 +1515,7 @@ subcktVisit(use, hierName, is_top)
|
|||
tchars += (1 + strlen(pptr->parm_name));
|
||||
}
|
||||
freeMagic(instname);
|
||||
|
||||
/* SPICE subcircuit names must begin with A-Z. This will also be */
|
||||
/* enforced when writing X subcircuit calls. */
|
||||
subcktname = def->def_name;
|
||||
while (!isalpha(*subcktname)) subcktname++;
|
||||
|
||||
if (tchars > 80) fprintf(esSpiceF, "\n+");
|
||||
fprintf(esSpiceF, " %s\n", subcktname); /* subcircuit model name */
|
||||
fprintf(esSpiceF, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1542,14 +1566,18 @@ subcktUndef(use, hierName, is_top)
|
|||
*
|
||||
* where
|
||||
* node1 node2 ... noden are the nodes connecting to the ports of
|
||||
* the subcircuit. "name" is the name of the cell def.
|
||||
* the subcircuit. "name" is the name of the cell def. If "doStub"
|
||||
* is TRUE, then the subcircuit is a stub (empty declaration) for a
|
||||
* subcircuit, and implicit substrate connections should not be
|
||||
* output.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
topVisit(def)
|
||||
topVisit(def, doStub)
|
||||
Def *def;
|
||||
bool doStub;
|
||||
{
|
||||
EFNode *snode;
|
||||
EFNodeName *sname, *nodeName;
|
||||
|
|
@ -1660,8 +1688,14 @@ topVisit(def)
|
|||
if (nodeName != NULL)
|
||||
break;
|
||||
else if (portidx < 0)
|
||||
// Node has not been assigned a port number
|
||||
unnumbered->efnn_port = ++portmax;
|
||||
{
|
||||
// Node has not been assigned a port number.
|
||||
// Give it one unless this is a black-box circuit
|
||||
// and "ext2spice blackbox on" is in effect.
|
||||
|
||||
if (esDoBlackBox == FALSE || !(def->def_flags & DEF_ABSTRACT))
|
||||
unnumbered->efnn_port = ++portmax;
|
||||
}
|
||||
}
|
||||
portorder++;
|
||||
}
|
||||
|
|
@ -1669,30 +1703,33 @@ topVisit(def)
|
|||
|
||||
/* Add all implicitly-defined local substrate node names */
|
||||
|
||||
HashStartSearch(&hs);
|
||||
while (he = HashNext(&def->def_nodes, &hs))
|
||||
if (!doStub)
|
||||
{
|
||||
sname = (EFNodeName *) HashGetValue(he);
|
||||
if (sname == NULL) continue;
|
||||
snode = sname->efnn_node;
|
||||
|
||||
if (snode->efnode_flags & EF_SUBS_PORT)
|
||||
HashStartSearch(&hs);
|
||||
while (he = HashNext(&def->def_nodes, &hs))
|
||||
{
|
||||
if (snode->efnode_name->efnn_port < 0)
|
||||
{
|
||||
char stmp[MAX_STR_SIZE];
|
||||
sname = (EFNodeName *) HashGetValue(he);
|
||||
if (sname == NULL) continue;
|
||||
snode = sname->efnn_node;
|
||||
|
||||
if (tchars > 80)
|
||||
if (snode->efnode_flags & EF_SUBS_PORT)
|
||||
{
|
||||
if (snode->efnode_name->efnn_port < 0)
|
||||
{
|
||||
/* Line continuation */
|
||||
fprintf(esSpiceF, "\n+");
|
||||
tchars = 1;
|
||||
char stmp[MAX_STR_SIZE];
|
||||
|
||||
if (tchars > 80)
|
||||
{
|
||||
/* Line continuation */
|
||||
fprintf(esSpiceF, "\n+");
|
||||
tchars = 1;
|
||||
}
|
||||
/* This is not a hierarchical name or node! */
|
||||
EFHNSprintf(stmp, snode->efnode_name->efnn_hier);
|
||||
fprintf(esSpiceF, " %s", stmp);
|
||||
snode->efnode_name->efnn_port = portorder++;
|
||||
tchars += strlen(stmp) + 1;
|
||||
}
|
||||
/* This is not a hierarchical name or node! */
|
||||
EFHNSprintf(stmp, snode->efnode_name->efnn_hier);
|
||||
fprintf(esSpiceF, " %s", stmp);
|
||||
snode->efnode_name->efnn_port = portorder++;
|
||||
tchars += strlen(stmp) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ extern bool extHierSDAttr();
|
|||
extern bool esDoExtResis;
|
||||
extern bool esDoPorts;
|
||||
extern bool esDoHierarchy;
|
||||
extern bool esDoBlackBox;
|
||||
extern bool esDoResistorTee;
|
||||
extern int esDoSubckt;
|
||||
extern bool esDevNodesOnly;
|
||||
|
|
|
|||
|
|
@ -387,7 +387,11 @@ efFlatNodesDeviceless(hc, cdata)
|
|||
/* Mark this definition as having no devices, so it will not be visited */
|
||||
hc->hc_use->use_def->def_flags |= DEF_NODEVICES;
|
||||
|
||||
(*usecount)--;
|
||||
/* If this definition has no devices but has ports, then it is treated */
|
||||
/* as a black-box device, so don't decrement the use count of the */
|
||||
/* parent. */
|
||||
if (!(hc->hc_use->use_def->def_flags & DEF_SUBCIRCUIT))
|
||||
(*usecount)--;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ typedef struct def
|
|||
#define DEF_PROCESSED 0x04 /* This def processed in hierarchical output */
|
||||
#define DEF_NODEVICES 0x08 /* This def contains no devices */
|
||||
#define DEF_SUBSNODES 0x10 /* This def contains implicit substrate nodes */
|
||||
#define DEF_ABSTRACT 0x20 /* This def is an abstract view (e.g., LEF) */
|
||||
|
||||
/*
|
||||
* Every Def has a NULL-terminated list of uses that correspond
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ char *extDevTable[] = {"fet", "mosfet", "asymmetric", "bjt", "devres",
|
|||
*/
|
||||
typedef enum
|
||||
{
|
||||
ADJUST, ATTR, CAP, DEVICE, DIST, EQUIV, FET, KILLNODE, MERGE, NODE,
|
||||
PARAMETERS, PORT, RESISTOR, RESISTCLASS, RNODE, SCALE, SUBCAP,
|
||||
ABSTRACT, ADJUST, ATTR, CAP, DEVICE, DIST, EQUIV, FET, KILLNODE, MERGE,
|
||||
NODE, PARAMETERS, PORT, RESISTOR, RESISTCLASS, RNODE, SCALE, SUBCAP,
|
||||
SUBSTRATE, TECH, TIMESTAMP, USE, VERSION, EXT_STYLE
|
||||
} Key;
|
||||
|
||||
|
|
@ -66,6 +66,7 @@ static struct
|
|||
}
|
||||
keyTable[] =
|
||||
{
|
||||
"abstract", ABSTRACT, 0, /* defines a LEF-like view */
|
||||
"adjust", ADJUST, 4,
|
||||
"attr", ATTR, 8,
|
||||
"cap", CAP, 4,
|
||||
|
|
@ -404,9 +405,9 @@ readfile:
|
|||
{
|
||||
DoResist = FALSE;
|
||||
def->def_flags |= DEF_SUBCIRCUIT;
|
||||
efBuildPortNode(def, argv[1], atoi(argv[2]), atoi(argv[3]),
|
||||
atoi(argv[4]), argv[7]);
|
||||
}
|
||||
efBuildPortNode(def, argv[1], atoi(argv[2]), atoi(argv[3]),
|
||||
atoi(argv[4]), argv[7]);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
|
@ -555,6 +556,11 @@ resistChanged:
|
|||
efBuildResistor(def, argv[1], argv[2], rscale*atoi(argv[3]));
|
||||
break;
|
||||
|
||||
/* abstract (no options/arguments) */
|
||||
case ABSTRACT:
|
||||
def->def_flags |= DEF_ABSTRACT;
|
||||
break;
|
||||
|
||||
/* To-do: compare timestamp against the cell */
|
||||
case TIMESTAMP:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -147,6 +147,18 @@ void extTransBad();
|
|||
|
||||
bool extLabType();
|
||||
|
||||
/* Function returns 1 if a tile is found by DBTreeSrTiles() */
|
||||
/* that is not in the topmost def of the search. */
|
||||
|
||||
int
|
||||
extFoundFunc(tile, cxp)
|
||||
Tile *tile;
|
||||
TreeContext *cxp;
|
||||
{
|
||||
CellDef *def = (CellDef *)cxp->tc_filter->tf_arg;
|
||||
return (def == cxp->tc_scx->scx_use->cu_def) ? 0 : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -187,10 +199,11 @@ extBasic(def, outFile)
|
|||
{
|
||||
NodeRegion *nodeList, *extFindNodes();
|
||||
bool coupleInitialized = FALSE;
|
||||
TransRegion *transList;
|
||||
TransRegion *transList, *reg;
|
||||
HashTable extCoupleHash;
|
||||
char *propptr;
|
||||
bool propfound = FALSE;
|
||||
bool isabstract = FALSE;
|
||||
|
||||
glob_subsnode = (NodeRegion *)NULL;
|
||||
|
||||
|
|
@ -206,6 +219,33 @@ extBasic(def, outFile)
|
|||
extUnInit, extTransFirst, extTransEach);
|
||||
ExtResetTiles(def, extUnInit);
|
||||
|
||||
for (reg = transList; reg && !SigInterruptPending; reg = reg->treg_next)
|
||||
{
|
||||
/* For each transistor region, check if there is an equivalent */
|
||||
/* region at the same location in a subcell. The device in the */
|
||||
/* subcell is given priority. This avoids duplicating devices */
|
||||
/* when, for example, a device contact is placed in another */
|
||||
/* cell, which can happen for devices like capacitors and */
|
||||
/* diodes, where the device identifier layer may include */
|
||||
/* a contact type. */
|
||||
|
||||
SearchContext scontext;
|
||||
CellUse dummy;
|
||||
int extFoundFunc();
|
||||
|
||||
scontext.scx_use = &dummy;
|
||||
dummy.cu_def = def;
|
||||
dummy.cu_id = NULL;
|
||||
scontext.scx_trans = GeoIdentityTransform;
|
||||
scontext.scx_area.r_ll = scontext.scx_area.r_ur = reg->treg_tile->ti_ll;
|
||||
scontext.scx_area.r_ur.p_x++;
|
||||
scontext.scx_area.r_ur.p_y++;
|
||||
|
||||
if (DBTreeSrTiles(&scontext, &ExtCurStyle->exts_transMask, 0,
|
||||
extFoundFunc, (ClientData)def) != 0)
|
||||
reg->treg_type = TT_SPACE; /* Disables the trans record */
|
||||
}
|
||||
|
||||
/*
|
||||
* Build up a list of the electrical nodes (equipotentials)
|
||||
* for extOutputNodes() below. For this, we definitely want
|
||||
|
|
@ -266,6 +306,12 @@ extBasic(def, outFile)
|
|||
}
|
||||
}
|
||||
|
||||
/* Check for "LEFview", for which special output handling */
|
||||
/* can be specified in ext2spice. */
|
||||
|
||||
DBPropGet(def, "LEFview", &isabstract);
|
||||
if (isabstract) fprintf(outFile, "abstract\n");
|
||||
|
||||
/* Output each node, along with its resistance and capacitance to substrate */
|
||||
if (!SigInterruptPending)
|
||||
extOutputNodes(nodeList, outFile);
|
||||
|
|
@ -1388,6 +1434,8 @@ extOutputParameters(def, transList, outFile)
|
|||
{
|
||||
TileType loctype = reg->treg_type;
|
||||
|
||||
if (loctype == TT_SPACE) continue; /* This has been disabled */
|
||||
|
||||
/* Watch for rare split reg->treg_type */
|
||||
if (loctype & TT_DIAGONAL)
|
||||
loctype = (reg->treg_type & TT_SIDE) ? ((reg->treg_type &
|
||||
|
|
@ -1602,6 +1650,8 @@ extOutputDevices(def, transList, outFile)
|
|||
|
||||
for (reg = transList; reg && !SigInterruptPending; reg = reg->treg_next)
|
||||
{
|
||||
if (reg->treg_type == TT_SPACE) continue; /* This has been disabled */
|
||||
|
||||
/*
|
||||
* Visit all of the tiles in the transistor region, updating
|
||||
* extTransRec.tr_termnode[] and extTransRec.tr_termlen[],
|
||||
|
|
@ -1706,6 +1756,13 @@ extOutputDevices(def, transList, outFile)
|
|||
}
|
||||
if (ExtDoWarn & EXTWARN_FETS)
|
||||
extTransBad(def, reg->treg_tile, mesg);
|
||||
|
||||
/* Devices with no terminals or a null node are badly */
|
||||
/* formed and should not be output. This can happen when */
|
||||
/* parts of devices are split into different cells. */
|
||||
|
||||
if ((extTransRec.tr_nterm == 0) || (node == NULL))
|
||||
continue;
|
||||
}
|
||||
else if (extTransRec.tr_nterm > nsd)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ ExtTree *extSubList = (ExtTree *) NULL;
|
|||
/* Forward declarations of filter functions */
|
||||
char *extSubtreeTileToNode();
|
||||
int extSubtreeFunc();
|
||||
int extSubstrateFunc();
|
||||
int extConnFindFunc();
|
||||
int extSubtreeHardUseFunc();
|
||||
int extHardProc();
|
||||
|
|
@ -212,6 +213,17 @@ extSubtree(parentUse, reg, f)
|
|||
extSubtreeClippedArea += RECTAREA(&ha.ha_clipArea);
|
||||
extSubtreeInteraction(&ha);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make sure substrate connections have been handled */
|
||||
/* even if there were no other interactions found. */
|
||||
SearchContext scx;
|
||||
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
scx.scx_area = ha.ha_interArea;
|
||||
scx.scx_use = ha.ha_parentUse;
|
||||
DBCellSrArea(&scx, extSubstrateFunc, (ClientData)&ha);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* exactinteractions */
|
||||
|
|
@ -790,6 +802,63 @@ extSubtreeFunc(scx, ha)
|
|||
return (2);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* extSubstrateFunc
|
||||
*
|
||||
* This contains just the part of extSubtreeFunc() dealing with the
|
||||
* substrate, so that substrate extraction can occur in cells not
|
||||
* otherwise having extraction interactions, without incurring the
|
||||
* overhead of all the other items handled by extHierSubtreeFunc().
|
||||
*
|
||||
* Results:
|
||||
* Always returns 2, to avoid further elements in arrays.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
extSubstrateFunc(scx, ha)
|
||||
SearchContext *scx;
|
||||
HierExtractArg *ha;
|
||||
{
|
||||
CellUse *use = scx->scx_use;
|
||||
int x, y;
|
||||
|
||||
/* Record information for finding node names the hard way */
|
||||
ha->ha_subUse = use;
|
||||
ha->ha_subArea = use->cu_bbox;
|
||||
GEOCLIP(&ha->ha_subArea, &ha->ha_interArea);
|
||||
|
||||
/* Process substrate connection. All substrates should be */
|
||||
/* connected together in the cell def, so in the case of an */
|
||||
/* array, just make sure that the first array entry is */
|
||||
/* connected. */
|
||||
|
||||
if (use->cu_xhi == use->cu_xlo && use->cu_yhi == use->cu_ylo)
|
||||
extHierSubstrate(ha, use, -1, -1);
|
||||
else if (use->cu_xhi == use->cu_xlo && use->cu_yhi > use->cu_ylo)
|
||||
{
|
||||
for (y = use->cu_ylo; y <= use->cu_yhi; y++)
|
||||
extHierSubstrate(ha, use, -1, y);
|
||||
}
|
||||
else if (use->cu_xhi > use->cu_xlo && use->cu_yhi == use->cu_ylo)
|
||||
{
|
||||
for (x = use->cu_xlo; x <= use->cu_xhi; x++)
|
||||
extHierSubstrate(ha, use, x, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = use->cu_xlo; x <= use->cu_xhi; x++)
|
||||
for (y = use->cu_ylo; y <= use->cu_yhi; y++)
|
||||
extHierSubstrate(ha, use, x, y);
|
||||
}
|
||||
return (2);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ static keydesc devTable[] = {
|
|||
"rsubcircuit", DEV_RSUBCKT, 4, 7,
|
||||
"name dev-types terminal-types [sub-types|None sub-node] [options]",
|
||||
|
||||
"msubcircuit", DEV_MSUBCKT, 4, 11,
|
||||
"msubcircuit", DEV_MSUBCKT, 3, 11,
|
||||
"name dev-types [N] [term1-types ... termN-types [sub-types|None sub-node]] [options]",
|
||||
|
||||
0
|
||||
|
|
@ -2127,14 +2127,35 @@ ExtTechLine(sectionName, argc, argv)
|
|||
|
||||
case DEV_SUBCKT:
|
||||
case DEV_MSUBCKT:
|
||||
// Determine if [substrate, name] optional arguments
|
||||
// are present by checking if the last argument
|
||||
// parses as a layer list.
|
||||
|
||||
if (DBTechNameMask(argv[argc - 1], &termtypes[0]) <= 0)
|
||||
{
|
||||
if (strcmp(argv[argc - 2], "None"))
|
||||
DBTechNoisyNameMask(argv[argc - 2], &subsTypes);
|
||||
else
|
||||
subsTypes = DBZeroTypeBits;
|
||||
subsName = argv[argc - 1];
|
||||
argc -= 2;
|
||||
}
|
||||
|
||||
if (StrIsInt(argv[4]))
|
||||
{
|
||||
nterm = atoi(argv[4]);
|
||||
iterm = 4 + nterm;
|
||||
iterm = 5;
|
||||
if (nterm > argc - 5)
|
||||
{
|
||||
TechError("Not enough terminals for subcircuit, "
|
||||
"%d were required, %d found.\n",
|
||||
nterm, argc - 5);
|
||||
nterm = argc - 5;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nterm = 1;
|
||||
nterm = argc - 4;
|
||||
iterm = 4;
|
||||
}
|
||||
|
||||
|
|
@ -2145,15 +2166,14 @@ ExtTechLine(sectionName, argc, argv)
|
|||
|
||||
if (nterm == 0) i++;
|
||||
|
||||
// Type MSUBCKT: Source and drain are symmetric. The
|
||||
// number of unique terminals in the definition is 1,
|
||||
// but nterm needs to be set to 2 for proper extraction.
|
||||
// Type MSUBCKT: If source and drain are symmetric (both
|
||||
// have the same types), then they must both be declared,
|
||||
// but only one is used (same policy as "device mosfet").
|
||||
|
||||
if ((dv->k_key == DEV_MSUBCKT) && (nterm == 1)) nterm = 2;
|
||||
if ((nterm == 2) && TTMaskEqual(&termtypes[nterm - 1],
|
||||
&termtypes[nterm - 2]))
|
||||
termtypes[nterm - 1] = DBZeroTypeBits;
|
||||
|
||||
if (argc > i)
|
||||
DBTechNoisyNameMask(argv[i], &subsTypes); /* substrate */
|
||||
if (argc > (i + 1)) subsName = argv[i + 1];
|
||||
break;
|
||||
|
||||
case DEV_RSUBCKT:
|
||||
|
|
|
|||
|
|
@ -689,6 +689,7 @@ DefReadPins(f, rootDef, sname, oscale, total)
|
|||
int keyword, subkey, values;
|
||||
int processed = 0;
|
||||
int pinDir = PORT_CLASS_DEFAULT;
|
||||
int pinNum = 0;
|
||||
TileType curlayer = -1;
|
||||
Rect *currect, topRect;
|
||||
Transform t;
|
||||
|
|
@ -807,8 +808,9 @@ DefReadPins(f, rootDef, sname, oscale, total)
|
|||
GeoTransRect(&t, currect, &topRect);
|
||||
DBPaint(rootDef, &topRect, curlayer);
|
||||
DBPutLabel(rootDef, &topRect, -1, pinname, curlayer,
|
||||
pinDir);
|
||||
pinNum | pinDir | PORT_DIR_MASK);
|
||||
pending = FALSE;
|
||||
pinNum++;
|
||||
}
|
||||
break;
|
||||
case DEF_PINS_PROP_FIXED:
|
||||
|
|
@ -821,7 +823,8 @@ DefReadPins(f, rootDef, sname, oscale, total)
|
|||
GeoTransRect(&t, currect, &topRect);
|
||||
DBPaint(rootDef, &topRect, curlayer);
|
||||
DBPutLabel(rootDef, &topRect, -1, pinname, curlayer,
|
||||
pinDir);
|
||||
pinNum | pinDir | PORT_DIR_MASK);
|
||||
pinNum++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1548,11 +1548,12 @@ defGetType(ttype, lefptr)
|
|||
while (he = HashNext(&LefInfo, &hs))
|
||||
{
|
||||
lefl = (lefLayer *)HashGetValue(he);
|
||||
if (lefl && (lefl->type == ttype) && (contact == lefl->lefClass))
|
||||
{
|
||||
if (lefptr) *lefptr = lefl;
|
||||
return lefl->canonName;
|
||||
}
|
||||
if (lefl && (contact == lefl->lefClass))
|
||||
if ((lefl->type == ttype) || (lefl->obsType == ttype))
|
||||
{
|
||||
if (lefptr) *lefptr = lefl;
|
||||
return lefl->canonName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
61
lef/lefCmd.c
61
lef/lefCmd.c
|
|
@ -61,7 +61,7 @@ CmdLef(w, cmd)
|
|||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
{
|
||||
int option;
|
||||
int option, i;
|
||||
char **msg, *namep;
|
||||
CellUse *selectedUse;
|
||||
CellDef *selectedDef;
|
||||
|
|
@ -79,12 +79,16 @@ CmdLef(w, cmd)
|
|||
* treat all geometry as "special"
|
||||
* nets in DEF format output.
|
||||
*/
|
||||
bool lefTech = FALSE; /* Indicates that technology info
|
||||
* will be output along with the
|
||||
* lef macro.
|
||||
*/
|
||||
|
||||
static char *cmdLefOption[] =
|
||||
{
|
||||
"read [filename] read a LEF file filename[.lef]\n"
|
||||
" read [filename] -import read a LEF file; import cells from .mag files",
|
||||
"write [cell] write LEF for current or indicated cell",
|
||||
"write [filename] [-tech] write LEF for current cell",
|
||||
"writeall write all cells including the top-level cell\n"
|
||||
" writeall -notop write all subcells of the top-level cell",
|
||||
"help print this help information",
|
||||
|
|
@ -167,31 +171,46 @@ CmdLef(w, cmd)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (cmd->tx_argc == 3)
|
||||
if (*(cmd->tx_argv[2]) == '-')
|
||||
if (!strncmp(cmd->tx_argv[2], "-notop", 6))
|
||||
lefTopCell = FALSE;
|
||||
|
||||
LefWriteAll(selectedUse, lefTopCell);
|
||||
}
|
||||
break;
|
||||
case LEF_WRITE:
|
||||
if (!is_lef)
|
||||
{
|
||||
allSpecial = FALSE;
|
||||
if (cmd->tx_argc == 4)
|
||||
for (i = 2; i < cmd->tx_argc; i++)
|
||||
{
|
||||
if (*(cmd->tx_argv[3]) == '-')
|
||||
if (*(cmd->tx_argv[i]) == '-')
|
||||
{
|
||||
if (!strncmp(cmd->tx_argv[3], "-allspec", 8))
|
||||
allSpecial = TRUE;
|
||||
if (!strncmp(cmd->tx_argv[i], "-notop", 6))
|
||||
lefTopCell = FALSE;
|
||||
else if (!strncmp(cmd->tx_argv[i], "-tech", 5))
|
||||
lefTech = TRUE;
|
||||
else goto wrongNumArgs;
|
||||
}
|
||||
else goto wrongNumArgs;
|
||||
}
|
||||
else if (cmd->tx_argc != 3) goto wrongNumArgs;
|
||||
LefWriteAll(selectedUse, lefTopCell, lefTech);
|
||||
}
|
||||
else if (cmd->tx_argc != 2) goto wrongNumArgs;
|
||||
break;
|
||||
case LEF_WRITE:
|
||||
allSpecial = FALSE;
|
||||
for (i = 2; i < cmd->tx_argc; i++)
|
||||
{
|
||||
if (*(cmd->tx_argv[i]) == '-')
|
||||
{
|
||||
if (!strncmp(cmd->tx_argv[i], "-allspec", 8))
|
||||
{
|
||||
if (!is_lef)
|
||||
allSpecial = TRUE;
|
||||
else
|
||||
TxPrintf("The \"-allspec\" option is only for def write\n");
|
||||
}
|
||||
else if (!strncmp(cmd->tx_argv[i], "-tech", 5))
|
||||
{
|
||||
if (is_lef)
|
||||
lefTech = TRUE;
|
||||
else
|
||||
TxPrintf("The \"-tech\" option is only for lef write\n");
|
||||
}
|
||||
else goto wrongNumArgs;
|
||||
}
|
||||
else goto wrongNumArgs;
|
||||
}
|
||||
if (cmd->tx_argc != 2 && cmd->tx_argc != 3) goto wrongNumArgs;
|
||||
if (selectedUse == NULL)
|
||||
{
|
||||
TxError("No cell selected\n");
|
||||
|
|
@ -205,7 +224,7 @@ CmdLef(w, cmd)
|
|||
DefWriteCell(selectedUse->cu_def, namep, allSpecial);
|
||||
else
|
||||
LefWriteCell(selectedUse->cu_def, namep, selectedUse->cu_def
|
||||
== EditRootDef);
|
||||
== EditRootDef, lefTech);
|
||||
break;
|
||||
case LEF_HELP:
|
||||
wrongNumArgs:
|
||||
|
|
|
|||
|
|
@ -1547,6 +1547,11 @@ origin_error:
|
|||
|
||||
DRCCheckThis(lefMacro, TT_CHECKPAINT, &lefMacro->cd_bbox);
|
||||
}
|
||||
|
||||
/* Note: The value here is ignored, setting to "TRUE". */
|
||||
/* The "extract" command only cares that the key exists. */
|
||||
|
||||
DBPropPut(lefMacro, "LEFview", StrDup((char **)NULL, "TRUE"));
|
||||
DBWAreaChanged(lefMacro, &lefMacro->cd_bbox, DBW_ALLWINDOWS,
|
||||
&DBAllButSpaceBits);
|
||||
}
|
||||
|
|
|
|||
534
lef/lefWrite.c
534
lef/lefWrite.c
|
|
@ -157,9 +157,10 @@ lefFileOpen(def, file, suffix, mode, prealfile)
|
|||
*/
|
||||
|
||||
void
|
||||
lefWriteHeader(def, f)
|
||||
lefWriteHeader(def, f, lefTech)
|
||||
CellDef *def; /* Def for which to generate LEF output */
|
||||
FILE *f; /* Output to this file */
|
||||
bool lefTech; /* If TRUE, write layer information */
|
||||
{
|
||||
TileType type;
|
||||
|
||||
|
|
@ -184,6 +185,8 @@ lefWriteHeader(def, f)
|
|||
fprintf(f, "END UNITS\n");
|
||||
fprintf(f, "\n");
|
||||
|
||||
if (!lefTech) return;
|
||||
|
||||
/* Layers (minimal information) */
|
||||
|
||||
if (LefInfo.ht_table != (HashEntry **)NULL)
|
||||
|
|
@ -277,14 +280,17 @@ lefWriteHeader(def, f)
|
|||
typedef struct
|
||||
{
|
||||
FILE *file; /* file to write to */
|
||||
TileType *lastType; /* last type output, so we minimize LAYER
|
||||
TileType lastType; /* last type output, so we minimize LAYER
|
||||
* statements.
|
||||
*/
|
||||
CellDef *lefFlat; /* Soure CellDef (flattened cell) */
|
||||
CellDef *lefYank; /* CellDef to write into */
|
||||
LefMapping *lefMagicMap; /* Layer inverse mapping table */
|
||||
TileTypeBitMask rmask; /* mask of routing layer types */
|
||||
Point origin; /* origin of cell */
|
||||
float oscale; /* units scale conversion factor */
|
||||
int pNum; /* Plane number for tile marking */
|
||||
int numWrites; /* Track number of writes to output */
|
||||
int lefMode; /* can be LEF_MODE_PORT when searching
|
||||
* connections into ports, or
|
||||
* LEF_MODE_OBSTRUCT when generating
|
||||
|
|
@ -296,6 +302,29 @@ typedef struct
|
|||
*/
|
||||
} lefClient;
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
lefEraseGeometry(tile, cdata)
|
||||
Tile *tile;
|
||||
ClientData cdata;
|
||||
{
|
||||
lefClient *lefdata = (lefClient *)cdata;
|
||||
CellDef *flatDef = lefdata->lefFlat;
|
||||
Rect area;
|
||||
TileType ttype;
|
||||
|
||||
TiToRect(tile, &area);
|
||||
|
||||
/* Erase the tile area out of lefFlat */
|
||||
DBErase(flatDef, &area, ttype);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -342,26 +371,13 @@ lefYankGeometry(tile, cdata)
|
|||
Rect area;
|
||||
TileType ttype, otype, ptype;
|
||||
LefMapping *lefMagicToLefLayer;
|
||||
TileTypeBitMask *sMask;
|
||||
TileTypeBitMask sMask;
|
||||
bool iscut;
|
||||
|
||||
/* To enumerate obstructions, we search all tiles in the */
|
||||
/* cell, and ignore all of those which were electrically */
|
||||
/* connected to any pin. These will have the tile's */
|
||||
/* ti_client record set to 1. */
|
||||
|
||||
/* Because DBSrPaintArea will look at each tile once and */
|
||||
/* only once, we can reset the ti_client record here, so */
|
||||
/* everything is back to normal after LEF output. */
|
||||
|
||||
if (lefdata->lefMode == LEF_MODE_OBSTRUCT)
|
||||
if (tile->ti_client == (ClientData)1)
|
||||
{
|
||||
tile->ti_client = (ClientData)CLIENTDEFAULT;
|
||||
return 0;
|
||||
}
|
||||
/* Ignore marked tiles */
|
||||
if (tile->ti_client != (ClientData)CLIENTDEFAULT) return 0;
|
||||
|
||||
otype = TiGetTypeExact(tile);
|
||||
|
||||
if (IsSplit(tile))
|
||||
ttype = (otype & TT_SIDE) ? SplitRightType(tile) :
|
||||
SplitLeftType(tile);
|
||||
|
|
@ -375,38 +391,30 @@ lefYankGeometry(tile, cdata)
|
|||
|
||||
if (DBIsContact(ttype))
|
||||
{
|
||||
sMask = DBResidueMask(ttype);
|
||||
DBFullResidueMask(ttype, &sMask);
|
||||
|
||||
/* First check if lefdata->lastType is in the residue, */
|
||||
/* and process first. */
|
||||
/* Use the first routing layer that is represented */
|
||||
/* in sMask. If none, then return. */
|
||||
|
||||
if (TTMaskHasType(sMask, *(lefdata->lastType)))
|
||||
ttype = *(lefdata->lastType);
|
||||
else
|
||||
{
|
||||
/* And if not, then switch to the first routing */
|
||||
/* layer that is represented in sMask. If none, */
|
||||
/* then return. */
|
||||
|
||||
for (ttype = TT_TECHDEPBASE; ttype < DBNumTypes; ttype++)
|
||||
for (ttype = TT_TECHDEPBASE; ttype < DBNumTypes; ttype++)
|
||||
if (TTMaskHasType(&sMask, ttype))
|
||||
if (TTMaskHasType(&lefdata->rmask, ttype))
|
||||
if (TTMaskHasType(sMask, ttype))
|
||||
break;
|
||||
break;
|
||||
|
||||
if (ttype == DBNumTypes) return 0;
|
||||
}
|
||||
if (ttype == DBNumTypes) return 0;
|
||||
iscut = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TTMaskHasType(&lefdata->rmask, ttype)) return 0;
|
||||
sMask = NULL;
|
||||
iscut = FALSE;
|
||||
}
|
||||
lefMagicToLefLayer = lefdata->lefMagicMap;
|
||||
|
||||
TiToRect(tile, &area);
|
||||
|
||||
while (ttype < DBNumTypes)
|
||||
{
|
||||
lefMagicToLefLayer = lefdata->lefMagicMap;
|
||||
if (lefMagicToLefLayer[ttype].lefInfo != NULL)
|
||||
{
|
||||
if (IsSplit(tile))
|
||||
|
|
@ -415,15 +423,19 @@ lefYankGeometry(tile, cdata)
|
|||
((otype & TT_SIDE) ? (ttype << 14) : ttype);
|
||||
else
|
||||
ptype = ttype;
|
||||
DBPaint(lefdata->lefYank, &area, ptype);
|
||||
|
||||
/* Paint into yank buffer */
|
||||
DBNMPaintPlane(lefdata->lefYank->cd_planes[lefdata->pNum],
|
||||
ptype, &area, DBStdPaintTbl(ttype, lefdata->pNum),
|
||||
(PaintUndoInfo *)NULL);
|
||||
}
|
||||
|
||||
if (sMask == NULL) break;
|
||||
if (iscut == FALSE) break;
|
||||
|
||||
for (++ttype; ttype < DBNumTypes; ttype++)
|
||||
if (TTMaskHasType(&lefdata->rmask, ttype))
|
||||
if (TTMaskHasType(sMask, ttype))
|
||||
break;
|
||||
if (TTMaskHasType(&sMask, ttype))
|
||||
if (TTMaskHasType(&lefdata->rmask, ttype))
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -452,6 +464,13 @@ lefWriteGeometry(tile, cdata)
|
|||
TileType ttype, otype = TiGetTypeExact(tile);
|
||||
LefMapping *lefMagicToLefLayer = lefdata->lefMagicMap;
|
||||
|
||||
/* Ignore tiles that have already been output */
|
||||
if (tile->ti_client != (ClientData)CLIENTDEFAULT)
|
||||
return 0;
|
||||
|
||||
/* Mark this tile as visited */
|
||||
TiSetClient(tile, (ClientData)1);
|
||||
|
||||
/* Get layer type */
|
||||
if (IsSplit(tile))
|
||||
ttype = (otype & TT_SIDE) ? SplitRightType(tile) :
|
||||
|
|
@ -463,13 +482,22 @@ lefWriteGeometry(tile, cdata)
|
|||
|
||||
if (!TTMaskHasType(&lefdata->rmask, ttype)) return 0;
|
||||
|
||||
if (ttype != *(lefdata->lastType))
|
||||
if (lefdata->numWrites == 0)
|
||||
{
|
||||
if (lefMagicToLefLayer[ttype].lefInfo != NULL)
|
||||
fprintf(f, " LAYER %s ;\n",
|
||||
lefMagicToLefLayer[ttype].lefName);
|
||||
*(lefdata->lastType) = ttype;
|
||||
if (lefdata->lefMode == LEF_MODE_PORT)
|
||||
fprintf(f, " PORT\n");
|
||||
else
|
||||
fprintf(f, " OBS\n");
|
||||
}
|
||||
lefdata->numWrites++;
|
||||
|
||||
if (ttype != lefdata->lastType)
|
||||
if (lefMagicToLefLayer[ttype].lefInfo != NULL)
|
||||
{
|
||||
fprintf(f, " LAYER %s ;\n",
|
||||
lefMagicToLefLayer[ttype].lefName);
|
||||
lefdata->lastType = ttype;
|
||||
}
|
||||
|
||||
if (IsSplit(tile))
|
||||
if (otype & TT_SIDE)
|
||||
|
|
@ -520,20 +548,6 @@ lefWriteGeometry(tile, cdata)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* When called from SimSrConnect(), the callback function needs another
|
||||
* argument for the plane.
|
||||
*/
|
||||
|
||||
int
|
||||
lefYankGeometry2(tile, plane, cdata)
|
||||
Tile *tile;
|
||||
Plane *plane;
|
||||
ClientData cdata;
|
||||
{
|
||||
return lefYankGeometry(tile, cdata);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -611,29 +625,56 @@ lefWriteMacro(def, f, scale)
|
|||
{
|
||||
bool propfound;
|
||||
char *propvalue, *class = NULL;
|
||||
Label *lab, *clab;
|
||||
Rect boundary;
|
||||
TileTypeBitMask lmask, boundmask;
|
||||
Label *lab;
|
||||
Rect boundary, labr;
|
||||
SearchContext scx;
|
||||
CellDef *lefFlatDef;
|
||||
CellUse lefFlatUse, lefSourceUse;
|
||||
TileTypeBitMask lmask, boundmask, *lrmask;
|
||||
TileType ttype;
|
||||
lefClient lc;
|
||||
int idx, pNum;
|
||||
int idx, pNum, maxport, curport;
|
||||
char *LEFtext;
|
||||
HashSearch hs;
|
||||
HashEntry *he;
|
||||
|
||||
extern CellDef *SelectDef;
|
||||
|
||||
UndoDisable();
|
||||
|
||||
TxPrintf("Diagnostic: Writing LEF output for cell %s\n", def->cd_name);
|
||||
|
||||
lefFlatDef = DBCellLookDef("__lefFlat__");
|
||||
if (lefFlatDef == (CellDef *)NULL)
|
||||
lefFlatDef = DBCellNewDef("__lefFlat__", (char *)NULL);
|
||||
DBCellSetAvail(lefFlatDef);
|
||||
lefFlatDef->cd_flags |= CDINTERNAL;
|
||||
|
||||
lefFlatUse.cu_id = StrDup((char **)NULL, "Flattened cell");
|
||||
lefFlatUse.cu_expandMask = CU_DESCEND_SPECIAL;
|
||||
lefFlatUse.cu_def = lefFlatDef;
|
||||
DBSetTrans(&lefFlatUse, &GeoIdentityTransform);
|
||||
|
||||
lefSourceUse.cu_id = StrDup((char **)NULL, "Source cell");
|
||||
lefSourceUse.cu_expandMask = CU_DESCEND_ALL;
|
||||
lefSourceUse.cu_def = def;
|
||||
DBSetTrans(&lefSourceUse, &GeoIdentityTransform);
|
||||
|
||||
scx.scx_use = &lefSourceUse;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
scx.scx_area = def->cd_bbox;
|
||||
DBCellCopyAllPaint(&scx, &DBAllButSpaceAndDRCBits, CU_DESCEND_ALL, &lefFlatUse);
|
||||
|
||||
/* Reset scx to point to the flattened use */
|
||||
scx.scx_use = &lefFlatUse;
|
||||
|
||||
/* Set up client record. */
|
||||
|
||||
lc.file = f;
|
||||
lc.lastType = &ttype;
|
||||
lc.oscale = scale;
|
||||
lc.lefMagicMap = defMakeInverseLayerMap();
|
||||
lc.lefYank = DBCellNewDef("lefYank", (char *)NULL);
|
||||
DBCellSetAvail(lc.lefYank);
|
||||
lc.lefYank->cd_flags |= CDINTERNAL;
|
||||
lc.lastType = TT_SPACE;
|
||||
lc.lefFlat = lefFlatDef;
|
||||
|
||||
TxPrintf("Diagnostic: Scale value is %f\n", lc.oscale);
|
||||
|
||||
|
|
@ -641,10 +682,18 @@ lefWriteMacro(def, f, scale)
|
|||
|
||||
TTMaskZero(&lc.rmask);
|
||||
TTMaskZero(&boundmask);
|
||||
|
||||
/* Any layer which has a port label attached to it should by */
|
||||
/* necessity be considered a routing layer. Usually this will not */
|
||||
/* add anything to the mask already created. */
|
||||
|
||||
for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next)
|
||||
if (lab->lab_flags & PORT_DIR_MASK)
|
||||
TTMaskSetType(&lc.rmask, lab->lab_type);
|
||||
|
||||
HashStartSearch(&hs);
|
||||
while (he = HashNext(&LefInfo, &hs))
|
||||
{
|
||||
TileTypeBitMask *lrmask;
|
||||
lefLayer *lefl = (lefLayer *)HashGetValue(he);
|
||||
if (lefl && (lefl->lefClass == CLASS_ROUTE || lefl->lefClass == CLASS_VIA))
|
||||
if (lefl->type != -1)
|
||||
|
|
@ -655,32 +704,15 @@ lefWriteMacro(def, f, scale)
|
|||
lrmask = DBResidueMask(lefl->type);
|
||||
TTMaskSetMask(&lc.rmask, lrmask);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Contact types whose residues contain a route
|
||||
// layer are included
|
||||
for (ttype = TT_TECHDEPBASE; ttype < DBNumTypes; ttype++)
|
||||
if (DBIsContact(ttype))
|
||||
{
|
||||
lrmask = DBResidueMask(ttype);
|
||||
TTMaskSetMask(&lc.rmask, lrmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lefl->obsType != -1)
|
||||
TTMaskSetType(&lc.rmask, lefl->obsType);
|
||||
|
||||
if (lefl && (lefl->lefClass == CLASS_BOUND))
|
||||
if (lefl->type != -1)
|
||||
TTMaskSetType(&boundmask, lefl->type);
|
||||
}
|
||||
|
||||
/* Any layer which has a port label attached to it should by */
|
||||
/* necessity be considered a routing layer. Usually this will not */
|
||||
/* add anything to the mask already created. */
|
||||
|
||||
for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next)
|
||||
if (lab->lab_flags & PORT_DIR_MASK)
|
||||
TTMaskSetType(&lc.rmask, lab->lab_type);
|
||||
|
||||
/* NOTE: This routine corresponds to Envisia LEF/DEF Language */
|
||||
/* Reference version 5.3 (May 31, 2000) */
|
||||
|
||||
|
|
@ -723,145 +755,206 @@ lefWriteMacro(def, f, scale)
|
|||
else
|
||||
boundary = def->cd_bbox;
|
||||
|
||||
/* Apparently ORIGIN is not reliable! Assume origin must be (0,0) */
|
||||
/* and adjust all geometry instead of adjusting the origin. */
|
||||
/* Write position and size information */
|
||||
|
||||
/*
|
||||
fprintf(f, " ORIGIN %.4f %.4f ;\n",
|
||||
lc.oscale * (float)boundary.r_xbot,
|
||||
lc.oscale * (float)boundary.r_ybot);
|
||||
*/
|
||||
fprintf(f, " ORIGIN 0.00 0.00 ;\n");
|
||||
lc.origin = boundary.r_ll;
|
||||
-lc.oscale * (float)boundary.r_xbot,
|
||||
-lc.oscale * (float)boundary.r_ybot);
|
||||
|
||||
fprintf(f, " SIZE %.4f BY %.4f ;\n",
|
||||
lc.oscale * (float)(boundary.r_xtop - boundary.r_xbot),
|
||||
lc.oscale * (float)(boundary.r_ytop - boundary.r_ybot));
|
||||
|
||||
lc.origin.p_x = 0;
|
||||
lc.origin.p_y = 0;
|
||||
|
||||
propvalue = (char *)DBPropGet(def, "LEFsymmetry", &propfound);
|
||||
if (propfound)
|
||||
fprintf(f, " SYMMETRY %s\n", propvalue);
|
||||
|
||||
/* Generate cell for yanking obstructions */
|
||||
|
||||
lc.lefYank = DBCellLookDef("__lefYank__");
|
||||
if (lc.lefYank == (CellDef *)NULL)
|
||||
lc.lefYank = DBCellNewDef("__lefYank__", (char *)NULL);
|
||||
|
||||
DBCellSetAvail(lc.lefYank);
|
||||
lc.lefYank->cd_flags |= CDINTERNAL;
|
||||
|
||||
/* List of pins (ports) (to be refined?) */
|
||||
|
||||
lc.lefMode = LEF_MODE_PORT;
|
||||
|
||||
/* Determine the maximum port number, then output ports in order */
|
||||
maxport = -1;
|
||||
curport = 0;
|
||||
for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next)
|
||||
{
|
||||
if (lab->lab_flags & PORT_DIR_MASK)
|
||||
{
|
||||
/* Ignore ports which we have already visited. */
|
||||
if (lab->lab_flags & PORT_VISITED) continue;
|
||||
|
||||
curport++;
|
||||
idx = lab->lab_flags & PORT_NUM_MASK;
|
||||
fprintf(f, " PIN %s\n", lab->lab_text);
|
||||
if (lab->lab_flags & PORT_CLASS_MASK)
|
||||
{
|
||||
fprintf(f, " DIRECTION ");
|
||||
switch(lab->lab_flags & PORT_CLASS_MASK)
|
||||
{
|
||||
case PORT_CLASS_INPUT:
|
||||
fprintf(f, "INPUT");
|
||||
break;
|
||||
case PORT_CLASS_OUTPUT:
|
||||
fprintf(f, "OUTPUT");
|
||||
break;
|
||||
case PORT_CLASS_TRISTATE:
|
||||
fprintf(f, "OUTPUT TRISTATE");
|
||||
break;
|
||||
case PORT_CLASS_BIDIRECTIONAL:
|
||||
fprintf(f, "INOUT");
|
||||
break;
|
||||
case PORT_CLASS_FEEDTHROUGH:
|
||||
fprintf(f, "FEEDTHRU");
|
||||
break;
|
||||
}
|
||||
fprintf(f, " ;\n");
|
||||
}
|
||||
if (lab->lab_flags & PORT_USE_MASK)
|
||||
{
|
||||
fprintf(f, " USE ");
|
||||
switch(lab->lab_flags & PORT_USE_MASK)
|
||||
{
|
||||
case PORT_USE_SIGNAL:
|
||||
fprintf(f, "SIGNAL");
|
||||
break;
|
||||
case PORT_USE_ANALOG:
|
||||
fprintf(f, "ANALOG");
|
||||
break;
|
||||
case PORT_USE_POWER:
|
||||
fprintf(f, "POWER");
|
||||
break;
|
||||
case PORT_USE_GROUND:
|
||||
fprintf(f, "GROUND");
|
||||
break;
|
||||
case PORT_USE_CLOCK:
|
||||
fprintf(f, "CLOCK");
|
||||
break;
|
||||
}
|
||||
fprintf(f, " ;\n");
|
||||
}
|
||||
|
||||
/* Query pin geometry for SHAPE (to be done?) */
|
||||
|
||||
/* Generate port layout geometry using SimSrConnect() */
|
||||
/* Selects all electrically-connected material into the */
|
||||
/* select def. Output all the layers and geometries of */
|
||||
/* the select def. */
|
||||
/* */
|
||||
/* We use SimSrConnect() and not DBSrConnect() because */
|
||||
/* SimSrConnect() leaves "marks" (tile->ti_client = 1) */
|
||||
/* which allows us to later search through all tiles for */
|
||||
/* anything that is not connected to a port, and generate */
|
||||
/* an "obstruction" record for it. */
|
||||
/* */
|
||||
/* Note: Use DBIsContact() to check if the layer is a VIA. */
|
||||
/* Presently, I am treating contacts like any other layer. */
|
||||
|
||||
for (clab = lab; clab != NULL; clab = clab->lab_next)
|
||||
{
|
||||
if ((clab->lab_flags & PORT_NUM_MASK) == idx)
|
||||
{
|
||||
Rect labr = clab->lab_rect;
|
||||
|
||||
/* Deal with degenerate (line or point) labels */
|
||||
/* by growing by 1 in each direction. */
|
||||
|
||||
if (labr.r_xtop - labr.r_xbot == 0)
|
||||
{
|
||||
labr.r_xtop++;
|
||||
labr.r_xbot--;
|
||||
}
|
||||
if (labr.r_ytop - labr.r_ybot == 0)
|
||||
{
|
||||
labr.r_ytop++;
|
||||
labr.r_ybot--;
|
||||
}
|
||||
|
||||
fprintf(f, " PORT\n");
|
||||
|
||||
TTMaskSetOnlyType(&lmask, clab->lab_type);
|
||||
|
||||
ttype = TT_SPACE;
|
||||
SimSrConnect(def, &labr, &lmask, DBConnectTbl,
|
||||
&TiPlaneRect, lefYankGeometry2, (ClientData) &lc);
|
||||
|
||||
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
||||
{
|
||||
DBSrPaintArea((Tile *)NULL, lc.lefYank->cd_planes[pNum],
|
||||
&TiPlaneRect, &lc.rmask,
|
||||
lefWriteGeometry, (ClientData) &lc);
|
||||
DBClearPaintPlane(lc.lefYank->cd_planes[pNum]);
|
||||
}
|
||||
|
||||
fprintf(f, " END\n"); /* end of port geometries */
|
||||
clab->lab_flags |= PORT_VISITED;
|
||||
}
|
||||
}
|
||||
LEFtext = MakeLegalLEFSyntax(lab->lab_text);
|
||||
fprintf(f, " END %s\n", lab->lab_text); /* end of pin */
|
||||
if (LEFtext != lab->lab_text) freeMagic(LEFtext);
|
||||
if (idx > maxport)
|
||||
maxport = idx;
|
||||
}
|
||||
|
||||
if (maxport < 0) lab = def->cd_labels;
|
||||
|
||||
/* Work through pins in port order, if defined, otherwise */
|
||||
/* in order of the label list. */
|
||||
|
||||
for (idx = 0; idx < ((maxport < 0) ? curport : maxport + 1); idx++)
|
||||
{
|
||||
if (maxport >= 0)
|
||||
{
|
||||
for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next)
|
||||
if (lab->lab_flags & PORT_DIR_MASK)
|
||||
if (!(lab->lab_flags & PORT_VISITED))
|
||||
if ((lab->lab_flags & PORT_NUM_MASK) == idx)
|
||||
break;
|
||||
}
|
||||
else
|
||||
while (lab && !(lab->lab_flags & PORT_DIR_MASK)) lab = lab->lab_next;
|
||||
|
||||
if (lab == NULL) continue; /* Happens if indexes are skipped */
|
||||
|
||||
/* Ignore ports which we have already visited (shouldn't happen */
|
||||
/* unless ports are shorted together). */
|
||||
|
||||
if (lab->lab_flags & PORT_VISITED) continue;
|
||||
|
||||
fprintf(f, " PIN %s\n", lab->lab_text);
|
||||
if (lab->lab_flags & PORT_CLASS_MASK)
|
||||
{
|
||||
fprintf(f, " DIRECTION ");
|
||||
switch(lab->lab_flags & PORT_CLASS_MASK)
|
||||
{
|
||||
case PORT_CLASS_INPUT:
|
||||
fprintf(f, "INPUT");
|
||||
break;
|
||||
case PORT_CLASS_OUTPUT:
|
||||
fprintf(f, "OUTPUT");
|
||||
break;
|
||||
case PORT_CLASS_TRISTATE:
|
||||
fprintf(f, "OUTPUT TRISTATE");
|
||||
break;
|
||||
case PORT_CLASS_BIDIRECTIONAL:
|
||||
fprintf(f, "INOUT");
|
||||
break;
|
||||
case PORT_CLASS_FEEDTHROUGH:
|
||||
fprintf(f, "FEEDTHRU");
|
||||
break;
|
||||
}
|
||||
fprintf(f, " ;\n");
|
||||
}
|
||||
if (lab->lab_flags & PORT_USE_MASK)
|
||||
{
|
||||
fprintf(f, " USE ");
|
||||
switch(lab->lab_flags & PORT_USE_MASK)
|
||||
{
|
||||
case PORT_USE_SIGNAL:
|
||||
fprintf(f, "SIGNAL");
|
||||
break;
|
||||
case PORT_USE_ANALOG:
|
||||
fprintf(f, "ANALOG");
|
||||
break;
|
||||
case PORT_USE_POWER:
|
||||
fprintf(f, "POWER");
|
||||
break;
|
||||
case PORT_USE_GROUND:
|
||||
fprintf(f, "GROUND");
|
||||
break;
|
||||
case PORT_USE_CLOCK:
|
||||
fprintf(f, "CLOCK");
|
||||
break;
|
||||
}
|
||||
fprintf(f, " ;\n");
|
||||
}
|
||||
|
||||
/* Query pin geometry for SHAPE (to be done?) */
|
||||
|
||||
/* Generate port layout geometry using SimSrConnect() */
|
||||
/* Selects all electrically-connected material into the */
|
||||
/* select def. Output all the layers and geometries of */
|
||||
/* the select def. */
|
||||
/* */
|
||||
/* We use SimSrConnect() and not DBSrConnect() because */
|
||||
/* SimSrConnect() leaves "marks" (tile->ti_client = 1) */
|
||||
/* which allows us to later search through all tiles for */
|
||||
/* anything that is not connected to a port, and generate */
|
||||
/* an "obstruction" record for it. */
|
||||
/* */
|
||||
/* Note: Use DBIsContact() to check if the layer is a VIA. */
|
||||
/* Presently, I am treating contacts like any other layer. */
|
||||
|
||||
labr = lab->lab_rect;
|
||||
|
||||
/* Deal with degenerate (line or point) labels */
|
||||
/* by growing by 1 in each direction. */
|
||||
|
||||
if (labr.r_xtop - labr.r_xbot == 0)
|
||||
{
|
||||
labr.r_xtop++;
|
||||
labr.r_xbot--;
|
||||
}
|
||||
if (labr.r_ytop - labr.r_ybot == 0)
|
||||
{
|
||||
labr.r_ytop++;
|
||||
labr.r_ybot--;
|
||||
}
|
||||
|
||||
// TTMaskSetOnlyType(&lmask, lab->lab_type);
|
||||
|
||||
ttype = TT_SPACE;
|
||||
scx.scx_area = labr;
|
||||
SelectClear();
|
||||
SelectNet(&scx, lab->lab_type, 0, NULL, FALSE);
|
||||
|
||||
// For all geometry in the selection, write LEF records,
|
||||
// and mark the corresponding tiles in lefFlatDef as
|
||||
// visited.
|
||||
|
||||
lc.numWrites = 0;
|
||||
lc.lastType = TT_SPACE;
|
||||
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
||||
{
|
||||
lc.pNum = pNum;
|
||||
DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[pNum],
|
||||
&TiPlaneRect, &DBAllButSpaceAndDRCBits,
|
||||
lefYankGeometry, (ClientData) &lc);
|
||||
|
||||
DBSrPaintArea((Tile *)NULL, lc.lefYank->cd_planes[pNum],
|
||||
&TiPlaneRect, &lc.rmask,
|
||||
lefWriteGeometry, (ClientData) &lc);
|
||||
|
||||
DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[pNum],
|
||||
&TiPlaneRect, &DBAllButSpaceAndDRCBits,
|
||||
lefEraseGeometry, (ClientData) &lc);
|
||||
}
|
||||
DBCellClearDef(lc.lefYank);
|
||||
|
||||
if (lc.numWrites > 0)
|
||||
fprintf(f, " END\n"); /* end of port geometries */
|
||||
lab->lab_flags |= PORT_VISITED;
|
||||
|
||||
LEFtext = MakeLegalLEFSyntax(lab->lab_text);
|
||||
fprintf(f, " END %s\n", lab->lab_text); /* end of pin */
|
||||
if (LEFtext != lab->lab_text) freeMagic(LEFtext);
|
||||
|
||||
if (maxport >= 0)
|
||||
{
|
||||
/* Sanity check to see if port number is a duplicate */
|
||||
for (lab = lab->lab_next; lab != NULL; lab = lab->lab_next)
|
||||
{
|
||||
if (lab->lab_flags & PORT_DIR_MASK)
|
||||
if ((lab->lab_flags & PORT_NUM_MASK) == idx)
|
||||
{
|
||||
TxError("Port index %d is used more than once\n", idx);
|
||||
idx--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
lab = lab->lab_next;
|
||||
}
|
||||
|
||||
/* Clear all PORT_VISITED bits in labels */
|
||||
|
|
@ -872,15 +965,15 @@ lefWriteMacro(def, f, scale)
|
|||
/* List of routing obstructions */
|
||||
|
||||
lc.lefMode = LEF_MODE_OBSTRUCT;
|
||||
ttype = TT_SPACE;
|
||||
lc.numWrites = 0;
|
||||
lc.lastType = TT_SPACE;
|
||||
|
||||
/* Restrict to routing planes only */
|
||||
|
||||
fprintf(f, " OBS\n");
|
||||
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
||||
{
|
||||
DBSrPaintArea((Tile *)NULL, def->cd_planes[pNum],
|
||||
&TiPlaneRect, &lc.rmask,
|
||||
DBSrPaintArea((Tile *)NULL, lefFlatDef->cd_planes[pNum],
|
||||
&TiPlaneRect, &DBAllButSpaceAndDRCBits,
|
||||
lefYankGeometry, (ClientData) &lc);
|
||||
|
||||
DBSrPaintArea((Tile *)NULL, lc.lefYank->cd_planes[pNum],
|
||||
|
|
@ -888,13 +981,18 @@ lefWriteMacro(def, f, scale)
|
|||
lefWriteGeometry, (ClientData) &lc);
|
||||
}
|
||||
|
||||
fprintf(f, " END\n"); /* end of obstruction geometries */
|
||||
if (lc.numWrites > 0)
|
||||
fprintf(f, " END\n"); /* end of obstruction geometries */
|
||||
|
||||
fprintf(f, "END %s\n", def->cd_name); /* end of macro */
|
||||
|
||||
SigDisableInterrupts();
|
||||
freeMagic(lc.lefMagicMap);
|
||||
DBCellClearDef(lc.lefYank);
|
||||
DBCellClearDef(lefFlatDef);
|
||||
freeMagic(lefSourceUse.cu_id);
|
||||
freeMagic(lefFlatUse.cu_id);
|
||||
SelectClear();
|
||||
SigEnableInterrupts();
|
||||
|
||||
UndoEnable();
|
||||
|
|
@ -918,9 +1016,10 @@ lefWriteMacro(def, f, scale)
|
|||
*/
|
||||
|
||||
void
|
||||
LefWriteAll(rootUse, writeTopCell)
|
||||
LefWriteAll(rootUse, writeTopCell, lefTech)
|
||||
CellUse *rootUse;
|
||||
bool writeTopCell;
|
||||
bool lefTech;
|
||||
{
|
||||
CellDef *def, *rootdef;
|
||||
FILE *f;
|
||||
|
|
@ -963,7 +1062,7 @@ LefWriteAll(rootUse, writeTopCell)
|
|||
|
||||
/* Now generate LEF output for all the cells we just found */
|
||||
|
||||
lefWriteHeader(rootdef, f);
|
||||
lefWriteHeader(rootdef, f, lefTech);
|
||||
|
||||
while (def = (CellDef *) StackPop(lefDefStack))
|
||||
{
|
||||
|
|
@ -1029,10 +1128,11 @@ lefDefPushFunc(use)
|
|||
*/
|
||||
|
||||
void
|
||||
LefWriteCell(def, outName, isRoot)
|
||||
LefWriteCell(def, outName, isRoot, lefTech)
|
||||
CellDef *def; /* Cell being written */
|
||||
char *outName; /* Name of output file, or NULL. */
|
||||
bool isRoot; /* Is this the root cell? */
|
||||
bool lefTech; /* Output layer information if TRUE */
|
||||
{
|
||||
char *filename;
|
||||
FILE *f;
|
||||
|
|
@ -1055,7 +1155,7 @@ LefWriteCell(def, outName, isRoot)
|
|||
}
|
||||
|
||||
if (isRoot)
|
||||
lefWriteHeader(def, f);
|
||||
lefWriteHeader(def, f, lefTech);
|
||||
lefWriteMacro(def, f, scale);
|
||||
fclose(f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ EXTRA_LIBS = ${MAGICDIR}/cmwind/libcmwind.o ${MAGICDIR}/commands/libcommands.o \
|
|||
BITMAPS = up.xbm down.xbm left.xbm right.xbm zoom.xbm lock.xbm
|
||||
DEST_XBM = $(BITMAPS:%=$(DESTDIR)${TCLDIR}/bitmaps/%)
|
||||
|
||||
DFLAGS += -DMAGIC_DATE="\"`date`\""
|
||||
DFLAGS += -DMAGIC_DATE="\"`date`\"" -DCAD_DIR="${LIBDIR}"
|
||||
LIBS += ${GR_LIBS} ${READLINE_LIBS} -lm ${LD_EXTRA_LIBS} \
|
||||
${OA_LIBS} ${TOP_EXTRA_LIBS}
|
||||
CLEANS += tclmagic${SHDLIB_EXT} libtclmagic${SHDLIB_EXT}.a proto.magicrc
|
||||
|
|
@ -37,9 +37,8 @@ tclmagic${SHDLIB_EXT}: ${EXTRA_LIBS}
|
|||
${CC} ${CFLAGS} ${CPPFLAGS} -o $@ ${LDDL_FLAGS} ${LD_RUN_PATH} \
|
||||
${EXTRA_LIBS} -lc ${LIBS}
|
||||
|
||||
proto.magicrc: proto.magicrc.m4
|
||||
sed -e /CAD_DIR/s%CAD_DIR%${LIBDIR}%g proto.magicrc.m4 | \
|
||||
${M4} ${GR_DFLAGS} ${DFLAGS} > proto.magicrc
|
||||
proto.magicrc: proto.magicrc.in
|
||||
${CPP} ${GR_DFLAGS} ${DFLAGS} proto.magicrc.in > proto.magicrc
|
||||
|
||||
install: $(DESTDIR)${BINDIR}/${MODULE}${EXEEXT} $(DESTDIR)${SYSDIR}/.magicrc \
|
||||
$(DESTDIR)${SYSDIR}/magicps.pro
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
# $(CAD_ROOT)/magic/sys/.magicrc
|
||||
# System wide start up file for magic, defines default macros.
|
||||
#
|
||||
# rcsid $Header: /usr/cvsroot/magic-8.0/magic/proto.magicrc.m4,v 1.4 2008/12/11 04:20:09 tim Exp $
|
||||
#
|
||||
dnl
|
||||
dnl Source file proto.magicrc.m4
|
||||
dnl Process this file with the m4 macro processor
|
||||
dnl
|
||||
changequote([,])dnl
|
||||
ifdef([MAGIC_WRAPPER],[dnl
|
||||
# Source file proto.magicrc.in
|
||||
# Process this file with the cpp macro processor
|
||||
#
|
||||
#ifdef MAGIC_WRAPPER
|
||||
puts stdout "Processing system .magicrc file"
|
||||
])dnl (MAGIC_WRAPPER)
|
||||
ifelse(USE_NEW_MACROS,1,[dnl
|
||||
#endif /* MAGIC_WRAPPER */
|
||||
#ifdef USE_NEW_MACROS
|
||||
###############################################################################
|
||||
# Default .magicrc macro file (new macros)
|
||||
###############################################################################
|
||||
|
|
@ -38,10 +35,16 @@ macro G "grid 2"
|
|||
# I key
|
||||
macro i "select cell"
|
||||
macro I "select more cell"
|
||||
ifdef([XLIB],[macro Control_XK_i "select less cell"],[dnl])
|
||||
#ifdef XLIB
|
||||
macro Control_XK_i "select less cell"
|
||||
#endif
|
||||
# L key
|
||||
ifdef([USE_READLINE],[imacro l "label "],[dnl])
|
||||
ifdef([MAGIC_WRAPPER],[imacro l "label "],[dnl])
|
||||
#ifdef USE_READLINE
|
||||
imacro l "label "
|
||||
#endif /* (USE_READLINE) */
|
||||
#ifdef MAGIC_WRAPPER
|
||||
imacro l "label "
|
||||
#endif /* (MAGIC_WRAPPER) */
|
||||
macro L "shell ls"
|
||||
macro ^L "redraw"
|
||||
# M key
|
||||
|
|
@ -53,10 +56,16 @@ macro ^N ""
|
|||
macro o "openwindow"
|
||||
macro O "closewindow"
|
||||
# P key
|
||||
ifdef([USE_READLINE],[imacro p "paint "],[dnl])
|
||||
ifdef([MAGIC_WRAPPER],[imacro p "paint "],[dnl])
|
||||
#ifdef USE_READLINE
|
||||
imacro p "paint "
|
||||
#endif /* (USE_READLINE) */
|
||||
#ifdef MAGIC_WRAPPER
|
||||
imacro p "paint "
|
||||
#endif /* (MAGIC_WRAPPER) */
|
||||
# Q key
|
||||
ifdef([XLIB],[macro Control_Shift_XK_q "quit"],[dnl])
|
||||
#ifdef XLIB
|
||||
macro Control_Shift_XK_q "quit"
|
||||
#endif /* (XLIB) */
|
||||
# R key
|
||||
macro r "clockwise"
|
||||
macro R "clockwise 270"
|
||||
|
|
@ -65,7 +74,9 @@ macro ^R "clockwise 180"
|
|||
macro s "select"
|
||||
macro S "select more"
|
||||
macro ^S "select less"
|
||||
ifdef([XLIB],[macro Control_Shift_XK_s "undo ; select"],[dnl])
|
||||
#ifdef XLIB
|
||||
macro Control_Shift_XK_s "undo ; select"
|
||||
#endif /* (XLIB) */
|
||||
# U key
|
||||
macro u "undo"
|
||||
macro U "redo"
|
||||
|
|
@ -83,20 +94,24 @@ macro ^X "expand toggle"
|
|||
macro z "zoom .5"
|
||||
macro Z "zoom 2"
|
||||
macro ^Z "findbox zoom"
|
||||
ifdef([XLIB],[macro Control_Shift_XK_z "center"],[dnl])
|
||||
#ifdef XLIB
|
||||
macro Control_Shift_XK_z "center"
|
||||
#endif /* (XLIB) */
|
||||
# Question mark
|
||||
macro ? "drc why"
|
||||
macro / "select area; what ; select clear"
|
||||
# Comma key
|
||||
macro , "select clear"
|
||||
# Exclamation mark
|
||||
ifdef([USE_READLINE],[imacro ! "shell "],[dnl])
|
||||
#ifdef USE_READLINE
|
||||
imacro ! "shell "
|
||||
#endif /* (USE_READLINE) */
|
||||
# Space bar
|
||||
macro " " "tool"
|
||||
# Colon and semicolon (interactive command)
|
||||
imacro XK_colon ":"
|
||||
imacro XK_semicolon ":"
|
||||
ifdef([XLIB],[dnl
|
||||
#ifdef XLIB
|
||||
macro Shift_XK_space "tool box"
|
||||
macro Control_XK_space "tool wiring"
|
||||
# Arrow keys (X11 versions only)
|
||||
|
|
@ -165,8 +180,8 @@ macro XK_F9 "paint ndc"
|
|||
macro XK_F10 "paint pdc"
|
||||
macro XK_F11 "paint pc"
|
||||
macro XK_F12 "paint via"
|
||||
])dnl (ifdef XLIB)
|
||||
],[dnl (else !USE_NEW_MACROS)
|
||||
#endif /* (XLIB) */
|
||||
#else /* USE_NEW_MACROS */
|
||||
###############################################################################
|
||||
# Default .magicrc macro file (original)
|
||||
###############################################################################
|
||||
|
|
@ -214,9 +229,9 @@ imacro XK_colon ":"
|
|||
imacro XK_semicolon ":"
|
||||
macro ^R "iroute route -dBox"
|
||||
macro ^N "iroute route -dSelection"
|
||||
])dnl (ifdef USE_NEW_MACROS)
|
||||
#endif /* USE_NEW_MACROS */
|
||||
# Allow some box manipulation from all tools.
|
||||
ifdef([MAGIC_WRAPPER],[
|
||||
#ifdef MAGIC_WRAPPER
|
||||
macro Control_Button1 "*bypass box move bl cursor"
|
||||
macro Control_Button2 "*bypass paint cursor"
|
||||
macro Control_Button3 "*bypass box corner ur cursor"
|
||||
|
|
@ -227,7 +242,7 @@ macro Button2 "*bypass paint cursor"
|
|||
macro Shift_Button2 "*bypass erase cursor"
|
||||
macro Button3 "*bypass box corner ur cursor"
|
||||
macro Shift_Button3 "*bypass box move ur cursor"
|
||||
],[
|
||||
#else /* (!MAGIC_WRAPPER) */
|
||||
macro Control_Button1 "box move bl cursor"
|
||||
macro Control_Button2 "paint cursor"
|
||||
macro Control_Button3 "box corner ur cursor"
|
||||
|
|
@ -238,7 +253,7 @@ macro Button2 "paint cursor"
|
|||
macro Shift_Button2 "erase cursor"
|
||||
macro Button3 "box corner ur cursor"
|
||||
macro Shift_Button3 "box move ur cursor"
|
||||
])
|
||||
#endif /* (!MAGIC_WRAPPER) */
|
||||
# Color window button bindings
|
||||
macro color Button1 "pushbutton left"
|
||||
macro color Button2 "pushbutton middle"
|
||||
|
|
@ -269,7 +284,7 @@ macro wind3d 7 "view 0 1 0 rel"
|
|||
macro wind3d 8 "view 0 -1 0 rel"
|
||||
macro wind3d 9 "view 1 0 0 rel"
|
||||
macro wind3d 0 "view -1 0 0 rel"
|
||||
ifdef([XLIB],[dnl
|
||||
#ifdef XLIB
|
||||
macro wind3d XK_Up "scroll 0 -0.25 0 rel"
|
||||
macro wind3d XK_Down "scroll 0 0.25 0 rel"
|
||||
macro wind3d XK_Left "scroll 0.25 0 0 rel"
|
||||
|
|
@ -278,7 +293,7 @@ macro wind3d XK_minus "view 0 0 1 rel"
|
|||
macro wind3d XK_equal "view 0 0 -1 rel"
|
||||
macro wind3d XK_greater "zoom 1 2.0 rel"
|
||||
macro wind3d XK_less "zoom 1 0.5 rel"
|
||||
])dnl (ifdef XLIB)
|
||||
#endif /* (XLIB) */
|
||||
#
|
||||
# Load basic set of fonts
|
||||
#
|
||||
|
|
@ -288,23 +303,20 @@ setlabel font FreeMono.pt3 0.6
|
|||
#
|
||||
# Additions for Tcl GUI wrapper
|
||||
#
|
||||
changequote(<,>)dnl
|
||||
ifelse(MAGIC_WRAPPER,1,<dnl
|
||||
#ifdef MAGIC_WRAPPER
|
||||
magic::suspendout
|
||||
if {![catch {set Opts(tools)}]} { magic::enable_tools }
|
||||
set GND "gnd!"
|
||||
set VDD "vdd!"
|
||||
magic::resumeout
|
||||
catch {source ${CAD_ROOT}/magic/sys/site.def}
|
||||
>,<dnl
|
||||
>)dnl (MAGIC_WRAPPER)
|
||||
changequote([,])dnl
|
||||
#endif /* (!MAGIC_WRAPPER) */
|
||||
#
|
||||
ifdef([SCHEME_INTERPRETER],[dnl
|
||||
#ifdef SCHEME_INTERPRETER
|
||||
#
|
||||
# additions for default scm path
|
||||
#
|
||||
define scm-library-path "CAD_DIR/lib/magic/scm"
|
||||
load-scm "default.scm"
|
||||
load-scm "layout.scm"
|
||||
])dnl (SCHEME_INTERPRETER)
|
||||
#endif /* (SCHEME_INTERPRETER) */
|
||||
|
|
@ -79,11 +79,11 @@ scmosWR.tech: $(OBJS)
|
|||
$(SC_CPP) -DV5 -DSTANDARD -DWELL_ROUTE_CHECK scmos.tech.out > scmosWR.tech
|
||||
$(RM) scmos.tech.out
|
||||
|
||||
minimum.tech: minimum.tech.m4
|
||||
$(SC_M4) minimum.tech.m4 > minimum.tech
|
||||
minimum.tech: minimum.tech.in
|
||||
$(SC_M4) minimum.tech.in > minimum.tech
|
||||
|
||||
gdsquery.tech: gdsquery.tech.m4
|
||||
$(SC_M4) gdsquery.tech.m4 > gdsquery.tech
|
||||
gdsquery.tech: gdsquery.tech.in
|
||||
$(SC_M4) gdsquery.tech.in > gdsquery.tech
|
||||
|
||||
$(CIFin):
|
||||
$(CIFout):
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -427,7 +427,7 @@ Copyright (C) 2012 Free Software Foundation, Inc.
|
|||
This config.status script is free software; the Free Software Foundation
|
||||
gives unlimited permission to copy, distribute and modify it."
|
||||
|
||||
ac_pwd='/home/tim/gitsrc/magic-8.1/scripts'
|
||||
ac_pwd='/home/tim/gitsrc/magic-8.2/scripts'
|
||||
srcdir='..'
|
||||
INSTALL='/bin/install -c'
|
||||
test -n "$AWK" || AWK=awk
|
||||
|
|
@ -588,15 +588,15 @@ S["INSTALL_TARGET"]="install-tcl"
|
|||
S["ALL_TARGET"]="tcl"
|
||||
S["OA_LIBS"]=""
|
||||
S["OA"]=""
|
||||
S["MAGIC_REVISION"]="151"
|
||||
S["MAGIC_VERSION"]="8.1"
|
||||
S["MAGIC_REVISION"]="0"
|
||||
S["MAGIC_VERSION"]="8.2"
|
||||
S["LD_RUN_PATH"]=""
|
||||
S["SHLIB_CFLAGS"]="-Wimplicit-int -fPIC"
|
||||
S["DEPEND_FLAG"]="-MM"
|
||||
S["gr_hprog"]=""
|
||||
S["gr_hsrcs"]=""
|
||||
S["gr_srcs"]=" ${TK_SRCS} ${TOGL_SRCS} ${TKCOMMON_SRCS}"
|
||||
S["gr_dflags"]=" -DX11 -DXLIB -DOGL"
|
||||
S["gr_srcs"]=" ${TK_SRCS} ${TOGL_SRCS} ${TOGL_SRCS} ${TKCOMMON_SRCS}"
|
||||
S["gr_dflags"]=" -DX11 -DXLIB -DOGL -DCAIRO"
|
||||
S["gr_cflags"]=""
|
||||
S["rl_libs"]=""
|
||||
S["rl_defs"]=""
|
||||
|
|
@ -614,7 +614,7 @@ S["extra_libs"]=" ${MAGICDIR}/ext2sim/libext2sim.o ${MAGICDIR}/ext2spice/libext2
|
|||
"ter/librouter.o ${MAGICDIR}/irouter/libirouter.o ${MAGICDIR}/grouter/libgrouter.o ${MAGICDIR}/gcr/libgcr.o ${MAGICDIR}/tcltk/libtcltk.o"
|
||||
S["SCRIPTS"]=""
|
||||
S["PACKAGE"]="magic"
|
||||
S["gr_libs"]=" -lX11 -lGL -lGLU -lXi -lXmu -lXext -lm -lstdc++"
|
||||
S["gr_libs"]=" -lX11 -lGL -lGLU -lXi -lXmu -lXext -lm -lcairo -lfontconfig -lfreetype -lstdc++"
|
||||
S["TCL_LIB_DIR"]="/usr/lib"
|
||||
S["TCLSH_EXE"]="/usr/bin/tclsh"
|
||||
S["WISH_EXE"]="/usr/bin/wish"
|
||||
|
|
@ -635,7 +635,7 @@ S["CSH"]="/bin/csh"
|
|||
S["GCORE"]="/bin/gcore"
|
||||
S["EGREP"]="/bin/grep -E"
|
||||
S["GREP"]="/bin/grep"
|
||||
S["M4"]="/bin/m4"
|
||||
S["PYTHON3"]="/bin/python3"
|
||||
S["RANLIB"]="ranlib"
|
||||
S["INSTALL_DATA"]="${INSTALL} -m 644"
|
||||
S["INSTALL_SCRIPT"]="${INSTALL}"
|
||||
|
|
@ -643,7 +643,7 @@ S["INSTALL_PROGRAM"]="${INSTALL}"
|
|||
S["ac_ct_CXX"]="g++"
|
||||
S["CXXFLAGS"]="-g -O2"
|
||||
S["CXX"]="g++"
|
||||
S["CPP"]="gcc -E -x c"
|
||||
S["CPP"]="/scripts/preproc.py"
|
||||
S["OBJEXT"]="o"
|
||||
S["EXEEXT"]=""
|
||||
S["ac_ct_CC"]="gcc"
|
||||
|
|
@ -666,16 +666,16 @@ S["build"]="x86_64-unknown-linux-gnu"
|
|||
S["target_alias"]=""
|
||||
S["host_alias"]=""
|
||||
S["build_alias"]=""
|
||||
S["LIBS"]="-lGLU -lGL "
|
||||
S["LIBS"]="-lcairo -lGLU -lGL "
|
||||
S["ECHO_T"]=""
|
||||
S["ECHO_N"]="-n"
|
||||
S["ECHO_C"]=""
|
||||
S["DEFS"]="-DPACKAGE_NAME=\\\"\\\" -DPACKAGE_TARNAME=\\\"\\\" -DPACKAGE_VERSION=\\\"\\\" -DPACKAGE_STRING=\\\"\\\" -DPACKAGE_BUGREPORT=\\\"\\\" -DPACKAGE_URL=\\\"\\\" -DMAGIC_VERSION="\
|
||||
"\\\"8.1\\\" -DMAGIC_REVISION=\\\"151\\\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DH"\
|
||||
"AVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_"\
|
||||
"UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAV"\
|
||||
"E_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DX11_BACKING_STORE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 "\
|
||||
"-DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1"
|
||||
"\\\"8.2\\\" -DMAGIC_REVISION=\\\"0\\\" -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DH"\
|
||||
"AVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG="\
|
||||
"8 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFIL"\
|
||||
"E_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DX11_BACKING_STORE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -D"\
|
||||
"HAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1"
|
||||
S["mandir"]="${datarootdir}/man"
|
||||
S["localedir"]="${datarootdir}/locale"
|
||||
S["libdir"]="${exec_prefix}/lib"
|
||||
|
|
|
|||
|
|
@ -671,7 +671,7 @@ CSH
|
|||
GCORE
|
||||
EGREP
|
||||
GREP
|
||||
M4
|
||||
PYTHON3
|
||||
RANLIB
|
||||
INSTALL_DATA
|
||||
INSTALL_SCRIPT
|
||||
|
|
@ -766,6 +766,7 @@ enable_route
|
|||
enable_rsim
|
||||
enable_new_macros
|
||||
with_opengl
|
||||
with_cairo
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
host_alias
|
||||
|
|
@ -1426,6 +1427,7 @@ Optional Packages:
|
|||
--with-tklibs=DIR Find Tk library in DIR
|
||||
--with-openaccess=DIR use OpenAccess libraries in DIR
|
||||
--with-opengl=DIR use OpenGL include files in DIR
|
||||
--with-cairo=DIR use Cairo include files in DIR
|
||||
|
||||
Some influential environment variables:
|
||||
CC C compiler command
|
||||
|
|
@ -4026,18 +4028,16 @@ else
|
|||
fi
|
||||
|
||||
|
||||
for ac_prog in gm4 gnum4 m4
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
# Extract the first word of "python3", so it can be a program name with args.
|
||||
set dummy python3; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_M4+:} false; then :
|
||||
if ${ac_cv_path_PYTHON3+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $M4 in
|
||||
case $PYTHON3 in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_M4="$M4" # Let the user override the test with a path.
|
||||
ac_cv_path_PYTHON3="$PYTHON3" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
|
|
@ -4047,7 +4047,7 @@ do
|
|||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_M4="$as_dir/$ac_word$ac_exec_ext"
|
||||
ac_cv_path_PYTHON3="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
|
|
@ -4055,30 +4055,29 @@ done
|
|||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
test -z "$ac_cv_path_PYTHON3" && ac_cv_path_PYTHON3="no"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
M4=$ac_cv_path_M4
|
||||
if test -n "$M4"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4" >&5
|
||||
$as_echo "$M4" >&6; }
|
||||
PYTHON3=$ac_cv_path_PYTHON3
|
||||
if test -n "$PYTHON3"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON3" >&5
|
||||
$as_echo "$PYTHON3" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
test -n "$M4" && break
|
||||
done
|
||||
test -n "$M4" || M4="no"
|
||||
|
||||
if test x$M4 = xno; then
|
||||
as_fn_error $? "M4 is required" "$LINENO" 5
|
||||
fi
|
||||
if test "x${PYTHON3}" == "x"; then
|
||||
|
||||
|
||||
if test "$CPP" = "$CC -E" ; then
|
||||
CPP="$CPP -x c"
|
||||
if test "$CPP" = "$CC -E" ; then
|
||||
CPP="$CPP -x c"
|
||||
fi
|
||||
|
||||
else
|
||||
CPP="${MAGICDIR}/scripts/preproc.py"
|
||||
fi
|
||||
|
||||
|
||||
|
|
@ -5276,6 +5275,7 @@ usingOGL=1
|
|||
use_libglu="-lGLU"
|
||||
usingTcl=1
|
||||
usingOA=0
|
||||
usingCairo=1
|
||||
|
||||
|
||||
# Extract the first word of "gcore", so it can be a program name with args.
|
||||
|
|
@ -6062,6 +6062,10 @@ else
|
|||
echo "Cannot use OpenGL/GLX without X11, disabling."
|
||||
usingOGL=
|
||||
fi
|
||||
if test $usingCairo ; then
|
||||
echo "Cannot use Cairo without X11, disabling."
|
||||
usingCairo=
|
||||
fi
|
||||
if test $usingTcl ; then
|
||||
echo "Cannot compile TCL version without X11, disabling."
|
||||
usingTcl=
|
||||
|
|
@ -7463,6 +7467,105 @@ if test $usingOGL ; then
|
|||
fi
|
||||
|
||||
|
||||
|
||||
# Check whether --with-cairo was given.
|
||||
if test "${with_cairo+set}" = set; then :
|
||||
withval=$with_cairo;
|
||||
if test "$withval" = "no" -o "$withval" = "NO" ; then
|
||||
usingCairo=
|
||||
elif test "$withval" != "no" -a "$withval" != "yes"; then
|
||||
CAIRO_INCLUDE_DIR=${withval}
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if test $usingCairo ; then
|
||||
ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
if test $CAIRO_INCLUDE_DIR ; then
|
||||
CPPFLAGS="$CPPFLAGS -I$CAIRO_INCLUDE_DIR"
|
||||
fi
|
||||
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "cairo/cairo.h" "ac_cv_header_cairo_cairo_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_cairo_cairo_h" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
echo "Cairo header files not found, disabling Cairo"
|
||||
usingCairo=
|
||||
|
||||
fi
|
||||
|
||||
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
fi
|
||||
|
||||
if test $usingCairo ; then
|
||||
ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
ac_save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS -lm"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cairo_user_to_device in -lcairo" >&5
|
||||
$as_echo_n "checking for cairo_user_to_device in -lcairo... " >&6; }
|
||||
if ${ac_cv_lib_cairo_cairo_user_to_device+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lcairo $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char cairo_user_to_device ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return cairo_user_to_device ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_cairo_cairo_user_to_device=yes
|
||||
else
|
||||
ac_cv_lib_cairo_cairo_user_to_device=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cairo_cairo_user_to_device" >&5
|
||||
$as_echo "$ac_cv_lib_cairo_cairo_user_to_device" >&6; }
|
||||
if test "x$ac_cv_lib_cairo_cairo_user_to_device" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBCAIRO 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-lcairo $LIBS"
|
||||
|
||||
else
|
||||
|
||||
echo "Cairo library files not found, disabling Cairo"
|
||||
usingCairo=
|
||||
|
||||
fi
|
||||
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
LDFLAGS="$ac_save_LDFLAGS"
|
||||
fi
|
||||
|
||||
if test $usingCairo ; then
|
||||
if test $CAIRO_INCLUDE_DIR ; then
|
||||
gr_cflags="${gr_cflags} -I${CAIRO_INCLUDE_DIR}"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test $usingTcl ; then
|
||||
cadinstall="$cadinstall graphics tcltk"
|
||||
modules="$modules tcltk"
|
||||
|
|
@ -7506,6 +7609,16 @@ if test $usingTcl ; then
|
|||
gr_libs="$gr_libs -lX11"
|
||||
fi
|
||||
fi
|
||||
if test $usingCairo ; then
|
||||
gr_dflags="$gr_dflags -DCAIRO"
|
||||
gr_libs="$gr_libs -lcairo -lfontconfig -lfreetype"
|
||||
gr_srcs="$gr_srcs \${TOGL_SRCS}"
|
||||
if ! test $usingX11 ; then
|
||||
usingX11=1
|
||||
gr_dflags="$gr_dflags -DXLIB"
|
||||
gr_libs="$gr_libs -lX11"
|
||||
fi
|
||||
fi
|
||||
gr_srcs="$gr_srcs \${TKCOMMON_SRCS}"
|
||||
else
|
||||
if test $usingX11 ; then
|
||||
|
|
@ -9260,6 +9373,20 @@ else
|
|||
echo
|
||||
fi
|
||||
|
||||
${ECHO_N} "Cairo: "
|
||||
if test $usingCairo ; then
|
||||
echo "yes"
|
||||
else
|
||||
echo "no"
|
||||
echo
|
||||
echo " Cairo graphics are considerably better than the standard 8-bit"
|
||||
echo " and 24-bit X11 graphics, provided that you have a video card and"
|
||||
echo " driver supporting hardware-accelerated graphics. If you get this"
|
||||
echo " message, you may need to download Cairo and fontconfig libraries"
|
||||
echo " and header files, which are usually found in package cairo-devel."
|
||||
echo
|
||||
fi
|
||||
|
||||
if test $usingTcl ; then
|
||||
${ECHO_N} "Tcl/Tk: "
|
||||
echo "yes"
|
||||
|
|
|
|||
|
|
@ -28,20 +28,23 @@ AC_ISC_POSIX
|
|||
AC_PROG_INSTALL
|
||||
AC_PROG_RANLIB
|
||||
|
||||
dnl GNU M4 is preferred due to some of the option switches.
|
||||
AC_PATH_PROGS([M4], [gm4 gnum4 m4], [no])
|
||||
if test x$M4 = xno; then
|
||||
AC_MSG_ERROR([M4 is required])
|
||||
fi
|
||||
dnl Python3 is preferred for running the preprocessor script
|
||||
dnl but CPP can be used instead.
|
||||
AC_PATH_PROG([PYTHON3], [python3], [no])
|
||||
if test "x${PYTHON3}" == "x"; then
|
||||
|
||||
dnl check size of pointer for correct behavior on 64-bit systems
|
||||
dnl If the C preprocessor is GCC, we need to force the flag to
|
||||
dnl assert that input files are of type C, or else the preprocessing
|
||||
dnl stage will not execute correctly on the ".in" files in the scmos
|
||||
dnl directory.
|
||||
dnl check size of pointer for correct behavior on 64-bit systems
|
||||
dnl If the C preprocessor is GCC, we need to force the flag to
|
||||
dnl assert that input files are of type C, or else the preprocessing
|
||||
dnl stage will not execute correctly on the ".in" files in the scmos
|
||||
dnl directory.
|
||||
|
||||
if test "$CPP" = "$CC -E" ; then
|
||||
CPP="$CPP -x c"
|
||||
if test "$CPP" = "$CC -E" ; then
|
||||
CPP="$CPP -x c"
|
||||
fi
|
||||
|
||||
else
|
||||
CPP="${MAGICDIR}/scripts/preproc.py"
|
||||
fi
|
||||
|
||||
dnl check if the linker is a GNU linker
|
||||
|
|
@ -289,6 +292,7 @@ usingOGL=1
|
|||
use_libglu="-lGLU"
|
||||
usingTcl=1
|
||||
usingOA=0
|
||||
usingCairo=1
|
||||
|
||||
dnl Check for gcore, used by niceabort.c
|
||||
|
||||
|
|
@ -318,6 +322,10 @@ else
|
|||
echo "Cannot use OpenGL/GLX without X11, disabling."
|
||||
usingOGL=
|
||||
fi
|
||||
if test $usingCairo ; then
|
||||
echo "Cannot use Cairo without X11, disabling."
|
||||
usingCairo=
|
||||
fi
|
||||
if test $usingTcl ; then
|
||||
echo "Cannot compile TCL version without X11, disabling."
|
||||
usingTcl=
|
||||
|
|
@ -1150,6 +1158,51 @@ if test $usingOGL ; then
|
|||
fi
|
||||
fi
|
||||
|
||||
dnl ----------------------------------------------------------------
|
||||
dnl Check for cairo graphics headers and libraries
|
||||
dnl ----------------------------------------------------------------
|
||||
|
||||
AC_ARG_WITH(cairo,
|
||||
[ --with-cairo=DIR use Cairo include files in DIR], [
|
||||
if test "$withval" = "no" -o "$withval" = "NO" ; then
|
||||
usingCairo=
|
||||
elif test "$withval" != "no" -a "$withval" != "yes"; then
|
||||
CAIRO_INCLUDE_DIR=${withval}
|
||||
fi
|
||||
])
|
||||
|
||||
if test $usingCairo ; then
|
||||
ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
if test $CAIRO_INCLUDE_DIR ; then
|
||||
CPPFLAGS="$CPPFLAGS -I$CAIRO_INCLUDE_DIR"
|
||||
fi
|
||||
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
|
||||
AC_CHECK_HEADER(cairo/cairo.h, , [
|
||||
echo "Cairo header files not found, disabling Cairo"
|
||||
usingCairo=
|
||||
],)
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
fi
|
||||
|
||||
if test $usingCairo ; then
|
||||
ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
ac_save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS $X_LIBS $X_EXTRA_LIBS -lm"
|
||||
AC_CHECK_LIB(cairo, cairo_user_to_device, , [
|
||||
echo "Cairo library files not found, disabling Cairo"
|
||||
usingCairo=
|
||||
],)
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
LDFLAGS="$ac_save_LDFLAGS"
|
||||
fi
|
||||
|
||||
if test $usingCairo ; then
|
||||
if test $CAIRO_INCLUDE_DIR ; then
|
||||
gr_cflags="${gr_cflags} -I${CAIRO_INCLUDE_DIR}"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
dnl ----------------------------------------------------------------
|
||||
dnl Once we're sure what, if any, interpreter is being compiled,
|
||||
dnl set all the appropriate definitions. For Tcl/Tk, override
|
||||
|
|
@ -1201,6 +1254,16 @@ if test $usingTcl ; then
|
|||
gr_libs="$gr_libs -lX11"
|
||||
fi
|
||||
fi
|
||||
if test $usingCairo ; then
|
||||
gr_dflags="$gr_dflags -DCAIRO"
|
||||
gr_libs="$gr_libs -lcairo -lfontconfig -lfreetype"
|
||||
gr_srcs="$gr_srcs \${TOGL_SRCS}"
|
||||
if ! test $usingX11 ; then
|
||||
usingX11=1
|
||||
gr_dflags="$gr_dflags -DXLIB"
|
||||
gr_libs="$gr_libs -lX11"
|
||||
fi
|
||||
fi
|
||||
gr_srcs="$gr_srcs \${TKCOMMON_SRCS}"
|
||||
else
|
||||
if test $usingX11 ; then
|
||||
|
|
@ -1740,6 +1803,20 @@ else
|
|||
echo
|
||||
fi
|
||||
|
||||
${ECHO_N} "Cairo: "
|
||||
if test $usingCairo ; then
|
||||
echo "yes"
|
||||
else
|
||||
echo "no"
|
||||
echo
|
||||
echo " Cairo graphics are considerably better than the standard 8-bit"
|
||||
echo " and 24-bit X11 graphics, provided that you have a video card and"
|
||||
echo " driver supporting hardware-accelerated graphics. If you get this"
|
||||
echo " message, you may need to download Cairo and fontconfig libraries"
|
||||
echo " and header files, which are usually found in package cairo-devel."
|
||||
echo
|
||||
fi
|
||||
|
||||
if test $usingTcl ; then
|
||||
${ECHO_N} "Tcl/Tk: "
|
||||
echo "yes"
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ AR = ar
|
|||
ARFLAGS = crv
|
||||
LINK = ld -r
|
||||
LD = /bin/ld
|
||||
M4 = /bin/m4
|
||||
M4 = @M4@
|
||||
RANLIB = ranlib
|
||||
SHDLIB_EXT = .so
|
||||
LDDL_FLAGS = ${LDFLAGS} -shared -Wl,-soname,$@ -Wl,--version-script=${MAGICDIR}/magic/symbol.map
|
||||
|
|
@ -58,15 +58,15 @@ LD_RUN_PATH =
|
|||
LIB_SPECS = -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6
|
||||
WISH_EXE = /usr/bin/wish
|
||||
TCL_LIB_DIR = /usr/lib
|
||||
MAGIC_VERSION = 8.1
|
||||
MAGIC_REVISION = 151
|
||||
MAGIC_VERSION = 8.2
|
||||
MAGIC_REVISION = 0
|
||||
|
||||
CC = gcc
|
||||
CPP = gcc -E -x c
|
||||
CPP = /scripts/preproc.py
|
||||
CXX = g++
|
||||
|
||||
CPPFLAGS = -I. -I${MAGICDIR}
|
||||
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.1\" -DMAGIC_REVISION=\"151\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DX11_BACKING_STORE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DNDEBUG -DGCORE=\"/bin/gcore\"
|
||||
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"0\" -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DX11_BACKING_STORE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DNDEBUG -DGCORE=\"/bin/gcore\"
|
||||
DFLAGS += -DSHDLIB_EXT=\".so\"
|
||||
CFLAGS = -g -m64 -fPIC -Wimplicit-int -fPIC
|
||||
|
||||
|
|
@ -78,9 +78,9 @@ DEPEND_FLAG = -MM
|
|||
EXEEXT =
|
||||
|
||||
GR_CFLAGS =
|
||||
GR_DFLAGS = -DX11 -DXLIB -DOGL -DNDEBUG
|
||||
GR_LIBS = -lX11 -lGL -lGLU -lXi -lXmu -lXext -lm -lstdc++ ${X11_LDFLAGS}
|
||||
GR_SRCS = ${TK_SRCS} ${TOGL_SRCS} ${TKCOMMON_SRCS}
|
||||
GR_DFLAGS = -DX11 -DXLIB -DOGL -DCAIRO -DNDEBUG
|
||||
GR_LIBS = -lX11 -lGL -lGLU -lXi -lXmu -lXext -lm -lcairo -lfontconfig -lfreetype -lstdc++ ${X11_LDFLAGS}
|
||||
GR_SRCS = ${TK_SRCS} ${TOGL_SRCS} ${TOGL_SRCS} ${TKCOMMON_SRCS}
|
||||
GR_HELPER_SRCS =
|
||||
GR_HELPER_PROG =
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,452 @@
|
|||
#!/ef/efabless/opengalaxy/venv/bin/python3
|
||||
#--------------------------------------------------------------------
|
||||
#
|
||||
# preproc.py
|
||||
#
|
||||
# General purpose macro preprocessor
|
||||
#
|
||||
#--------------------------------------------------------------------
|
||||
# Usage:
|
||||
#
|
||||
# preproc.py input_file [output_file] [-D<variable> ...]
|
||||
#
|
||||
# Where <variable> may be a keyword or a key=value pair
|
||||
#
|
||||
# Syntax: Basically like cpp. However, this preprocessor handles
|
||||
# only a limited set of keywords, so it does not otherwise mangle
|
||||
# the file in the belief that it must be C code. Handling of boolean
|
||||
# relations is important, so these are thoroughly defined (see below)
|
||||
#
|
||||
# #if defined(<variable>) [...]
|
||||
# #ifdef <variable>
|
||||
# #ifndef <variable>
|
||||
# #elseif <variable>
|
||||
# #else
|
||||
# #endif
|
||||
#
|
||||
# #define <variable> [...]
|
||||
# #undef <variable>
|
||||
#
|
||||
# #include <filename>
|
||||
#
|
||||
# <variable> may be
|
||||
# <keyword>
|
||||
# <keyword>=<value>
|
||||
#
|
||||
# <keyword> without '=' is effectively the same as <keyword>=1
|
||||
# Lack of a keyword is equivalent to <keyword>=0, in a conditional.
|
||||
#
|
||||
# Boolean operators (in order of precedence):
|
||||
# ! NOT
|
||||
# && AND
|
||||
# || OR
|
||||
#
|
||||
# Comments:
|
||||
# Most comments (C-like or Tcl-like) are output as-is. A
|
||||
# line beginning with "###" is treated as a preprocessor
|
||||
# comment and is not copied to the output.
|
||||
#
|
||||
# Examples;
|
||||
# #if defined(X) || defined(Y)
|
||||
# #else
|
||||
# #if defined(Z)
|
||||
# #endif
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
def solve_statement(condition):
|
||||
|
||||
defrex = re.compile('defined[ \t]*\(([^\)]+)\)')
|
||||
orrex = re.compile('(.+)\|\|(.+)')
|
||||
andrex = re.compile('(.+)&&(.+)')
|
||||
notrex = re.compile('!([^&\|]+)')
|
||||
parenrex = re.compile('\(([^\)]+)\)')
|
||||
leadspacerex = re.compile('^[ \t]+(.*)')
|
||||
endspacerex = re.compile('(.*)[ \t]+$')
|
||||
|
||||
matchfound = True
|
||||
while matchfound:
|
||||
matchfound = False
|
||||
|
||||
# Search for defined(K) (K must be a single keyword)
|
||||
# If the keyword was defined, then it should have been replaced by 1
|
||||
lmatch = defrex.search(condition)
|
||||
if lmatch:
|
||||
key = lmatch.group(1)
|
||||
if key == 1 or key == '1' or key == True:
|
||||
repl = 1
|
||||
else:
|
||||
repl = 0
|
||||
|
||||
condition = defrex.sub(str(repl), condition)
|
||||
matchfound = True
|
||||
|
||||
# Search for (X) recursively
|
||||
lmatch = parenrex.search(condition)
|
||||
if lmatch:
|
||||
repl = solve_statement(lmatch.group(1))
|
||||
condition = parenrex.sub(str(repl), condition)
|
||||
matchfound = True
|
||||
|
||||
# Search for !X recursively
|
||||
lmatch = notrex.search(condition)
|
||||
if lmatch:
|
||||
only = solve_statement(lmatch.group(1))
|
||||
if only == '1':
|
||||
repl = '0'
|
||||
else:
|
||||
repl = '1'
|
||||
condition = notrex.sub(str(repl), condition)
|
||||
matchfound = True
|
||||
|
||||
# Search for A&&B recursively
|
||||
lmatch = andrex.search(condition)
|
||||
if lmatch:
|
||||
first = solve_statement(lmatch.group(1))
|
||||
second = solve_statement(lmatch.group(2))
|
||||
if first == '1' and second == '1':
|
||||
repl = '1'
|
||||
else:
|
||||
repl = '0'
|
||||
condition = andrex.sub(str(repl), condition)
|
||||
matchfound = True
|
||||
|
||||
# Search for A||B recursively
|
||||
lmatch = orrex.search(condition)
|
||||
if lmatch:
|
||||
first = solve_statement(lmatch.group(1))
|
||||
second = solve_statement(lmatch.group(2))
|
||||
if first == '1' or second == '1':
|
||||
repl = '1'
|
||||
else:
|
||||
repl = '0'
|
||||
condition = orrex.sub(str(repl), condition)
|
||||
matchfound = True
|
||||
|
||||
# Remove whitespace
|
||||
lmatch = leadspacerex.match(condition)
|
||||
if lmatch:
|
||||
condition = lmatch.group(1)
|
||||
lmatch = endspacerex.match(condition)
|
||||
if lmatch:
|
||||
condition = lmatch.group(1)
|
||||
|
||||
return condition
|
||||
|
||||
def solve_condition(condition, keys, defines, keyrex):
|
||||
# Do definition replacement on the conditional
|
||||
for keyword in keys:
|
||||
condition = keyrex[keyword].sub(defines[keyword], condition)
|
||||
|
||||
value = solve_statement(condition)
|
||||
if value == '1':
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def runpp(keys, keyrex, defines, ccomm, incdirs, inputfile, ofile):
|
||||
|
||||
includerex = re.compile('^[ \t]*#include[ \t]+"*([^ \t\n\r"]+)')
|
||||
definerex = re.compile('^[ \t]*#define[ \t]+([^ \t]+)[ \t]+(.+)')
|
||||
defrex = re.compile('^[ \t]*#define[ \t]+([^ \t\n\r]+)')
|
||||
undefrex = re.compile('^[ \t]*#undef[ \t]+([^ \t\n\r]+)')
|
||||
ifdefrex = re.compile('^[ \t]*#ifdef[ \t]+(.+)')
|
||||
ifndefrex = re.compile('^[ \t]*#ifndef[ \t]+(.+)')
|
||||
ifrex = re.compile('^[ \t]*#if[ \t]+(.+)')
|
||||
elseifrex = re.compile('^[ \t]*#elseif[ \t]+(.+)')
|
||||
elserex = re.compile('^[ \t]*#else')
|
||||
endifrex = re.compile('^[ \t]*#endif')
|
||||
commentrex = re.compile('^###[^#]*$')
|
||||
ccstartrex = re.compile('/\*') # C-style comment start
|
||||
ccendrex = re.compile('\*/') # C-style comment end
|
||||
|
||||
badifrex = re.compile('^[ \t]*#if[ \t]*.*')
|
||||
badelserex = re.compile('^[ \t]*#else[ \t]*.*')
|
||||
|
||||
# This code is not designed to operate on huge files. Neither is it designed to be
|
||||
# efficient.
|
||||
|
||||
# ifblock state:
|
||||
# -1 : not in an if/else block
|
||||
# 0 : no condition satisfied yet
|
||||
# 1 : condition satisfied
|
||||
# 2 : condition was handled, waiting for endif
|
||||
|
||||
ifile = False
|
||||
try:
|
||||
ifile = open(inputfile, 'r')
|
||||
except FileNotFoundError:
|
||||
for dir in incdirs:
|
||||
try:
|
||||
ifile = open(dir + '/' + inputfile, 'r')
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
||||
if not ifile:
|
||||
print("Error: Cannot open file " + inputfile + " for reading.\n")
|
||||
return
|
||||
|
||||
ccblock = -1
|
||||
ifblock = -1
|
||||
ifstack = []
|
||||
lineno = 0
|
||||
|
||||
filetext = ifile.readlines()
|
||||
for line in filetext:
|
||||
lineno += 1
|
||||
|
||||
# C-style comments override everything else
|
||||
if ccomm:
|
||||
if ccblock == -1:
|
||||
pmatch = ccstartrex.search(line)
|
||||
if pmatch:
|
||||
ematch = ccendrex.search(line[pmatch.end(0):])
|
||||
if ematch:
|
||||
line = line[0:pmatch.start(0)] + line[ematch.end(0)+2:]
|
||||
else:
|
||||
line = line[0:pmatch.start(0)]
|
||||
ccblock = 1
|
||||
elif ccblock == 1:
|
||||
ematch = ccendrex.search(line)
|
||||
if ematch:
|
||||
line = line[ematch.end(0)+2:]
|
||||
ccblock = -1
|
||||
else:
|
||||
continue
|
||||
|
||||
# Ignore lines beginning with "###"
|
||||
pmatch = commentrex.match(line)
|
||||
if pmatch:
|
||||
continue
|
||||
|
||||
# Handle include. Note that this code does not expect or
|
||||
# handle 'if' blocks that cross file boundaries.
|
||||
pmatch = includerex.match(line)
|
||||
if pmatch:
|
||||
inclfile = pmatch.group(1)
|
||||
runpp(keys, keyrex, defines, ccomm, incdirs, inclfile, ofile)
|
||||
continue
|
||||
|
||||
# Handle define (with value)
|
||||
pmatch = definerex.match(line)
|
||||
if pmatch:
|
||||
condition = pmatch.group(1)
|
||||
value = pmatch.group(2)
|
||||
defines[condition] = value
|
||||
keyrex[condition] = re.compile(condition)
|
||||
if condition not in keys:
|
||||
keys.append(condition)
|
||||
continue
|
||||
|
||||
# Handle define (simple case, no value)
|
||||
pmatch = defrex.match(line)
|
||||
if pmatch:
|
||||
condition = pmatch.group(1)
|
||||
print("Defrex condition is " + condition)
|
||||
defines[condition] = '1'
|
||||
keyrex[condition] = re.compile(condition)
|
||||
if condition not in keys:
|
||||
keys.append(condition)
|
||||
print("Defrex value is " + defines[condition])
|
||||
continue
|
||||
|
||||
# Handle undef
|
||||
pmatch = undefrex.match(line)
|
||||
if pmatch:
|
||||
condition = pmatch.group(1)
|
||||
if condition in keys:
|
||||
defines.pop(condition)
|
||||
keyrex.pop(condition)
|
||||
keys.remove(condition)
|
||||
continue
|
||||
|
||||
# Handle ifdef
|
||||
pmatch = ifdefrex.match(line)
|
||||
if pmatch:
|
||||
if ifblock != -1:
|
||||
ifstack.append(ifblock)
|
||||
|
||||
if ifblock == 1 or ifblock == -1:
|
||||
condition = pmatch.group(1)
|
||||
ifblock = solve_condition(condition, keys, defines, keyrex)
|
||||
else:
|
||||
ifblock = 2
|
||||
continue
|
||||
|
||||
# Handle ifndef
|
||||
pmatch = ifndefrex.match(line)
|
||||
if pmatch:
|
||||
if ifblock != -1:
|
||||
ifstack.append(ifblock)
|
||||
|
||||
if ifblock == 1 or ifblock == -1:
|
||||
condition = pmatch.group(1)
|
||||
ifblock = solve_condition(condition, keys, defines, keyrex)
|
||||
ifblock = 1 if ifblock == 0 else 0
|
||||
else:
|
||||
ifblock = 2
|
||||
continue
|
||||
|
||||
# Handle if
|
||||
pmatch = ifrex.match(line)
|
||||
if pmatch:
|
||||
if ifblock != -1:
|
||||
ifstack.append(ifblock)
|
||||
|
||||
if ifblock == 1 or ifblock == -1:
|
||||
condition = pmatch.group(1)
|
||||
ifblock = solve_condition(condition, keys, defines, keyrex)
|
||||
else:
|
||||
ifblock = 2
|
||||
continue
|
||||
|
||||
# Handle elseif
|
||||
pmatch = elseifrex.match(line)
|
||||
if pmatch:
|
||||
if ifblock == -1:
|
||||
print("Error: #elseif without preceding #if at line " + str(lineno) + ".")
|
||||
ifblock = 0
|
||||
|
||||
if ifblock == 1:
|
||||
ifblock = 2
|
||||
elif ifblock != 2:
|
||||
condition = pmatch.group(1)
|
||||
ifblock = solve_condition(condition, keys, defines, keyrex)
|
||||
continue
|
||||
|
||||
# Handle else
|
||||
pmatch = elserex.match(line)
|
||||
if pmatch:
|
||||
if ifblock == -1:
|
||||
print("Error: #else without preceding #if at line " + str(lineno) + ".")
|
||||
ifblock = 0
|
||||
|
||||
if ifblock == 1:
|
||||
ifblock = 2
|
||||
elif ifblock == 0:
|
||||
ifblock = 1
|
||||
continue
|
||||
|
||||
# Handle endif
|
||||
pmatch = endifrex.match(line)
|
||||
if pmatch:
|
||||
if ifblock == -1:
|
||||
print("Error: #endif outside of #if block at line " + str(lineno) + " (ignored)")
|
||||
elif ifstack:
|
||||
ifblock = ifstack.pop()
|
||||
else:
|
||||
ifblock = -1
|
||||
continue
|
||||
|
||||
# Check for 'if' or 'else' that were not properly formed
|
||||
pmatch = badifrex.match(line)
|
||||
if pmatch:
|
||||
print("Error: Badly formed #if statement at line " + str(lineno) + " (ignored)")
|
||||
if ifblock != -1:
|
||||
ifstack.append(ifblock)
|
||||
|
||||
if ifblock == 1 or ifblock == -1:
|
||||
ifblock = 0
|
||||
else:
|
||||
ifblock = 2
|
||||
continue
|
||||
|
||||
pmatch = badelserex.match(line)
|
||||
if pmatch:
|
||||
print("Error: Badly formed #else statement at line " + str(lineno) + " (ignored)")
|
||||
ifblock = 2
|
||||
continue
|
||||
|
||||
# Ignore all lines that are not satisfied by a conditional
|
||||
if ifblock == 0 or ifblock == 2:
|
||||
continue
|
||||
|
||||
# Now do definition replacement on what's left (if anything)
|
||||
for keyword in keys:
|
||||
line = keyrex[keyword].sub(defines[keyword], line)
|
||||
|
||||
# Output the line
|
||||
print(line, file=ofile, end='')
|
||||
|
||||
if ifblock != -1 or ifstack != []:
|
||||
print("Error: input file ended with an unterminated #if block.")
|
||||
|
||||
if ifile != sys.stdin:
|
||||
ifile.close()
|
||||
return
|
||||
|
||||
def printusage(progname):
|
||||
print('Usage: ' + progname + ' input_file [output_file] [-options]')
|
||||
print(' Options are:')
|
||||
print(' -help Print this help text.')
|
||||
print(' -ccomm Remove C comments in /* ... */ delimiters.')
|
||||
print(' -D<def> Define word <def> and set its value to 1.')
|
||||
print(' -D<def>=<val> Define word <def> and set its value to <val>.')
|
||||
print(' -I<dir> Add <dir> to search path for input files.')
|
||||
return
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# Parse command line for options and arguments
|
||||
options = []
|
||||
arguments = []
|
||||
for item in sys.argv[1:]:
|
||||
if item.find('-', 0) == 0:
|
||||
options.append(item)
|
||||
else:
|
||||
arguments.append(item)
|
||||
|
||||
if len(arguments) > 0:
|
||||
inputfile = arguments[0]
|
||||
if len(arguments) > 1:
|
||||
outputfile = arguments[1]
|
||||
else:
|
||||
outputfile = []
|
||||
else:
|
||||
printusage(sys.argv[0])
|
||||
sys.exit(0)
|
||||
|
||||
defines = {}
|
||||
keyrex = {}
|
||||
keys = []
|
||||
incdirs = []
|
||||
ccomm = False
|
||||
for item in options:
|
||||
result = item.split('=')
|
||||
if result[0] == '-help':
|
||||
printusage(sys.argv[0])
|
||||
sys.exit(0)
|
||||
elif result[0] == '-ccomm':
|
||||
ccomm = True
|
||||
elif result[0][0:2] == '-I':
|
||||
incdirs.append(result[0][2:])
|
||||
elif result[0][0:2] == '-D':
|
||||
keyword = result[0][2:]
|
||||
try:
|
||||
value = result[1]
|
||||
except:
|
||||
value = '1'
|
||||
defines[keyword] = value
|
||||
keyrex[keyword] = re.compile(keyword)
|
||||
keys.append(keyword)
|
||||
else:
|
||||
print('Bad option ' + item + ', options are -help, -ccomm, -D<def> -I<dir>\n')
|
||||
sys.exit(1)
|
||||
|
||||
if outputfile:
|
||||
ofile = open(outputfile, 'w')
|
||||
else:
|
||||
ofile = sys.stdout
|
||||
|
||||
if not ofile:
|
||||
print("Error: Cannot open file " + output_file + " for writing.")
|
||||
sys.exit(1)
|
||||
|
||||
runpp(keys, keyrex, defines, ccomm, incdirs, inputfile, ofile)
|
||||
if ofile != sys.stdout:
|
||||
ofile.close()
|
||||
sys.exit(0)
|
||||
|
|
@ -840,11 +840,12 @@ SelectNet(scx, type, xMask, pArea, less)
|
|||
}
|
||||
|
||||
TTMaskZero(&mask);
|
||||
TTMaskSetType(&mask, type);
|
||||
|
||||
/* Clear out the temporary selection cell and yank all of the
|
||||
* connected paint into it.
|
||||
*/
|
||||
// Make sure that SelectNet() matches connection-compatible
|
||||
// types with the type passed to the routine.
|
||||
|
||||
// TTMaskSetType(&mask, type);
|
||||
TTMaskSetMask(&mask, &DBConnectTbl[type]);
|
||||
|
||||
UndoDisable();
|
||||
DBCellClearDef(Select2Def);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ TCL_FILES = \
|
|||
console.tcl \
|
||||
techbuilder.tcl \
|
||||
cellmgr.tcl \
|
||||
libmgr.tcl \
|
||||
texthelper.tcl \
|
||||
tools.tcl \
|
||||
mazeroute.tcl \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,212 @@
|
|||
#------------------------------------------------------
|
||||
# Script for generating the "library manager" window.
|
||||
#
|
||||
# Written by Tim Edwards, July 2017
|
||||
#------------------------------------------------------
|
||||
|
||||
global Opts
|
||||
|
||||
if {$::tk_version >= 8.5} {
|
||||
|
||||
set Opts(libmgr) 0
|
||||
|
||||
magic::tag addpath "magic::libmanager"
|
||||
magic::tag path "magic::libmanager"
|
||||
|
||||
# Callback to the library manager
|
||||
|
||||
proc magic::libcallback {command} {
|
||||
global Opts
|
||||
|
||||
set rpath [ split [.libmgr.box.view focus] "/"]
|
||||
set rootdef [lindex $rpath 0]
|
||||
set cellpath [lrange $rpath 1 end]
|
||||
set celldef [lrange $rpath end end]
|
||||
|
||||
if { $Opts(target) == "default" } {
|
||||
set winlist [magic::windownames layout]
|
||||
set winname [lindex $winlist 0]
|
||||
} else {
|
||||
set winname $Opts(target)
|
||||
}
|
||||
|
||||
switch $command {
|
||||
load {$winname load $celldef}
|
||||
place {$winname getcell $celldef}
|
||||
pick {
|
||||
magic::tool pick
|
||||
$winname getcell $celldef
|
||||
magic::startselect $winname pick
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------
|
||||
# Create the library manager window
|
||||
#----------------------------------------------
|
||||
|
||||
proc magic::makelibmanager { mgrpath } {
|
||||
|
||||
toplevel ${mgrpath}
|
||||
wm withdraw ${mgrpath}
|
||||
frame ${mgrpath}.actionbar
|
||||
frame ${mgrpath}.box
|
||||
frame ${mgrpath}.target
|
||||
|
||||
ttk::treeview ${mgrpath}.box.view -show tree -selectmode browse \
|
||||
-yscrollcommand "${mgrpath}.box.vert set" \
|
||||
-xscrollcommand "${mgrpath}.box.vert set" \
|
||||
-columns 1
|
||||
scrollbar ${mgrpath}.box.vert -orient vertical -command "${mgrpath}.box.view yview"
|
||||
|
||||
pack ${mgrpath}.actionbar -side top -fill x
|
||||
pack ${mgrpath}.box.view -side left -fill both -expand true
|
||||
pack ${mgrpath}.box.vert -side right -fill y
|
||||
pack ${mgrpath}.box -side top -fill both -expand true
|
||||
pack ${mgrpath}.target -side top -fill x
|
||||
|
||||
button ${mgrpath}.actionbar.load -text "Load" -command {magic::libcallback load}
|
||||
button ${mgrpath}.actionbar.place -text "Place" -command {magic::libcallback place}
|
||||
button ${mgrpath}.actionbar.pick -text "Pick" -command {magic::libcallback pick}
|
||||
|
||||
pack ${mgrpath}.actionbar.load -side left
|
||||
pack ${mgrpath}.actionbar.place -side left
|
||||
pack ${mgrpath}.actionbar.pick -side left
|
||||
|
||||
label ${mgrpath}.target.name -text "Target window:"
|
||||
menubutton ${mgrpath}.target.list -text "default" \
|
||||
-menu ${mgrpath}.target.list.winmenu
|
||||
|
||||
pack ${mgrpath}.target.name -side left -padx 2
|
||||
pack ${mgrpath}.target.list -side left
|
||||
|
||||
#.winmenu clone ${mgrpath}.target.list.winmenu
|
||||
|
||||
#Withdraw the window when the close button is pressed
|
||||
wm protocol ${mgrpath} WM_DELETE_WINDOW "set Opts(libmgr) 0 ; \
|
||||
wm withdraw ${mgrpath}"
|
||||
|
||||
#-------------------------------------------------
|
||||
# Callback when a treeview item is opened
|
||||
#-------------------------------------------------
|
||||
|
||||
bind .libmgr <<TreeviewOpen>> {
|
||||
set s [.libmgr.box.view selection]
|
||||
# puts stdout "open $s"
|
||||
foreach i [.libmgr.box.view children $s] {
|
||||
magic::addtolibset $i
|
||||
.libmgr.box.view item $i -open false
|
||||
}
|
||||
}
|
||||
|
||||
bind .libmgr <<TreeviewClose>> {
|
||||
set s [.libmgr.box.view selection]
|
||||
# puts stdout "close $s"
|
||||
foreach i [.libmgr.box.view children $s] {
|
||||
foreach j [.libmgr.box.view children $i] {
|
||||
.libmgr.box.view delete $j
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc magic::addlibentry {parent child tech} {
|
||||
if {$child != 0} {
|
||||
set hiername [join [list $parent $child] "/"]
|
||||
# puts stdout "libentry $hiername"
|
||||
if {[.libmgr.box.view exists $hiername] == 0} {
|
||||
.libmgr.box.view insert $parent end -id $hiername -text "$child"
|
||||
.libmgr.box.view set $hiername 0 "$tech"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
proc magic::addtolibset {item} {
|
||||
set pathname [.libmgr.box.view item $item -text]
|
||||
set pathfiles [glob -nocomplain -directory $pathname *.mag]
|
||||
|
||||
# Sort files alphabetically
|
||||
|
||||
foreach f [lsort $pathfiles] {
|
||||
set rootname [file tail [file root $f]]
|
||||
if {![catch {open $f r} fin]} {
|
||||
# Read first two lines, break on error
|
||||
if {[gets $fin line] < 0} {continue} ;# empty file error
|
||||
if {$line != "magic"} {continue} ;# not a magic file
|
||||
if {[gets $fin line] < 0} {continue} ;# truncated file
|
||||
set tokens [split $line]
|
||||
if {[llength $tokens] != 2} {continue}
|
||||
set keyword [lindex $tokens 0]
|
||||
if {$keyword != "tech"} {continue}
|
||||
set tech [lindex $tokens 1]
|
||||
close $fin
|
||||
|
||||
# filter here for compatible technology
|
||||
|
||||
magic::addlibentry $item $rootname $tech
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------
|
||||
# The cell manager window main callback function
|
||||
#--------------------------------------------------------------
|
||||
|
||||
proc magic::libmanager {{option "update"}} {
|
||||
global editstack
|
||||
global CAD_ROOT
|
||||
|
||||
# Use of command "path" is recursive, so break if level > 0
|
||||
if {[info level] > 1} {return}
|
||||
|
||||
# Check for existence of the manager widget
|
||||
if {[catch {wm state .libmgr}]} {
|
||||
if {$option == "create"} {
|
||||
magic::makelibmanager .libmgr
|
||||
} else {
|
||||
return
|
||||
}
|
||||
} elseif { $option == "create"} {
|
||||
return
|
||||
}
|
||||
|
||||
magic::suspendall
|
||||
|
||||
# Get existing list of paths
|
||||
set curpaths [.libmgr.box.view children {}]
|
||||
|
||||
# Find all library paths for cell searches
|
||||
# (Separated so that system default path can be viewed or ignored
|
||||
# by option selection (to be done).)
|
||||
set spath1 [magic::path search] ;# Rank 1 search
|
||||
set spath2 [magic::path cell] ;# Rank 2 search
|
||||
|
||||
# If any component of curpaths is not in spath1 or spath2, remove it.
|
||||
set allpaths [concat $spath1 $spath2]
|
||||
foreach path $curpaths {
|
||||
if {[lsearch $allpaths $path] == -1} {
|
||||
.libmgr.box.view delete $path
|
||||
}
|
||||
}
|
||||
|
||||
foreach i $spath1 {
|
||||
if {[.libmgr.box.view exists $i] == 0} {
|
||||
.libmgr.box.view insert {} end -id $i -text $i
|
||||
}
|
||||
magic::addtolibset $i
|
||||
.libmgr.box.view item $i -open false
|
||||
}
|
||||
foreach i $spath2 {
|
||||
set expandname [subst $i]
|
||||
if {[.libmgr.box.view exists $expandname] == 0} {
|
||||
.libmgr.box.view insert {} end -id $expandname -text $expandname
|
||||
}
|
||||
magic::addtolibset $expandname
|
||||
.libmgr.box.view item $expandname -open false
|
||||
}
|
||||
magic::resumeall
|
||||
}
|
||||
|
||||
} ;# (if Tk version 8.5)
|
||||
|
||||
|
|
@ -485,16 +485,17 @@ proc magic::enable_tools {} {
|
|||
|
||||
proc magic::trackwire {window {option {}}} {
|
||||
global Opts
|
||||
|
||||
if {$Opts(motion) == {}} {
|
||||
if {$option == "done"} {
|
||||
wire switch
|
||||
} elseif {$option == "pick"} {
|
||||
puts stdout $window
|
||||
wire type
|
||||
set Opts(motion) [bind ${window} <Motion>]
|
||||
bind ${window} <Motion> [subst {$Opts(motion); *bypass wire show}]
|
||||
set Opts(motion) [bind ${window} <Motion>]
|
||||
bind ${window} <Motion> [subst {$Opts(motion); *bypass wire show}]
|
||||
if {$Opts(motion) == {}} {set Opts(motion) "null"}
|
||||
cursor 21
|
||||
cursor 21
|
||||
}
|
||||
} else {
|
||||
if {$option != "cancel"} {
|
||||
|
|
|
|||
|
|
@ -363,6 +363,10 @@ proc magic::maketechmanager { mgrpath } {
|
|||
|
||||
catch {source ${CAD_ROOT}/magic/tcl/cellmgr.tcl}
|
||||
|
||||
# Generate the library manager
|
||||
|
||||
catch {source ${CAD_ROOT}/magic/tcl/libmgr.tcl}
|
||||
|
||||
# Generate the text helper
|
||||
|
||||
catch {source ${CAD_ROOT}/magic/tcl/texthelper.tcl}
|
||||
|
|
@ -511,7 +515,7 @@ magic::tag findbox "magic::scrollupdate %W"
|
|||
magic::tag see "magic::toolupdate %W %1 %2"
|
||||
magic::tag tech "magic::techrebuild %W %1; magic::captions %1"
|
||||
magic::tag drc "magic::drcupdate %1"
|
||||
magic::tag path "magic::techmanager update"
|
||||
magic::tag path "[magic::tag path]; magic::techmanager update"
|
||||
magic::tag cellname "magic::mgrupdate %W %1"
|
||||
magic::tag cif "magic::mgrupdate %W %1"
|
||||
magic::tag gds "magic::mgrupdate %W %1"
|
||||
|
|
@ -1383,7 +1387,16 @@ proc magic::openwrapper {{cell ""} {framename ""}} {
|
|||
.winmenu entryconfigure last -command ".cellmgr.target.list configure \
|
||||
-text ${framename}"
|
||||
}
|
||||
|
||||
if {$tk_version >= 8.5} {
|
||||
$m add check -label "Library Manager" -variable Opts(libmgr) \
|
||||
-command [subst { magic::libmanager create; \
|
||||
if { \$Opts(libmgr) } { \
|
||||
wm deiconify .libmgr ; raise .libmgr \
|
||||
} else { \
|
||||
wm withdraw .libmgr } }]
|
||||
.winmenu entryconfigure last -command ".libmgr.target.list configure \
|
||||
-text ${framename}"
|
||||
}
|
||||
$m add check -label "Tech Manager" -variable Opts(techmgr) \
|
||||
-command [subst { magic::techmanager create; \
|
||||
if { \$Opts(techmgr) } { \
|
||||
|
|
@ -1423,7 +1436,7 @@ proc magic::openwrapper {{cell ""} {framename ""}} {
|
|||
|
||||
$m add check -label "Crosshair" \
|
||||
-variable Opts(crosshair) \
|
||||
-command "if {$Opts(crosshair) == 0} {crosshair off}"
|
||||
-command {if {$Opts(crosshair) == 0} {crosshair off}}
|
||||
|
||||
catch {addmazehelper $m}
|
||||
|
||||
|
|
@ -1450,9 +1463,9 @@ proc magic::openwrapper {{cell ""} {framename ""}} {
|
|||
set rptx \[lindex \$rpt 0\] ;\
|
||||
set rpty \[lindex \$rpt 1\] ;\
|
||||
set Winopts(.owindow\$owindow,geometry) 500x500+\$rptx+\$rpty ;\
|
||||
openwrapper \[\$Opts(focus).magic cellname list window\] \
|
||||
openwrapper \[\$Opts(focus)*.magic cellname list window\] \
|
||||
.owindow\$owindow ;\
|
||||
.owindow\$owindow.magic view \[box values\]"
|
||||
.owindow\$owindow*.magic view \[box values\]"
|
||||
}
|
||||
if {[magic::macro list O] == "closewindow"} {
|
||||
magic::macro O "closewrapper \$Opts(focus)"
|
||||
|
|
|
|||
21
utils/main.c
21
utils/main.c
|
|
@ -554,14 +554,29 @@ mainInitAfterArgs()
|
|||
|
||||
StrDup(&SysLibPath, MAGIC_SYS_PATH);
|
||||
|
||||
/*
|
||||
* Historic behavior: Expect to search for cells in a directory
|
||||
* inside the install area with the same name as the technology.
|
||||
* Deprecated but kept for backwards compatibility. If directory
|
||||
* does not exist, it will be ignored.
|
||||
*/
|
||||
|
||||
if (TechFileName != NULL)
|
||||
{
|
||||
CellLibPath = (char *)mallocMagic(strlen(MAGIC_LIB_PATH)
|
||||
CellLibPath = (char *)mallocMagic(strlen(MAGIC_LIB_PATH_FORMAT)
|
||||
+ strlen(TechFileName) - 1);
|
||||
sprintf(CellLibPath, MAGIC_LIB_PATH, TechFileName);
|
||||
sprintf(CellLibPath, MAGIC_LIB_PATH_FORMAT, TechFileName);
|
||||
PaAppend(&CellLibPath, MAGIC_LIB_PATH_DEFAULT);
|
||||
}
|
||||
else if ((TechDefault != NULL) && TechOverridesDefault)
|
||||
{
|
||||
CellLibPath = (char *)mallocMagic(strlen(MAGIC_LIB_PATH_FORMAT)
|
||||
+ strlen(TechDefault) - 1);
|
||||
sprintf(CellLibPath, MAGIC_LIB_PATH_FORMAT, TechDefault);
|
||||
PaAppend(&CellLibPath, MAGIC_LIB_PATH_DEFAULT);
|
||||
}
|
||||
else
|
||||
CellLibPath = StrDup((char **)NULL, MAGIC_LIB_PATH);
|
||||
StrDup(&CellLibPath, MAGIC_LIB_PATH_DEFAULT);
|
||||
|
||||
if (MainGraphicsFile == NULL) MainGraphicsFile = "/dev/null";
|
||||
if (MainMouseFile == NULL) MainMouseFile = MainGraphicsFile;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@
|
|||
#define MAGIC_SYS_PATH ". $CAD_ROOT/magic/sys $CAD_ROOT/magic/sys/current"
|
||||
#define MAGIC_SYS_DOT "$CAD_ROOT/magic/sys/.magicrc"
|
||||
#define MAGIC_PRE_DOT "$CAD_ROOT/magic/sys/.initrc"
|
||||
#define MAGIC_LIB_PATH "$CAD_ROOT/magic/%s $CAD_ROOT/magic/tutorial"
|
||||
#define MAGIC_LIB_PATH_FORMAT "$CAD_ROOT/magic/%s"
|
||||
#define MAGIC_LIB_PATH_DEFAULT "$CAD_ROOT/magic/sys/current $CAD_ROOT/magic/tutorial"
|
||||
#define HELPER_PATH ". BIN_DIR" /* Used by graphics drivers */
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -427,6 +427,8 @@ windSpecialOpenCmd(w, cmd)
|
|||
if ((wc == (WindClient) NULL) || (client[0] == '*')) goto usage;
|
||||
|
||||
if (haveCoords) {
|
||||
windCheckOnlyWindow(&w, wc);
|
||||
|
||||
area.r_xbot = atoi(cmd->tx_argv[1]);
|
||||
area.r_ybot = atoi(cmd->tx_argv[2]);
|
||||
area.r_xtop = MAX(atoi(cmd->tx_argv[3]), area.r_xbot + WIND_MIN_WIDTH);
|
||||
|
|
@ -490,6 +492,12 @@ windNamesCmd(w, cmd)
|
|||
{
|
||||
if (!strncmp(cmd->tx_argv[1], "all", 3))
|
||||
doforall = TRUE;
|
||||
#ifndef THREE_D
|
||||
else if (!strncmp(cmd->tx_argv[1], "wind3d", 6))
|
||||
{
|
||||
return; // do nothing
|
||||
}
|
||||
#endif /* THREE_D */
|
||||
else
|
||||
{
|
||||
wc = WindGetClient(cmd->tx_argv[1], FALSE);
|
||||
|
|
|
|||
|
|
@ -61,12 +61,16 @@ extern MagWindow *windSearchPoint();
|
|||
|
||||
/* the width of window borders */
|
||||
extern int windCaptionPixels;
|
||||
#define THIN_LINE (((w)->w_flags & WIND_BORDER) ? 2 : 0)
|
||||
#define TOP_BORDER(w) (((w)->w_flags & WIND_CAPTION) \
|
||||
#define THIN_LINE ((((w == NULL) ? WindDefaultFlags \
|
||||
: (w)->w_flags) & WIND_BORDER) ? 2 : 0)
|
||||
#define TOP_BORDER(w) ((((w == NULL) ? WindDefaultFlags \
|
||||
: (w)->w_flags) & WIND_CAPTION) \
|
||||
? windCaptionPixels : 2*THIN_LINE)
|
||||
#define BOT_BORDER(w) (((w)->w_flags & WIND_SCROLLBARS) \
|
||||
#define BOT_BORDER(w) ((((w == NULL) ? WindDefaultFlags \
|
||||
: (w)->w_flags) & WIND_SCROLLBARS) \
|
||||
? 2*THIN_LINE + WindScrollBarWidth : 2*THIN_LINE)
|
||||
#define LEFT_BORDER(w) (((w)->w_flags & WIND_SCROLLBARS) \
|
||||
#define LEFT_BORDER(w) ((((w == NULL) ? WindDefaultFlags \
|
||||
: (w)->w_flags) & WIND_SCROLLBARS) \
|
||||
? 2*THIN_LINE + WindScrollBarWidth : 2*THIN_LINE)
|
||||
#define RIGHT_BORDER(w) 2*THIN_LINE
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue