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:
Tim Edwards 2017-08-01 22:14:42 -04:00
parent d97fff5b08
commit 088fc759c4
51 changed files with 2556 additions and 835 deletions

4
README
View File

@ -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:
---------------------------------

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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 */
}

View File

@ -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,

View File

@ -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++)
{

View File

@ -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);
}

View File

@ -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.

View File

@ -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();

View File

@ -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 =

View File

@ -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,

View File

@ -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))

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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)
{

View File

@ -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);
}
/*
* ----------------------------------------------------------------------------
*

View File

@ -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:

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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:

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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) */

View File

@ -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

View File

@ -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"

171
scripts/configure vendored
View File

@ -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"

View File

@ -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"

View File

@ -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 =

452
scripts/preproc.py Executable file
View File

@ -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)

View File

@ -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);

View File

@ -18,6 +18,7 @@ TCL_FILES = \
console.tcl \
techbuilder.tcl \
cellmgr.tcl \
libmgr.tcl \
texthelper.tcl \
tools.tcl \
mazeroute.tcl \

212
tcltk/libmgr.tcl Normal file
View File

@ -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)

View File

@ -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"} {

View File

@ -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)"

View File

@ -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;

View File

@ -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 */
/*

View File

@ -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);

View File

@ -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