Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / yagle / yagle / yag_constrain.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI Alliance */
4 /* */
5 /* Produit : YAGLE v3.50 */
6 /* Fichier : yag_constrain.c */
7 /* */
8 /* (c) copyright 1995 Laboratoire MASI equipe CAO & VLSI */
9 /* Tous droits reserves */
10 /* Support : e-mail alliance-support@asim.lip6.fr */
11 /* */
12 /* Auteur(s) : Anthony LESTER le : 30/05/1995 */
13 /* */
14 /* Modifie par : le : ../../.... */
15 /* Modifie par : le : ../../.... */
16 /* Modifie par : le : ../../.... */
17 /* */
18 /****************************************************************************/
19
20 #include "yag_headers.h"
21
22 static chain_list *getOppositeSwitchList(losig_list *ptsig);
23 static void markConstrained (list_list *headlist);
24 static locon_list *getLocon (char *name);
25 static cone_list *getCone (char *name);
26
27 static ht *YAG_CONSTRAINT_HT = NULL;
28 static ht *YAG_VARLIST_HT = NULL;
29
30 /*****************************************************************************
31 * function yagInitConstraints() *
32 *****************************************************************************/
33
34 /* generate the list of constraints, mark the connectors and cones */
35 /* concerned, and generate the list of constrained variables. */
36
37 void
38 yagInitConstraints(inffig_list *ifl)
39 {
40 chain_list *ptconstraints = NULL;
41 chain_list *ptchain, *ptvarlist;
42 list_list *ptlist;
43 void *object;
44 long *common;
45
46 ptconstraints = yagMuxToConstraint(ifl);
47 if (ptconstraints != NULL) {
48 if (yagCountChains(ptconstraints) > 10) {
49 YAG_CONSTRAINT_HT = addht(100);
50 YAG_VARLIST_HT = addht(100);
51 }
52 else {
53 YAG_CONSTRAINT_HT = NULL;
54 YAG_VARLIST_HT = NULL;
55 }
56 markConstrained((list_list *)ptconstraints->DATA);
57 YAG_CONTEXT->YAG_CONSTRAINT_LIST = ptconstraints;
58 if (YAG_VARLIST_HT) {
59 for (ptlist = (list_list *)ptconstraints->DATA; ptlist; ptlist = ptlist->NEXT) {
60 addhtitem(YAG_VARLIST_HT, ptlist->DATA, (long)ptlist);
61 }
62 }
63 for (ptchain = YAG_CONTEXT->YAG_CONSTRAINT_LIST->NEXT; ptchain; ptchain = ptchain->NEXT) {
64 common=(long *)mbkalloc(sizeof(long));
65 *common=0;
66 for (ptlist = (list_list *) ptchain->DATA; ptlist; ptlist = ptlist->NEXT) {
67 ptlist->COMMON=common;
68 (*common)++;
69 if (YAG_CONSTRAINT_HT) {
70 object = ptlist->DATA;
71 if ((ptvarlist = (chain_list *)gethtitem(YAG_CONSTRAINT_HT, object)) != (void *)EMPTYHT) {
72 ptvarlist = addchain(ptvarlist, ptlist);
73 sethtitem(YAG_CONSTRAINT_HT, object, (long)ptvarlist);
74 }
75 else addhtitem(YAG_CONSTRAINT_HT, object, (long)addchain(NULL, ptlist));
76 }
77 }
78 }
79 }
80 }
81
82 void
83 yagDeleteConstraints()
84 {
85 chain_list *ptchain, *ptvarlist;
86 list_list *ptlist, *ptnextlist;
87 void *object;
88
89 if (YAG_CONTEXT->YAG_CONSTRAINT_LIST != NULL) {
90 for (ptlist = (list_list *)YAG_CONTEXT->YAG_CONSTRAINT_LIST->DATA; ptlist; ptlist = ptnextlist) {
91 ptnextlist = ptlist->NEXT;
92 freechain(ptlist->SUPDATA);
93 mbkfree(ptlist);
94 }
95 for (ptchain = YAG_CONTEXT->YAG_CONSTRAINT_LIST->NEXT; ptchain; ptchain = ptchain->NEXT) {
96 for (ptlist = (list_list *) ptchain->DATA; ptlist; ptlist = ptnextlist) {
97 ptnextlist = ptlist->NEXT;
98 freechain(ptlist->SUPDATA);
99 if (ptlist == ptchain->DATA) mbkfree(ptlist->COMMON);
100 if (YAG_CONSTRAINT_HT) {
101 object = ptlist->DATA;
102 ptvarlist = (chain_list *)gethtitem(YAG_CONSTRAINT_HT, object);
103 if (ptvarlist != (void *)EMPTYHT && ptvarlist != (void *)DELETEHT) {
104 freechain(ptvarlist);
105 delhtitem(YAG_CONSTRAINT_HT, object);
106 }
107 }
108 mbkfree(ptlist);
109 }
110 }
111 freechain(YAG_CONTEXT->YAG_CONSTRAINT_LIST);
112 YAG_CONTEXT->YAG_CONSTRAINT_LIST = NULL;
113 if (YAG_CONSTRAINT_HT) {
114 delht(YAG_CONSTRAINT_HT);
115 YAG_CONSTRAINT_HT = NULL;
116 }
117 if (YAG_VARLIST_HT) {
118 delht(YAG_VARLIST_HT);
119 YAG_VARLIST_HT = NULL;
120 }
121 }
122 }
123
124 /*****************************************************************************
125 * function yagGetConstraint() *
126 *****************************************************************************/
127
128 /* scans the list of constraints and return the first */
129 /* for which all the variables have been tagged. */
130
131 chain_list *
132 yagGetConstraint(chain_list *ptcontraints)
133 {
134 chain_list *ptchain;
135 list_list *ptlist;
136 long common;
137 for (ptchain = ptcontraints; ptchain; ptchain = ptchain->NEXT) {
138 ptlist = (list_list *)ptchain->DATA;
139 common = *(long *)ptlist->COMMON;
140 if (common==0) return ptchain;
141 }
142 return ptchain;
143 }
144
145 /*****************************************************************************
146 * function yagTagConstraint() *
147 *****************************************************************************/
148
149 /* tag the constraint variables which refer to the given object */
150
151 void
152 yagTagConstraint(void *object)
153 {
154 chain_list *pt;
155 chain_list *ptchain, *ptvarlist;
156 list_list *list;
157 list_list *ptmainvar;
158 chain_list *ptnamechain;
159 char *ptothername;
160
161
162 if (YAG_CONSTRAINT_HT) {
163 if ((ptvarlist = (chain_list *)gethtitem(YAG_CONSTRAINT_HT, object)) != (void *)EMPTYHT) {
164 for (ptchain = ptvarlist; ptchain; ptchain = ptchain->NEXT) {
165 list=(list_list *)ptchain->DATA;
166 if (list->TYPE == 0) {
167 (*(long *)list->COMMON)--;
168 list->TYPE = -1L;
169 }
170 }
171 }
172 /* Tag also the opposite switch variables */
173 ptmainvar = (list_list *)gethtitem(YAG_VARLIST_HT, object);
174 if (ptmainvar != (list_list *)EMPTYHT) {
175 for (ptnamechain = ptmainvar->SUPDATA; ptnamechain; ptnamechain = ptnamechain->NEXT) {
176 ptothername = (char *)ptnamechain->DATA;
177 if ((ptvarlist = (chain_list *)gethtitem(YAG_CONSTRAINT_HT, ptothername)) != (void *)EMPTYHT) {
178 for (ptchain = ptvarlist; ptchain; ptchain = ptchain->NEXT) {
179 list=(list_list *)ptchain->DATA;
180 if (list->TYPE == 0) {
181 (*(long *)list->COMMON)--;
182 list->TYPE = -1L;
183 }
184 }
185 }
186 }
187 }
188 }
189 else if (YAG_CONTEXT->YAG_CONSTRAINT_LIST) { /* Without the hash table */
190 for (pt = YAG_CONTEXT->YAG_CONSTRAINT_LIST->NEXT; pt; pt = pt->NEXT) {
191 for (list = (list_list *) pt->DATA; list; list = list->NEXT) {
192 if (object == list->DATA) {
193 if (list->TYPE == 0) {
194 (*(long *)list->COMMON)--;
195 list->TYPE = -1L;
196 }
197 }
198 }
199 }
200 /* Tag also the opposite switch variables */
201 for (ptmainvar = YAG_CONTEXT->YAG_CONSTRAINT_LIST->DATA; ptmainvar && ptmainvar->DATA != object; ptmainvar = ptmainvar->NEXT);
202 if (ptmainvar) {
203 for (ptnamechain = ptmainvar->SUPDATA; ptnamechain; ptnamechain = ptnamechain->NEXT) {
204 ptothername = (char *)ptnamechain->DATA;
205 for (pt = YAG_CONTEXT->YAG_CONSTRAINT_LIST->NEXT; pt; pt = pt->NEXT) {
206 for (list = (list_list *) pt->DATA; list; list = list->NEXT) {
207 if (ptothername == list->DATA) {
208 if (list->TYPE == 0) {
209 (*(long *)list->COMMON)--;
210 list->TYPE = -1L;
211 }
212 }
213 }
214 }
215 }
216 }
217 }
218 }
219
220 /*****************************************************************************
221 * function yagRemoveConstraintTags() *
222 *****************************************************************************/
223
224 /* remove all the tags of the constraint list */
225
226 void
227 yagRemoveConstraintTags()
228 {
229 chain_list *ptchain;
230 list_list *ptlist;
231
232 for (ptchain = YAG_CONTEXT->YAG_CONSTRAINT_LIST->NEXT; ptchain; ptchain = ptchain->NEXT) {
233 for (ptlist = (list_list *)ptchain->DATA; ptlist; ptlist = ptlist->NEXT)
234 {
235 (*(long *)ptlist->COMMON)++;
236 }
237 }
238 }
239
240
241 /*****************************************************************************
242 * function yagGetOppositeConstraintVars() *
243 *****************************************************************************/
244
245 /* given a name returns list of any names on other side of eventual switches */
246
247 chain_list *
248 yagGetOppositeConstraintVars(char *name)
249 {
250 list_list *ptmainvar;
251
252 if (YAG_CONTEXT->YAG_CONSTRAINT_LIST == NULL) return NULL;
253 if (YAG_VARLIST_HT) {
254 ptmainvar = (list_list *)gethtitem(YAG_VARLIST_HT, name);
255 if (ptmainvar != (list_list *)EMPTYHT) {
256 return ptmainvar->SUPDATA;
257 }
258 }
259 else {
260 for (ptmainvar = YAG_CONTEXT->YAG_CONSTRAINT_LIST->DATA; ptmainvar && ptmainvar->DATA != name; ptmainvar = ptmainvar->NEXT);
261 if (ptmainvar) {
262 return ptmainvar->SUPDATA;
263 }
264 }
265 return NULL;
266 }
267
268 /*****************************************************************************
269 * function getOppositeSwitchList() *
270 *****************************************************************************/
271
272 /* given a losig returns list of any names on other side of eventual switches */
273
274 static chain_list *
275 getOppositeSwitchList(losig_list *ptsig)
276 {
277 chain_list *reschain = NULL;
278 chain_list *loconchain;
279 chain_list *ptchain;
280 locon_list *ptlocon;
281 lotrs_list *pttrans, *ptothertrans;
282 char *oppositename;
283 ptype_list *ptuser;
284
285
286 loconchain = (chain_list *)getptype(ptsig->USER, LOFIGCHAIN)->DATA;
287 for (ptchain = loconchain; ptchain; ptchain = ptchain->NEXT) {
288 ptlocon = (locon_list *)ptchain->DATA;
289 if (ptlocon->TYPE == 'T' && ptlocon->NAME == CNS_GRIDNAME) {
290 pttrans = ptlocon->ROOT;
291 if ((ptuser = getptype(pttrans->USER, CNS_SWITCH)) != NULL) {
292 ptothertrans = (lotrs_list *)ptuser->DATA;
293 oppositename = ((cone_list *)ptothertrans->GRID)->NAME;
294 if (yagGetChain(reschain, oppositename) == NULL) {
295 reschain = addchain(reschain, oppositename);
296 }
297 }
298 }
299 }
300 return reschain;
301 }
302
303 /*****************************************************************************
304 * function markConstrained() *
305 *****************************************************************************/
306
307 /* mark all constrained cones and connectors */
308 /* build list of opposite switch names */
309
310 static void
311 markConstrained(list_list *headlist)
312 {
313 list_list *ptlist;
314 locon_list *ptcon;
315 cone_list *ptcone;
316 losig_list *ptsig;
317 char *varName;
318 int found;
319
320 for (ptlist = headlist; ptlist; ptlist = ptlist->NEXT) {
321 varName = (char *)ptlist->DATA;
322 found = FALSE;
323 ptsig = NULL;
324 if ((ptcon = getLocon(varName)) != NULL) {
325 ptcon->USER = addptype(ptcon->USER, YAG_CONSTRAINT_PTYPE, NULL);
326 found = TRUE;
327 }
328 if ((ptcone = getCone(varName)) != NULL) {
329 ptcone->TYPE |= YAG_CONSTRAINT;
330 ptsig = (losig_list *)getptype(ptcone->USER, CNS_SIGNAL)->DATA;
331 found = TRUE;
332 }
333 if (found == FALSE) {
334 avt_errmsg(YAG_ERRMSG, "008", AVT_FATAL, varName);
335 }
336 if (ptsig) ptlist->SUPDATA = getOppositeSwitchList(ptsig);
337 }
338 }
339
340 /*****************************************************************************
341 * function getLocon() *
342 *****************************************************************************/
343
344 /* returns a connector pointer from its name */
345
346 static locon_list *
347 getLocon(char *name)
348 {
349 locon_list *ptcon;
350
351 for (ptcon = CNS_HEADCNSFIG->LOCON; ptcon != NULL; ptcon = ptcon->NEXT) {
352 if (ptcon->NAME == name) break;
353 }
354 return ptcon;
355 }
356
357 /*****************************************************************************
358 * function getCone() *
359 *****************************************************************************/
360
361 /* returns a cone pointer from its name */
362
363 static cone_list *
364 getCone(char *name)
365 {
366 cone_list *ptcone = NULL;
367
368 for (ptcone = CNS_HEADCNSFIG->CONE; ptcone; ptcone = ptcone->NEXT) {
369 if (ptcone->NAME == name) break;
370 }
371 return ptcone;
372 }
373