Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / yagle / yagle / yag_chain.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI Alliance */
4 /* */
5 /* Produit : YAGLE v3.50 */
6 /* Fichier : yag_chain.c */
7 /* */
8 /* (c) copyright 1994 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 : 26/05/1994 */
13 /* */
14 /* Modifie par : le : ../../.... */
15 /* Modifie par : le : ../../.... */
16 /* Modifie par : le : ../../.... */
17 /* */
18 /****************************************************************************/
19
20 #include "yag_headers.h"
21
22 #define BLOCKED 0
23 #define PATH_FOUND 1
24 #define BRLOOP 2
25
26 static ht *TRANSHT;
27 static chain_list *VISITED;
28 static ht *VISITED_FAST;
29 static ptype_list *INPUT_TYPE;
30 static int search_depth;
31
32 static int find_inputs(inffig_list *ifl, cone_list *ptcone, locon_list *ptcon, edge_list **ptptinputs, ht **FASTSEARCH);
33
34 /****************************************************************************
35 * function yagChainTrans(); *
36 ****************************************************************************/
37
38 /* remplissage des champs GRID des transistors */
39
40 void
41 yagChainTrans(lotrs_list *pttrans)
42 {
43 losig_list *ptsig = NULL;
44 ptype_list *user = NULL;
45
46 ptsig = pttrans->GRID->SIG;
47
48 user = getptype(ptsig->USER, YAG_CONE_PTYPE);
49
50 if (user != NULL && (((cone_list *)user->DATA)->TYPE & YAG_TEMPCONE) == 0) {
51 pttrans->GRID = (locon_list *)user->DATA;
52 pttrans->USER = addptype(pttrans->USER, CNS_DRIVINGCONE, user->DATA);
53 }
54 else {
55 if (getptype(pttrans->USER, YAG_GRIDCON_PTYPE) == NULL) {
56 pttrans->USER = addptype(pttrans->USER, YAG_GRIDCON_PTYPE, pttrans->GRID);
57 }
58 pttrans->GRID = NULL;
59 pttrans->USER = addptype(pttrans->USER, CNS_DRIVINGCONE, NULL);
60 }
61 }
62
63 /****************************************************************************
64 * function yagChainDual(); *
65 ****************************************************************************/
66 /*---------------------------------------------------*
67 | fill INCONE fields of CMOS duals |
68 *---------------------------------------------------*/
69
70 void
71 yagChainDual(cone_list *ptcone)
72 {
73 branch_list *ptbranch = NULL;
74 link_list *ptlink = NULL;
75 cone_list *ptincone;
76 edge_list *ptedge, *ptinputs = NULL;
77 lotrs_list *ptlotrs;
78 long inputtype;
79
80 for (ptbranch = ptcone->BRVDD; ptbranch != NULL; ptbranch = ptbranch->NEXT) {
81 for (ptlink = ptbranch->LINK; ptlink != NULL; ptlink = ptlink->NEXT) {
82 if ((ptlink->TYPE & CNS_SHORT) == CNS_SHORT) continue;
83 ptlotrs = ptlink->ULINK.LOTRS;
84 if ((ptlink->TYPE & CNS_TPLINK) == CNS_TPLINK) {
85 ptincone = (cone_list *)ptlotrs->GRID;
86 if (ptincone == NULL) {
87 ptbranch->TYPE |= CNS_NOT_FUNCTIONAL;
88 continue;
89 }
90 if (yagGetEdge(ptcone->INCONE, ptincone) == NULL) {
91 inputtype = ptincone->TYPE & (CNS_VDD|CNS_VSS);
92 if (inputtype == 0) inputtype = CNS_CONE;
93 addincone(ptcone, inputtype, ptincone);
94 }
95 }
96 else {
97 yagBug(DBG_ILL_LINKTYPE, "yagChainDual", ptcone->NAME, NULL, 0);
98 }
99 }
100 }
101 for (ptbranch = ptcone->BRVSS; ptbranch != NULL; ptbranch = ptbranch->NEXT) {
102 for (ptlink = ptbranch->LINK; ptlink != NULL; ptlink = ptlink->NEXT) {
103 if ((ptlink->TYPE & CNS_SHORT) == CNS_SHORT) continue;
104 ptlotrs = ptlink->ULINK.LOTRS;
105 if ((ptlink->TYPE & CNS_TNLINK) == CNS_TNLINK) {
106 ptincone = (cone_list *)ptlink->ULINK.LOTRS->GRID;
107 if (ptincone == NULL) {
108 ptbranch->TYPE |= CNS_NOT_FUNCTIONAL;
109 continue;
110 }
111 if (yagGetEdge(ptcone->INCONE, ptincone) == NULL) {
112 inputtype = ptincone->TYPE & (CNS_VDD|CNS_VSS);
113 if (inputtype == 0) inputtype = CNS_CONE;
114 addincone(ptcone, inputtype, ptincone);
115 }
116 }
117 else {
118 yagBug(DBG_ILL_LINKTYPE, "yagChainDual", ptcone->NAME, NULL, 0);
119 }
120 }
121 }
122 for (ptedge = ptcone->INCONE; ptedge; ptedge = ptedge->NEXT) {
123 ptinputs = addedge(ptinputs, ptedge->TYPE, ptedge->UEDGE.PTR);
124 }
125 ptcone->USER = addptype(ptcone->USER, YAG_DUALINPUTS_PTYPE, ptinputs);
126 }
127
128 /****************************************************************************
129 * function yagChainBranch(); *
130 ****************************************************************************/
131 /*---------------------------------------------------*
132 | update INCONE fields |
133 *---------------------------------------------------*/
134
135 void
136 yagChainBranch(cone_list *ptcone, branch_list *ptbranch)
137 {
138 link_list *ptlink;
139 ptype_list *ptuser;
140 locon_list *ptcon;
141 cone_list *ptincone;
142 edge_list *ptedge;
143 lotrs_list *ptlotrs;
144 long linktype, branchtype;
145 long inputtype;
146
147 branchtype = ptbranch->TYPE & (CNS_VSS|CNS_VDD|CNS_EXT);
148
149 for (ptlink = ptbranch->LINK; ptlink != NULL; ptlink = ptlink->NEXT) {
150
151 if ((ptlink->TYPE & CNS_SHORT) == CNS_SHORT) continue;
152 if ((ptlink->TYPE & CNS_DIODE_UP) == CNS_DIODE_UP) continue;
153 if ((ptlink->TYPE & CNS_DIODE_DOWN) == CNS_DIODE_DOWN) continue;
154 linktype = ptlink->TYPE & (CNS_TNLINK|CNS_TPLINK|CNS_IN|CNS_INOUT);
155 if (linktype == 0) {
156 yagBug(DBG_ILL_LINKTYPE, "yagChainBranch", ptcone->NAME, NULL, 0);
157 continue;
158 }
159
160 if (linktype == CNS_TNLINK || linktype == CNS_TPLINK) {
161 ptlotrs = ptlink->ULINK.LOTRS;
162 ptincone = (cone_list *)ptlink->ULINK.LOTRS->GRID;
163 if (ptincone == NULL) {
164 ptbranch->TYPE |= CNS_NOT_FUNCTIONAL;
165 continue;
166 }
167 inputtype = ptincone->TYPE & (CNS_VDD|CNS_VSS);
168 if (inputtype == 0) inputtype = CNS_CONE;
169 if ((ptlink->TYPE & CNS_RESIST) != CNS_RESIST) {
170 if ((ptbranch->TYPE & CNS_BLEEDER) == CNS_BLEEDER && inputtype == CNS_CONE) {
171 inputtype |= CNS_BLEEDER|CNS_LOOP;
172 }
173 }
174 if ((ptlink->TYPE & CNS_COMMAND) != 0) inputtype |= CNS_COMMAND;
175 if ((ptedge = yagGetEdge(ptcone->INCONE, ptincone)) != NULL) {
176 if ((ptedge->TYPE & YAG_FALSECONF) != 0 && (ptbranch->TYPE & YAG_FALSECONF) == 0) {
177 ptedge->TYPE &= ~YAG_FALSECONF;
178 }
179 if ((ptedge->TYPE & YAG_NOT_FUNCTIONAL) != 0 && (ptbranch->TYPE & CNS_NOT_FUNCTIONAL) == 0) {
180 ptedge->TYPE &= ~YAG_NOT_FUNCTIONAL;
181 }
182 ptedge->TYPE |= inputtype;
183 }
184 else {
185 if ((ptbranch->TYPE & YAG_FALSECONF) != 0) inputtype |= YAG_FALSECONF;
186 if ((ptbranch->TYPE & CNS_NOT_FUNCTIONAL) != 0) inputtype |= YAG_NOT_FUNCTIONAL;
187 addincone(ptcone, inputtype, ptincone);
188 }
189 }
190
191 /*------------------------------+
192 | external connector link |
193 +------------------------------*/
194 else {
195 ptcon = ptlink->ULINK.LOCON;
196 inputtype = CNS_EXT;
197 if ((ptedge = yagGetEdge(ptcone->INCONE, ptcon)) != NULL) {
198 if ((ptedge->TYPE & YAG_FALSECONF) != 0 && (ptbranch->TYPE & YAG_FALSECONF) == 0) {
199 ptedge->TYPE &= ~YAG_FALSECONF;
200 }
201 if ((ptedge->TYPE & YAG_NOT_FUNCTIONAL) != 0 && (ptbranch->TYPE & CNS_NOT_FUNCTIONAL) == 0) {
202 ptedge->TYPE &= ~YAG_NOT_FUNCTIONAL;
203 }
204 }
205 else {
206 if ((ptbranch->TYPE & YAG_FALSECONF) != 0) inputtype |= YAG_FALSECONF;
207 if ((ptbranch->TYPE & CNS_NOT_FUNCTIONAL) != 0) inputtype |= YAG_NOT_FUNCTIONAL;
208 addincone(ptcone, inputtype, ptcon);
209 }
210
211 /* Add CNS_CONE and CNS_LOCON ptypes to LOCON and CONE */
212 ptuser = getptype(ptcon->USER, CNS_CONE);
213 if (ptuser != NULL) {
214 if (yagGetChain(ptuser->DATA, ptcone) == NULL) {
215 ptuser->DATA = addchain(ptuser->DATA, ptcone);
216 }
217 }
218 else ptcon->USER = addptype(ptcon->USER, CNS_CONE, addchain(NULL, ptcone));
219 ptuser = getptype(ptcone->USER, CNS_LOCON);
220 if (ptuser != NULL) {
221 if (yagGetChain(ptuser->DATA, ptcon) == NULL) {
222 ptuser->DATA = addchain(ptuser->DATA, ptcon);
223 }
224 }
225 else ptcone->USER = addptype(ptcone->USER, CNS_LOCON, addchain(NULL, ptcon));
226 }
227 }
228 }
229
230 /****************************************************************************
231 * function yagChainCone(); *
232 ****************************************************************************/
233 /*---------------------------------------------------*
234 | update INCONE fields after branch removal |
235 *---------------------------------------------------*/
236
237 void
238 yagChainCone(cone_list *ptcone)
239 {
240 edge_list *old_edge_list;
241 edge_list *ptedge;
242 edge_list *ptoldedge;
243 locon_list *ptcon;
244 ptype_list *ptuser;
245 branch_list *ptbranch;
246 branch_list *brlist[4];
247 int i;
248
249 /* destroy connector references to cone */
250 for (ptedge = ptcone->INCONE; ptedge; ptedge = ptedge->NEXT) {
251 if (ptedge->TYPE == CNS_EXT) {
252 ptcon = ptedge->UEDGE.LOCON;
253 ptuser = getptype(ptcon->USER, CNS_CONE);
254 if (ptuser != NULL) {
255 ptuser->DATA = yagRmvChain(ptuser->DATA, ptcone);
256 if (ptuser->DATA == NULL) {
257 ptcon->USER = delptype(ptcon->USER, CNS_CONE);
258 }
259 }
260 }
261 }
262
263 /* delete the INCONE list */
264 old_edge_list = ptcone->INCONE;
265 ptcone->INCONE = NULL;
266
267 /* rebuild the INCONE list */
268 brlist[0] = ptcone->BRVDD;
269 brlist[1] = ptcone->BRVSS;
270 brlist[2] = ptcone->BREXT;
271 brlist[3] = ptcone->BRGND;
272
273 for (i=0; i<4; i++) {
274 for (ptbranch = brlist[i]; ptbranch; ptbranch = ptbranch->NEXT) {
275 if ((ptbranch->TYPE & YAG_IGNORE) != 0) continue;
276 yagChainBranch(ptcone, ptbranch);
277 }
278 }
279
280 /* Recuperate edge TYPE information */
281 if (old_edge_list != NULL) {
282 for (ptedge = ptcone->INCONE; ptedge; ptedge = ptedge->NEXT) {
283 ptoldedge = yagGetEdge(old_edge_list, ptedge->UEDGE.PTR);
284 if (ptoldedge != NULL) ptedge->TYPE |= ptoldedge->TYPE & ~(CNS_COMMAND|YAG_FALSECONF);
285 }
286 yagFreeEdgeList(old_edge_list);
287 }
288 }
289
290 /****************************************************************************
291 * function yagBuildOutputs(); *
292 ****************************************************************************/
293 /*---------------------------------------------------*
294 | build OUTCONE fields |
295 *---------------------------------------------------*/
296
297 void
298 yagBuildOutputs(cone_list *ptcone)
299 {
300 edge_list *ptinedge;
301 cone_list *ptincone;
302 locon_list *ptcon;
303 chain_list *ptconlist, *ptchain;
304 long outtype;
305
306 for (ptinedge = ptcone->INCONE; ptinedge; ptinedge = ptinedge->NEXT) {
307 if ((ptinedge->TYPE & (CNS_CONE|CNS_VDD|CNS_VSS)) != 0) {
308 ptincone = ptinedge->UEDGE.CONE;
309 outtype = CNS_CONE;
310 if ((ptinedge->TYPE & CNS_LOOP) != 0) outtype |= CNS_LOOP;
311 if ((ptinedge->TYPE & CNS_BLEEDER) != 0) outtype |= CNS_BLEEDER;
312 if ((ptinedge->TYPE & CNS_FEEDBACK) != 0) outtype |= CNS_FEEDBACK;
313 if ((ptinedge->TYPE & CNS_MEMSYM) != 0) outtype |= CNS_MEMSYM;
314 if ((ptinedge->TYPE & CNS_IGNORE) != 0) outtype |= CNS_IGNORE;
315 addoutcone(ptincone, outtype, ptcone);
316 }
317 }
318
319 if (yagIsOutput(ptcone)) {
320 ptconlist = (chain_list *)getptype(ptcone->USER, CNS_EXT)->DATA;
321 for (ptchain = ptconlist; ptchain; ptchain = ptchain->NEXT) {
322 ptcon = (locon_list *)ptchain->DATA;
323 addoutcone(ptcone, CNS_EXT, ptcon);
324 }
325 }
326 }
327
328 /****************************************************************************
329 * function yagGetTransList(); *
330 ****************************************************************************/
331
332 ht *
333 yagGetTransList(inffig_list *ifl, cone_list *ptcone, losig_list *ptsig)
334 {
335 edge_list *ptinputs = NULL;
336 chain_list *ptchain;
337 chain_list *locon_chain;
338 locon_list *ptcon;
339 ht *listht;
340 ht *FASTSEARCH=NULL;
341
342 listht = addht(50);
343 TRANSHT = listht;
344
345 VISITED = addchain(NULL, ptsig);
346 VISITED_FAST = NULL;
347
348 search_depth = 0;
349 locon_chain = (chain_list *)getptype(ptsig->USER, LOFIGCHAIN)->DATA;
350 for (ptchain = locon_chain; ptchain; ptchain = ptchain->NEXT) {
351 ptcon = (locon_list *)ptchain->DATA;
352 if (ptcon->TYPE == 'T' && ptcon->NAME != CNS_GRIDNAME && ptcon->NAME != CNS_BULKNAME) {
353 if ((((lotrs_list *)ptcon->ROOT)->TYPE & USED) == 0) {
354 find_inputs(ifl, ptcone, ptcon, &ptinputs, &FASTSEARCH);
355 }
356 }
357 }
358 if (VISITED_FAST!=NULL) delht(VISITED_FAST);
359 freechain(VISITED);
360 if (ptinputs != NULL) yagFreeEdgeList(ptinputs);
361 if (FASTSEARCH!=NULL) delht(FASTSEARCH);
362 return listht;
363 }
364
365 /****************************************************************************
366 * function yagGetConeInputs(); *
367 ****************************************************************************/
368 /*---------------------------------------------------*
369 | return up to date list of possible cone inputs |
370 *---------------------------------------------------*/
371
372 edge_list *
373 yagGetConeInputs(inffig_list *ifl, cone_list *ptcone)
374 {
375 losig_list *ptsig;
376 edge_list *ptinputs = NULL;
377 chain_list *ptchain;
378 chain_list *locon_chain;
379 locon_list *ptcon;
380 edge_list *ptedge;
381 ht *FASTSEARCH=NULL;
382
383 avt_log(LOGYAG,1, "Inputs for '%s'\n",ptcone->NAME);
384
385 /* obtain inputs due to completed branches */
386
387 for (ptedge = ptcone->INCONE; ptedge; ptedge = ptedge->NEXT) {
388 ptinputs = addedge(ptinputs, ptedge->TYPE, ptedge->UEDGE.PTR);
389 }
390
391 if ((ptcone->TYPE & YAG_PARTIAL) == 0) return ptinputs;
392
393 TRANSHT = addht(50);
394
395 /* inputs on trees starting on unused transistors */
396
397 ptsig = getlosig(YAG_CONTEXT->YAG_CURLOFIG, ptcone->INDEX);
398
399 VISITED = addchain(NULL, ptsig);
400 VISITED_FAST=NULL;
401
402 INPUT_TYPE = NULL;
403
404 search_depth = 0;
405 locon_chain = (chain_list *)getptype(ptsig->USER, LOFIGCHAIN)->DATA;
406 for (ptchain = locon_chain; ptchain; ptchain = ptchain->NEXT) {
407 ptcon = (locon_list *)ptchain->DATA;
408 if (ptcon->TYPE == 'T' && ptcon->NAME != CNS_GRIDNAME && ptcon->NAME != CNS_BULKNAME) {
409 if ((((lotrs_list *)ptcon->ROOT)->TYPE & USED) == 0) {
410 find_inputs(ifl, ptcone, ptcon, &ptinputs, &FASTSEARCH);
411 search_depth--;
412 }
413 }
414 }
415 if (VISITED_FAST!=NULL) delht(VISITED_FAST);
416 freechain(VISITED);
417
418 delht(TRANSHT);
419 if (FASTSEARCH!=NULL) delht(FASTSEARCH);
420 return ptinputs;
421 }
422
423 /****************************************************************************
424 * function find_inputs(); *
425 ****************************************************************************/
426 /*-------------------------------------*
427 | return list of possible cone inputs |
428 | beyond a given connector |
429 *-------------------------------------*/
430
431 static int
432 find_inputs(inffig_list *ifl, cone_list *ptcone, locon_list *ptcon, edge_list **ptptinputs, ht **FASTSEARCH)
433 {
434 losig_list *ptinsig, *ptnextsig;
435 chain_list *ptnextconlist;
436 chain_list *locon_chain;
437 chain_list *ptchain;
438 lotrs_list *pttrans;
439 locon_list *ptnextcon;
440 ptype_list *ptuser;
441 ptype_list *ptintype;
442 long inputtype;
443 long insigtype;
444 long current_s, next_s;
445 int rescode;
446 int found, blocked, nonblocklatch, is_input;
447
448 search_depth++;
449
450 pttrans = (lotrs_list *)ptcon->ROOT;
451
452 /* transistor already encountered */
453 if ((rescode = gethtitem(TRANSHT, pttrans)) != EMPTYHT) return rescode;
454
455 /* check for NEVER directive on transistor */
456 if ((ptuser = getptype(pttrans->USER, FCL_TRANSFER_PTYPE)) != NULL) {
457 if (((long)ptuser->DATA & FCL_NEVER) != 0) return BLOCKED;
458 }
459
460 /* filter transistors without driver */
461 if (pttrans->GRID == NULL) return BLOCKED;
462
463 /* check that transistor is not blocked off by power supply */
464 ptinsig = getlosig(YAG_CONTEXT->YAG_CURLOFIG, ((cone_list *)pttrans->GRID)->INDEX);
465 if (ptinsig->TYPE == CNS_VDD && (pttrans->TYPE & CNS_TP) == CNS_TP) return BLOCKED;
466 if (ptinsig->TYPE == CNS_VSS && (pttrans->TYPE & CNS_TN) == CNS_TN) return BLOCKED;
467
468 /* refute auto-referential inputs */
469 if (yagGetChain_QUICK(VISITED, ptinsig, &VISITED_FAST) != NULL) return BLOCKED;
470
471 if (ptcon->NAME == CNS_SOURCENAME)
472 ptnextsig = pttrans->DRAIN->SIG;
473 else
474 ptnextsig = pttrans->SOURCE->SIG;
475
476 if ((next_s = yagGetVal_s(ptnextsig)) >= 0) {
477 current_s = yagGetVal_s(ptcon->SIG);
478 if (current_s < 0) return BLOCKED;
479 if (current_s > next_s) return BLOCKED;
480 if (current_s == next_s) yagWarning(WAR_SAME_S, ptcon->SIG->NAMECHAIN->DATA, ptnextsig->NAMECHAIN->DATA, NULL, 0);
481 }
482
483 if (YAG_CONTEXT->YAG_USE_CONNECTOR_DIRECTION==TRUE && !mbk_can_cross_transistor_to(ptcon->SIG, pttrans, 'i')) {
484 // printf("(3)blocked: %s from %s to %s\n", pttrans->TRNAME, getsigname(ptcon->SIG), getsigname(ptnextsig));
485 return BLOCKED;
486 }
487
488 /* check for BLOCKER directive on next signal */
489 nonblocklatch = FALSE;
490 if ((ptuser = getptype(ptnextsig->USER, FCL_TRANSFER_PTYPE)) != NULL) {
491 if (((long)ptuser->DATA & FCL_BLOCKER) != 0) return BLOCKED;
492 if (((long)ptuser->DATA & (FCL_LATCH|FCL_MEMSYM|FCL_MASTER|FCL_SLAVE)) != 0) nonblocklatch = TRUE;
493 }
494
495 /* check if next signal is a latch or a symmetric memory */
496 if (!nonblocklatch && (ptuser = getptype(ptnextsig->USER, YAG_CONE_PTYPE)) != NULL) {
497 if ((((cone_list *)ptuser->DATA)->TYPE & (CNS_LATCH|CNS_MEMSYM)) == CNS_LATCH) return BLOCKED;
498 if (YAG_CONTEXT->YAG_MEMSYM_HEURISTIC && (((cone_list *)ptuser->DATA)->TYPE & CNS_MEMSYM) == CNS_MEMSYM) {
499 if ((ptcone->TYPE & (CNS_LATCH|CNS_MEMSYM)) != 0) return BLOCKED;
500 }
501 }
502
503 /* check for transistors of different types with same input */
504 insigtype = ((pttrans->TYPE & CNS_TN) == CNS_TN ? CNS_TNLINK : CNS_TPLINK);
505 if ((ptintype = yagGetPtype(INPUT_TYPE, ptinsig)) != NULL) {
506 if (ptintype->TYPE != insigtype) return BLOCKED;
507 }
508
509 /* next signal is power supply */
510 if (ptnextsig->TYPE == CNS_SIGVDD || ptnextsig->TYPE == CNS_SIGVSS) {
511 if (yagGetEdge_QUICK(*ptptinputs, pttrans->GRID, FASTSEARCH) == NULL) {
512 inputtype = CNS_CONE;
513 if ((pttrans->TYPE & BLEEDER) != 0) {
514 if (search_depth != 1) return BLOCKED;
515 inputtype |= CNS_BLEEDER;
516 }
517 *ptptinputs = addedge(*ptptinputs, inputtype, pttrans->GRID);
518 if (*FASTSEARCH!=NULL) addhtitem(*FASTSEARCH, pttrans->GRID, (long)*ptptinputs);
519 }
520 addhtitem(TRANSHT, pttrans, PATH_FOUND);
521 return PATH_FOUND;
522 }
523
524 /* next signal is a forced input */
525 if ((YAG_CONTEXT->YAG_FLAGS & YAG_HAS_INF_INPUTS)!=0 && ptnextsig->TYPE == CNS_SIGEXT) {
526 ptnextconlist = yagGetExtLoconList(ptnextsig);
527 is_input = FALSE;
528 for (ptchain = ptnextconlist; ptchain; ptchain = ptchain->NEXT) {
529 if (getptype(((locon_list *)ptchain->DATA)->USER, YAG_INPUT_PTYPE) != NULL) is_input = TRUE;
530 }
531 if (is_input) {
532 *ptptinputs = addedge(*ptptinputs, CNS_CONE, pttrans->GRID);
533 if (*FASTSEARCH!=NULL) addhtitem(*FASTSEARCH, pttrans->GRID, (long)*ptptinputs);
534 for (ptchain = ptnextconlist; ptchain; ptchain = ptchain->NEXT) {
535 *ptptinputs = addedge(*ptptinputs, CNS_EXT, (locon_list *)ptchain->DATA);
536 if (*FASTSEARCH!=NULL) addhtitem(*FASTSEARCH, (locon_list *)ptchain->DATA, (long)*ptptinputs);
537 }
538 addhtitem(TRANSHT, pttrans, PATH_FOUND);
539 freechain(ptnextconlist);
540 return PATH_FOUND;
541 }
542 freechain(ptnextconlist);
543 }
544
545 /* if (search_depth == YAG_CONTEXT->YAG_MAX_LINKS) return BLOCKED;*/
546
547 if (yagGetChain_QUICK(VISITED, ptnextsig, &VISITED_FAST) != NULL) return BRLOOP;
548 VISITED = addchain(VISITED, ptnextsig);
549 if (VISITED_FAST!=NULL) addhtitem(VISITED_FAST, ptnextsig, (long)VISITED);
550 INPUT_TYPE = addptype(INPUT_TYPE, insigtype, ptinsig);
551
552 found = FALSE;
553 blocked = TRUE;
554 locon_chain = (chain_list *)getptype(ptnextsig->USER, LOFIGCHAIN)->DATA;
555 for (ptchain = locon_chain; ptchain; ptchain = ptchain->NEXT) {
556 ptnextcon = (locon_list *)ptchain->DATA;
557 if (ptnextcon->TYPE == 'T') {
558 if (ptnextcon->NAME == CNS_GRIDNAME) continue;
559 if (ptnextcon->NAME == CNS_BULKNAME) continue;
560
561 rescode = find_inputs(ifl, ptcone, ptnextcon, ptptinputs, FASTSEARCH);
562 search_depth--;
563 if (rescode == PATH_FOUND) found = TRUE;
564 if (rescode != BLOCKED) blocked = FALSE;
565 }
566 else if (ptnextcon->TYPE == 'E') {
567 *ptptinputs = addedge(*ptptinputs, CNS_EXT, ptnextcon);
568 if (*FASTSEARCH!=NULL) addhtitem(*FASTSEARCH, ptnextcon, (long)*ptptinputs);
569 found = TRUE;
570 }
571 }
572
573 if (VISITED_FAST!=NULL) delhtitem(VISITED_FAST, VISITED->DATA);
574 VISITED = delchain(VISITED, VISITED);
575 ptintype = INPUT_TYPE;
576 INPUT_TYPE = INPUT_TYPE->NEXT;
577 ptintype->NEXT = NULL;
578 freeptype(ptintype);
579
580 if (found) {
581 if (yagGetEdge_QUICK(*ptptinputs, pttrans->GRID, FASTSEARCH) == NULL) {
582 inputtype = CNS_CONE;
583 if ((pttrans->TYPE & BLEEDER) != 0) inputtype |= CNS_BLEEDER;
584 *ptptinputs = addedge(*ptptinputs, inputtype, pttrans->GRID);
585 if (*FASTSEARCH!=NULL) addhtitem(*FASTSEARCH, pttrans->GRID, (long)*ptptinputs);
586 }
587 addhtitem(TRANSHT, pttrans, PATH_FOUND);
588 return PATH_FOUND;
589 }
590 else if (blocked) {
591 addhtitem(TRANSHT, pttrans, BLOCKED);
592 return BLOCKED;
593 }
594 else return BRLOOP;
595 }
596