1 /****************************************************************************/
3 /* Chaine de CAO & VLSI Alliance */
5 /* Produit : YAGLE v3.50 */
6 /* Fichier : yag_chain.c */
8 /* (c) copyright 1994 Laboratoire MASI equipe CAO & VLSI */
9 /* Tous droits reserves */
10 /* Support : e-mail alliance-support@asim.lip6.fr */
12 /* Auteur(s) : Anthony LESTER le : 26/05/1994 */
14 /* Modifie par : le : ../../.... */
15 /* Modifie par : le : ../../.... */
16 /* Modifie par : le : ../../.... */
18 /****************************************************************************/
20 #include "yag_headers.h"
27 static chain_list
*VISITED
;
28 static ht
*VISITED_FAST
;
29 static ptype_list
*INPUT_TYPE
;
30 static int search_depth
;
32 static int find_inputs(inffig_list
*ifl
, cone_list
*ptcone
, locon_list
*ptcon
, edge_list
**ptptinputs
, ht
**FASTSEARCH
);
34 /****************************************************************************
35 * function yagChainTrans(); *
36 ****************************************************************************/
38 /* remplissage des champs GRID des transistors */
41 yagChainTrans(lotrs_list
*pttrans
)
43 losig_list
*ptsig
= NULL
;
44 ptype_list
*user
= NULL
;
46 ptsig
= pttrans
->GRID
->SIG
;
48 user
= getptype(ptsig
->USER
, YAG_CONE_PTYPE
);
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
);
55 if (getptype(pttrans
->USER
, YAG_GRIDCON_PTYPE
) == NULL
) {
56 pttrans
->USER
= addptype(pttrans
->USER
, YAG_GRIDCON_PTYPE
, pttrans
->GRID
);
59 pttrans
->USER
= addptype(pttrans
->USER
, CNS_DRIVINGCONE
, NULL
);
63 /****************************************************************************
64 * function yagChainDual(); *
65 ****************************************************************************/
66 /*---------------------------------------------------*
67 | fill INCONE fields of CMOS duals |
68 *---------------------------------------------------*/
71 yagChainDual(cone_list
*ptcone
)
73 branch_list
*ptbranch
= NULL
;
74 link_list
*ptlink
= NULL
;
76 edge_list
*ptedge
, *ptinputs
= NULL
;
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
;
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
);
97 yagBug(DBG_ILL_LINKTYPE
, "yagChainDual", ptcone
->NAME
, NULL
, 0);
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
;
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
);
118 yagBug(DBG_ILL_LINKTYPE
, "yagChainDual", ptcone
->NAME
, NULL
, 0);
122 for (ptedge
= ptcone
->INCONE
; ptedge
; ptedge
= ptedge
->NEXT
) {
123 ptinputs
= addedge(ptinputs
, ptedge
->TYPE
, ptedge
->UEDGE
.PTR
);
125 ptcone
->USER
= addptype(ptcone
->USER
, YAG_DUALINPUTS_PTYPE
, ptinputs
);
128 /****************************************************************************
129 * function yagChainBranch(); *
130 ****************************************************************************/
131 /*---------------------------------------------------*
132 | update INCONE fields |
133 *---------------------------------------------------*/
136 yagChainBranch(cone_list
*ptcone
, branch_list
*ptbranch
)
144 long linktype
, branchtype
;
147 branchtype
= ptbranch
->TYPE
& (CNS_VSS
|CNS_VDD
|CNS_EXT
);
149 for (ptlink
= ptbranch
->LINK
; ptlink
!= NULL
; ptlink
= ptlink
->NEXT
) {
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
);
156 yagBug(DBG_ILL_LINKTYPE
, "yagChainBranch", ptcone
->NAME
, NULL
, 0);
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
;
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
;
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
;
179 if ((ptedge
->TYPE
& YAG_NOT_FUNCTIONAL
) != 0 && (ptbranch
->TYPE
& CNS_NOT_FUNCTIONAL
) == 0) {
180 ptedge
->TYPE
&= ~YAG_NOT_FUNCTIONAL
;
182 ptedge
->TYPE
|= inputtype
;
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
);
191 /*------------------------------+
192 | external connector link |
193 +------------------------------*/
195 ptcon
= ptlink
->ULINK
.LOCON
;
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
;
201 if ((ptedge
->TYPE
& YAG_NOT_FUNCTIONAL
) != 0 && (ptbranch
->TYPE
& CNS_NOT_FUNCTIONAL
) == 0) {
202 ptedge
->TYPE
&= ~YAG_NOT_FUNCTIONAL
;
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
);
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
);
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
);
225 else ptcone
->USER
= addptype(ptcone
->USER
, CNS_LOCON
, addchain(NULL
, ptcon
));
230 /****************************************************************************
231 * function yagChainCone(); *
232 ****************************************************************************/
233 /*---------------------------------------------------*
234 | update INCONE fields after branch removal |
235 *---------------------------------------------------*/
238 yagChainCone(cone_list
*ptcone
)
240 edge_list
*old_edge_list
;
242 edge_list
*ptoldedge
;
245 branch_list
*ptbranch
;
246 branch_list
*brlist
[4];
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
);
263 /* delete the INCONE list */
264 old_edge_list
= ptcone
->INCONE
;
265 ptcone
->INCONE
= NULL
;
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
;
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
);
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
);
286 yagFreeEdgeList(old_edge_list
);
290 /****************************************************************************
291 * function yagBuildOutputs(); *
292 ****************************************************************************/
293 /*---------------------------------------------------*
294 | build OUTCONE fields |
295 *---------------------------------------------------*/
298 yagBuildOutputs(cone_list
*ptcone
)
303 chain_list
*ptconlist
, *ptchain
;
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
;
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
);
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
);
328 /****************************************************************************
329 * function yagGetTransList(); *
330 ****************************************************************************/
333 yagGetTransList(inffig_list
*ifl
, cone_list
*ptcone
, losig_list
*ptsig
)
335 edge_list
*ptinputs
= NULL
;
337 chain_list
*locon_chain
;
345 VISITED
= addchain(NULL
, ptsig
);
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
);
358 if (VISITED_FAST
!=NULL
) delht(VISITED_FAST
);
360 if (ptinputs
!= NULL
) yagFreeEdgeList(ptinputs
);
361 if (FASTSEARCH
!=NULL
) delht(FASTSEARCH
);
365 /****************************************************************************
366 * function yagGetConeInputs(); *
367 ****************************************************************************/
368 /*---------------------------------------------------*
369 | return up to date list of possible cone inputs |
370 *---------------------------------------------------*/
373 yagGetConeInputs(inffig_list
*ifl
, cone_list
*ptcone
)
376 edge_list
*ptinputs
= NULL
;
378 chain_list
*locon_chain
;
383 avt_log(LOGYAG
,1, "Inputs for '%s'\n",ptcone
->NAME
);
385 /* obtain inputs due to completed branches */
387 for (ptedge
= ptcone
->INCONE
; ptedge
; ptedge
= ptedge
->NEXT
) {
388 ptinputs
= addedge(ptinputs
, ptedge
->TYPE
, ptedge
->UEDGE
.PTR
);
391 if ((ptcone
->TYPE
& YAG_PARTIAL
) == 0) return ptinputs
;
395 /* inputs on trees starting on unused transistors */
397 ptsig
= getlosig(YAG_CONTEXT
->YAG_CURLOFIG
, ptcone
->INDEX
);
399 VISITED
= addchain(NULL
, ptsig
);
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
);
415 if (VISITED_FAST
!=NULL
) delht(VISITED_FAST
);
419 if (FASTSEARCH
!=NULL
) delht(FASTSEARCH
);
423 /****************************************************************************
424 * function find_inputs(); *
425 ****************************************************************************/
426 /*-------------------------------------*
427 | return list of possible cone inputs |
428 | beyond a given connector |
429 *-------------------------------------*/
432 find_inputs(inffig_list
*ifl
, cone_list
*ptcone
, locon_list
*ptcon
, edge_list
**ptptinputs
, ht
**FASTSEARCH
)
434 losig_list
*ptinsig
, *ptnextsig
;
435 chain_list
*ptnextconlist
;
436 chain_list
*locon_chain
;
439 locon_list
*ptnextcon
;
441 ptype_list
*ptintype
;
444 long current_s
, next_s
;
446 int found
, blocked
, nonblocklatch
, is_input
;
450 pttrans
= (lotrs_list
*)ptcon
->ROOT
;
452 /* transistor already encountered */
453 if ((rescode
= gethtitem(TRANSHT
, pttrans
)) != EMPTYHT
) return rescode
;
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
;
460 /* filter transistors without driver */
461 if (pttrans
->GRID
== NULL
) return BLOCKED
;
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
;
468 /* refute auto-referential inputs */
469 if (yagGetChain_QUICK(VISITED
, ptinsig
, &VISITED_FAST
) != NULL
) return BLOCKED
;
471 if (ptcon
->NAME
== CNS_SOURCENAME
)
472 ptnextsig
= pttrans
->DRAIN
->SIG
;
474 ptnextsig
= pttrans
->SOURCE
->SIG
;
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);
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));
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
;
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
;
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
;
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
;
517 *ptptinputs
= addedge(*ptptinputs
, inputtype
, pttrans
->GRID
);
518 if (*FASTSEARCH
!=NULL
) addhtitem(*FASTSEARCH
, pttrans
->GRID
, (long)*ptptinputs
);
520 addhtitem(TRANSHT
, pttrans
, PATH_FOUND
);
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
);
528 for (ptchain
= ptnextconlist
; ptchain
; ptchain
= ptchain
->NEXT
) {
529 if (getptype(((locon_list
*)ptchain
->DATA
)->USER
, YAG_INPUT_PTYPE
) != NULL
) is_input
= TRUE
;
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
);
538 addhtitem(TRANSHT
, pttrans
, PATH_FOUND
);
539 freechain(ptnextconlist
);
542 freechain(ptnextconlist
);
545 /* if (search_depth == YAG_CONTEXT->YAG_MAX_LINKS) return BLOCKED;*/
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
);
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;
561 rescode
= find_inputs(ifl
, ptcone
, ptnextcon
, ptptinputs
, FASTSEARCH
);
563 if (rescode
== PATH_FOUND
) found
= TRUE
;
564 if (rescode
!= BLOCKED
) blocked
= FALSE
;
566 else if (ptnextcon
->TYPE
== 'E') {
567 *ptptinputs
= addedge(*ptptinputs
, CNS_EXT
, ptnextcon
);
568 if (*FASTSEARCH
!=NULL
) addhtitem(*FASTSEARCH
, ptnextcon
, (long)*ptptinputs
);
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
;
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
);
587 addhtitem(TRANSHT
, pttrans
, PATH_FOUND
);
591 addhtitem(TRANSHT
, pttrans
, BLOCKED
);