2017-04-25 14:41:48 +02:00
|
|
|
/* SimSelect.c -
|
|
|
|
|
*
|
|
|
|
|
* This file provides routines to make selections for Rsim by copying
|
|
|
|
|
* things into a special cell named "__SELECT__". It is based
|
|
|
|
|
* on code in the select module.
|
|
|
|
|
*
|
2020-05-23 23:13:14 +02:00
|
|
|
* *********************************************************************
|
|
|
|
|
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
|
|
|
|
* * Permission to use, copy, modify, and distribute this *
|
|
|
|
|
* * software and its documentation for any purpose and without *
|
|
|
|
|
* * fee is hereby granted, provided that the above copyright *
|
|
|
|
|
* * notice appear in all copies. The University of California *
|
|
|
|
|
* * makes no representations about the suitability of this *
|
|
|
|
|
* * software for any purpose. It is provided "as is" without *
|
|
|
|
|
* * express or implied warranty. Export of this software outside *
|
|
|
|
|
* * of the United States of America may require an export license. *
|
2017-04-25 14:41:48 +02:00
|
|
|
* *********************************************************************
|
|
|
|
|
* of California
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef lint
|
|
|
|
|
static char sccsid[] = "@(#)SimSelect.c 4.14 MAGIC (Berkeley) 10/3/85";
|
|
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "tcltk/tclmagic.h"
|
|
|
|
|
#include "utils/magic.h"
|
|
|
|
|
#include "utils/geometry.h"
|
|
|
|
|
#include "tiles/tile.h"
|
|
|
|
|
#include "utils/hash.h"
|
|
|
|
|
#include "database/database.h"
|
|
|
|
|
#include "windows/windows.h"
|
|
|
|
|
#include "dbwind/dbwind.h"
|
|
|
|
|
#include "utils/undo.h"
|
|
|
|
|
#include "commands/commands.h"
|
|
|
|
|
#include "select/selInt.h"
|
|
|
|
|
#include "utils/main.h"
|
|
|
|
|
#include "utils/malloc.h"
|
|
|
|
|
#include "utils/signals.h"
|
|
|
|
|
#include "sim/sim.h"
|
|
|
|
|
|
2022-10-10 11:50:15 +02:00
|
|
|
/* C99 compat */
|
|
|
|
|
#include "textio/textio.h"
|
|
|
|
|
#include "extract/extract.h"
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/* Two cells worth of information are kept around by the selection
|
|
|
|
|
* module. SelectDef and SelectUse are for the cells whose contents
|
|
|
|
|
* are the current selection. Select2Def and Select2Use provide a
|
|
|
|
|
* temporary working space for procedures that manipulate the selection.
|
|
|
|
|
* for example, Select2Def is used to hold nets or regions while they
|
|
|
|
|
* are being extracted by SelectRegion or SelectNet. Once completely
|
|
|
|
|
* extracted, information is copied to SelectDef. Changes to
|
|
|
|
|
* SelectDef are undo-able and redo-able (so that the undo package
|
|
|
|
|
* can deal with selection changes), but changes to Select2Def are
|
|
|
|
|
* not undo-able (undoing is always disabled when the cell is modified).
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
extern CellDef *SelectDef, *Select2Def;
|
|
|
|
|
extern CellUse *SelectUse, *Select2Use;
|
|
|
|
|
|
|
|
|
|
typedef struct def_list_elt
|
|
|
|
|
{
|
|
|
|
|
CellDef *dl_def;
|
|
|
|
|
struct def_list_elt *dl_next;
|
|
|
|
|
bool dl_isMarked;
|
|
|
|
|
} SimDefListElt;
|
|
|
|
|
|
|
|
|
|
static SimDefListElt *SimCellLabList = (SimDefListElt *) NULL;
|
|
|
|
|
/* list of all the cell defs we have
|
2020-05-23 23:13:14 +02:00
|
|
|
* put RSIM labels in
|
2017-04-25 14:41:48 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* Data structure for node names extracted from the current selection. For
|
2020-05-23 23:13:14 +02:00
|
|
|
* each node, save the node name, a tile which lies in the node, and
|
2017-04-25 14:41:48 +02:00
|
|
|
* the text for the label corresponding to the node's rsim value.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
typedef struct TLE {
|
|
|
|
|
char *tl_nodeName;
|
|
|
|
|
Tile *tl_nodeTile;
|
|
|
|
|
char *tl_simLabel;
|
|
|
|
|
struct TLE *tl_next;
|
|
|
|
|
} TileListElt;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TileListElt *NodeList = (TileListElt *) NULL;
|
|
|
|
|
/* list of all nodes in the selected area */
|
|
|
|
|
HashTable SimNodeNameTbl; /* node names found in the selected area */
|
|
|
|
|
HashTable SimGetnodeTbl; /* node names to abort name search on */
|
|
|
|
|
HashTable SimGNAliasTbl; /* node name aliases found during search */
|
|
|
|
|
HashTable SimAbortSeenTbl; /* aborted node names found during search */
|
|
|
|
|
|
|
|
|
|
bool SimRecomputeSel = TRUE; /* selection has changed */
|
|
|
|
|
bool SimInitGetnode = TRUE; /* Getnode called for the 1st time */
|
|
|
|
|
bool SimGetnodeAlias = FALSE; /* if node aliases are to be printed */
|
|
|
|
|
bool SimSawAbortString; /* if saw string to abort name search */
|
|
|
|
|
bool SimIsGetnode; /* true if command was issued from Getnode */
|
|
|
|
|
bool SimUseCoords; /* true if we should use trans. position */
|
|
|
|
|
bool SimIgnoreGlobals = TRUE; /* If FALSE, node names ending in "!" */
|
|
|
|
|
/* are treated as global node names. */
|
|
|
|
|
|
|
|
|
|
#ifndef RSIM_MODULE
|
|
|
|
|
bool SimRsimRunning = FALSE; /* Always false if there's no rsim module */
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* SimSelectNode --
|
|
|
|
|
*
|
|
|
|
|
* This procedure selects an entire node. It is similar to SelectNet.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Returns the node name.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Starting from material of type "type" under scx, this procedure
|
|
|
|
|
* finds all material in all expanded cells that are electrically-
|
2020-05-23 23:13:14 +02:00
|
|
|
* connected to the starting material through a chain of expanded
|
2017-04-25 14:41:48 +02:00
|
|
|
* cells.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
SimSelectNode(scx, type, xMask, buffer)
|
|
|
|
|
SearchContext *scx; /* Area to tree-search for material. The
|
|
|
|
|
* transform must map to EditRoot coordinates.
|
|
|
|
|
*/
|
|
|
|
|
TileType type; /* The type of material to be considered. */
|
|
|
|
|
int xMask; /* Indicates window (or windows) where cells
|
|
|
|
|
* must be expanded for their contents to be
|
|
|
|
|
* considered. 0 means treat everything as
|
|
|
|
|
* expanded.
|
|
|
|
|
*/
|
|
|
|
|
char *buffer; /* buffer to hold node name */
|
|
|
|
|
{
|
|
|
|
|
TileTypeBitMask mask;
|
|
|
|
|
char *strptr;
|
|
|
|
|
|
|
|
|
|
TTMaskZero(&mask);
|
|
|
|
|
TTMaskSetType(&mask, type);
|
|
|
|
|
|
|
|
|
|
/* Clear out the temporary selection cell and yank all of the
|
|
|
|
|
* connected paint into it.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
UndoDisable();
|
|
|
|
|
DBCellClearDef(Select2Def);
|
|
|
|
|
SimTreeCopyConnect(scx, &mask, xMask, DBConnectTbl,
|
|
|
|
|
&TiPlaneRect, Select2Use, buffer);
|
|
|
|
|
UndoEnable();
|
|
|
|
|
|
|
|
|
|
/* Strip out path if name is global (ends with a "!") */
|
|
|
|
|
/* and flag SimIgnoreGlobals is not set. */
|
|
|
|
|
|
|
|
|
|
if (!SimIgnoreGlobals)
|
|
|
|
|
{
|
2020-05-23 23:13:14 +02:00
|
|
|
strptr = buffer + strlen(buffer) - 1;
|
|
|
|
|
if (*strptr == '!') {
|
2017-04-25 14:41:48 +02:00
|
|
|
*strptr = '\0';
|
|
|
|
|
while (strptr != buffer) {
|
|
|
|
|
if (*strptr == '/') {
|
|
|
|
|
strptr++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
strptr--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
strptr = buffer;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
strptr = buffer;
|
|
|
|
|
|
|
|
|
|
return(strptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
NullFunc()
|
|
|
|
|
{
|
|
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
* SimFreeNodeList
|
|
|
|
|
*
|
|
|
|
|
* This procedure frees all space allocated for the node list
|
|
|
|
|
* data structure.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* After the list has been deallocated, the head pointer is set to
|
|
|
|
|
* a NULL value.
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
SimFreeNodeList(List)
|
|
|
|
|
TileListElt **List;
|
|
|
|
|
{
|
|
|
|
|
TileListElt *current;
|
|
|
|
|
TileListElt *temp;
|
|
|
|
|
|
|
|
|
|
temp = *List;
|
|
|
|
|
while (temp != NULL) {
|
|
|
|
|
current = temp;
|
|
|
|
|
temp = temp->tl_next;
|
|
|
|
|
freeMagic(current->tl_nodeName);
|
|
|
|
|
freeMagic(current);
|
|
|
|
|
}
|
|
|
|
|
*List = (TileListElt *) NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TileListElt *
|
|
|
|
|
simFreeNodeEntry(list, entry)
|
|
|
|
|
TileListElt *list, *entry;
|
|
|
|
|
{
|
|
|
|
|
TileListElt *prev, *curr;
|
|
|
|
|
|
|
|
|
|
prev = list;
|
|
|
|
|
for( curr = prev->tl_next; curr != NULL; prev = curr,curr = curr->tl_next )
|
|
|
|
|
if( curr == entry )
|
|
|
|
|
{
|
|
|
|
|
prev->tl_next = curr->tl_next;
|
|
|
|
|
freeMagic( entry->tl_nodeName );
|
|
|
|
|
freeMagic( entry );
|
|
|
|
|
return( prev ); /* next element in list */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* should never get here */
|
|
|
|
|
return(entry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
* SimSelectArea
|
|
|
|
|
*
|
|
|
|
|
* This procedure checks the current selected paint in the circuit and
|
|
|
|
|
* extracts the names of all the nodes in the selected area.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Returns a list of node name data structures.
|
|
|
|
|
*
|
|
|
|
|
* Side Effects:
|
|
|
|
|
* The tiles of the selection cell definition are first marked in the
|
2020-05-23 23:13:14 +02:00
|
|
|
* search algorithm. After finishing the search, these marks are
|
2017-04-25 14:41:48 +02:00
|
|
|
* erased.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
TileListElt *
|
|
|
|
|
SimSelectArea(Rect *rect)
|
|
|
|
|
{
|
|
|
|
|
int plane;
|
|
|
|
|
int SimSelectFunc();
|
|
|
|
|
|
|
|
|
|
/* only need to extract node names if the selection has changed or
|
|
|
|
|
* if node aliases are to be printed.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if (SimRecomputeSel || (SimGetnodeAlias && SimIsGetnode)) {
|
|
|
|
|
SimFreeNodeList(&NodeList);
|
|
|
|
|
HashInit(&SimAbortSeenTbl, 20, HT_STRINGKEYS);
|
|
|
|
|
|
|
|
|
|
/* find all nodes in the current selection */
|
|
|
|
|
|
|
|
|
|
for (plane = PL_TECHDEPBASE; plane < DBNumPlanes; plane++)
|
|
|
|
|
{
|
|
|
|
|
(void) DBSrPaintArea((Tile *) NULL, SelectDef->cd_planes[plane],
|
|
|
|
|
&TiPlaneRect, &DBAllButSpaceAndDRCBits,
|
|
|
|
|
SimSelectFunc, (ClientData) &NodeList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HashKill(&SimAbortSeenTbl);
|
|
|
|
|
ExtResetTiles(SelectDef, (ClientData) CLIENTDEFAULT);
|
|
|
|
|
SimGetNodeCleanUp();
|
|
|
|
|
SimRecomputeSel = FALSE;
|
|
|
|
|
}
|
|
|
|
|
if (SigInterruptPending) {
|
|
|
|
|
|
|
|
|
|
/* if caught an interrupt, be sure to recompute the selection
|
|
|
|
|
* next time around.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
SimRecomputeSel = TRUE;
|
|
|
|
|
}
|
|
|
|
|
return(NodeList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
* SimSelectFunc
|
|
|
|
|
*
|
|
|
|
|
* This procedure is called for each tile in the current selection.
|
|
|
|
|
* It first checks to see if the node the tile belongs to has not
|
|
|
|
|
* yet been visited. If it has not been visited, then the node name
|
2020-05-23 23:13:14 +02:00
|
|
|
* is extracted and all other tiles in the selection which belong to
|
2017-04-25 14:41:48 +02:00
|
|
|
* this node are marked.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Return 0 to keep the search going.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
2020-05-23 23:13:14 +02:00
|
|
|
* The tiles in the selection cell definition are left marked.
|
2017-04-25 14:41:48 +02:00
|
|
|
* It is the responsibility of the calling function to erase these
|
|
|
|
|
* tile marks when finished.
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
SimSelectFunc(tile, pHead)
|
|
|
|
|
Tile *tile; /* Tile in SelectDef. */
|
|
|
|
|
TileListElt **pHead; /* list of node names found */
|
|
|
|
|
{
|
|
|
|
|
TileTypeBitMask mask;
|
|
|
|
|
SearchContext scx;
|
|
|
|
|
DBWclientRec *crec;
|
|
|
|
|
MagWindow *window;
|
|
|
|
|
char nameBuff[256], *nodeName;
|
|
|
|
|
TileListElt *newNodeTile;
|
|
|
|
|
TileType type;
|
|
|
|
|
bool coord;
|
|
|
|
|
|
|
|
|
|
window = CmdGetRootPoint((Point *) NULL, &scx.scx_area);
|
|
|
|
|
if (window == NULL) return 1;
|
|
|
|
|
|
|
|
|
|
/* check to see if the node has already been extracted */
|
|
|
|
|
|
2025-02-21 18:54:11 +01:00
|
|
|
if (TiGetClientINT(tile) == 1) {
|
2017-04-25 14:41:48 +02:00
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsSplit(tile))
|
|
|
|
|
{
|
|
|
|
|
type = (SplitSide(tile)) ? SplitRightType(tile):
|
|
|
|
|
SplitLeftType(tile);
|
2020-05-23 23:13:14 +02:00
|
|
|
}
|
2017-04-25 14:41:48 +02:00
|
|
|
else
|
|
|
|
|
type = TiGetTypeExact(tile);
|
|
|
|
|
|
|
|
|
|
/* get the tile's area, and initialize the tile's search context. */
|
|
|
|
|
|
|
|
|
|
TITORECT(tile, &scx.scx_area);
|
|
|
|
|
|
|
|
|
|
/* make sure that search context isn't placed on an empty */
|
|
|
|
|
/* corner of a split tile. */
|
|
|
|
|
if (IsSplit(tile))
|
|
|
|
|
{
|
|
|
|
|
if (SplitSide(tile))
|
|
|
|
|
scx.scx_area.r_xbot = scx.scx_area.r_xtop - 1;
|
|
|
|
|
if (!(SplitDirection(tile) ^ SplitSide(tile)))
|
|
|
|
|
scx.scx_area.r_ybot = scx.scx_area.r_ytop - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
scx.scx_area.r_xtop = scx.scx_area.r_xbot + 1;
|
|
|
|
|
scx.scx_area.r_ytop = scx.scx_area.r_ybot + 1;
|
|
|
|
|
|
|
|
|
|
scx.scx_use = (CellUse *) window->w_surfaceID;
|
|
|
|
|
scx.scx_trans = GeoIdentityTransform;
|
|
|
|
|
crec = (DBWclientRec *) window->w_clientData;
|
|
|
|
|
|
|
|
|
|
TTMaskZero(&mask);
|
|
|
|
|
TTMaskSetType(&mask, type);
|
|
|
|
|
TTMaskAndMask(&mask, &crec->dbw_visibleLayers);
|
|
|
|
|
TTMaskAndMask(&mask, &DBAllButSpaceAndDRCBits);
|
|
|
|
|
|
|
|
|
|
/* Check if the area is above a layer which is not visible. */
|
|
|
|
|
|
|
|
|
|
if (TTMaskIsZero(&mask)) {
|
|
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* mark all other tiles in the selection that are part of this node */
|
|
|
|
|
|
2020-05-23 23:13:14 +02:00
|
|
|
SimSrConnect(SelectDef, &scx.scx_area, &DBAllButSpaceAndDRCBits,
|
2017-04-25 14:41:48 +02:00
|
|
|
DBConnectTbl, &TiPlaneRect, NullFunc, (ClientData) NULL);
|
|
|
|
|
|
|
|
|
|
/* Pick a tile type to use for selection. */
|
|
|
|
|
|
|
|
|
|
for (type = TT_TECHDEPBASE; type < DBNumTypes; type += 1)
|
|
|
|
|
{
|
|
|
|
|
if (TTMaskHasType(&mask, type)) break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nodeName = SimSelectNode(&scx, type, CU_DESCEND_ALL, nameBuff);
|
|
|
|
|
|
|
|
|
|
/* add the node name to the list only if it has not been seen yet */
|
|
|
|
|
|
|
|
|
|
coord = (nodeName[0] == '@' && nodeName[1] == '=') ? TRUE : FALSE;
|
|
|
|
|
|
|
|
|
|
if(coord || HashLookOnly(&SimNodeNameTbl, nodeName) == (HashEntry *) NULL)
|
|
|
|
|
{
|
|
|
|
|
if( ! coord )
|
|
|
|
|
HashFind(&SimNodeNameTbl, nodeName);
|
|
|
|
|
newNodeTile = (TileListElt *) mallocMagic((unsigned) (sizeof (TileListElt)));
|
|
|
|
|
newNodeTile->tl_nodeName = (char *) mallocMagic((unsigned) (strlen(nodeName) + 1));
|
|
|
|
|
strcpy(newNodeTile->tl_nodeName, nodeName);
|
|
|
|
|
newNodeTile->tl_nodeTile = tile;
|
|
|
|
|
newNodeTile->tl_next = *pHead;
|
|
|
|
|
*pHead = newNodeTile;
|
|
|
|
|
}
|
|
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef RSIM_MODULE
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
* SimSelection
|
|
|
|
|
*
|
|
|
|
|
* This procedure applies the specified rsim command to the list of
|
|
|
|
|
* nodes in the current selection and also attaches the rsim node
|
|
|
|
|
* value string to each node.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* returns FALSE if no nodes are in the selection.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
SimSelection(cmd)
|
|
|
|
|
char *cmd; /* rsim command to apply to the selection */
|
|
|
|
|
{
|
|
|
|
|
static char Hstring[] = "RSIM=1";
|
|
|
|
|
static char Lstring[] = "RSIM=0";
|
|
|
|
|
static char Xstring[] = "RSIM=X";
|
|
|
|
|
static char QUESTstring[] = "?";
|
|
|
|
|
|
|
|
|
|
char timeString[256];
|
|
|
|
|
TileListElt *current, *node_list;
|
|
|
|
|
char *replyLine;
|
|
|
|
|
char *strPtr;
|
|
|
|
|
bool goodReply;
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2024-10-02 07:59:00 +02:00
|
|
|
extern void RsimErrorMsg();
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
timeString[0] = 0;
|
|
|
|
|
|
|
|
|
|
/* check to see if Rsim has been started yet */
|
|
|
|
|
|
|
|
|
|
if (!SimRsimRunning) {
|
|
|
|
|
RsimErrorMsg();
|
|
|
|
|
return(FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* get the list of all nodes in the selection */
|
|
|
|
|
|
|
|
|
|
SimIsGetnode = FALSE;
|
|
|
|
|
SimUseCoords = SimHasCoords;
|
|
|
|
|
|
|
|
|
|
HashInit(&SimNodeNameTbl, 60, HT_STRINGKEYS);
|
|
|
|
|
node_list = SimSelectArea((Rect *)NULL);
|
|
|
|
|
|
|
|
|
|
if (node_list == (TileListElt *) NULL) {
|
|
|
|
|
TxPrintf("You must select paint (rather than a cell) to use Rsim on \
|
|
|
|
|
the selection.\n");
|
|
|
|
|
goto bad;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Walk the list of node names, apply the rsim command to each node,
|
|
|
|
|
* and then process the results.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
for (current = node_list; current != NULL; current = current->tl_next)
|
|
|
|
|
{
|
|
|
|
|
current->tl_simLabel = QUESTstring;
|
|
|
|
|
SimRsimIt(cmd, current->tl_nodeName);
|
|
|
|
|
|
|
|
|
|
if (!SimGetReplyLine(&replyLine)) {
|
|
|
|
|
goto bad;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!replyLine) {
|
|
|
|
|
/* Rsim's reponse to the command was just a prompt. We are done
|
2020-05-23 23:13:14 +02:00
|
|
|
* with the current node, so process the next node in the
|
2017-04-25 14:41:48 +02:00
|
|
|
* selection.
|
|
|
|
|
*/
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* check for node names not recognized by Rsim */
|
|
|
|
|
|
|
|
|
|
if (strncmp(replyLine, "time = ", 7) == 0) {
|
|
|
|
|
if (timeString[0] == 0) {
|
|
|
|
|
strcpy(timeString, replyLine);
|
|
|
|
|
}
|
|
|
|
|
TxPrintf("%s not recognized in sim file\n", current->tl_nodeName);
|
|
|
|
|
while(replyLine) {
|
|
|
|
|
/* swallow Rsim reply until no more is left */
|
|
|
|
|
if (!SimGetReplyLine(&replyLine)) {
|
|
|
|
|
goto bad;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* update the node value label strings */
|
|
|
|
|
|
|
|
|
|
if (*cmd == 'd')
|
|
|
|
|
{
|
|
|
|
|
char *name = current->tl_nodeName;
|
|
|
|
|
bool coord = (name[0] == '@' && name[1] == '=') ? TRUE : FALSE;
|
|
|
|
|
|
|
|
|
|
strPtr = strrchr( replyLine, '=' );
|
|
|
|
|
if( strPtr == NULL )
|
|
|
|
|
strPtr = QUESTstring;
|
|
|
|
|
else if( coord )
|
|
|
|
|
{
|
|
|
|
|
*strPtr = '\0';
|
|
|
|
|
name = replyLine;
|
|
|
|
|
if( HashLookOnly(&SimNodeNameTbl, name) == (HashEntry *) NULL)
|
|
|
|
|
{
|
|
|
|
|
freeMagic(current->tl_nodeName);
|
|
|
|
|
current->tl_nodeName = (char *) mallocMagic((unsigned) (strlen(name) + 1));
|
|
|
|
|
strcpy(current->tl_nodeName, name);
|
|
|
|
|
HashFind(&SimNodeNameTbl, current->tl_nodeName);
|
|
|
|
|
*strPtr++ = '=';
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
current = simFreeNodeEntry( node_list, current );
|
|
|
|
|
*strPtr = '=';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
strPtr++;
|
|
|
|
|
|
|
|
|
|
switch (*strPtr) {
|
|
|
|
|
case '1' :
|
|
|
|
|
current->tl_simLabel = Hstring;
|
|
|
|
|
break;
|
|
|
|
|
case '0' :
|
|
|
|
|
current->tl_simLabel = Lstring;
|
|
|
|
|
break;
|
|
|
|
|
case 'X' :
|
|
|
|
|
current->tl_simLabel = Xstring;
|
|
|
|
|
break;
|
|
|
|
|
case '=' :
|
|
|
|
|
break;
|
|
|
|
|
default :
|
|
|
|
|
current->tl_simLabel = QUESTstring;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/* read all lines of the Rsim reply */
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
goodReply = TRUE;
|
|
|
|
|
for (;replyLine; goodReply = SimGetReplyLine(&replyLine)) {
|
|
|
|
|
if (!goodReply) {
|
|
|
|
|
goto bad;
|
|
|
|
|
}
|
|
|
|
|
if (!strncmp(replyLine, "time = ", 7)) {
|
|
|
|
|
if (!(timeString[0])) {
|
|
|
|
|
strcpy(timeString, replyLine);
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
} else if( *strPtr != '=' ) {
|
|
|
|
|
TxPrintf("%s\n", replyLine);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (timeString[0] != 0) {
|
|
|
|
|
TxPrintf("%s\n", timeString);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HashKill(&SimNodeNameTbl);
|
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
|
|
bad:
|
|
|
|
|
HashKill(&SimNodeNameTbl);
|
|
|
|
|
return(FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
* SimAddLabels
|
|
|
|
|
*
|
|
|
|
|
* This procedure adds the node value labels to the Magic database
|
2020-05-23 23:13:14 +02:00
|
|
|
* so they will be displayed in the layout.
|
2017-04-25 14:41:48 +02:00
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
2020-05-23 23:13:14 +02:00
|
|
|
* The cell modified flags are deliberately not set when these labels
|
2017-04-25 14:41:48 +02:00
|
|
|
* are added to the database.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
SimAddLabels(SelectNodeList, rootuse)
|
|
|
|
|
TileListElt *SelectNodeList;
|
|
|
|
|
CellDef *rootuse; /* the root cell def for the window */
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
TileListElt *current;
|
|
|
|
|
Rect selectBox;
|
|
|
|
|
int pos;
|
|
|
|
|
|
|
|
|
|
/* walk the list of selected nodes, add the node value label to the
|
|
|
|
|
* database.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
for (current = SelectNodeList; current != (TileListElt *) NULL;
|
|
|
|
|
current = current->tl_next) {
|
|
|
|
|
if (*(current->tl_simLabel) == '?') {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
TiToRect(current->tl_nodeTile, &selectBox);
|
2020-05-23 23:13:14 +02:00
|
|
|
pos = SimPutLabel(rootuse, &selectBox, GEO_CENTER,
|
2017-04-25 14:41:48 +02:00
|
|
|
current->tl_simLabel, TT_SPACE);
|
|
|
|
|
DBReComputeBbox(rootuse);
|
|
|
|
|
DBWLabelChanged(rootuse, current->tl_simLabel, &selectBox,
|
|
|
|
|
pos, DBW_ALLWINDOWS);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef RSIM_MODULE
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
* SimRsimMouse
|
|
|
|
|
*
|
|
|
|
|
* This procedure erases the old rsim node labels and display the
|
|
|
|
|
* node labels of the current selection.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
SimRsimMouse(w)
|
|
|
|
|
MagWindow *w;
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
CellUse *cu;
|
|
|
|
|
bool sawcell;
|
|
|
|
|
SimDefListElt *dummy;
|
|
|
|
|
|
|
|
|
|
if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID))
|
|
|
|
|
{
|
|
|
|
|
TxError("Put the cursor in a layout window\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cu = (CellUse *)w->w_surfaceID; /* get root cell use for wind */
|
|
|
|
|
|
|
|
|
|
/* check to see if the cell def is already in our list */
|
|
|
|
|
sawcell = FALSE;
|
|
|
|
|
for (dummy = SimCellLabList; dummy; dummy = dummy->dl_next) {
|
2020-05-23 23:13:14 +02:00
|
|
|
if (dummy->dl_def == cu->cu_def) {
|
2017-04-25 14:41:48 +02:00
|
|
|
sawcell = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!sawcell) {
|
|
|
|
|
/* add the cell def to the list */
|
|
|
|
|
if (SimCellLabList == (SimDefListElt *) NULL) {
|
|
|
|
|
SimCellLabList = (SimDefListElt *) mallocMagic((unsigned) (sizeof(SimDefListElt)));
|
|
|
|
|
SimCellLabList->dl_isMarked = FALSE;
|
|
|
|
|
SimCellLabList->dl_def = cu->cu_def;
|
|
|
|
|
SimCellLabList->dl_next = (SimDefListElt *) NULL;
|
|
|
|
|
dummy = SimCellLabList;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
dummy = (SimDefListElt *) mallocMagic((unsigned) (sizeof(SimDefListElt)));
|
|
|
|
|
dummy->dl_isMarked = FALSE;
|
|
|
|
|
dummy->dl_next = SimCellLabList;
|
|
|
|
|
dummy->dl_def = cu->cu_def;
|
|
|
|
|
SimCellLabList= dummy;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SimEraseLabels();
|
|
|
|
|
if (SimSelection("d")) {
|
|
|
|
|
dummy->dl_isMarked = TRUE;
|
|
|
|
|
SimAddLabels(NodeList, dummy->dl_def);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
* SimGetnode
|
|
|
|
|
*
|
|
|
|
|
* This procedure prints the node names of all selected nodes.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
SimGetnode()
|
|
|
|
|
{
|
|
|
|
|
TileListElt *current;
|
|
|
|
|
|
|
|
|
|
/* get the list of node names */
|
|
|
|
|
|
|
|
|
|
SimIsGetnode = TRUE;
|
|
|
|
|
SimUseCoords = FALSE;
|
|
|
|
|
|
|
|
|
|
HashInit(&SimNodeNameTbl, 60, HT_STRINGKEYS);
|
|
|
|
|
current = SimSelectArea((Rect *)NULL);
|
|
|
|
|
HashKill(&SimNodeNameTbl);
|
|
|
|
|
|
|
|
|
|
if (current == (TileListElt *) NULL) {
|
|
|
|
|
TxPrintf("You must select paint (not a cell) to use getnode.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-23 23:13:14 +02:00
|
|
|
for (; current != (TileListElt *) NULL; current = current->tl_next)
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
|
|
|
|
#ifdef MAGIC_WRAPPER
|
|
|
|
|
/* Return the node name as the result of the command */
|
|
|
|
|
Tcl_AppendElement(magicinterp, current->tl_nodeName);
|
|
|
|
|
#else
|
|
|
|
|
TxPrintf("node name : %s\n", current->tl_nodeName);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
* SimGetsnode
|
|
|
|
|
*
|
|
|
|
|
* This procedure prints the short node names of all selected nodes.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
SimGetsnode()
|
|
|
|
|
{
|
|
|
|
|
TileListElt *current;
|
|
|
|
|
|
|
|
|
|
/* get the list of node names */
|
|
|
|
|
|
|
|
|
|
SimIsGetnode = TRUE;
|
|
|
|
|
SimUseCoords = TRUE;
|
|
|
|
|
|
|
|
|
|
HashInit(&SimNodeNameTbl, 60, HT_STRINGKEYS);
|
|
|
|
|
current = SimSelectArea((Rect *)NULL);
|
|
|
|
|
HashKill(&SimNodeNameTbl);
|
|
|
|
|
|
|
|
|
|
if (current == (TileListElt *) NULL) {
|
|
|
|
|
TxPrintf("You must select paint (not a cell) to use getnode.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-23 23:13:14 +02:00
|
|
|
for (; current != (TileListElt *) NULL; current = current->tl_next)
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
|
|
|
|
#ifdef MAGIC_WRAPPER
|
|
|
|
|
/* Return the node short name as the result of the command */
|
|
|
|
|
Tcl_AppendElement(magicinterp, current->tl_nodeName);
|
|
|
|
|
#else
|
|
|
|
|
TxPrintf("short node name : %s\n", current->tl_nodeName);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
* SimEraseLabels
|
|
|
|
|
*
|
|
|
|
|
* This procedure erases the RSIM labels from any cell defs they
|
|
|
|
|
* may have been added to.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Removes the RSIM labels from "marked" cell defs.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
SimEraseLabels()
|
|
|
|
|
{
|
|
|
|
|
SimDefListElt *p;
|
|
|
|
|
|
|
|
|
|
for (p = SimCellLabList; p; p = p->dl_next) {
|
|
|
|
|
if (p->dl_isMarked) {
|
|
|
|
|
p->dl_isMarked = FALSE;
|
|
|
|
|
DBEraseLabelsByContent(p->dl_def, (Rect *)NULL, -1, "RSIM=X");
|
|
|
|
|
DBEraseLabelsByContent(p->dl_def, (Rect *)NULL, -1, "RSIM=1");
|
|
|
|
|
DBEraseLabelsByContent(p->dl_def, (Rect *)NULL, -1, "RSIM=0");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|