Compare commits
No commits in common. "master" and "8.3.634" have entirely different histories.
|
|
@ -5696,12 +5696,9 @@ CIFGenLayer(
|
||||||
(ClientData)NULL);
|
(ClientData)NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
TTMaskSetMask(&bls.connect, &op->co_paintMask);
|
|
||||||
DBSrPaintArea((Tile *)NULL, cellDef->cd_planes[bloats->bl_plane],
|
DBSrPaintArea((Tile *)NULL, cellDef->cd_planes[bloats->bl_plane],
|
||||||
&TiPlaneRect, &bls.connect, cifProcessResetFunc,
|
&TiPlaneRect, &bls.connect, cifProcessResetFunc,
|
||||||
(ClientData)NULL);
|
(ClientData)NULL);
|
||||||
}
|
|
||||||
|
|
||||||
/* Replace the client data */
|
/* Replace the client data */
|
||||||
op->co_client = (ClientData)text;
|
op->co_client = (ClientData)text;
|
||||||
|
|
|
||||||
|
|
@ -131,11 +131,8 @@ DBWAddButtonHandler(
|
||||||
for (i = 0; i < MAXBUTTONHANDLERS; i++)
|
for (i = 0; i < MAXBUTTONHANDLERS; i++)
|
||||||
{
|
{
|
||||||
if (dbwButtonHandlers[i] != NULL) continue;
|
if (dbwButtonHandlers[i] != NULL) continue;
|
||||||
StrDup(&dbwButtonHandlers[i], name);
|
(void) StrDup(&dbwButtonHandlers[i], name);
|
||||||
if (doc != NULL)
|
(void) StrDup(&dbwButtonDoc[i], doc);
|
||||||
StrDup(&dbwButtonDoc[i], doc);
|
|
||||||
else
|
|
||||||
dbwButtonDoc[i] = (char *)NULL;
|
|
||||||
dbwButtonProcs[i] = proc;
|
dbwButtonProcs[i] = proc;
|
||||||
dbwButtonCursors[i] = cursor;
|
dbwButtonCursors[i] = cursor;
|
||||||
return;
|
return;
|
||||||
|
|
@ -276,37 +273,6 @@ DBWGetButtonHandler()
|
||||||
return dbwButtonHandlers[dbwButtonCurrentIndex];
|
return dbwButtonHandlers[dbwButtonCurrentIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* DBWButtonHandlerIndex()
|
|
||||||
*
|
|
||||||
* Given a string, return the index of the button handler. If the
|
|
||||||
* string does not correspond to any button handler name, then
|
|
||||||
* return -1.
|
|
||||||
*
|
|
||||||
* Results:
|
|
||||||
* Index of button handler, if it exists; -1 otherwise.
|
|
||||||
*
|
|
||||||
* Side effects:
|
|
||||||
* None.
|
|
||||||
*
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
DBWButtonHandlerIndex(char *toolName)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < MAXBUTTONHANDLERS; i++)
|
|
||||||
{
|
|
||||||
if (dbwButtonHandlers[i] == NULL) return -1;
|
|
||||||
else if (!strcmp(toolName, dbwButtonHandlers[i])) return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -328,10 +294,7 @@ DBWButtonHandlerIndex(char *toolName)
|
||||||
void
|
void
|
||||||
DBWPrintButtonDoc()
|
DBWPrintButtonDoc()
|
||||||
{
|
{
|
||||||
if (dbwButtonDoc[dbwButtonCurrentIndex])
|
TxPrintf("%s", dbwButtonDoc[dbwButtonCurrentIndex]);
|
||||||
TxPrintf("%s", dbwButtonDoc[dbwButtonCurrentIndex]);
|
|
||||||
else
|
|
||||||
TxPrintf("(no usage information)\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,6 @@ extern void DBWAddButtonHandler(const char *name, const cb_database_buttonhandle
|
||||||
int cursor, const char *doc);
|
int cursor, const char *doc);
|
||||||
extern char *DBWGetButtonHandler();
|
extern char *DBWGetButtonHandler();
|
||||||
extern char *DBWChangeButtonHandler();
|
extern char *DBWChangeButtonHandler();
|
||||||
extern int DBWButtonHandlerIndex();
|
|
||||||
extern void DBWPrintButtonDoc();
|
extern void DBWPrintButtonDoc();
|
||||||
extern void DBWBoxHandler();
|
extern void DBWBoxHandler();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,64 +20,22 @@
|
||||||
|
|
||||||
<H2>macro</H2>
|
<H2>macro</H2>
|
||||||
<HR>
|
<HR>
|
||||||
Define or print a key or button macro binding.
|
Define or print a macro called char
|
||||||
<HR>
|
<HR>
|
||||||
|
|
||||||
<H3>Usage:</H3>
|
<H3>Usage:</H3>
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
<B>macro</B> [<I>window_type</I>] [<I>option</I>] [<I>key</I> [<I>value</I>]]
|
<B>macro</B> [<I>window_type</I>] [<I>key</I> [<I>value</I>]] <BR><BR>
|
||||||
<BR><BR>
|
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
where <I>key</I> is the name of a valid key (see below), and
|
where <I>key</I> is the name of a valid key (see below), and
|
||||||
<I>value</I> is a <B>magic</B> command-line command. If
|
<I>value</I> is a <B>magic</B> command-line command. If
|
||||||
present, <I>window_type</I> must be one of the known valid window
|
present, <I>window_type</I> must be one of the four window
|
||||||
types accepted by the <B>specialopen</B> command (<B>color</B>,
|
types accepted by the <B>specialopen</B> command: <B>layout</B>,
|
||||||
<B>netlist</B>, and <B>wind3d</B>), or a known layout tool
|
<B>color</B>, <B>netlist</B>, and <B>wind3d</B>. If omitted,
|
||||||
(<B>box</B>, <B>wiring</B>, <B>nettool</B>, or <B>pick</B>). If
|
the layout window is assumed by default, unless the command has
|
||||||
omitted, the layout window is assumed by default, unless the command
|
been called from inside a window (using the colon or semicolon
|
||||||
has been called from inside a window (using the colon or semicolon
|
|
||||||
escape to the command-line), in which case that window type is
|
escape to the command-line), in which case that window type is
|
||||||
assumed. <P>
|
assumed.
|
||||||
|
|
||||||
In the non-Tcl version of magic, the <I>window_type</I> must be
|
|
||||||
one of the three valid window types listed above, or <B>layout</B>.
|
|
||||||
Tool button bindings are hard-coded, fixed, and unknown to the
|
|
||||||
macro handler. <P>
|
|
||||||
|
|
||||||
In the Tcl version of magic, tool types are generated by
|
|
||||||
procedure and can be modified or overridden. The four tools
|
|
||||||
listed above are the default tools known to magic. If no window
|
|
||||||
or tool type is given, then the current tool in the current
|
|
||||||
active layout window is assumed.<P>
|
|
||||||
|
|
||||||
<I>option</I> may be one of the following:
|
|
||||||
<DL>
|
|
||||||
<DT> <B>list</B> [<B>-reverse</B>]
|
|
||||||
<DD> The key bindings are returned in the form of a Tcl list
|
|
||||||
(Tcl version of magic only). The returned value is a
|
|
||||||
single list with alternating entries of the macro key and
|
|
||||||
the macro binding. In Tcl, this list can be treated as a
|
|
||||||
dictionary type of key:value pairs. With the <B>-reverse</B>
|
|
||||||
option, the keys and values are reversed, resulting in a
|
|
||||||
dictionary that can be searched or listed by function.
|
|
||||||
<DT> <B>help</B>
|
|
||||||
<DD> Curently, <B>macro help</B> is equivalent to <B>macro</B>
|
|
||||||
without arguments, and returns a full list of macro names
|
|
||||||
and their bindings.
|
|
||||||
<DT> <B>search</B> <I>text</I>
|
|
||||||
<DD> Return only results which match (all or in part) the string
|
|
||||||
<I>text</I>. For example, <B>macro search grid</B> will
|
|
||||||
return all key bindings that include the command <B>grid</B>.
|
|
||||||
<DT> <B>copy</B> <I>tool_name</I>
|
|
||||||
<DD> This is a method introduced to allow the interactive creation
|
|
||||||
of new tools, in the Tcl version of magic. Each tool is defined
|
|
||||||
specifically by its unique button and key bindings. Because
|
|
||||||
tools generally keep most of the same default bindings, the
|
|
||||||
<B>copy</B> option will copy all the existing bindings to the
|
|
||||||
new tool from the current tool. This can be followed by
|
|
||||||
switching to the new tool and replacing macros with ones
|
|
||||||
unique to the tool.
|
|
||||||
</DL>
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
@ -114,6 +72,7 @@ Define or print a key or button macro binding.
|
||||||
etc., the <B>macro</B> command accepts the abbreviated
|
etc., the <B>macro</B> command accepts the abbreviated
|
||||||
forms <B>Button1</B>, and so forth. <P>
|
forms <B>Button1</B>, and so forth. <P>
|
||||||
|
|
||||||
|
|
||||||
Finally, key modifiers may be prepended to the key name.
|
Finally, key modifiers may be prepended to the key name.
|
||||||
Valid key modifiers are <B>Shift_</B>, <B>Control_</B>,
|
Valid key modifiers are <B>Shift_</B>, <B>Control_</B>,
|
||||||
<B>Alt_</B>, and <B>Meta_</B>, and may be coupled in any
|
<B>Alt_</B>, and <B>Meta_</B>, and may be coupled in any
|
||||||
|
|
@ -130,7 +89,6 @@ Define or print a key or button macro binding.
|
||||||
<H3>See Also:</H3>
|
<H3>See Also:</H3>
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
<A HREF=imacro.html><B>imacro</B></A> <BR>
|
<A HREF=imacro.html><B>imacro</B></A> <BR>
|
||||||
<A HREF=toolchange.html><B>tool</B></A> (Tcl version) <BR>
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<P><IMG SRC=graphics/line1.gif><P>
|
<P><IMG SRC=graphics/line1.gif><P>
|
||||||
|
|
|
||||||
|
|
@ -524,13 +524,6 @@ DRCBasicCheck (celldef, checkRect, clipRect, function, cdata)
|
||||||
return (errors);
|
return (errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expect that keeping around 3 MaxRectsData records should be sufficient
|
|
||||||
* to avoid recomputing drcCanonicalMaxwidth() multiple times. Note that
|
|
||||||
* if a PDK sets up multiple rules on an edge which all require running
|
|
||||||
* drcCanonicalMaxwidth(), then this cache size may need to be revisited.
|
|
||||||
*/
|
|
||||||
#define MAXRECTSCACHE 3
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -568,19 +561,6 @@ drcTile (tile, dinfo, arg)
|
||||||
int triggered;
|
int triggered;
|
||||||
int cdist, dist, ccdist, result;
|
int cdist, dist, ccdist, result;
|
||||||
|
|
||||||
/* Keep up to three MaxRectsData records to avoid doing the same
|
|
||||||
* expensive computation more than once.
|
|
||||||
*
|
|
||||||
* mrdcache[0] will be used for the tpleft tile, since it will never
|
|
||||||
* be reused. mrdcache[1] and mrdcache[2] will be used for the tile
|
|
||||||
* itself. Note that if more than 2 DRCCookie entries for the same
|
|
||||||
* edge require drcCanonicalMaxwidth(), then mrdcache[2] will be
|
|
||||||
* re-used so that at least mrdcache[1] is always a cache hit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static MaxRectsData *mrdcache[MAXRECTSCACHE] = {NULL, NULL, NULL};
|
|
||||||
DRCCookie *cptrcache;
|
|
||||||
|
|
||||||
arg->dCD_constraint = &errRect;
|
arg->dCD_constraint = &errRect;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -722,8 +702,6 @@ drcTile (tile, dinfo, arg)
|
||||||
DRCstatEdges++;
|
DRCstatEdges++;
|
||||||
}
|
}
|
||||||
|
|
||||||
cptrcache = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check design rules along a vertical boundary between two tiles.
|
* Check design rules along a vertical boundary between two tiles.
|
||||||
*
|
*
|
||||||
|
|
@ -879,23 +857,12 @@ drcTile (tile, dinfo, arg)
|
||||||
|
|
||||||
if (cptr->drcc_flags & DRC_REVERSE)
|
if (cptr->drcc_flags & DRC_REVERSE)
|
||||||
{
|
{
|
||||||
mrd = drcCanonicalMaxwidth(tpleft, GEO_WEST, arg, cptr,
|
mrd = drcCanonicalMaxwidth(tpleft, GEO_WEST, arg, cptr);
|
||||||
&mrdcache[0]);
|
|
||||||
triggered = 0;
|
triggered = 0;
|
||||||
}
|
}
|
||||||
else
|
else if (firsttile)
|
||||||
{
|
{
|
||||||
if (cptrcache == NULL)
|
mrd = drcCanonicalMaxwidth(tile, GEO_EAST, arg, cptr);
|
||||||
{
|
|
||||||
mrd = drcCanonicalMaxwidth(tile, GEO_EAST, arg, cptr,
|
|
||||||
&mrdcache[1]);
|
|
||||||
cptrcache = cptr;
|
|
||||||
}
|
|
||||||
else if (cptrcache != cptr)
|
|
||||||
mrd = drcCanonicalMaxwidth(tile, GEO_EAST, arg, cptr,
|
|
||||||
&mrdcache[2]);
|
|
||||||
else
|
|
||||||
mrd = mrdcache[1];
|
|
||||||
triggered = 0;
|
triggered = 0;
|
||||||
}
|
}
|
||||||
if (!trigpending || (DRCCurStyle->DRCFlags
|
if (!trigpending || (DRCCurStyle->DRCFlags
|
||||||
|
|
@ -1186,8 +1153,6 @@ drcTile (tile, dinfo, arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cptrcache = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check design rules along a horizontal boundary between two tiles.
|
* Check design rules along a horizontal boundary between two tiles.
|
||||||
*
|
*
|
||||||
|
|
@ -1334,23 +1299,12 @@ drcTile (tile, dinfo, arg)
|
||||||
|
|
||||||
if (cptr->drcc_flags & DRC_REVERSE)
|
if (cptr->drcc_flags & DRC_REVERSE)
|
||||||
{
|
{
|
||||||
mrd = drcCanonicalMaxwidth(tpbot, GEO_SOUTH, arg, cptr,
|
mrd = drcCanonicalMaxwidth(tpbot, GEO_SOUTH, arg, cptr);
|
||||||
&mrdcache[0]);
|
|
||||||
triggered = 0;
|
triggered = 0;
|
||||||
}
|
}
|
||||||
else
|
else if (firsttile)
|
||||||
{
|
{
|
||||||
if (cptrcache == NULL)
|
mrd = drcCanonicalMaxwidth(tile, GEO_NORTH, arg, cptr);
|
||||||
{
|
|
||||||
mrd = drcCanonicalMaxwidth(tile, GEO_NORTH, arg, cptr,
|
|
||||||
&mrdcache[1]);
|
|
||||||
cptrcache = cptr;
|
|
||||||
}
|
|
||||||
else if (cptrcache != cptr)
|
|
||||||
mrd = drcCanonicalMaxwidth(tile, GEO_NORTH, arg, cptr,
|
|
||||||
&mrdcache[2]);
|
|
||||||
else
|
|
||||||
mrd = mrdcache[1];
|
|
||||||
triggered = 0;
|
triggered = 0;
|
||||||
}
|
}
|
||||||
if (!trigpending || (DRCCurStyle->DRCFlags
|
if (!trigpending || (DRCCurStyle->DRCFlags
|
||||||
|
|
|
||||||
|
|
@ -510,17 +510,16 @@ MaxRectsExclude(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MaxRectsData *
|
MaxRectsData *
|
||||||
drcCanonicalMaxwidth(starttile, dir, arg, cptr, mrdptr)
|
drcCanonicalMaxwidth(starttile, dir, arg, cptr)
|
||||||
Tile *starttile;
|
Tile *starttile;
|
||||||
int dir; /* direction of rule */
|
int dir; /* direction of rule */
|
||||||
struct drcClientData *arg;
|
struct drcClientData *arg;
|
||||||
DRCCookie *cptr;
|
DRCCookie *cptr;
|
||||||
MaxRectsData **mrdptr;
|
|
||||||
{
|
{
|
||||||
int s, edgelimit;
|
int s, edgelimit;
|
||||||
Tile *tile,*tp;
|
Tile *tile,*tp;
|
||||||
TileTypeBitMask wrongtypes;
|
TileTypeBitMask wrongtypes;
|
||||||
MaxRectsData *mrd = *mrdptr;
|
static MaxRectsData *mrd = (MaxRectsData *)NULL;
|
||||||
Rect *boundrect, boundorig;
|
Rect *boundrect, boundorig;
|
||||||
|
|
||||||
/* Generate an initial array size of 8 for rlist and swap. */
|
/* Generate an initial array size of 8 for rlist and swap. */
|
||||||
|
|
@ -530,7 +529,6 @@ drcCanonicalMaxwidth(starttile, dir, arg, cptr, mrdptr)
|
||||||
mrd->rlist = (Rect *)mallocMagic(8 * sizeof(Rect));
|
mrd->rlist = (Rect *)mallocMagic(8 * sizeof(Rect));
|
||||||
mrd->swap = (Rect *)mallocMagic(8 * sizeof(Rect));
|
mrd->swap = (Rect *)mallocMagic(8 * sizeof(Rect));
|
||||||
mrd->listdepth = 8;
|
mrd->listdepth = 8;
|
||||||
*mrdptr = mrd;
|
|
||||||
}
|
}
|
||||||
if (starttile == NULL) return mrd;
|
if (starttile == NULL) return mrd;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2755,56 +2755,6 @@ extOutputDevices(def, transList, outFile)
|
||||||
/* get corrected by extComputeEffectiveLW(). */
|
/* get corrected by extComputeEffectiveLW(). */
|
||||||
length = (extTransRec.tr_gatelen - width) / 2;
|
length = (extTransRec.tr_gatelen - width) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((n == 1) && (length == 0) && (extTransRec.tr_gatelen == 0))
|
|
||||||
{
|
|
||||||
/* If a one-terminal device has not recorded any
|
|
||||||
* gate length, then get W and L from the bounding
|
|
||||||
* box of the device. This routine could be much
|
|
||||||
* better optimized but it is probably not worth
|
|
||||||
* the effort. Just reusing the code from above
|
|
||||||
* for creating extSpecialDevice, a list of device
|
|
||||||
* tiles. Note that W and L are not distinguishable
|
|
||||||
* and hopefully the PDK defines the device by area
|
|
||||||
* and perimeter.
|
|
||||||
*/
|
|
||||||
LinkedTile *lt;
|
|
||||||
Rect devbbox, ltbox;
|
|
||||||
|
|
||||||
extSpecialDevice = (LinkedTile *)NULL;
|
|
||||||
|
|
||||||
arg.fra_uninit = (ClientData)extTransRec.tr_gatenode;
|
|
||||||
arg.fra_region = (ExtRegion *)reg;
|
|
||||||
arg.fra_each = extSDTileFunc;
|
|
||||||
ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo,
|
|
||||||
arg.fra_pNum, &arg);
|
|
||||||
|
|
||||||
arg.fra_uninit = (ClientData) reg;
|
|
||||||
arg.fra_region = (ExtRegion *) extTransRec.tr_gatenode;
|
|
||||||
arg.fra_each = (int (*)()) NULL;
|
|
||||||
ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo,
|
|
||||||
arg.fra_pNum, &arg);
|
|
||||||
|
|
||||||
lt = extSpecialDevice;
|
|
||||||
if (lt)
|
|
||||||
{
|
|
||||||
TiToRect(lt->t, &devbbox);
|
|
||||||
for (; lt; lt = lt->t_next)
|
|
||||||
{
|
|
||||||
TiToRect(lt->t, <box);
|
|
||||||
GeoInclude(<box, &devbbox);
|
|
||||||
}
|
|
||||||
free_magic1_t mm1 = freeMagic1_init();
|
|
||||||
for (lt = extSpecialDevice; lt; lt = lt->t_next)
|
|
||||||
freeMagic1(&mm1, (char *)lt);
|
|
||||||
freeMagic1_end(&mm1);
|
|
||||||
}
|
|
||||||
length = devbbox.r_xtop - devbbox.r_xbot;
|
|
||||||
/* Width was likely a perimeter value and will
|
|
||||||
* be recalculated as the actual device width.
|
|
||||||
*/
|
|
||||||
width = devbbox.r_ytop - devbbox.r_ybot;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------*/
|
/*------------------------------------------------------*/
|
||||||
|
|
|
||||||
|
|
@ -1299,11 +1299,6 @@ proc magic::add_check_callbacks {gencell_type library} {
|
||||||
# A final default dependency will be added to all entries
|
# A final default dependency will be added to all entries
|
||||||
# to run the "check" procedure for the device. Dependencies
|
# to run the "check" procedure for the device. Dependencies
|
||||||
# that are more targeted get run first.
|
# that are more targeted get run first.
|
||||||
#
|
|
||||||
# NOTE: The "check" procedure must be the first in the
|
|
||||||
# list, as otherwise, any invalid entry that is corrected
|
|
||||||
# by the check callback will have been used to evaluate
|
|
||||||
# dependent values.
|
|
||||||
#----------------------------------------------------------
|
#----------------------------------------------------------
|
||||||
|
|
||||||
proc magic::add_dependency {callback gencell_type library args} {
|
proc magic::add_dependency {callback gencell_type library args} {
|
||||||
|
|
@ -1360,13 +1355,13 @@ proc magic::update_dialog {callback pname gencell_type library} {
|
||||||
set parameters [dict merge $pdefaults [magic::gencell_getparams]]
|
set parameters [dict merge $pdefaults [magic::gencell_getparams]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if {$callback != {}} {
|
||||||
|
set parameters [$callback $pname $parameters]
|
||||||
|
}
|
||||||
if {[catch {set parameters [${library}::${gencell_type}_check $parameters]} \
|
if {[catch {set parameters [${library}::${gencell_type}_check $parameters]} \
|
||||||
checkerr]} {
|
checkerr]} {
|
||||||
puts stderr $checkerr
|
puts stderr $checkerr
|
||||||
}
|
}
|
||||||
if {$callback != {}} {
|
|
||||||
set parameters [$callback $pname $parameters]
|
|
||||||
}
|
|
||||||
magic::gencell_setparams $parameters
|
magic::gencell_setparams $parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -534,11 +534,8 @@ proc magic::enable_tools {} {
|
||||||
# The user can change these bindings at will by using the
|
# The user can change these bindings at will by using the
|
||||||
# "macro" command when the tool is active.
|
# "macro" command when the tool is active.
|
||||||
|
|
||||||
# NOTE: Do not name a tool "netlist" because it will get
|
|
||||||
# confused with the "netlist" window.
|
|
||||||
|
|
||||||
magic::macro copy wiring
|
magic::macro copy wiring
|
||||||
magic::macro copy nettool
|
magic::macro copy netlist
|
||||||
magic::macro copy pick
|
magic::macro copy pick
|
||||||
|
|
||||||
magic::tool wiring
|
magic::tool wiring
|
||||||
|
|
@ -552,7 +549,7 @@ proc magic::enable_tools {} {
|
||||||
macro Button4 "wire incr width ; wire show"
|
macro Button4 "wire incr width ; wire show"
|
||||||
macro Button5 "wire decr width ; wire show"
|
macro Button5 "wire decr width ; wire show"
|
||||||
|
|
||||||
magic::tool nettool
|
magic::tool netlist
|
||||||
macro Button1 "netlist select"
|
macro Button1 "netlist select"
|
||||||
macro Button2 "netlist join"
|
macro Button2 "netlist join"
|
||||||
macro Button3 "netlist terminal"
|
macro Button3 "netlist terminal"
|
||||||
|
|
@ -707,8 +704,8 @@ proc magic::tool {{type next}} {
|
||||||
if {$type == "next"} {
|
if {$type == "next"} {
|
||||||
switch $Opts(tool) {
|
switch $Opts(tool) {
|
||||||
box { set type wiring }
|
box { set type wiring }
|
||||||
wiring { set type nettool }
|
wiring { set type netlist }
|
||||||
nettool { set type pick }
|
netlist { set type pick }
|
||||||
pick { set type box }
|
pick { set type box }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -764,9 +761,9 @@ proc magic::tool {{type next}} {
|
||||||
set Opts(tool) wiring
|
set Opts(tool) wiring
|
||||||
cursor 19 ;# sets the cursor
|
cursor 19 ;# sets the cursor
|
||||||
}
|
}
|
||||||
nettool {
|
netlist {
|
||||||
puts stdout {Switching to NETLIST tool.}
|
puts stdout {Switching to NETLIST tool.}
|
||||||
set Opts(tool) nettool
|
set Opts(tool) netlist
|
||||||
cursor 18 ;# sets the cursor
|
cursor 18 ;# sets the cursor
|
||||||
}
|
}
|
||||||
pick {
|
pick {
|
||||||
|
|
|
||||||
|
|
@ -1056,7 +1056,6 @@ windDoMacro(w, cmd, interactive)
|
||||||
bool do_help = FALSE;
|
bool do_help = FALSE;
|
||||||
bool do_reverse = FALSE;
|
bool do_reverse = FALSE;
|
||||||
char *searchterm = NULL;
|
char *searchterm = NULL;
|
||||||
char *clientName = NULL;
|
|
||||||
macrodef *cMacro;
|
macrodef *cMacro;
|
||||||
HashTable *clienttable;
|
HashTable *clienttable;
|
||||||
HashEntry *h;
|
HashEntry *h;
|
||||||
|
|
@ -1074,25 +1073,9 @@ windDoMacro(w, cmd, interactive)
|
||||||
|
|
||||||
argstart = 1;
|
argstart = 1;
|
||||||
if (cmd->tx_argc == 1)
|
if (cmd->tx_argc == 1)
|
||||||
wc = DBWclientID; /* Default client */
|
wc = DBWclientID; /* Added by NP 11/15/04 */
|
||||||
else if (cmd->tx_argc > 1)
|
else if (cmd->tx_argc > 1)
|
||||||
{
|
|
||||||
wc = WindGetClient(cmd->tx_argv[1], TRUE);
|
wc = WindGetClient(cmd->tx_argv[1], TRUE);
|
||||||
if (wc != NULL)
|
|
||||||
{
|
|
||||||
clientName = cmd->tx_argv[1];
|
|
||||||
argstart++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Check if argument is a known layout button handler */
|
|
||||||
if (DBWButtonHandlerIndex(cmd->tx_argv[1]) != -1)
|
|
||||||
{
|
|
||||||
clientName = cmd->tx_argv[1];
|
|
||||||
argstart++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (cmd->tx_argc > argstart)
|
while (cmd->tx_argc > argstart)
|
||||||
{
|
{
|
||||||
|
|
@ -1133,15 +1116,6 @@ windDoMacro(w, cmd, interactive)
|
||||||
wc = DBWclientID;
|
wc = DBWclientID;
|
||||||
}
|
}
|
||||||
MacroCopy(wc, cmd->tx_argv[argstart]);
|
MacroCopy(wc, cmd->tx_argv[argstart]);
|
||||||
|
|
||||||
/* If tool name did not previously exist, then add
|
|
||||||
* it to the list of known tool names, so that it
|
|
||||||
* can be found later by the "macro" command.
|
|
||||||
*/
|
|
||||||
if (DBWButtonHandlerIndex(cmd->tx_argv[argstart]) == -1)
|
|
||||||
DBWAddButtonHandler(cmd->tx_argv[argstart],
|
|
||||||
(const cb_database_buttonhandler_t)NULL,
|
|
||||||
0, (const char *)NULL);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1173,53 +1147,26 @@ windDoMacro(w, cmd, interactive)
|
||||||
|
|
||||||
if (MacroKey(cmd->tx_argv[argstart], &verbose) == 0)
|
if (MacroKey(cmd->tx_argv[argstart], &verbose) == 0)
|
||||||
if (MacroKey(cmd->tx_argv[argstart + 1], &verbose) != 0)
|
if (MacroKey(cmd->tx_argv[argstart + 1], &verbose) != 0)
|
||||||
|
{
|
||||||
|
wc = 0;
|
||||||
|
argstart++;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* If a clientName wasn't given, but wc is DBWclientID, then get
|
argstart++;
|
||||||
* the clientName from the default button handler.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((clientName == NULL) && (wc == DBWclientID))
|
|
||||||
clientName = DBWGetButtonHandler();
|
|
||||||
|
|
||||||
if (cmd->tx_argc == argstart)
|
if (cmd->tx_argc == argstart)
|
||||||
{
|
{
|
||||||
if (clientName == NULL)
|
if (wc == (WindClient)0)
|
||||||
h = NULL;
|
|
||||||
else
|
|
||||||
h = HashLookOnly(&MacroClients, (char *)clientName);
|
|
||||||
|
|
||||||
if (h == NULL)
|
|
||||||
{
|
{
|
||||||
#ifdef MAGIC_WRAPPER
|
TxError("No such client.\n");
|
||||||
Tcl_Obj *lobj;
|
|
||||||
lobj = Tcl_NewListObj(0, NULL);
|
|
||||||
#endif
|
|
||||||
TxError("Cannot get macro list from current window.\n");
|
|
||||||
#ifndef MAGIC_WRAPPER
|
|
||||||
TxError("List of known macro clients:\n");
|
|
||||||
#endif
|
|
||||||
/* If clientName was not in MacroClients, then what is? */
|
|
||||||
HashStartSearch(&hs);
|
|
||||||
while ((h = HashNext(&MacroClients, &hs)) != NULL)
|
|
||||||
{
|
|
||||||
char *clientName = h->h_key.h_name;
|
|
||||||
#ifdef MAGIC_WRAPPER
|
|
||||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
|
||||||
Tcl_NewStringObj(clientName, -1));
|
|
||||||
#else
|
|
||||||
TxError("%s ", clientName);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#ifdef MAGIC_WRAPPER
|
|
||||||
Tcl_SetObjResult(magicinterp, lobj);
|
|
||||||
#else
|
|
||||||
TxError("\n");
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
h = HashLookOnly(&MacroClients, (char *)wc);
|
||||||
|
if (h == NULL)
|
||||||
|
return;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clienttable = (HashTable *)HashGetValue(h);
|
clienttable = (HashTable *)HashGetValue(h);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue