forked from RTimothyEdwards/magic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
oa.c
192 lines (170 loc) · 6.36 KB
/
oa.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*--------------------------------------------------------------*/
/* oa.c -- */
/* OpenAccess database support for magic */
/* */
/* Written by R. Timothy Edwards 4/22/04 */
/* Open Circuit Design, Inc. for */
/* MultiGiG, Inc. */
/*--------------------------------------------------------------*/
#ifdef MAGIC_WRAPPER
#ifdef OPENACCESS
#include "tcltk/tclmagic.h"
#include "utils/geometry.h"
#include "utils/magic.h"
#include "tiles/tile.h"
#include "utils/hash.h"
#include "database/database.h"
#include "oa/oa.h"
/*
*-----------------------------------------------------------------------------
*
* OAInit --
*
* Initialize variables required by the OpenAccess module.
*
*-----------------------------------------------------------------------------
*/
void
OAInit()
{
/* This generates the TCL commands for magicoa */
Magicoa_Init(magicinterp);
}
/*
*-----------------------------------------------------------------------------
*
* OACellSearch --
*
* The OpenAccess equivalent of DBTreeSrCells. This function is called by
* DBTreeSrCells when the cell def has the flag CDOPENACCESS set.
*
* The procedure should be of the following form:
* int
* func(scx, cdarg)
* SearchContext *scx;
* ClientData cdarg;
* {
* }
*
* In the above, the transform scx->scx_trans is from coordinates of
* the def of scx->scx_use to the "root". The array indices
* scx->scx_x and scx->scx_y identify this element if it is a
* component of an array. Func normally returns 0. If func returns
* 1, then the search is aborted. If func returns 2, then all
* remaining elements of the current array are skipped, but the
* search is not aborted.
*
* Each element of an array is returned separately.
*
* Results:
* 0 is returned if the search terminated normally. 1 is
* returned if it was aborted.
*
* Side effects:
* Whatever side effects are brought about by applying the
* procedure supplied.
*
* Warnings:
* The OpenAccess routines should only be used when (*func)()
* is read-only; that is, the function should not attempt to
* alter the cell structure.
*-----------------------------------------------------------------------------
*/
int
OACellSearch(scx, xMask, func, cdarg)
SearchContext *scx; /* Pointer to search context specifying a cell use to
* search, an area in the coordinates of the cell's
* def, and a transform back to "root" coordinates.
*/
int xMask; /* All subcells are visited recursively until we
* encounter uses whose flags, when anded with
* xMask, are not equal to xMask. Func is called
* for these cells. A zero mask means all cells in
* the root use are considered not to be expanded,
* and hence are passed to func.
*/
int (*func)(); /* Function to apply to each qualifying cell */
ClientData cdarg; /* Client data for above function */
{
TreeContext context;
TreeFilter filter;
char *instname;
filter.tf_xmask = xMask;
filter.tf_func = func;
filter.tf_arg = cdarg;
context.tc_scx = scx;
context.tc_filter = &filter;
/* Get the name of the instance, which should have been set by */
/* rexlite when the OpenAccess database was opened under magic. */
instname = scx->scx_use->cu_id;
/* Query the OpenAccess database. For each cell overlapping the
* area scx->scx_area, call the function (*func)() with client
* data cdarg. Currently, xMask is not used (assumed to be 0).
*/
/* The rexlite function is tentatively called REXSearchInstances(): */
/* REXSearchInstances(name, func, arg) { */
/* char *name; */
/* (int)(*func)(); */
/* ClientData arg; */
/* */
/* This function should return 0 normally, 1 in case of error. */
/* For each cell instance which is in the hierarchy of "instname", */
/* REXSearchInstances() should call "func" with arguments: */
/* */
/* (int)(*func)(char *iname, char *dname, int llx, int lly, */
/* int urx, int urx, ClientData arg); */
/* */
/* where "iname" is the name of the instance, "dname" is the name */
/* of the master cell, and "llx", "lly", "urx", and "ury" are the */
/* bounding box coordinates. "arg" is passed on from above. */
/* If func() returns 0, then the database search should continue. */
/* If func() returns 1, then the database search should stop and */
/* REXSearchInstances() should return 1. */
/* return REXSearchInstances(instname, oaTreeCellSrFunc, (ClientData)&context); */
return 0; /* placeholder */
}
/*
* Callback function called from REXSearchInstances() for each instance
* encountered in the cell search.
*
* For the time being, we pass back a minimal amount of information: The
* instance name and the bounding box. The bounding box will be compared
* against the search area to check for overlap, and the function buried
* in the TreeContext structure (passed as a generic client data pointer)
* will be called.
*/
int
oaTreeCellSrFunc(instname, defname, llx, lly, urx, ury, cdarg)
char *instname;
char *defname;
int llx, lly, urx, ury;
ClientData cdarg;
{
TreeContext *context = (TreeContext *)cdarg;
TreeFilter *filter = context->tc_filter;
SearchContext newscx, *scx = context->tc_scx;
int fres;
Rect r, *area = &scx->scx_area;
CellUse newuse;
/* Check for area overlap */
r.r_xbot = llx;
r.r_xtop = urx;
r.r_ybot = lly;
r.r_ytop = ury;
/* Transform---for now, assuming that llx, etc., are relative to */
/* the top-level coordinate system. */
/* Check for area overlap */
if (!GEO_OVERLAP(area, &r))
return 0; /* Don't call function but keep the search going */
newuse.cu_id = instname;
newuse.cu_bbox = r;
/* Need to fill in more of the CellUse structure! */
newscx.scx_use = &newuse;
newscx.scx_area = scx->scx_area;
/* Need to fill in more of the SearchContext structure! */
/* Call the function */
fres = (*(filter->tf_func))(newscx, (ClientData)filter->tf_arg);
return fres; /* keep the search going */
}
#endif /* OPENACCESS */
#endif /* MAGIC_WRAPPER */