1 /*
2  * This file is part of the Alliance CAD System
3  * Copyright (C) Laboratoire LIP6 - D�partement ASIM
4  * Universite Pierre et Marie Curie
5  *
6  * Home page          : http://www-asim.lip6.fr/alliance/
7  * E-mail             : mailto:alliance-users@asim.lip6.fr
8  *
9  * This library is free software; you  can redistribute it and/or modify it
10  * under the terms  of the GNU Library General Public  License as published
11  * by the Free Software Foundation; either version 2 of the License, or (at
12  * your option) any later version.
13  *
14  * Alliance VLSI  CAD System  is distributed  in the hope  that it  will be
15  * useful, but WITHOUT  ANY WARRANTY; without even the  implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17  * Public License for more details.
18  *
19  * You should have received a copy  of the GNU General Public License along
20  * with the GNU C Library; see the  file COPYING. If not, write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 /*
25  * Purpose : utilities for logical structures
26  * Date    : 05/11/92
27  * Author  : Frederic Petrot <Frederic.Petrot@lip6.fr>
28  * Modified by Czo <Olivier.Sirol@lip6.fr> 1997,98
29  */
30 
31 #ident "$Id: mbk_lo_util.c,v 1.6 2012/05/14 14:20:23 alliance Exp $"
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <ctype.h>
36 #include <unistd.h>
37 #include <string.h>
38 #include <strings.h>
39 
40 #include "mut.h"
41 #include "mlo.h"
42 #include "rcn.h"
43 #include "mlu.h"
44 #include "mbk_lo_util.h"
45 #include "rcn_lo.h"
46 
47 /* local for flattenlofig */
48 #define FLATTEN_CTC 19971215
49 #define FLATTEN_POSTRAIT 19971216
50 
51 void debugctc ( losig_list*, int );
52 void debugctc2 ( lofig_list* );
53 
54 /*******************************************************************************
55 * function getlofig()                                                          *
56 * if mode == 'A'  all the figure is needed                                     *
57 * if mode == 'P'  interface only is needed                                     *
58 *******************************************************************************/
getlofig(const char * fname,char mode)59 lofig_list *getlofig(const char *fname, char mode)
60 {
61 lofig_list *ptfig;
62 char *figname = namealloc(fname);
63    /* scan figure list */
64    for (ptfig = HEAD_LOFIG; ptfig; ptfig = ptfig->NEXT)
65       if (ptfig->NAME == figname)
66          break;
67 
68    if (ptfig == NULL) { /* figure doesn't exist */
69       ptfig = (lofig_list *)mbkalloc(sizeof(lofig_list));
70       ptfig->NAME   = figname;
71       ptfig->MODELCHAIN  = NULL;
72       ptfig->LOINS  = NULL;
73       ptfig->LOTRS  = NULL;
74       ptfig->LOCAP  = NULL;
75       ptfig->LORES  = NULL;
76       ptfig->LOSELF = NULL;
77       ptfig->LOCON  = NULL;
78       ptfig->LOSIG  = NULL;
79       ptfig->BKSIG  = NULL;
80       ptfig->USER   = NULL;
81       ptfig->NEXT   = HEAD_LOFIG;
82       HEAD_LOFIG = ptfig;
83       ptfig->MODE = mode;
84       loadlofig(ptfig, figname, mode );
85       return ptfig;
86    }
87 
88    return ptfig;
89 }
90 
91 /*******************************************************************************
92 * function givelosig()                                                         *
93 *******************************************************************************/
givelosig(lofig_list * ptfig,long index)94 losig_list *givelosig(lofig_list *ptfig, long index)
95 {
96 losig_list *ptsig = NULL;
97 ptype_list *pt = NULL;
98 int low;
99 int type;
100 int sigsize;
101         sigsize = getsigsize( ptfig );
102    low = (index % sigsize);
103    type = (index / sigsize);
104    for (pt = ptfig->BKSIG; pt; pt = pt->NEXT)
105    if (pt->TYPE == type)
106       break;
107    if (pt != NULL) {
108       ptsig = (losig_list *)(pt->DATA) + low;
109       if (ptsig->INDEX == index)
110          return ptsig;
111    }
112    return addlosig(ptfig, index, (chain_list *)NULL, 'I' );
113 }
114 
115 /*******************************************************************************
116 * function  flattenlofig()                                                     *
117 *                                                                              *
118 * the instance "insname" is suppressed as a hierarchical level                 *
119 * in figure pointed by "ptfig". Capacitances and netlist                       *
120 * consistency is preserved.                                                    *
121 * Modified by Gregoire AVOT for rcn support.                                   *
122 *******************************************************************************/
flattenlofig(lofig_list * ptfig,const char * iname,char concat)123 void flattenlofig(lofig_list *ptfig, const char *iname, char concat)
124 {
125   struct st_interf
126   {
127     struct st_interf    *next;
128     int                  base;
129     losig_list          *sig;
130   };
131 
132   struct st_contact
133   {
134     struct st_contact   *next;
135     locon_list          *con1;  /* on instance */
136     int                  node1;
137     locon_list          *con2;  /* on lofig of instance */
138     int                   node2;
139     int                  interf;
140   };
141 
142   chain_list            *nextscanctc;
143   loins_list           *ptins;
144   lofig_list           *figins;
145   losig_list           *scanlosig;
146   int             maxsig;
147   locon_list            *ptcon;
148   chain_list            *scanchain;
149   ptype_list            *ptptype;
150   struct st_interf      *interf;
151   struct st_interf      *ptinterf;
152   struct st_contact     *contact;
153   struct st_contact     *ptcontact;
154   int                    nbinterf;
155   num_list              *sn1;
156   num_list              *sn2;
157   lowire_list           *scanwire;
158   int                    node1;
159   struct st_interf      *ctinterf;
160   int       *newnode;
161   losig_list            *newsig;
162   locon_list            *scanlocon;
163   int                    maxnode;
164   chain_list            *scanctc;
165   locon_list            *nextlocon;
166   void         *forfree;
167   loctc_list            *ptctc;
168   loctc_list            *ptctc2;
169   chain_list            *prevctc;
170   chain_list            *prevctc2;
171   chain_list            *scanctc2;
172   losig_list            *sigctc2;
173   int                    othernode;
174   int                    scanctcnode;
175   losig_list            *othersig;
176   chain_list            *posttreatsig=NULL;
177   ptype_list            *ptbksig=NULL;
178   int                    maxnode_itrf;
179   int                    newnode_itrf;
180   chain_list            *scanmodel;
181   chain_list            *lofigc;
182   chain_list            *chainhtab;
183   chain_list            *chainht;
184   chain_list            *loconchain;
185   chain_list            *chain;
186   htitem                *ptitem ;
187   long                  nbi;
188 
189   int                    verif;
190 
191   lotrs_list            *scantrs;
192   locap_list            *scancap;
193   lores_list            *scanres;
194   loself_list           *scanself;
195   loins_list            *scanins;
196 
197   int                    i;
198   char                   all;
199   long                   key ;
200   ht                     *htab ;
201   const char             *insname;
202 
203   /* recupere l'index maximum des signaux sur la figure */
204   maxsig = -1 ;
205   for( ptptype = ptfig->BKSIG ; ptptype ; ptptype = ptptype->NEXT )
206   {
207     if( ptptype->TYPE > maxsig )
208     {
209       maxsig = ptptype->TYPE;
210       ptbksig = ptptype;
211     }
212   }
213 
214   scanlosig = (losig_list*)(ptbksig->DATA);
215   verif = getsigsize( ptfig );
216   for( i=0 ; i< verif ; i++ )
217   {
218     if( scanlosig[i].INDEX > maxsig )
219       maxsig = scanlosig[i].INDEX;
220   }
221 
222   maxsig++;
223 
224  /* si insname == NULL on met a plat au niveau transistor */
225 
226   if(iname == NULL)
227     all = 'Y' ;
228   else
229    all = 'N' ;
230 
231   /* On verifie que le lofigchain est bien a jour. Tous les signaux d'une
232    * lofig ont le ptype dans leur champ USER, meme si il est vide */
233 
234   if (!getptype(ptfig->LOSIG->USER, LOFIGCHAIN)) {
235 #if 0
236     fflush( stdout );
237     fprintf( stderr, "*** mbk warning ***\n" );
238     fprintf( stderr, "lofigchain is missing on lofig %s.\n", ptfig->NAME );
239 #endif
240 
241     lofigchain( ptfig );
242   }
243 
244 while(ptfig->LOINS != NULL)
245 {
246   if(all == 'Y')
247    {
248     insname = ptfig->LOINS->INSNAME ;
249    }
250   else
251      insname = iname;
252 
253   ptins  = getloins( ptfig, insname );
254   figins = rduplofig( getlofig( ptins->FIGNAME, 'A' ) );
255 
256   lofigchain( figins );
257 
258   for( ptcon = ptins->LOCON ; ptcon ; ptcon = ptcon->NEXT )
259     if( ptcon->SIG->PRCN && gettabnode( ptcon->SIG->PRCN ) )
260       freetable( ptcon->SIG );
261 
262   /* Si un seul signal a un RC, on en cree un sur tous les autres */
263 
264   for( ptcon = ptins->LOCON ; ptcon ; ptcon = ptcon->NEXT )
265     if( ptcon->SIG->PRCN )
266       break;
267 
268   if( !ptcon )
269     for( scanlosig = figins->LOSIG ; scanlosig ; scanlosig = scanlosig->NEXT )
270       if( scanlosig->PRCN )
271         break;
272 
273   if( scanlosig || ptcon )
274   {
275     for( ptcon = ptins->LOCON ; ptcon ; ptcon = ptcon->NEXT )
276     {
277       if( ! ptcon->SIG->PRCN )
278       {
279         addlorcnet( ptcon->SIG );
280       }
281 
282       if( gettabnode( ptcon->SIG->PRCN ) )
283         freetable( ptcon->SIG );
284     }
285 
286     for( scanlosig = figins->LOSIG ; scanlosig ; scanlosig = scanlosig->NEXT )
287     {
288       if( ! scanlosig->PRCN )
289         addlorcnet( scanlosig );
290 
291       if( gettabnode( scanlosig->PRCN ) )
292         freetable( scanlosig );
293     }
294   }
295 
296   /* Au boulot */
297   for( scanlosig = figins->LOSIG ; scanlosig ; scanlosig = scanlosig->NEXT )
298   {
299     if( scanlosig->TYPE == INTERNAL )
300     {
301       newsig = addlosig( ptfig, maxsig, NULL, INTERNAL );
302       maxsig++;
303 
304       newsig->USER = addptype( newsig->USER, LOFIGCHAIN, NULL );
305 
306       /* concatene les nom si necessaire */
307       if( concat != NO )
308         for( scanchain = scanlosig->NAMECHAIN ;
309              scanchain ;
310              scanchain = scanchain->NEXT
311            )
312           scanchain->DATA = concatname( insname, (char*)(scanchain->DATA) );
313       newsig->NAMECHAIN = scanlosig->NAMECHAIN;
314       scanlosig->NAMECHAIN = NULL;
315 
316       ptptype       = getptype( newsig->USER, LOFIGCHAIN );
317       for( scanchain = getptype( scanlosig->USER, LOFIGCHAIN )->DATA ;
318            scanchain ;
319            scanchain = scanchain->NEXT )
320       {
321         ptcon         = (locon_list*)(scanchain->DATA);
322         ptcon->SIG    = newsig;
323         ptptype->DATA = (void*)addchain( (chain_list*)ptptype->DATA, ptcon );
324       }
325 
326       if( scanlosig->PRCN )
327       {
328         duplorcnet( newsig, scanlosig );
329 
330         /* Duplication des CTC */
331 
332         for( scanctc = scanlosig->PRCN->PCTC ;
333              scanctc ;
334              scanctc = scanctc->NEXT )
335         {
336           ptctc = (loctc_list*)scanctc->DATA;
337           if( !ptctc )
338           {
339             fflush( stdout );
340             fprintf( stderr, "*** mbk error ***\n" );
341             fprintf( stderr,
342                      "Null CTC on signal %ld (1) in instance %s.\n",
343                      scanlosig->INDEX,
344                      insname
345                    );
346           }
347 
348           if( ptctc->SIG1 == scanlosig )
349           {
350             newsig->PRCN->PCTC = addchain( newsig->PRCN->PCTC, ptctc );
351             ptctc->SIG1 = newsig;
352           }
353 
354           if( ptctc->SIG2 == scanlosig )
355           {
356             newsig->PRCN->PCTC = addchain( newsig->PRCN->PCTC, ptctc );
357             ptctc->SIG2 = newsig;
358           }
359         }
360       }
361     }
362     else /* scanlosig->TYPE == EXTERNAL */
363     {
364       if (DEBUG_MODE == 'Y')
365         (void)printf( "--- mbk --- scanlosig (EXTERNAL): %s\n", getsigname(scanlosig) );
366 
367       /* cree la liste interf */
368       interf = (struct st_interf*)mbkalloc( sizeof( struct st_interf ) );
369       interf->base = 0;
370       interf->next = NULL;
371       interf->sig  = scanlosig;
372 
373       loconchain = NULL ;
374 
375       for( scanchain =
376                   (chain_list*)(getptype( scanlosig->USER, LOFIGCHAIN )->DATA) ;
377            scanchain ;
378            scanchain = scanchain->NEXT
379          )
380       {
381         ptcon = (locon_list*)(scanchain->DATA);
382         if (DEBUG_MODE == 'Y') {
383           (void)printf( "--- mbk ---    scanchain: con:%s", ptcon->NAME );
384           (void)printf( " sig:%s", getsigname(ptcon->SIG) );
385           if (ptcon->TYPE == EXTERNAL) {
386             (void)printf( " lofig:%s\n", ((lofig_list*)ptcon->ROOT)->NAME );
387           } else {
388             (void)printf( " loins:%s\n", ((loins_list*)ptcon->ROOT)->INSNAME );
389           }
390         }
391 
392         if( ptcon->ROOT == figins )
393         {
394           for( scanlocon = ptins->LOCON ;
395                scanlocon ;
396                scanlocon = scanlocon->NEXT
397              )
398           {
399             if( scanlocon->NAME == ptcon->NAME )
400               break;
401           }
402 
403           if( ! scanlocon )
404           {
405             fflush( stdout );
406             fprintf( stderr, "*** mbk error ***\n" );
407             fprintf( stderr,
408                      "flattenlofig : Connector %s exist only in instance %s.\n",
409                      ptcon->NAME,
410                      insname
411                    );
412             EXIT(1);
413           }
414 
415           loconchain = addchain(loconchain,scanlocon) ;
416 
417           ptinterf = (struct st_interf*)
418                           mbkalloc( sizeof( struct st_interf ) );
419           ptinterf->base = 0;
420           ptinterf->next = interf;
421           ptinterf->sig  = scanlocon->SIG;
422           interf         = ptinterf;
423 
424           if( ! scanlocon->PNODE && ptcon->PNODE )
425           {
426             for( maxnode_itrf = 0, sn1 = ptcon->PNODE ; sn1 ; sn1 = sn1->NEXT, maxnode_itrf++ );
427 
428             newnode_itrf = addlonode( scanlocon->SIG, NULL );
429 
430             for( i = 1 ; i <= maxnode_itrf ; i++ )
431               setloconnode( scanlocon, newnode_itrf );
432           }
433 
434           if( scanlocon->PNODE && ! ptcon->PNODE )
435           {
436             for( maxnode_itrf = 0, sn1 = scanlocon->PNODE ; sn1 ; sn1 = sn1->NEXT, maxnode_itrf++ );
437 
438             newnode_itrf = addlonode( ptcon->SIG, NULL );
439 
440             for( i = 1 ; i <= maxnode_itrf ; i++ )
441               setloconnode( ptcon, newnode_itrf );
442           }
443 
444         }
445       }
446 
447       for( ptinterf = interf ; ptinterf ; ptinterf = ptinterf->next )
448          if(ptinterf->sig != scanlosig)
449           break ;
450 
451       if(ptinterf)
452        {
453         newsig = ptinterf->sig ;
454         ptptype = getptype(newsig->USER,LOFIGCHAIN) ;
455         for(chain = loconchain ; chain != NULL ; chain = chain->NEXT)
456          {
457           scanchain = (chain_list*)ptptype->DATA ;
458           while( scanchain )
459            {
460             ptcon = (locon_list*)(scanchain->DATA);
461 
462             if((locon_list *)chain->DATA == ptcon)
463              {
464               if(scanchain == (chain_list*)ptptype->DATA)
465                {
466                 ptptype->DATA = delchain((chain_list*)ptptype->DATA,
467                                          scanchain) ;
468                 scanchain =  ptptype->DATA ;
469                }
470               else
471                {
472                 lofigc->NEXT = delchain(lofigc->NEXT,
473                                          scanchain) ;
474                 scanchain = lofigc->NEXT ;
475                }
476               break ;
477              }
478             else
479              {
480               lofigc = scanchain ;
481               scanchain = scanchain->NEXT ;
482              }
483            }
484          }
485        }
486       else
487        {
488         newsig = addlosig( ptfig, maxsig, NULL, INTERNAL );
489         maxsig++;
490         newsig->USER = addptype( newsig->USER, LOFIGCHAIN, NULL );
491         ptptype = newsig->USER ;
492        }
493 
494       freechain(loconchain) ;
495 
496       if(getptype(newsig->USER,FLATTEN_POSTRAIT) == NULL)
497        {
498         posttreatsig = addchain( posttreatsig, newsig );
499         newsig->USER = addptype(newsig->USER,FLATTEN_POSTRAIT,NULL) ;
500        }
501 
502       /* cree la liste contact */
503       contact  = NULL;
504       if( newsig->PRCN )
505         nbinterf = newsig->PRCN->NBNODE ;
506       else
507         nbinterf = 1;
508 
509       for( scanchain =
510                   (chain_list*)(getptype( scanlosig->USER, LOFIGCHAIN )->DATA) ;
511            scanchain ;
512            scanchain = scanchain->NEXT )
513       {
514         ptcon = (locon_list*)(scanchain->DATA);
515         if( ptcon->ROOT == figins )
516         {
517           for( scanlocon = ptins->LOCON ;
518                scanlocon ;
519                scanlocon = scanlocon->NEXT
520              )
521           {
522             if( scanlocon->NAME == ptcon->NAME )
523               break;
524           }
525 
526           if( !scanlocon )
527           {
528             fflush( stdout );
529             fprintf( stderr, "*** mbk error ***\n" );
530             fprintf( stderr,
531                      "flattenlofig : Connector %s exist only in instance %s.\n",
532                      ptcon->NAME,
533                      ptfig->NAME
534                    );
535             EXIT(1);
536           }
537 
538           if( scanlocon->PNODE || ptcon->PNODE )
539           {
540             for( sn1 = scanlocon->PNODE, sn2 = ptcon->PNODE ;
541                  sn1 && sn2 ;
542                  sn1 = sn1->NEXT, sn2 = sn2->NEXT
543                )
544             {
545               ptcontact =
546                     (struct st_contact*)mbkalloc( sizeof( struct st_contact ) );
547 
548               ptcontact->next   = contact;
549               ptcontact->con1   = scanlocon;
550               ptcontact->con2   = ptcon;
551               ptcontact->node1  = sn1->DATA;
552               ptcontact->node2  = sn2->DATA;
553               if(scanlocon->SIG == newsig)
554                ptcontact->interf = sn1->DATA ;
555               else
556                {
557                 ptcontact->interf = nbinterf++;
558                }
559 
560               contact = ptcontact;
561             }
562 
563             if( sn1 || sn2 )
564             {
565               fflush( stdout );
566               fprintf( stderr, "*** mbk error ***\n" );
567               fprintf( stderr,
568                        "flattenlofig : Connector %s in instance %s : Number of physical node differ.\n",
569                        ptcon->NAME,
570                        figins->NAME
571                      );
572               EXIT(1);
573             }
574           }
575           else
576           {
577             ptcontact =
578                     (struct st_contact*)mbkalloc( sizeof( struct st_contact ) );
579 
580             ptcontact->next   = contact;
581             ptcontact->con1   = scanlocon;
582             ptcontact->con2   = ptcon;
583             ptcontact->node1  = 0;
584             ptcontact->node2  = 0;
585             ptcontact->interf = 0;
586 
587             contact = ptcontact;
588           }
589         }
590       }
591 
592       /* Met a jour le champs base des structures inter */
593       if( interf->sig->PRCN )
594       {
595         if(!newsig->PRCN)
596      addlorcnet( newsig );
597 
598         maxnode = nbinterf ;
599 
600         for( ptinterf = interf ; ptinterf ; ptinterf = ptinterf->next )
601         {
602           if(ptinterf->sig != newsig)
603            {
604             ptinterf->base = maxnode - 1 ;
605             maxnode        = maxnode + ptinterf->sig->PRCN->NBNODE - 1 ;
606 
607        newsig->PRCN->CAPA += ptinterf->sig->PRCN->CAPA;
608            }
609           else
610             ptinterf->base = 0 ;
611         }
612       }
613 
614       /* calcul le type de newsig */
615 
616       for( ptinterf = interf ; ptinterf ; ptinterf = ptinterf->next )
617         if( ptinterf->sig != scanlosig && ptinterf->sig->TYPE == EXTERNAL )
618           break;
619 
620       if( ptinterf )
621         newsig->TYPE = EXTERNAL;
622       else
623         newsig->TYPE = INTERNAL;
624 
625       /* met a jour le nom de newsig */
626       for( ptinterf = interf ; ptinterf ; ptinterf = ptinterf->next )
627       {
628         if(ptinterf->sig == newsig)
629           continue ;
630         if( concat != NO )
631         {
632           if( ptinterf->sig == scanlosig )
633             for( scanchain = ptinterf->sig->NAMECHAIN ;
634                  scanchain ;
635                  scanchain = scanchain->NEXT
636                )
637               scanchain->DATA = concatname( insname, (char*)scanchain->DATA );
638         }
639         newsig->NAMECHAIN = append( ptinterf->sig->NAMECHAIN, newsig->NAMECHAIN );
640         ptinterf->sig->NAMECHAIN = NULL;
641       }
642 
643       /* Pour chaque signal S de interf */
644       for( ptinterf = interf ; ptinterf ; ptinterf = ptinterf->next )
645       {
646         if(ptinterf->sig == newsig)
647           continue ;
648         /* Pour chaque connecteur C de S */
649         for( scanchain =
650                (chain_list*)(getptype( ptinterf->sig->USER, LOFIGCHAIN )->DATA);
651              scanchain ;
652              scanchain = scanchain->NEXT )
653         {
654           ptcon = (locon_list*)(scanchain->DATA);
655 
656           for( ptcontact = contact ; ptcontact ; ptcontact = ptcontact->next )
657             if( ptcon == ptcontact->con1 || ptcon == ptcontact->con2 )
658               break;
659 
660           /* Si C n'est pas sur l'interface */
661           if( !ptcontact )
662           {
663             ptptype->DATA = (void*)addchain( (chain_list*)ptptype->DATA,ptcon);
664 
665             for( sn1 = ptcon->PNODE ; sn1 ; sn1 = sn1->NEXT )
666             {
667               for( ptcontact = contact ;
668                    ptcontact ;
669                    ptcontact = ptcontact->next
670                  )
671               {
672                 if( ptcontact->node1     == sn1->DATA  &&
673                     ptcontact->con1->SIG == ptcon->SIG
674                   )
675                   break;
676                 if( ptcontact->node2     == sn1->DATA  &&
677                     ptcontact->con2->SIG == ptcon->SIG
678                   )
679                   break;
680               }
681 
682               if( ptcontact )
683                 /* cas particulier : si un noeud appartient aussi a un
684                  * connecteur de l'interface */
685                 sn1->DATA = ptcontact->interf;
686               else
687                 sn1->DATA = sn1->DATA + ptinterf->base ;
688             }
689 
690             ptcon->SIG = newsig;
691             for(sn1 = ptcon->PNODE ; sn1 ; sn1 = sn1->NEXT)
692               if(ptcon->SIG->PRCN->NBNODE <= sn1->DATA)
693                 ptcon->SIG->PRCN->NBNODE = sn1->DATA + 1 ;
694           }
695         }
696 
697         if( ptinterf->sig->PRCN )
698         {
699           /* Pour chaque noeud de S, on calcule son nouvel index dans
700            * un tableau newnode */
701           newnode = mbkalloc( sizeof(int) * ( ptinterf->sig->PRCN->NBNODE + 1 ));
702           bzero( newnode, sizeof(int) * ( ptinterf->sig->PRCN->NBNODE + 1 ) );
703 
704           for( ptcontact = contact ; ptcontact ; ptcontact = ptcontact->next )
705           {
706             if(ptinterf->sig == ptcontact->con1->SIG)
707              {
708               newnode[ptcontact->node1] = ptcontact->interf;
709              }
710             else if(ptinterf->sig == ptcontact->con2->SIG)
711              {
712               newnode[ptcontact->node2] = ptcontact->interf;
713              }
714           }
715 
716           for( node1 = 1 ; node1 <= ptinterf->sig->PRCN->NBNODE ; node1++ )
717             if( newnode[node1] == 0 )
718               newnode[node1] = node1 + ptinterf->base;
719 
720           /* Pour chaque wire W de S */
721           for( scanwire = ptinterf->sig->PRCN->PWIRE ;
722                scanwire ;
723                scanwire = scanwire->NEXT
724              )
725           {
726             addlowire( newsig,
727                        scanwire->LAYER,
728                        scanwire->FLAG,
729                        scanwire->RESI,
730                        scanwire->CAPA,
731                        scanwire->X,
732                        scanwire->Y,
733                        scanwire->DX,
734                        scanwire->DY,
735                        newnode[ scanwire->NODE1 ],
736                        newnode[ scanwire->NODE2 ]
737                      );
738           }
739 
740           /* Pour chaque CTC de S */
741           for( scanctc = ptinterf->sig->PRCN->PCTC ;
742                scanctc ;
743                scanctc = scanctc->NEXT
744              )
745           {
746 
747             ptctc = (loctc_list*)scanctc->DATA;
748 
749             if( ptctc->SIG1 == ptinterf->sig )
750             {
751               ptctc->SIG1  = newsig;
752               if( ptctc->NODE1 )
753                 ptctc->NODE1 = newnode[ ptctc->NODE1 ];
754             }
755             else
756             {
757               for( ctinterf = interf ; ctinterf ; ctinterf = ctinterf->next )
758               {
759                 if( ptctc->SIG1 == ctinterf->sig )
760                 {
761                   ptctc->SIG1 = newsig;
762 
763                   if( ptctc->NODE1 )
764                   {
765                     for( ptcontact = contact ;
766                          ptcontact ;
767                          ptcontact = ptcontact->next
768                        )
769                     {
770                       if( ( ctinterf->sig   == ptcontact->con1->SIG &&
771                             ptctc->NODE1    == ptcontact->node1          ) ||
772                           ( ctinterf->sig   == ptcontact->con2->SIG &&
773                             ptctc->NODE1    == ptcontact->node2          )    )
774                       {
775                         ptctc->NODE1 = ptcontact->interf;
776                         break;
777                       }
778                     }
779                     if( !ptcontact )
780                       ptctc->NODE1 = ptctc->NODE1 + ctinterf->base;
781                     break;
782                   }
783                 }
784               }
785             }
786 
787             if( ptctc->SIG2 == ptinterf->sig )
788             {
789               ptctc->SIG2  = newsig;
790               if( ptctc->NODE2 )
791                 ptctc->NODE2 = newnode[ ptctc->NODE2 ];
792             }
793             else
794             {
795               for( ctinterf = interf ; ctinterf ; ctinterf = ctinterf->next )
796               {
797                 if( ptctc->SIG2 == ctinterf->sig )
798                 {
799                   ptctc->SIG2 = newsig;
800 
801                   if( ptctc->NODE2 )
802                   {
803                     for( ptcontact = contact ;
804                          ptcontact ;
805                          ptcontact = ptcontact->next
806                        )
807                     {
808                       if( ( ctinterf->sig   == ptcontact->con1->SIG &&
809                             ptctc->NODE2    == ptcontact->node1          ) ||
810                           ( ctinterf->sig   == ptcontact->con2->SIG &&
811                             ptctc->NODE2    == ptcontact->node2          )    )
812                       {
813                         ptctc->NODE2 = ptcontact->interf;
814                         break;
815                       }
816                     }
817                     if( !ptcontact )
818                       ptctc->NODE2 = ptctc->NODE2 + ctinterf->base;
819                     break;
820                   }
821                 }
822               }
823             }
824 
825             if(!ptctc)
826             {
827               fflush( stdout );
828               fprintf( stderr, "*** mbk error ***\n" );
829               fprintf( stderr,
830                        "Null CTC on signal %ld (2) in instance %s.\n",
831                        scanlosig->INDEX,
832                        insname
833                      );
834             }
835             newsig->PRCN->PCTC = addchain( newsig->PRCN->PCTC, ptctc );
836 
837           }
838 
839           mbkfree( newnode );
840 
841         }
842       }
843 
844       for( ptinterf = interf ; ptinterf ; ptinterf = ptinterf->next )
845       {
846         if(( ptinterf->sig != scanlosig ) && ( ptinterf->sig != newsig ))
847         {
848           ptptype = getptype( ptinterf->sig->USER, LOFIGCHAIN );
849           freechain( (chain_list*)ptptype->DATA );
850           ptptype->DATA = NULL;
851           if( ptinterf->sig->PRCN && ptinterf->sig->PRCN->PCTC )
852           {
853             freechain( ptinterf->sig->PRCN->PCTC );
854             ptinterf->sig->PRCN->PCTC = NULL;
855           }
856           dellosig( ptfig, ptinterf->sig->INDEX );
857         }
858       }
859 
860       forfree = NULL;
861       for( ptcontact = contact ; ptcontact ; ptcontact=ptcontact->next )
862       {
863         if( forfree )
864      mbkfree( forfree );
865    forfree = ptcontact;
866       }
867       if( forfree )
868         mbkfree( forfree );
869 
870       forfree = NULL;
871       for( ptinterf = interf ; ptinterf ; ptinterf=ptinterf->next )
872       {
873         if( forfree )
874      mbkfree( forfree );
875    forfree = ptinterf;
876       }
877       if( forfree )
878         mbkfree( forfree );
879     }
880     /* vire scanlosig */
881     ptptype = getptype( scanlosig->USER, LOFIGCHAIN );
882     freechain( (chain_list*)ptptype->DATA );
883     ptptype->DATA = NULL;
884 
885     if( scanlosig->PRCN && scanlosig->PRCN->PCTC )
886     {
887       freechain( scanlosig->PRCN->PCTC );
888       scanlosig->PRCN->PCTC = NULL;
889     }
890 
891     dellosig( figins, scanlosig->INDEX );
892 
893 
894   }
895 
896   delloins( ptfig, ptins->INSNAME );
897 
898   if( concat != NO )
899   {
900     for( scanins = figins->LOINS ; scanins ; scanins = scanins->NEXT )
901     {
902       scanins->INSNAME = concatname( insname, scanins->INSNAME );
903 
904       for( scanlocon = scanins->LOCON ; scanlocon ; scanlocon = scanlocon->NEXT)
905       {
906         ptptype = getptype(scanlocon->USER, PNODENAME);
907         if( ptptype )
908         {
909           for( scanchain = (chain_list*)(ptptype->DATA) ;
910                scanchain ;
911                scanchain = scanchain->NEXT
912              )
913             scanchain->DATA = concatname( insname, (char*)(scanchain->DATA) );
914         }
915       }
916     }
917 
918     for( scantrs = figins->LOTRS ; scantrs ; scantrs = scantrs->NEXT )
919     {
920       if( scantrs->TRNAME )
921         scantrs->TRNAME = concatname( insname, scantrs->TRNAME );
922 
923       ptptype = getptype( scantrs->DRAIN->USER, PNODENAME);
924       if( ptptype )
925       {
926         for( scanchain = (chain_list*)(ptptype->DATA) ;
927              scanchain ;
928              scanchain = scanchain->NEXT
929            )
930           scanchain->DATA = concatname( insname, (char*)(scanchain->DATA) );
931       }
932 
933       ptptype = getptype( scantrs->GRID->USER, PNODENAME);
934       if( ptptype )
935       {
936         for( scanchain = (chain_list*)(ptptype->DATA) ;
937              scanchain ;
938              scanchain = scanchain->NEXT
939            )
940           scanchain->DATA = concatname( insname, (char*)(scanchain->DATA) );
941       }
942 
943       ptptype = getptype( scantrs->SOURCE->USER, PNODENAME);
944       if( ptptype )
945       {
946         for( scanchain = (chain_list*)(ptptype->DATA) ;
947              scanchain ;
948              scanchain = scanchain->NEXT
949            )
950           scanchain->DATA = concatname( insname, (char*)(scanchain->DATA) );
951       }
952 
953       ptptype = getptype( scantrs->BULK->USER, PNODENAME);
954       if( ptptype )
955       {
956         for( scanchain = (chain_list*)(ptptype->DATA) ;
957              scanchain ;
958              scanchain = scanchain->NEXT
959            )
960           scanchain->DATA = concatname( insname, (char*)(scanchain->DATA) );
961       }
962     }
963 
964     for(scancap = figins -> LOCAP ; scancap != NULL ; scancap = scancap -> NEXT)
965       {
966         if(scancap -> NAME != NULL)
967 	  {
968             scancap -> NAME = concatname(insname,scancap -> NAME) ;
969 	  }
970 
971         ptptype = getptype(scancap -> TCON -> USER,PNODENAME) ;
972 
973         if(ptptype)
974           {
975              for(scanchain = (chain_list *)(ptptype -> DATA) ; scanchain ; scanchain = scanchain->NEXT)
976 	       {
977                  scanchain -> DATA = concatname(insname,(char *)(scanchain -> DATA)) ;
978 	       }
979 	  }
980 
981 	ptptype = getptype( scancap -> BCON -> USER,PNODENAME) ;
982 
983 	if(ptptype)
984 	  {
985 	    for(scanchain = (chain_list *)(ptptype -> DATA) ; scanchain ; scanchain = scanchain->NEXT)
986 	      {
987 		scanchain -> DATA = concatname(insname,(char *)(scanchain -> DATA)) ;
988 	      }
989 	  }
990       }
991 
992     for(scanres = figins -> LORES ; scanres != NULL ; scanres = scanres -> NEXT)
993       {
994         if(scanres -> NAME != NULL)
995 	  {
996             scanres -> NAME = concatname(insname,scanres -> NAME) ;
997 	  }
998 
999         ptptype = getptype(scanres -> RCON1 -> USER,PNODENAME) ;
1000 
1001         if(ptptype)
1002           {
1003              for(scanchain = (chain_list *)(ptptype -> DATA) ; scanchain ; scanchain = scanchain->NEXT)
1004 	       {
1005                  scanchain -> DATA = concatname(insname,(char *)(scanchain -> DATA)) ;
1006 	       }
1007 	  }
1008 
1009 	ptptype = getptype( scanres -> RCON2 -> USER,PNODENAME) ;
1010 
1011 	if(ptptype)
1012 	  {
1013 	    for(scanchain = (chain_list *)(ptptype -> DATA) ; scanchain ; scanchain = scanchain->NEXT)
1014 	      {
1015 		scanchain -> DATA = concatname(insname,(char *)(scanchain -> DATA)) ;
1016 	      }
1017 	  }
1018       }
1019 
1020     for(scanself = figins -> LOSELF ; scanself != NULL ; scanself = scanself -> NEXT)
1021       {
1022         if(scanself -> NAME != NULL)
1023 	  {
1024             scanself -> NAME = concatname(insname,scanself -> NAME) ;
1025 	  }
1026 
1027         ptptype = getptype(scanself -> SCON1 -> USER,PNODENAME) ;
1028 
1029         if(ptptype)
1030           {
1031              for(scanchain = (chain_list *)(ptptype -> DATA) ; scanchain ; scanchain = scanchain->NEXT)
1032 	       {
1033                  scanchain -> DATA = concatname(insname,(char *)(scanchain -> DATA)) ;
1034 	       }
1035 	  }
1036 
1037 	ptptype = getptype( scanself -> SCON2 -> USER,PNODENAME) ;
1038 
1039 	if(ptptype)
1040 	  {
1041 	    for(scanchain = (chain_list *)(ptptype -> DATA) ; scanchain ; scanchain = scanchain->NEXT)
1042 	      {
1043 		scanchain -> DATA = concatname(insname,(char *)(scanchain -> DATA)) ;
1044 	      }
1045 	  }
1046       }
1047   }
1048 
1049   for( scanins = figins->LOINS ; scanins ; scanins = scanins->NEXT )
1050   {
1051     for( scanmodel = ptfig->MODELCHAIN ;
1052          scanmodel ;
1053          scanmodel = scanmodel->NEXT )
1054       if( (char*)scanmodel->DATA == scanins->FIGNAME )
1055         break;
1056     if( !scanmodel )
1057       ptfig->MODELCHAIN = addchain( ptfig->MODELCHAIN, scanins->FIGNAME );
1058   }
1059 
1060   ptfig->LOINS = (loins_list*)append( (chain_list*)figins->LOINS,
1061                                       (chain_list*)ptfig->LOINS );
1062   ptfig->LOTRS = (lotrs_list*)append( (chain_list*)figins->LOTRS,
1063                                       (chain_list*)ptfig->LOTRS );
1064 
1065   ptfig->LOCAP = (locap_list*)append( (chain_list*)figins->LOCAP,
1066                                       (chain_list*)ptfig->LOCAP );
1067 
1068   ptfig->LORES = (lores_list*)append( (chain_list*)figins->LORES,
1069                                       (chain_list*)ptfig->LORES );
1070 
1071   ptfig->LOSELF = (loself_list*)append( (chain_list*)figins->LOSELF,
1072                                       (chain_list*)ptfig->LOSELF );
1073 
1074   figins->LOINS = NULL;
1075   figins->LOTRS = NULL;
1076 
1077   figins->LOCAP = NULL;
1078   figins->LORES = NULL;
1079   figins->LOSELF = NULL;
1080 
1081 
1082   for( scanlocon = figins->LOCON ; scanlocon ; scanlocon = nextlocon )
1083   {
1084     nextlocon = scanlocon->NEXT;
1085     delloconuser( scanlocon );
1086     mbkfree( (void*)scanlocon );
1087   }
1088   figins->LOCON = NULL;
1089 
1090   for( ptptype = figins->BKSIG ; ptptype ; ptptype = ptptype->NEXT )
1091     mbkfree( (void*)ptptype->DATA );
1092   freeptype( figins->BKSIG );
1093   figins->BKSIG = NULL;
1094   figins->LOSIG = NULL;
1095 
1096   freechain( figins->MODELCHAIN );
1097   figins->MODELCHAIN = NULL;
1098 
1099   /* Les seules valeurs qui peuvent arriver sont : PTSIGSIZE */
1100 
1101   dellofiguser( figins );
1102 
1103   if( figins->MODELCHAIN     ||
1104       figins->LOCON          ||
1105       figins->LOSIG          ||
1106       figins->BKSIG          ||
1107       figins->LOINS          ||
1108       figins->LOTRS          ||
1109       figins->LOCAP          ||
1110       figins->LORES          ||
1111       figins->LOSELF         ||
1112       figins->USER              )
1113   {
1114     fflush( stdout );
1115     fprintf( stderr,
1116              "*** mbk warning *** : figure %s not empty (type=%ld)\n",
1117              figins->NAME,
1118              figins->USER->TYPE
1119            );
1120   }
1121   mbkfree( (void*)figins );
1122 
1123   if(all == 'N')
1124    break ;
1125   }
1126 
1127   /* Post traitement sur les CTC dont un des noeuds est a 0 */
1128 
1129   /* Variable de debuggage */
1130   verif = 0;
1131 
1132   /* Regroupe les CTC en double */
1133   for( scanchain = posttreatsig ; scanchain ; scanchain = scanchain->NEXT )
1134   {
1135     scanlosig = (losig_list*)(scanchain->DATA);
1136     if(getptype(scanlosig->USER,FLATTEN_POSTRAIT) != NULL)
1137       scanlosig->USER = delptype(scanlosig->USER,FLATTEN_POSTRAIT) ;
1138 
1139     if((scanlosig->INDEX == 0) || ( ! scanlosig->PRCN ))
1140       continue;
1141 
1142     htab = addht(scanlosig->PRCN->NBNODE + 100) ;
1143 
1144     for( scanctc = scanlosig->PRCN->PCTC ; scanctc ; scanctc = scanctc->NEXT )
1145     {
1146       ptctc = (loctc_list*)( scanctc->DATA );
1147 
1148       if( ptctc->CAPA >= 0.0 )
1149       {
1150         if( ptctc->SIG1 == scanlosig )
1151         {
1152           othersig    = ptctc->SIG2  ;
1153           othernode   = ptctc->NODE2 ;
1154           scanctcnode = ptctc->NODE1 ;
1155         }
1156         else
1157         {
1158           othersig    = ptctc->SIG1  ;
1159           othernode   = ptctc->NODE1 ;
1160           scanctcnode = ptctc->NODE2 ;
1161         }
1162      if( othersig == scanlosig && othernode == scanctcnode )
1163         {
1164           ptctc->CAPA = -1.0 ;
1165         //verif = verif + 2 ;
1166         }
1167       else
1168         {
1169          key = othersig->INDEX << 11 ;
1170          key = (key | othernode) << 11 ;
1171          key = (key | scanctcnode) ;
1172 
1173          if((chainhtab = (chain_list *)gethtitem(htab,(void *)key)) == (chain_list *)EMPTYHT)
1174           {
1175            chainhtab = addchain(NULL,ptctc) ;
1176            addhtitem(htab,(void *)key,(long)chainhtab) ;
1177           }
1178          else
1179           {
1180            for(chainht = chainhtab ; chainht ; chainht = chainht->NEXT)
1181             {
1182              ptctc2 = (loctc_list*)(chainht->DATA);
1183 
1184              if( ptctc2->CAPA < 0.0 )
1185               continue;
1186 
1187              if((( ptctc2->SIG1  == scanlosig && ptctc2->SIG2 == othersig) &&
1188                 (ptctc2->NODE1 == scanctcnode && ptctc2->NODE2 == othernode)) ||
1189                ((ptctc2->SIG2  == scanlosig && ptctc2->SIG1 == othersig) &&
1190                 (ptctc2->NODE2 == scanctcnode && ptctc2->NODE1 == othernode)))
1191                 {
1192                   ptctc->CAPA+= ptctc2->CAPA;
1193                   ptctc2->CAPA = -1.0;
1194                 //verif = verif + 2 ;
1195                 }
1196             }
1197            chainhtab = addchain(chainhtab,ptctc) ;
1198            addhtitem(htab,(void *)key,(long)chainhtab) ;
1199           }
1200         }
1201      }
1202     }
1203    for( nbi = 0 ; nbi < htab->length ; nbi++)
1204     if((((ptitem = htab->pElem + nbi)->value) != (long)EMPTYHT) &&
1205        ((htab->pElem + nbi)->value != (long)DELETEHT))
1206       freechain((chain_list *)ptitem->value) ;
1207    delht(htab) ;
1208   }
1209 
1210   /* On fait le menage en virant les CTC dont la capa vaut -1 */
1211 
1212   for( scanchain = posttreatsig ; scanchain ; scanchain = scanchain->NEXT )
1213   {
1214     scanlosig = ( losig_list*)( scanchain->DATA );
1215     if((scanlosig->INDEX == 0) || ( ! scanlosig->PRCN ))
1216      continue ;
1217 
1218     prevctc = NULL;
1219     for( scanctc = scanlosig->PRCN->PCTC ; scanctc ; scanctc = nextscanctc )
1220     {
1221       nextscanctc = scanctc->NEXT;
1222 
1223       ptctc = (loctc_list*)( scanctc->DATA );
1224 
1225       if( ptctc->CAPA < 0.0 )
1226       {
1227         if( prevctc )
1228           prevctc->NEXT = nextscanctc ;
1229         else
1230           scanlosig->PRCN->PCTC = nextscanctc ;
1231 
1232         scanctc->NEXT = NULL;
1233         freechain( scanctc );
1234 
1235         prevctc2 = NULL;
1236         sigctc2 = ( ptctc->SIG1 == scanlosig ? ptctc->SIG2 : ptctc->SIG1 );
1237         for( scanctc2 = sigctc2->PRCN->PCTC ;
1238              scanctc2 ;
1239              scanctc2 = scanctc2->NEXT
1240            )
1241         {
1242           if( scanctc2->DATA == ptctc )
1243           {
1244             /* cas particulier : une CTC sur un  meme signal, dont les
1245                chain_list sont consecutifs */
1246             if( scanctc2 == nextscanctc )
1247               nextscanctc = nextscanctc->NEXT;
1248 
1249             if( prevctc2 )
1250               prevctc2->NEXT = scanctc2->NEXT;
1251             else
1252               sigctc2->PRCN->PCTC = scanctc2->NEXT;
1253 
1254             scanctc2->NEXT = NULL;
1255             freechain( scanctc2 );
1256             break;
1257           }
1258           prevctc2 = scanctc2;
1259         }
1260 
1261         freeloctc( ptctc );
1262       }
1263       else
1264         prevctc = scanctc;
1265     }
1266   }
1267 
1268   freechain( posttreatsig );
1269 }
1270 
debugctc2(lofig_list * ptfig)1271 void debugctc2 ( lofig_list *ptfig )
1272 {
1273    losig_list   *sig;
1274    chain_list   *scanchain;
1275    loctc_list   *ptctc;
1276 
1277    printf( "Information sur la figure %s.\n", ptfig->NAME );
1278    for( sig = ptfig->LOSIG ; sig ; sig = sig->NEXT )
1279    {
1280      printf( "Signal %2ld (%08lX)\n", sig->INDEX, (unsigned long)sig );
1281      if( sig->PRCN )
1282      {
1283        for( scanchain = sig->PRCN->PCTC ;
1284             scanchain ;
1285             scanchain = scanchain->NEXT
1286           )
1287        {
1288          ptctc = ( loctc_list* )( scanchain->DATA );
1289          printf(
1290                 "  CTC (%lX) entre le signal %2ld (%lX) et le signal %2ld (%lX).\n",
1291                  (unsigned long)ptctc,
1292                  ptctc->SIG1->INDEX,
1293                  (unsigned long)ptctc->SIG1,
1294                  ptctc->SIG2->INDEX,
1295                  (unsigned long)ptctc->SIG2
1296                );
1297        }
1298      }
1299    }
1300 }
1301 
debugctc(losig_list * headlosig,int niveau)1302 void debugctc ( losig_list *headlosig, int niveau )
1303 {
1304   losig_list            *scanlosig;
1305   chain_list            *scanctc;
1306   chain_list            *scanctc2;
1307   loctc_list            *ptctc;
1308 
1309   /* Boucle de debuggage */
1310   for( scanlosig = headlosig ; scanlosig ; scanlosig = scanlosig->NEXT )
1311   {
1312     if( ! scanlosig->PRCN )
1313       continue;
1314 
1315     for( scanctc = scanlosig->PRCN->PCTC ; scanctc ; scanctc = scanctc->NEXT )
1316     {
1317       ptctc = (loctc_list*)( scanctc->DATA );
1318       if( getptype( ptctc->USER, FLATTEN_CTC ) )
1319       {
1320         printf( "(%d) FLATTEN_CTC trouve dans la CTC (%lX)  entre %ld.%ld et %ld.%ld.\n",
1321                 niveau,
1322                 (unsigned long)ptctc,
1323                 ptctc->SIG1->INDEX,
1324                 ptctc->NODE1,
1325                 ptctc->SIG2->INDEX,
1326                 ptctc->NODE2
1327               );
1328         exit(-1);
1329       }
1330 
1331       for( scanctc2 = ( ptctc->SIG1 == scanlosig ? ptctc->SIG2 : ptctc->SIG1 )->PRCN->PCTC ;
1332            scanctc2 ;
1333            scanctc2 = scanctc2->NEXT )
1334       {
1335         if( scanctc2->DATA == ptctc )
1336           break;
1337       }
1338       if( !scanctc2 )
1339       {
1340         printf( "(%d) CTC (%lX) entre %ld:%ld et %ld:%ld sur signal %ld non trouvee sur l'autre signal.\n",
1341                 niveau,
1342                 (unsigned long)ptctc,
1343                 ptctc->SIG1->INDEX, ptctc->NODE1,
1344                 ptctc->SIG2->INDEX, ptctc->NODE2,
1345                 scanlosig->INDEX
1346               );
1347         exit(-1);
1348       }
1349     }
1350   }
1351 }
1352 
1353 /*******************************************************************************
1354 * function loadlofig                                                           *
1355 *******************************************************************************/
loadlofig(lofig_list * ptfig,const char * name,char mode)1356 void loadlofig(lofig_list *ptfig, const char *name, char mode)
1357 {
1358    if (TRACE_MODE == 'Y')
1359       (void)fprintf(stdout,
1360                      "--- mbk --- loadlofig : reading file %s.%s mode %c\n",
1361                      name, IN_LO, mode);
1362    if ((!strcmp(IN_LO, "hns")) || (!strcmp(IN_LO, "fne"))
1363          || (!strcmp(IN_LO, "hdn")) || (!strcmp(IN_LO, "fdn")))
1364       vtiloadlofig(ptfig, name, mode);
1365    else if ((!strcmp(IN_LO, "al")) || (!strcmp(IN_LO, "alx")))
1366       alcloadlofig(ptfig, name, mode);
1367    else if (!strcmp(IN_LO, "spi") || !strcmp( IN_LO, "sp" ) ||
1368                 !strcmp(IN_LO, "cir"))
1369       spiceloadlofig(ptfig, name, mode);
1370    else if (!strcmp(IN_LO, "edi"))
1371       edifloadlofig(ptfig, name, mode);
1372    else if (!strcmp(IN_LO, "vst"))
1373       vhdlloadlofig(ptfig, name, mode);
1374    else {
1375       (void)fflush(stdout);
1376       (void)fprintf(stderr, "*** mbk error ***\n");
1377       (void)fprintf(stderr, "MBK_IN_LO : '%s' unknown format\n", IN_LO);
1378       EXIT(1);
1379    }
1380    if (TRACE_MODE == 'Y')
1381       (void)fprintf(stdout,
1382                      "--- mbk --- loadlofig : done reading file %s.%s\n",
1383                      name, IN_LO);
1384 }
1385 
1386 /*******************************************************************************
1387 * function savelofig                                                           *
1388 *******************************************************************************/
savelofig(lofig_list * ptfig)1389 void savelofig(lofig_list *ptfig)
1390 {
1391    if ((!strcmp(OUT_LO, "hns")) || (!strcmp(OUT_LO, "fne"))
1392          || (!strcmp(OUT_LO, "hdn")) || (!strcmp(OUT_LO, "fdn")))
1393       vtisavelofig(ptfig);
1394    else if ((!strcmp(OUT_LO, "al")) || (!strcmp(OUT_LO, "alx")))
1395       alcsavelofig(ptfig);
1396    else if (!strcmp(OUT_LO, "spi")  || !strcmp( OUT_LO, "sp" ) ||
1397                 !strcmp(OUT_LO, "cir"))
1398       spicesavelofig(ptfig);
1399    else if (!strcmp(OUT_LO, "edi"))
1400       edifsavelofig(ptfig);
1401    else if (!strcmp(OUT_LO, "vst"))
1402       vhdlsavelofig(ptfig);
1403    else if (!strcmp(OUT_LO, "cct"))
1404       hilosavelofig(ptfig);
1405         else if (!strcmp(OUT_LO, "vlg"))
1406                 vlogsavelofig(ptfig);
1407    else {
1408       (void)fflush(stdout);
1409       (void)fprintf(stderr, "*** mbk error ***\n");
1410       (void)fprintf(stderr, "MBK_OUT_LO : %s unknown format\n", OUT_LO);
1411       EXIT(1);
1412    }
1413 }
1414 
1415 /*******************************************************************************
1416 * function rflattenlofig()                                                     *
1417 * flatten recursif sur une figure logique ptfig.                               *
1418 * concat permet de generer les cheminons (concat != 'N')                       *
1419 * la mise a plat s'effectue jusqu'au cellules du catalogue                     *
1420 * non comprises.                                                               *
1421 * catal = `y` ou catal=`Y` indique qu`il faut tenir compte du                  *
1422 * catalogue. Une autre valeur implique un flatten complet.                     *
1423 *******************************************************************************/
rflattenlofig(lofig_list * ptfig,char concat,char catal)1424 void rflattenlofig(lofig_list *ptfig, char concat, char catal)
1425 {
1426 loins_list *p;
1427 chain_list *c;
1428 
1429    catal = catal == NO ? 0 : 1;
1430    for (p = ptfig->LOINS; p != NULL;) {
1431       if (!catal || !incatalog(p->FIGNAME) || incatalogdelete(p->FIGNAME)) {
1432          flattenlofig(ptfig, p->INSNAME, concat);
1433          p = ptfig->LOINS;
1434       }
1435       else
1436          p = p->NEXT;
1437    }
1438    freechain(ptfig->MODELCHAIN);
1439    ptfig->MODELCHAIN = NULL;
1440    p = ptfig->LOINS;
1441    while (p != NULL) {
1442       c = ptfig->MODELCHAIN;
1443       while (c != NULL) {
1444          if ((char *)c->DATA == p->FIGNAME)
1445             break;
1446          c = c->NEXT;
1447       }
1448       if (c == NULL)
1449          ptfig->MODELCHAIN = addchain(ptfig->MODELCHAIN, (void *)p->FIGNAME);
1450       p = p->NEXT;
1451    }
1452 }
1453 
1454 /*
1455 UNFLATLOFIG
1456 
1457 II. Algorithme
1458 --------------
1459 
1460 1. On fait un LOFIGCHAIN sur 'ptfig'.
1461 
1462 2. On veut construire deux 'chain_list' :
1463    LI : signaux internes a la nouvelle figure
1464    LX : signaux externes a la nouvelle figure
1465 
1466    Pour la figure 'ptfig', on parcourt la liste des signaux :
1467       Pour chaque signal, on parcourt la liste des connecteurs qui lui
1468       sont associes (par LOFIGCHAIN):
1469         * Si AUCUN connecteur n'appartient a une instance presente dans
1470           la liste 'list', on passe au signal suivant (pas d'insertion)
1471 
1472         * Sinon, si TOUS les connecteurs appartiennent a une instance
1473           presente dans la liste 'list', le signal est insere dans la
1474           liste LI
1475         * Sinon, le signal est insere dans la liste LX
1476           (au moins un connecteur n'appartient pas a la nouvelle figure)
1477 
1478 3. On construit la nouvelle figure. Il faut creer :
1479    - une liste des signaux
1480    - une liste des connecteurs externes
1481    - une liste des instances, chacune contenant une liste de connecteurs
1482 
1483  a. liste des signaux
1484     on parcourt la liste LI et la liste LX : on ajoute chaque signal a
1485     la liste des signaux de la nouvelle figure.
1486     On construit une structure ptype (de nom UNFLATLOFIG), donnant a
1487     chaque signal de LI ou LX un pointeur vers le signal cree dans la
1488     nouvelle figure.
1489 
1490  b. liste des connecteurs externes
1491     on parcourt la liste LX :
1492     pour chaque signal, on cherche le premier connecteur interne (a la
1493     nouvelle figure) et le premier connecteur externe (a la nouvelle
1494     figure), de preference un terminal de la figure pere: s'il en
1495     existe un (terminal) on prend celui-la, sinon on prend le
1496     premier externe a la nouvelle figure, mais non terminal dans
1497     la figure pere.
1498     On ajoute un connecteur externe a la nouvelle figure. Il pointe
1499     sur le signal courant (dans la nouvelle). Sa direction est:
1500     - si le connecteur n'appartenant pas a la nouvelle figure est
1501       un terminal du pere (externe), le nouveau connecteur prend la
1502       direction de ce terminal.
1503     - si le connecteur n'appartenant pas a la nouvelle figure est un
1504       connecteur d'instance, le nouveau connecteur prend la direction
1505       du premier connecteur INTERNE a la nouvelle figure trouve
1506       precedemment.
1507     Le nom du nouveau connecteur est:
1508     - le nom du signal auquel il est connecte si ce dernier en a un.
1509     - sinon :
1510       . si le premier connecteur n'appartenant pas a la nouvelle
1511         figure est un terminal, le nouveau prend ce nom,
1512       . si le premier connecteur n'appartenant pas a la nouvelle
1513         figure est un connecteur d'instance, le nouveau prend le
1514         nom du connecteur INTERNE a la nouvelle figure (comme pour
1515         la direction).
1516     Dans tous les cas, on concatene au nom un compteur (comptant le
1517     nombre de connecteurs externes crees) pour assurer l'unicite.
1518 
1519  c. liste des instances
1520     on parcourt la liste 'list' :
1521     on insere chaque instance dans la liste d'instances de la nouvelle
1522     figure. Pour chaque connecteur d'une instance de 'list', on
1523     ajoute un connecteur dans la liste des connecteurs de l'instance
1524     dans la nouvelle figure, dont le signal dans la nouvelle figure est
1525     obtenu en consultant la structure ptype du signal dans la figure pere.
1526     Les connecteurs prennent les directions des connecteurs dans les
1527     instances de la figure pere.
1528 
1529 4. On modifie la figure pere.
1530     On instancie la nouvelle figure.
1531     On detruit les signaux internes (LI).
1532     On detruit les instances de la liste 'list'.
1533 */
1534 /*******************************************************************************
1535 * function unflattenlofig                                                      *
1536 *******************************************************************************/
unflattenlofig(lofig_list * ptfig,const char * figname,const char * insname,chain_list * list)1537 lofig_list *unflattenlofig(lofig_list *ptfig, const char  *figname, const char  *insname, chain_list *list)
1538 {
1539 lofig_list *newlofig = NULL;
1540 chain_list *li_head = NULL, *lx_head = NULL, *ptchain;
1541 losig_list *ptsig;
1542 
1543    if (ptfig == NULL)
1544       return NULL;
1545    lofigchain(ptfig);
1546    /* scan signals:
1547       construct LI and LX. */
1548    for (ptsig = ptfig->LOSIG; ptsig != NULL; ptsig = ptsig->NEXT) {
1549    chain_list *loconchain;
1550    int found_int = 0, found_ext = 0;
1551       /* scan connectors of signal */
1552       for (loconchain =
1553             (chain_list * )((getptype (ptsig->USER, (long)LOFIGCHAIN))->DATA);
1554             loconchain != NULL; loconchain = loconchain->NEXT) {
1555       locon_list *ptcon;
1556       chain_list *loinschain;
1557          ptcon = (locon_list * )(loconchain->DATA);
1558          for (loinschain = list; loinschain != NULL;
1559                loinschain = loinschain->NEXT)
1560             if ((void *)(loinschain->DATA) == ptcon->ROOT)
1561                break;
1562          if (loinschain == NULL)
1563             found_ext ++;
1564          else
1565             found_int ++;
1566       }
1567       if (found_int == 0)
1568          continue; /* no insertion */
1569       if (found_ext == 0)
1570          li_head = addchain(li_head, (void *)(ptsig)); /* insert LI */
1571       else
1572          lx_head = addchain(lx_head, (void *)(ptsig)); /* insert LX */
1573    } /* endfor ptsig */
1574 
1575    /***** add new figure : */
1576    /* create signals list */
1577    newlofig = addlofig(figname);
1578    for (ptchain = li_head; ptchain != NULL; ptchain = ptchain->NEXT) {
1579    losig_list * ptlosig;
1580    ptype_list * ptype;
1581    chain_list * namechain = NULL, *ptaux;
1582 
1583       ptlosig = (losig_list *)(ptchain->DATA);
1584       for (ptaux = ptlosig->NAMECHAIN; ptaux != NULL; ptaux =
1585           ptaux->NEXT)
1586          namechain = addchain(namechain, ptaux->DATA);
1587       newlofig->LOSIG = addlosig(newlofig, ptlosig->INDEX, namechain, INTERNAL );
1588          if( ptlosig->PRCN ) {
1589             addlorcnet( newlofig->LOSIG );
1590             addcapa( newlofig->LOSIG, ptlosig->PRCN->CAPA );
1591          }
1592       ptlosig->USER = addptype(ptlosig->USER, (long)UNFLATLOFIG,
1593            (void * )NULL);
1594       ptype = getptype(ptlosig->USER, (long)UNFLATLOFIG);
1595       ptype->DATA = (void *)addchain((chain_list * )ptype->DATA,
1596            (void *)(newlofig->LOSIG));
1597    }
1598    for (ptchain = lx_head; ptchain != NULL; ptchain = ptchain->NEXT) {
1599    losig_list *ptlosig;
1600    ptype_list *ptype;
1601    chain_list *namechain = NULL, *ptaux;
1602 
1603       ptlosig = (losig_list *)(ptchain->DATA);
1604       for (ptaux = ptlosig->NAMECHAIN; ptaux != NULL; ptaux =
1605           ptaux->NEXT)
1606          namechain = addchain(namechain, ptaux->DATA);
1607       newlofig->LOSIG = addlosig(newlofig, ptlosig->INDEX, namechain, EXTERNAL );
1608       if( ptlosig->PRCN ) {
1609          addlorcnet( newlofig->LOSIG );
1610          addcapa( newlofig->LOSIG, ptlosig->PRCN->CAPA );
1611       }
1612 
1613       ptlosig->USER = addptype(ptlosig->USER, (long)UNFLATLOFIG,
1614            (void * )NULL);
1615       ptype = getptype (ptlosig->USER, (long)UNFLATLOFIG);
1616       ptype->DATA = (void *)addchain((chain_list *)ptype->DATA,
1617            (void *)(newlofig->LOSIG));
1618    }
1619 
1620    /* create terminals list */
1621    for (ptchain = lx_head; ptchain != NULL; ptchain = ptchain->NEXT) {
1622    locon_list *intlocon = NULL, *extlocon = NULL;
1623    losig_list *ptlosig, *newlosig;
1624    ptype_list *ptype;
1625    chain_list *loconchain, *auxchain;
1626    static char loconname[BUFSIZE];
1627    char  *name;
1628    char  locondir;
1629  /*int   i;*/
1630    int   foundterm = 0;
1631 
1632       /* scan connectors list of the current signal */
1633       ptlosig = (losig_list *)(ptchain->DATA);
1634       for (loconchain =
1635             (chain_list *)((getptype (ptlosig->USER, (long)LOFIGCHAIN))->DATA);
1636             loconchain != NULL; loconchain = loconchain->NEXT) {
1637       locon_list *ptlocon;
1638       chain_list *loinschain;
1639 
1640          ptlocon = (locon_list *)(loconchain->DATA);
1641          for (loinschain = list; loinschain != NULL; loinschain =
1642              loinschain->NEXT)
1643             if ((void *)(loinschain->DATA) == ptlocon->ROOT)
1644                break;
1645          if (loinschain == NULL) { /* external connector of new figure */
1646             if (ptlocon->TYPE == EXTERNAL) /* external con. in root figure too */ {
1647                foundterm++;
1648                extlocon = ptlocon;
1649             } else if (extlocon == NULL)
1650                extlocon = ptlocon;
1651          } else if (intlocon == NULL)
1652             intlocon = ptlocon; /* internal con. in new */
1653       } /* endfor loconchain */
1654 
1655       /* create new external connector for the new figure */
1656       locondir = foundterm ? extlocon->DIRECTION : intlocon->DIRECTION;
1657       name = (ptlosig->NAMECHAIN != NULL) ?  getsigname(ptlosig) :
1658           foundterm ? extlocon->NAME : intlocon->NAME;
1659       /*
1660       i = 0;
1661       while ( (name[i] != '\0') && (name[i] != ' ') ) {
1662          loconname [i] = name[i];
1663          i++;
1664       }
1665       loconname[i] = '\0';
1666       */
1667       /* Franck */
1668       strcpy(loconname, name);
1669       if ((name = strchr(loconname, ' ')) != NULL)
1670          *name = '_';
1671 
1672       /* the format used to be %s%lu%s but it generates vectors with a
1673          unique base name.
1674          sprintf(loconname, "%s%lu%s", loconname, newtermcount++, &(name[i]));
1675          Since the interface of the resulting figure is not supposed to be
1676          used by humans, let's make simple names.
1677          Hey Hey, this was true a while ago, but as always, now we want
1678          humans to predict the ouput of the function. Fun, ain'it? */
1679       /* !Franck
1680       sprintf(loconname, "%s_%lu", loconname, newtermcount++);
1681       */
1682       ptype = getptype(ptlosig->USER, (long)UNFLATLOFIG);
1683       auxchain = (chain_list *)(ptype->DATA);
1684       newlosig = (losig_list *)(auxchain->DATA);
1685       newlofig->LOCON = addlocon(newlofig, loconname, newlosig, locondir);
1686    } /* endfor ptchain */
1687 
1688 
1689    /* create instances list */
1690    for (ptchain = list; ptchain != NULL; ptchain = ptchain->NEXT) {
1691    loins_list *ptloins;
1692    locon_list *ptlocon, *ptaux, *con;
1693    chain_list *signal = NULL;
1694    lofig_list *model;
1695    /* Why this model ?
1696       we need a name matching and not an order matching.
1697       we have to read in the file, because we need to have a lofig in order
1698       to be able to call addloins.
1699       The matching is done trivially, using a n^2 loop: since the number of
1700       connectors on an instance is small, an unflattenlofig very seldom
1701       called :-) it's not worth some malloc + qsort, and furthermore, I'm
1702       lazy today! */
1703    int i = 0, j = 0;
1704 
1705       ptloins = (loins_list *)(ptchain->DATA);
1706       model = getlofig(ptloins->FIGNAME, 'P');
1707       for (con = model->LOCON; con != NULL; con = con->NEXT)
1708          i++;
1709       for (ptlocon = ptloins->LOCON; ptlocon != NULL; ptlocon = ptlocon->NEXT)
1710          j++;
1711       if (i != j) {
1712          fflush(stdout);
1713          fputs("*** mbk error ***\n", stderr);
1714          fputs("unflattenlofig : connector number inconsistency between model",
1715                stderr);
1716          fprintf(stderr, " '%s' and instance '%s'\n",
1717                model->NAME, ptloins->INSNAME);
1718          EXIT(1);
1719       }
1720       for (con = model->LOCON; con != NULL; con = con->NEXT) {
1721          for (ptlocon = ptloins->LOCON; ptlocon != NULL;
1722             ptlocon = ptlocon->NEXT) {
1723          chain_list *sigchain;
1724             if (ptlocon->NAME == con->NAME) {
1725                sigchain = (chain_list *)((getptype(ptlocon->SIG->USER,
1726                                            (long)UNFLATLOFIG))->DATA);
1727                signal = addchain(signal, (void *)(sigchain->DATA));
1728                break;
1729             }
1730          }
1731       }
1732       signal = reverse(signal);
1733       newlofig->LOINS = addloins(newlofig, ptloins->INSNAME, model, signal);
1734       for (ptlocon = newlofig->LOINS->LOCON, ptaux = ptloins->LOCON;
1735           (ptlocon != NULL) && (ptaux != NULL);  ptlocon = ptlocon->NEXT,
1736            ptaux = ptaux->NEXT)
1737          ptlocon->DIRECTION = ptaux->DIRECTION;
1738    }
1739 
1740    /***** free ptype lists (lofigchain and unflatlofig) */
1741    /* free lofigchain */
1742    for (ptsig = ptfig->LOSIG; ptsig != NULL; ptsig = ptsig->NEXT) {
1743    ptype_list *ptype;
1744 
1745       ptype = getptype(ptsig->USER, (long)LOFIGCHAIN);
1746       freechain ((chain_list *)ptype->DATA);
1747       ptype->DATA = (void *)NULL;
1748       ptsig->USER = delptype(ptsig->USER, (long)LOFIGCHAIN);
1749    }
1750 
1751    /* free unflatlofig in lx signals */
1752    for (ptchain = lx_head; ptchain != NULL; ptchain = ptchain->NEXT) {
1753    ptype_list *ptype;
1754    losig_list *ptlosig;
1755 
1756       ptlosig = (losig_list *)(ptchain->DATA);
1757       ptype = getptype(ptlosig->USER, (long)UNFLATLOFIG);
1758       freechain ((chain_list *)ptype->DATA);
1759       ptype->DATA = (void *)NULL;
1760       ptlosig->USER = delptype(ptlosig->USER, (long)UNFLATLOFIG);
1761    }
1762 
1763    /* free unflatlofig in li signals */
1764    for (ptchain = li_head; ptchain != NULL; ptchain = ptchain->NEXT) {
1765    ptype_list *ptype;
1766    losig_list *ptlosig;
1767 
1768       ptlosig = (losig_list *)(ptchain->DATA);
1769       ptype = getptype (ptlosig->USER, (long)UNFLATLOFIG);
1770       freechain ((chain_list *)ptype->DATA);
1771       ptype->DATA = (void *)NULL;
1772       ptlosig->USER = delptype(ptlosig->USER, (long)UNFLATLOFIG);
1773    }
1774 
1775    /***** modify the root figure :*/
1776    /* add new instancied figure */
1777    lx_head = reverse (lx_head);
1778    ptfig->LOINS = addloins(ptfig, insname, getlofig(figname, 'P'), lx_head);
1779 
1780    /* delete signals */
1781    for (ptchain = li_head; ptchain != NULL; ptchain = ptchain->NEXT)
1782       dellosig(ptfig, ((losig_list *)(ptchain->DATA))->INDEX);
1783 
1784    /* delete instances */
1785    for (ptchain = list; ptchain != NULL; ptchain = ptchain->NEXT)
1786       delloins(ptfig, ((loins_list *)(ptchain->DATA))->INSNAME);
1787    return newlofig;
1788 }
1789 
1790 #define OK      1
1791 #define PROBLEM 0
1792 #define NOVBE  -1
1793 
restoredirvbe(lofig_list * lof)1794 int restoredirvbe(lofig_list *lof)
1795 {
1796 FILE *f = NULL;
1797 char line[BUFSIZ];
1798 int p, q, r, from, to, inc, nbcon;
1799 int run = 0; /* shall we interpret what we read? */
1800 char string[128], hook[128];
1801 locon_list * fc, *fct;
1802 char dir;
1803 
1804    if (!lof) {
1805       fprintf(stderr, "*** mbk error *** restoredirvbe : no figure given\n");
1806       return PROBLEM;
1807    }
1808    if ((f = mbkfopen(lof->NAME, "vbe", "r")) == NULL)
1809       if ((f = mbkfopen(lof->NAME, "vst", "r")) == NULL)
1810          return NOVBE;
1811    lof->LOCON = (locon_list * )reverse((chain_list * )lof->LOCON);
1812    nbcon = 0;
1813    while (1) {
1814       if (fgets(line, BUFSIZ, f) == NULL)
1815          break;
1816       for (p = 0; p < BUFSIZ && line[p] && line[p] != '\n'; p++)
1817          if (isupper((int)line[p]))
1818             line[p] = tolower(line[p]);
1819       p = 0;
1820       while (isspace((int)line[p]))
1821          p++;
1822       switch (line[p]) {
1823       case 'e': /* either entity or end for us */
1824          if (!strncmp("entity", &line[p], 6)) /* we shall treat now */
1825             run = 1;
1826          if (!strncmp("end", &line[p], 3)) /* we shall exit gracefully */ {
1827             fclose(f);
1828             for (p = 0, fct = lof->LOCON; fct; fct = fct->NEXT)
1829                p++;
1830             if (p != nbcon) {
1831                fprintf(stderr, "*** mbk error *** restoredirvbe : figure %s have more connectors than vbe\n",
1832                     lof->NAME);
1833                return PROBLEM;
1834             }
1835             return OK;
1836          }
1837          continue; /* next line guys */
1838       case 'p': /* port or nothing! */
1839          if (!run)
1840             continue;
1841          if (!strncmp("port", &line[p], 4)) {
1842             p += 4;
1843             while (isspace((int)line[p])) {
1844                if (line[p] == '\n') {
1845                   fgets(line, BUFSIZ, f);
1846                   p = 0;
1847                } else
1848                   p++;
1849             }
1850             if (line[p] != '(') {
1851                fprintf(stderr, "*** mbk error *** restoredirvbe : cannot read port well!\n");
1852                fclose(f);
1853                return PROBLEM;
1854             }
1855 
1856             while (1) {
1857                fgets(line, BUFSIZ, f);
1858                for (p = 0; p < BUFSIZ && line[p]; p++)
1859                   if (isupper((int)line[p]))
1860                      line[p] = tolower(line[p]);
1861                p = 0;
1862                while (isspace((int)line[p]))
1863                   p++;
1864                if (line[p] == ')')
1865                   break;
1866                q = p;
1867                while (!isspace((int)line[p]) && line[p] != ':')
1868                   p++;
1869                strncpy(hook, &line[q], p - q);
1870                hook[p - q] = '\0';
1871 
1872                while (isspace((int)line[p]) || line[p] == ':')
1873                   p++;
1874                q = p;
1875                while (!isspace((int)line[p]))
1876                   p++;
1877                strncpy(string, &line[q], p - q);
1878                string[p - q] = '\0';
1879                while (isspace((int)line[p]))
1880                   p++;
1881                if (line[p] == 'b' || line[p] == 'r') /* finished, dir ok */ {
1882                   if (!strcmp("in", string))
1883                      dir = IN;
1884                   else if (!strcmp("out", string))
1885                      dir = OUT;
1886                   else
1887                      dir = UNKNOWN;
1888                } else {
1889                   if (!strcmp("inout", string))
1890                      dir = TRANSCV;
1891                   else if (!strcmp("out", string))
1892                      dir = TRISTATE;
1893                   else
1894                      dir = UNKNOWN;
1895                }
1896                while (line[p] != '(' && line[p] != '\0')
1897                   p++;
1898                if (line[p] == '\0') {
1899                   fc = getlocon(lof, hook);
1900                   fc->DIRECTION = dir;
1901                   if (lof->LOCON != fc) {
1902                      for (fct = lof->LOCON; fct->NEXT != fc; fct = fct->NEXT)
1903                         ;
1904                      fct->NEXT = fc->NEXT;
1905                      fc->NEXT = lof->LOCON;
1906                      lof->LOCON = fc;
1907                   }
1908                   nbcon++;
1909                } else { /* bit vector indeed */
1910                   p++; /* skip ( */
1911                   from = atoi(&line[p]);
1912                   while (isdigit((int)line[p]))
1913                      p++;
1914                   while (isspace((int)line[p]))
1915                      p++;
1916                   if (line[p] == 'd')
1917                      inc = -1;
1918                   else if (line[p] == 't')
1919                      inc = 1;
1920                   else
1921                    {
1922                      fprintf(stderr, "*** mbk error *** restoredirvbe : bit_vect neither to nor downto\n");
1923                      fclose(f);
1924                      return PROBLEM;
1925                   }
1926                   while (!isspace((int)line[p]))
1927                      p++;
1928                   to = atoi(&line[p]);
1929 
1930                   for (r = from; r <= to; r += inc) {
1931                      sprintf(string, "%s %d", hook, r);
1932                      fc = getlocon(lof, string);
1933                      fc->DIRECTION = dir;
1934                      if (lof->LOCON != fc) {
1935                         for (fct = lof->LOCON; fct->NEXT != fc; fct = fct->NEXT)
1936 /* code folded from here */
1937    ;
1938 /* unfolding */
1939                         fct->NEXT = fc->NEXT;
1940                         fc->NEXT = lof->LOCON;
1941                         lof->LOCON = fc;
1942                      }
1943                      nbcon++;
1944                   }
1945                }
1946                continue;
1947             }
1948          }
1949          continue;
1950       default :
1951          continue;
1952       }
1953    }
1954    fclose(f);
1955    for (p = 0, fct = lof->LOCON; fct; fct = fct->NEXT)
1956       p++;
1957    if (p != nbcon) {
1958       fprintf(stderr, "*** mbk error *** restoredirvbe : figure %s have more connectors than vbe\n", lof->NAME);
1959       return PROBLEM;
1960    }
1961    return OK;
1962 }
1963 
guessextdir(lofig_list * lof)1964 int guessextdir(lofig_list *lof)
1965 {
1966 int ret = OK;
1967 char dir;
1968 locon_list *ec;
1969 chain_list *pch;
1970 ptype_list *getptype();
1971 
1972    lofigchain(lof);
1973    for (ec = lof->LOCON; ec; ec = ec->NEXT) {
1974       dir = UNKNOWN;
1975       for (pch = (chain_list * )(getptype(ec->SIG->USER, (long)LOFIGCHAIN)->DATA);           pch; pch = pch->NEXT) {
1976          if (((locon_list * )(pch->DATA))->TYPE != INTERNAL)
1977             continue;
1978          switch (((locon_list * )(pch->DATA))->DIRECTION) {
1979          case IN :
1980             switch (dir) {
1981             case IN :
1982                dir = IN;
1983                break;
1984             case OUT :
1985                dir = INOUT;
1986                break;
1987             case INOUT :
1988                dir = INOUT;
1989                break;
1990             case UNKNOWN :
1991                dir = IN;
1992                break;
1993             case TRISTATE :
1994                dir = TRANSCV;
1995                break;
1996             case TRANSCV  :
1997             case TRANSCV2 :
1998             case TRANSCV3 :
1999             case TRANSCV4 :
2000                dir = TRANSCV;
2001                break;
2002             }
2003             break;
2004          case OUT :
2005             switch (dir) {
2006             case IN :
2007                dir = INOUT;
2008                break;
2009             case OUT :
2010                dir = OUT;
2011                fprintf(stderr, "Warning : signal %s have two OUT",
2012                         getsigname(ec->SIG));
2013                ret = PROBLEM;
2014                break;
2015             case INOUT :
2016                dir = INOUT;
2017                fprintf(stderr, "Warning : signal %s have an OUT and an INOUT",
2018                         getsigname(ec->SIG));
2019                ret = PROBLEM;
2020                break;
2021             case UNKNOWN :
2022                dir = OUT;
2023                break;
2024             case TRISTATE :
2025                dir = OUT;
2026                fprintf(stderr, "Warning : signal %s have an OUT and a TRISTATE",
2027                         getsigname(ec->SIG));
2028                ret = PROBLEM;
2029                break;
2030             case TRANSCV  :
2031             case TRANSCV2 :
2032             case TRANSCV3 :
2033             case TRANSCV4 :
2034                dir = TRANSCV;
2035                fprintf(stderr, "Warning : signal %s have an OUT and a TRANSCV",
2036                         getsigname(ec->SIG));
2037                ret = PROBLEM;
2038                break;
2039             }
2040             break;
2041          case INOUT :
2042             switch (dir) {
2043             case IN :
2044                dir = INOUT;
2045                break;
2046             case OUT :
2047                dir = INOUT;
2048                fprintf(stderr, "Warning : signal %s have an INOUT and an OUT",
2049                         getsigname(ec->SIG));
2050                ret = PROBLEM;
2051                break;
2052             case INOUT :
2053                dir = INOUT;
2054                fprintf(stderr, "Warning : signal %s have two INOUT",
2055                         getsigname(ec->SIG));
2056                ret = PROBLEM;
2057                break;
2058             case UNKNOWN :
2059                dir = INOUT;
2060                break;
2061             case TRISTATE :
2062                dir = INOUT;
2063                fprintf(stderr, "Warning : signal %s have an INOUT and a TRISTATE",
2064                         getsigname(ec->SIG));
2065                ret = PROBLEM;
2066                break;
2067             case TRANSCV  :
2068             case TRANSCV2 :
2069             case TRANSCV3 :
2070             case TRANSCV4 :
2071                dir = INOUT;
2072                fprintf(stderr, "Warning : signal %s have an INOUT and a TRANSCV",
2073                         getsigname(ec->SIG));
2074                ret = PROBLEM;
2075                break;
2076             }
2077             break;
2078          case UNKNOWN :
2079             switch (dir) {
2080             case IN :
2081                dir = IN;
2082                break;
2083             case OUT :
2084                dir = OUT;
2085                break;
2086             case INOUT :
2087                dir = INOUT;
2088                break;
2089             case UNKNOWN :
2090                dir = UNKNOWN;
2091                break;
2092             case TRISTATE :
2093                dir = TRISTATE;
2094                break;
2095             case TRANSCV :
2096             case TRANSCV2 :
2097             case TRANSCV3 :
2098             case TRANSCV4 :
2099                dir = TRANSCV;
2100                break;
2101             }
2102             break;
2103          case TRISTATE :
2104             switch (dir) {
2105             case IN :
2106                dir = TRANSCV;
2107                break;
2108             case OUT :
2109                dir = OUT;
2110                fprintf(stderr, "Warning : signal %s have a TRISTATE and an OUT", getsigname(ec->SIG));
2111                ret = PROBLEM;
2112                break;
2113             case INOUT :
2114                dir = INOUT;
2115                fprintf(stderr, "Warning : signal %s have a TRISTATE and an INOUT", getsigname(ec->SIG));
2116                ret = PROBLEM;
2117                break;
2118             case UNKNOWN :
2119                dir = TRISTATE;
2120                break;
2121             case TRISTATE :
2122                dir = TRISTATE;
2123                break;
2124             case TRANSCV  :
2125             case TRANSCV2 :
2126             case TRANSCV3 :
2127             case TRANSCV4 :
2128                dir = TRANSCV;
2129                break;
2130             }
2131             break;
2132          case TRANSCV  :
2133          case TRANSCV2 :
2134          case TRANSCV3 :
2135          case TRANSCV4 :
2136 
2137             switch (dir) {
2138             case IN :
2139                dir = TRANSCV;
2140                break;
2141             case OUT :
2142                dir = TRANSCV;
2143                fprintf(stderr, "Warning : signal %s have a TRANSCV and an OUT", getsigname(ec->SIG));
2144                ret = PROBLEM;
2145                break;
2146             case INOUT :
2147                dir = INOUT;
2148                fprintf(stderr, "Warning : signal %s have a TRANSCV and an INOUT", getsigname(ec->SIG));
2149                ret = PROBLEM;
2150                break;
2151             case UNKNOWN :
2152                dir = TRANSCV;
2153                break;
2154             case TRISTATE :
2155                dir = TRANSCV;
2156                break;
2157             case TRANSCV  :
2158             case TRANSCV2 :
2159             case TRANSCV3 :
2160             case TRANSCV4 :
2161                dir = TRANSCV;
2162                break;
2163             }
2164             break;
2165          }
2166       }
2167       if (dir != UNKNOWN)
2168          ec->DIRECTION = dir;
2169    }
2170    return ret;
2171 }
2172 
restorealldir(lofig_list * lf)2173 int restorealldir(lofig_list *lf)
2174 {
2175 int ret = OK, res;
2176 lofig_list *lof;
2177 loins_list *li;
2178 locon_list *ic, *fc;
2179 
2180    for (li = lf->LOINS; li; li = li->NEXT) {
2181       /* get model of the instance and restore connector direction in it */
2182       for (lof = HEAD_LOFIG; lof; lof = lof->NEXT)
2183          if (lof->NAME == li->FIGNAME)
2184             break;
2185       if (!lof) {
2186          lof = getlofig(li->FIGNAME, 'P');
2187          res = restoredirvbe(lof);
2188          if (res == PROBLEM)
2189             ret = PROBLEM;
2190          else if (res == NOVBE) {
2191             lof = getlofig(lof->NAME, 'A');
2192             res = restorealldir(lof);
2193             if (res == PROBLEM)
2194                ret = PROBLEM;
2195             res = guessextdir(lof);
2196             if (res == PROBLEM)
2197                ret = PROBLEM;
2198          }
2199       } else if (lof->LOCON->DIRECTION == UNKNOWN) {
2200          res = restoredirvbe(lof);
2201          if (res == PROBLEM)
2202             ret = PROBLEM;
2203          else if (res == NOVBE) {
2204             if (lof->MODE != 'A')
2205                lof = getlofig(lof->NAME, 'A');
2206             res = restorealldir(lof);
2207             if (res == PROBLEM)
2208                ret = PROBLEM;
2209             res = guessextdir(lof);
2210             if (res == PROBLEM)
2211                ret = PROBLEM;
2212          }
2213       }
2214 
2215       /* restore connector direction in the instance */
2216       for (ic = li->LOCON; ic; ic = ic->NEXT) {
2217          fc = getlocon(lof, ic->NAME);
2218          ic->DIRECTION = fc->DIRECTION;
2219       }
2220    }
2221    return ret;
2222 }
2223 
2224 struct typoin           /* structure used by dast_dbg */
2225   {               /* to store its state      */
2226   short  type;          /* code of the current structure*/
2227   short  mark;          /* stop mark         */
2228   void  *data;          /* pointer of the structure   */
2229   };
2230 
2231 #define VHD_ERRDFN  -1
2232 #define VHD__XTDFN  0
2233 #define VHD__UPDFN  1
2234 #define VHD__TPDFN  2
2235 #define VHD__SPDFN  3
2236 #define VHD__BKDFN  4
2237 
2238 #define VHD_lofigDFN 5
2239 #define VHD_nextDFN 6
2240 #define VHD_modelchainDFN 7
2241 #define VHD_loconDFN 8
2242 #define VHD_losigDFN 9
2243 #define VHD_bksigDFN 10
2244 #define VHD_loinsDFN 11
2245 #define VHD_lotrsDFN 13
2246 #define VHD_nameDFN 14
2247 #define VHD_modeDFN 15
2248 #define VHD_userDFN 16
2249 #define VHD_drainDFN 17
2250 #define VHD_gridDFN 18
2251 #define VHD_sourceDFN 19
2252 #define VHD_bulkDFN 36
2253 #define VHD_widthDFN 20
2254 #define VHD_lengthDFN 21
2255 #define VHD_xDFN 22
2256 #define VHD_yDFN 23
2257 #define VHD_typeDFN 24
2258 #define VHD_insnameDFN 25
2259 #define VHD_fignameDFN 26
2260 #define VHD_sigDFN 27
2261 #define VHD_rootDFN 28
2262 #define VHD_directionDFN 29
2263 #define VHD_valDFN 30
2264 #define VHD_namechainDFN 31
2265 #define VHD_capaDFN 32
2266 #define VHD_indexDFN 33
2267 #define VHD_ptypeDFN 34
2268 #define VHD_dataDFN 35
2269 
2270 #define VHD_locapDFN 36
2271 #define VHD_loresDFN 37
2272 #define VHD_loselfDFN 38
2273 #define VHD_tconDFN 39
2274 #define VHD_bconDFN 40
2275 #define VHD_rcon1DFN 41
2276 #define VHD_rcon2DFN 42
2277 #define VHD_scon1DFN 43
2278 #define VHD_scon2DFN 44
2279 
2280 #define VHD_MAXDFN 45
2281 
2282 static int vhd_getcmd();
2283 static int vhd_hash();
2284 
mlodebug(head_pnt,stru_name)2285 void mlodebug (head_pnt,stru_name)
2286 
2287 void  *head_pnt;
2288 char  *stru_name;
2289 
2290   {
2291 
2292   int     i;
2293   int     state;
2294   int     newsta0;
2295   int     readcmd = 0;
2296   char       readtab[3][20];
2297   int     stk_pnt = 0;
2298   int            type = VHD__XTDFN;
2299   struct chain  *ptchain;
2300 
2301   struct typoin  current_pnt;
2302   struct typoin  stk[200];
2303 
2304   char           empty[4];
2305   char           avail[12];
2306 
2307   int     key[VHD_MAXDFN];
2308   char      *tab[VHD_MAXDFN];
2309   void      *nxt[VHD_MAXDFN];
2310   short      typ[VHD_MAXDFN];
2311 
2312   struct lofig *lofig_pnt;
2313   struct locon *locon_pnt;
2314   struct losig *losig_pnt;
2315   struct ptype *ptype_pnt;
2316   struct loins *loins_pnt;
2317   struct lotrs *lotrs_pnt;
2318 
2319   struct locap  *locap_pnt;
2320   struct lores  *lores_pnt;
2321   struct loself *loself_pnt;
2322 
2323 key[VHD_lofigDFN]      = vhd_hash ("lofig");
2324 key[VHD_nextDFN]       = vhd_hash ("next");
2325 key[VHD_modelchainDFN] = vhd_hash ("modelchain");
2326 key[VHD_loconDFN]      = vhd_hash ("locon");
2327 key[VHD_losigDFN]      = vhd_hash ("losig");
2328 key[VHD_bksigDFN]      = vhd_hash ("bksig");
2329 key[VHD_loinsDFN]      = vhd_hash ("loins");
2330 key[VHD_lotrsDFN]      = vhd_hash ("lotrs");
2331 key[VHD_nameDFN]       = vhd_hash ("name");
2332 key[VHD_modeDFN]       = vhd_hash ("mode");
2333 key[VHD_userDFN]       = vhd_hash ("user");
2334 key[VHD_drainDFN]      = vhd_hash ("drain");
2335 key[VHD_gridDFN]       = vhd_hash ("grid");
2336 key[VHD_sourceDFN]     = vhd_hash ("source");
2337 key[VHD_bulkDFN]       = vhd_hash ("bulk");
2338 key[VHD_widthDFN]      = vhd_hash ("width");
2339 key[VHD_lengthDFN]     = vhd_hash ("length");
2340 key[VHD_xDFN]          = vhd_hash ("x");
2341 key[VHD_yDFN]          = vhd_hash ("y");
2342 key[VHD_typeDFN]       = vhd_hash ("type");
2343 key[VHD_insnameDFN]    = vhd_hash ("insname");
2344 key[VHD_fignameDFN]    = vhd_hash ("figname");
2345 key[VHD_sigDFN]        = vhd_hash ("sig");
2346 key[VHD_rootDFN]       = vhd_hash ("root");
2347 key[VHD_directionDFN]  = vhd_hash ("direction");
2348 key[VHD_valDFN]        = vhd_hash ("val");
2349 key[VHD_namechainDFN]  = vhd_hash ("namechain");
2350 key[VHD_capaDFN]       = vhd_hash ("capa");
2351 key[VHD_indexDFN]      = vhd_hash ("index");
2352 key[VHD_ptypeDFN]      = vhd_hash ("ptype");
2353 
2354 key[VHD_locapDFN]      = vhd_hash ("locap");
2355 key[VHD_loresDFN]      = vhd_hash ("lores");
2356 key[VHD_loselfDFN]     = vhd_hash ("loself");
2357 key[VHD_tconDFN]       = vhd_hash ("tcon");
2358 key[VHD_bconDFN]       = vhd_hash ("bcon");
2359 key[VHD_rcon1DFN]      = vhd_hash ("rcon1");
2360 key[VHD_rcon2DFN]      = vhd_hash ("rcon2");
2361 key[VHD_scon1DFN]      = vhd_hash ("scon1");
2362 key[VHD_scon2DFN]      = vhd_hash ("scon2");
2363 
2364    /* ###------------------------------------------------------### */
2365    /*    Set of predefined commands          */
2366    /* ###------------------------------------------------------### */
2367 
2368   key[0] = vhd_hash ("_exit");
2369   key[1] = vhd_hash ("_up");
2370   key[2] = vhd_hash ("_top");
2371   key[3] = vhd_hash ("_stop");
2372   key[4] = vhd_hash ("_back");
2373 
2374   (void)strcpy (empty,"");
2375   (void)strcpy (avail,"AVAILABLE");
2376 
2377   for (i=0 ; i<VHD_MAXDFN ; i++)
2378     typ[i] = i;
2379 
2380    /* ###------------------------------------------------------### */
2381    /*    Find the type of the head structure       */
2382    /* ###------------------------------------------------------### */
2383 
2384   readcmd = vhd_hash (stru_name);
2385   for (i=0 ; i<VHD_MAXDFN ; i++)
2386     {
2387     if (readcmd == key[i])
2388       {
2389       type = typ[i];
2390       break;
2391       }
2392     }
2393 
2394    /* ###------------------------------------------------------### */
2395    /*    Exit if the head structure is empty       */
2396    /* ###------------------------------------------------------### */
2397 
2398   if (head_pnt == NULL)
2399     type = VHD__XTDFN;
2400 
2401   current_pnt.data = head_pnt;
2402   current_pnt.type = type;
2403   current_pnt.mark = 0;
2404   state            = type;
2405 
2406   while (state != VHD__XTDFN)
2407     {
2408    /* ###------------------------------------------------------### */
2409    /*    Print structure's field until the exit command is read   */
2410    /* ###------------------------------------------------------### */
2411 
2412     for (i=0 ; i<VHD_MAXDFN ; i++)
2413       {
2414       tab[i] = empty;
2415       nxt[i] = NULL;
2416       }
2417 
2418    /* ###------------------------------------------------------### */
2419    /*    _exit and _stop commands are allways available     */
2420    /* ###------------------------------------------------------### */
2421 
2422     tab[VHD__XTDFN] = avail;
2423     tab[VHD__SPDFN] = avail;
2424 
2425    /* ###------------------------------------------------------### */
2426    /*    _up, _top, and _back commands are available only if the  */
2427    /* stack is not empty                  */
2428    /* ###------------------------------------------------------### */
2429 
2430     if (stk_pnt != 0)
2431       {
2432       tab[VHD__UPDFN] = avail;
2433       tab[VHD__TPDFN] = avail;
2434       tab[VHD__BKDFN] = avail;
2435       }
2436 
2437     switch (state)
2438       {
2439 
2440     case (VHD_lofigDFN):
2441 
2442       /* ###--------- lofig ---------### */
2443 
2444       lofig_pnt = (struct lofig *)(current_pnt.data);
2445 
2446       if (lofig_pnt->NEXT != NULL)
2447         {
2448         tab[VHD_nextDFN] = avail;
2449         nxt[VHD_nextDFN] = (void *)lofig_pnt->NEXT;
2450         typ[VHD_nextDFN] = VHD_lofigDFN;
2451         }
2452       if (lofig_pnt->LOCON != NULL)
2453         {
2454         tab[VHD_loconDFN] = avail;
2455         nxt[VHD_loconDFN] = (void *)lofig_pnt->LOCON;
2456         typ[VHD_loconDFN] = VHD_loconDFN;
2457         }
2458       if (lofig_pnt->LOSIG != NULL)
2459         {
2460         tab[VHD_losigDFN] = avail;
2461         nxt[VHD_losigDFN] = (void *)lofig_pnt->LOSIG;
2462         typ[VHD_losigDFN] = VHD_losigDFN;
2463         }
2464       if (lofig_pnt->BKSIG != NULL)
2465         {
2466         tab[VHD_bksigDFN] = avail;
2467         nxt[VHD_bksigDFN] = (void *)lofig_pnt->BKSIG;
2468         typ[VHD_bksigDFN] = VHD_ptypeDFN;
2469         }
2470       if (lofig_pnt->LOINS != NULL)
2471         {
2472         tab[VHD_loinsDFN] = avail;
2473         nxt[VHD_loinsDFN] = (void *)lofig_pnt->LOINS;
2474         typ[VHD_loinsDFN] = VHD_loinsDFN;
2475         }
2476       if (lofig_pnt->LOTRS != NULL)
2477         {
2478         tab[VHD_lotrsDFN] = avail;
2479         nxt[VHD_lotrsDFN] = (void *)lofig_pnt->LOTRS;
2480         typ[VHD_lotrsDFN] = VHD_lotrsDFN;
2481         }
2482 
2483       if (lofig_pnt->LOCAP != NULL)
2484         {
2485         tab[VHD_locapDFN] = avail;
2486         nxt[VHD_locapDFN] = (void *)lofig_pnt->LOCAP;
2487         typ[VHD_locapDFN] = VHD_locapDFN;
2488         }
2489       if (lofig_pnt->LORES != NULL)
2490         {
2491         tab[VHD_loresDFN] = avail;
2492         nxt[VHD_loresDFN] = (void *)lofig_pnt->LORES;
2493         typ[VHD_loresDFN] = VHD_loresDFN;
2494         }
2495       if (lofig_pnt->LOSELF != NULL)
2496         {
2497         tab[VHD_loselfDFN] = avail;
2498         nxt[VHD_loselfDFN] = (void *)lofig_pnt->LOSELF;
2499         typ[VHD_loselfDFN] = VHD_loselfDFN;
2500         }
2501 
2502 
2503       if (lofig_pnt->USER != NULL)
2504         {
2505         tab[VHD_userDFN] = avail;
2506         nxt[VHD_userDFN] = (void *)lofig_pnt->USER;
2507         typ[VHD_userDFN] = VHD_ptypeDFN;
2508         }
2509 
2510       ptchain = lofig_pnt->MODELCHAIN;
2511       (void)printf ("   modelchain  :\n");
2512       while (ptchain != NULL)
2513         {
2514         (void)printf ("                 %s\n",(char *)ptchain->DATA);
2515         ptchain = ptchain->NEXT;
2516         }
2517 
2518       (void)printf ("   name        : %s\n",lofig_pnt->NAME);
2519       (void)printf ("   mode        : %c\n",lofig_pnt->MODE);
2520       (void)printf ("-> locon       : %s\n",tab[VHD_loconDFN]);
2521       (void)printf ("-> losig       : %s\n",tab[VHD_losigDFN]);
2522       (void)printf ("-> bksig       : %s\n",tab[VHD_bksigDFN]);
2523       (void)printf ("-> loins       : %s\n",tab[VHD_loinsDFN]);
2524       (void)printf ("-> lotrs       : %s\n",tab[VHD_lotrsDFN]);
2525 
2526       (void)printf ("-> locap       : %s\n",tab[VHD_locapDFN]);
2527       (void)printf ("-> lores       : %s\n",tab[VHD_loresDFN]);
2528       (void)printf ("-> loself      : %s\n",tab[VHD_loselfDFN]);
2529 
2530       (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
2531       (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);
2532 
2533       break;
2534 
2535     case (VHD_lotrsDFN):
2536 
2537       /* ###--------- lotrs ---------### */
2538 
2539       lotrs_pnt = (struct lotrs *)(current_pnt.data);
2540 
2541       if (lotrs_pnt->NEXT != NULL)
2542         {
2543         tab[VHD_nextDFN] = avail;
2544         nxt[VHD_nextDFN] = (void *)lotrs_pnt->NEXT;
2545         typ[VHD_nextDFN] = VHD_lotrsDFN;
2546         }
2547       if (lotrs_pnt->DRAIN != NULL)
2548         {
2549         tab[VHD_drainDFN] = avail;
2550         nxt[VHD_drainDFN] = (void *)lotrs_pnt->DRAIN;
2551         typ[VHD_drainDFN] = VHD_loconDFN;
2552         }
2553       if (lotrs_pnt->GRID != NULL)
2554         {
2555         tab[VHD_gridDFN] = avail;
2556         nxt[VHD_gridDFN] = (void *)lotrs_pnt->GRID;
2557         typ[VHD_gridDFN] = VHD_loconDFN;
2558         }
2559       if (lotrs_pnt->SOURCE != NULL)
2560         {
2561         tab[VHD_sourceDFN] = avail;
2562         nxt[VHD_sourceDFN] = (void *)lotrs_pnt->SOURCE;
2563         typ[VHD_sourceDFN] = VHD_loconDFN;
2564         }
2565       if (lotrs_pnt->BULK != NULL)
2566         {
2567         tab[VHD_sourceDFN] = avail;
2568         nxt[VHD_sourceDFN] = (void *)lotrs_pnt->BULK;
2569         typ[VHD_sourceDFN] = VHD_loconDFN;
2570         }
2571       if (lotrs_pnt->USER != NULL)
2572         {
2573         tab[VHD_userDFN] = avail;
2574         nxt[VHD_userDFN] = (void *)lotrs_pnt->USER;
2575         typ[VHD_userDFN] = VHD_ptypeDFN;
2576         }
2577 
2578       (void)printf ("-> drain       : %s\n",tab[VHD_drainDFN]);
2579       (void)printf ("-> grid        : %s\n",tab[VHD_gridDFN]);
2580       (void)printf ("-> source      : %s\n",tab[VHD_sourceDFN]);
2581       (void)printf ("-> bulk        : %s\n",tab[VHD_bulkDFN]);
2582       (void)printf ("   length      : %ld\n",lotrs_pnt->LENGTH);
2583       (void)printf ("   width       : %ld\n",lotrs_pnt->WIDTH);
2584       (void)printf ("   y           : %ld\n",lotrs_pnt->Y);
2585       (void)printf ("   x           : %ld\n",lotrs_pnt->X);
2586       (void)printf ("   type        : %c\n",lotrs_pnt->TYPE);
2587       (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
2588       (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);
2589 
2590       break;
2591 
2592 
2593     case (VHD_locapDFN):
2594 
2595       /* ###--------- locap ---------### */
2596 
2597       locap_pnt = (struct locap *)(current_pnt.data);
2598 
2599       if (locap_pnt->NEXT != NULL)
2600         {
2601         tab[VHD_nextDFN] = avail;
2602         nxt[VHD_nextDFN] = (void *)locap_pnt->NEXT;
2603         typ[VHD_nextDFN] = VHD_locapDFN;
2604         }
2605       if (locap_pnt->TCON != NULL)
2606         {
2607         tab[VHD_tconDFN] = avail;
2608         nxt[VHD_tconDFN] = (void *)locap_pnt->TCON;
2609         typ[VHD_tconDFN] = VHD_loconDFN;
2610         }
2611       if (locap_pnt->BCON != NULL)
2612         {
2613         tab[VHD_bconDFN] = avail;
2614         nxt[VHD_bconDFN] = (void *)locap_pnt->BCON;
2615         typ[VHD_bconDFN] = VHD_loconDFN;
2616         }
2617       if (locap_pnt->USER != NULL)
2618         {
2619         tab[VHD_userDFN] = avail;
2620         nxt[VHD_userDFN] = (void *)locap_pnt->USER;
2621         typ[VHD_userDFN] = VHD_ptypeDFN;
2622         }
2623 
2624       (void)printf ("-> tcon        : %s\n",tab[VHD_tconDFN]);
2625       (void)printf ("-> bcon        : %s\n",tab[VHD_bconDFN]);
2626       (void)printf ("   type        : %c\n",locap_pnt->TYPE);
2627       (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
2628       (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);
2629 
2630       break;
2631 
2632 
2633     case (VHD_loresDFN):
2634 
2635       /* ###--------- lores ---------### */
2636 
2637       lores_pnt = (struct lores *)(current_pnt.data);
2638 
2639       if (lores_pnt->NEXT != NULL)
2640         {
2641         tab[VHD_nextDFN] = avail;
2642         nxt[VHD_nextDFN] = (void *)lores_pnt->NEXT;
2643         typ[VHD_nextDFN] = VHD_loresDFN;
2644         }
2645       if (lores_pnt->RCON1 != NULL)
2646         {
2647         tab[VHD_rcon1DFN] = avail;
2648         nxt[VHD_rcon1DFN] = (void *)lores_pnt->RCON1;
2649         typ[VHD_rcon1DFN] = VHD_loconDFN;
2650         }
2651       if (lores_pnt->RCON2 != NULL)
2652         {
2653         tab[VHD_rcon2DFN] = avail;
2654         nxt[VHD_rcon2DFN] = (void *)lores_pnt->RCON2;
2655         typ[VHD_rcon2DFN] = VHD_loconDFN;
2656         }
2657       if (lores_pnt->USER != NULL)
2658         {
2659         tab[VHD_userDFN] = avail;
2660         nxt[VHD_userDFN] = (void *)lores_pnt->USER;
2661         typ[VHD_userDFN] = VHD_ptypeDFN;
2662         }
2663 
2664       (void)printf ("-> rcon1       : %s\n",tab[VHD_rcon1DFN]);
2665       (void)printf ("-> rcon2       : %s\n",tab[VHD_rcon2DFN]);
2666       (void)printf ("   type        : %c\n",lores_pnt->TYPE);
2667       (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
2668       (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);
2669 
2670       break;
2671 
2672     case (VHD_loselfDFN):
2673 
2674       /* ###--------- loself ---------### */
2675 
2676       loself_pnt = (struct loself *)(current_pnt.data);
2677 
2678       if (loself_pnt->NEXT != NULL)
2679         {
2680         tab[VHD_nextDFN] = avail;
2681         nxt[VHD_nextDFN] = (void *)loself_pnt->NEXT;
2682         typ[VHD_nextDFN] = VHD_loselfDFN;
2683         }
2684       if (loself_pnt->SCON1 != NULL)
2685         {
2686         tab[VHD_scon1DFN] = avail;
2687         nxt[VHD_scon1DFN] = (void *)loself_pnt->SCON1;
2688         typ[VHD_scon1DFN] = VHD_loconDFN;
2689         }
2690       if (loself_pnt->SCON2 != NULL)
2691         {
2692         tab[VHD_scon2DFN] = avail;
2693         nxt[VHD_scon2DFN] = (void *)loself_pnt->SCON2;
2694         typ[VHD_scon2DFN] = VHD_loconDFN;
2695         }
2696       if (loself_pnt->USER != NULL)
2697         {
2698         tab[VHD_userDFN] = avail;
2699         nxt[VHD_userDFN] = (void *)loself_pnt->USER;
2700         typ[VHD_userDFN] = VHD_ptypeDFN;
2701         }
2702 
2703       (void)printf ("-> scon1       : %s\n",tab[VHD_scon1DFN]);
2704       (void)printf ("-> scon2       : %s\n",tab[VHD_scon2DFN]);
2705       (void)printf ("   type        : %c\n",loself_pnt->TYPE);
2706       (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
2707       (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);
2708 
2709       break;
2710 
2711 
2712     case (VHD_loinsDFN):
2713 
2714       /* ###--------- loins ---------### */
2715 
2716       loins_pnt = (struct loins *)(current_pnt.data);
2717 
2718       if (loins_pnt->NEXT != NULL)
2719         {
2720         tab[VHD_nextDFN] = avail;
2721         nxt[VHD_nextDFN] = (void *)loins_pnt->NEXT;
2722         typ[VHD_nextDFN] = VHD_loinsDFN;
2723         }
2724       if (loins_pnt->LOCON != NULL)
2725         {
2726         tab[VHD_loconDFN] = avail;
2727         nxt[VHD_loconDFN] = (void *)loins_pnt->LOCON;
2728         typ[VHD_loconDFN] = VHD_loconDFN;
2729         }
2730       if (loins_pnt->USER != NULL)
2731         {
2732         tab[VHD_userDFN] = avail;
2733         nxt[VHD_userDFN] = (void *)loins_pnt->USER;
2734         typ[VHD_userDFN] = VHD_ptypeDFN;
2735         }
2736 
2737       (void)printf ("   insname     : %s\n",loins_pnt->INSNAME);
2738       (void)printf ("   figname     : %s\n",loins_pnt->FIGNAME);
2739       (void)printf ("-> locon       : %s\n",tab[VHD_loconDFN]);
2740       (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
2741       (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);
2742 
2743       break;
2744 
2745     case (VHD_loconDFN):
2746 
2747       /* ###--------- locon ---------### */
2748 
2749       locon_pnt = (struct locon *)(current_pnt.data);
2750 
2751       if (locon_pnt->NEXT != NULL)
2752         {
2753         tab[VHD_nextDFN] = avail;
2754         nxt[VHD_nextDFN] = (void *)locon_pnt->NEXT;
2755         typ[VHD_nextDFN] = VHD_loconDFN;
2756         }
2757       if (locon_pnt->SIG != NULL)
2758         {
2759         tab[VHD_sigDFN] = avail;
2760         nxt[VHD_sigDFN] = (void *)locon_pnt->SIG;
2761         typ[VHD_sigDFN] = VHD_losigDFN;
2762         }
2763       if (locon_pnt->ROOT != NULL)
2764         {
2765         tab[VHD_rootDFN] = avail;
2766         nxt[VHD_rootDFN] = (void *)locon_pnt->ROOT;
2767         if (locon_pnt->TYPE == 'I')
2768           typ[VHD_rootDFN] = VHD_loinsDFN;
2769         else
2770           typ[VHD_rootDFN] = VHD_lofigDFN;
2771         }
2772       if (locon_pnt->USER != NULL)
2773         {
2774         tab[VHD_userDFN] = avail;
2775         nxt[VHD_userDFN] = (void *)locon_pnt->USER;
2776         typ[VHD_userDFN] = VHD_ptypeDFN;
2777         }
2778 
2779       (void)printf ("   name        : %s\n",locon_pnt->NAME);
2780       (void)printf ("-> sig         : %s\n",tab[VHD_sigDFN]);
2781       (void)printf ("-> root        : %s\n",tab[VHD_rootDFN]);
2782       (void)printf ("   direction   : %c\n",locon_pnt->DIRECTION);
2783       (void)printf ("   type        : %c\n",locon_pnt->TYPE);
2784       (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
2785       (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);
2786 
2787       break;
2788 
2789     case (VHD_losigDFN):
2790 
2791       /* ###--------- losig ---------### */
2792 
2793       losig_pnt = (struct losig *)(current_pnt.data);
2794 
2795       if (losig_pnt->NEXT != NULL)
2796         {
2797         tab[VHD_nextDFN] = avail;
2798         nxt[VHD_nextDFN] = (void *)losig_pnt->NEXT;
2799         typ[VHD_nextDFN] = VHD_losigDFN;
2800         }
2801       if (losig_pnt->USER != NULL)
2802         {
2803         tab[VHD_userDFN] = avail;
2804         nxt[VHD_userDFN] = (void *)losig_pnt->USER;
2805         typ[VHD_userDFN] = VHD_ptypeDFN;
2806         }
2807 
2808       ptchain = losig_pnt->NAMECHAIN;
2809       (void)printf ("   namechain   :\n");
2810       while (ptchain != NULL)
2811         {
2812         (void)printf ("                 %s\n",(char *)ptchain->DATA);
2813         ptchain = ptchain->NEXT;
2814         }
2815 
2816       if (losig_pnt->PRCN)
2817         (void)printf ("   capa        : %f\n",(losig_pnt->PRCN->CAPA?losig_pnt->PRCN->CAPA:0.0) );
2818       else
2819         (void)printf ("   capa        : NULL\n" );
2820       (void)printf ("   index       : %ld\n",losig_pnt->INDEX);
2821       (void)printf ("   type        : %c\n",losig_pnt->TYPE);
2822       (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
2823       (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);
2824 
2825       break;
2826 
2827     case (VHD_ptypeDFN):
2828 
2829       /* ###--------- ptype ---------### */
2830 
2831       ptype_pnt = (struct ptype *)(current_pnt.data);
2832 
2833       if (ptype_pnt->NEXT != NULL)
2834         {
2835         tab[VHD_nextDFN] = avail;
2836         nxt[VHD_nextDFN] = (void *)ptype_pnt->NEXT;
2837         typ[VHD_nextDFN] = VHD_ptypeDFN;
2838         }
2839       if (ptype_pnt->DATA != NULL)
2840         {
2841         tab[VHD_dataDFN] = avail;
2842         nxt[VHD_dataDFN] = (void *)ptype_pnt->DATA;
2843         typ[VHD_dataDFN] = VHD_ERRDFN;
2844 /*......typ[VHD_dataDFN] = .......................*/
2845         }
2846 
2847       (void)printf ("   type        : %ld\n",ptype_pnt->TYPE);
2848       (void)printf ("-> data        : %s\n",tab[VHD_dataDFN]);
2849       (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);
2850 
2851       break;
2852 
2853 
2854       }
2855 
2856    /* ###------------------------------------------------------### */
2857    /*    Reading new command              */
2858    /* ###------------------------------------------------------### */
2859 
2860     readcmd = vhd_getcmd (readtab);
2861 
2862     for (i=0 ; i<VHD_MAXDFN ; i++)
2863       {
2864       if (readcmd == key[i])
2865         break;
2866       }
2867     if ((i != VHD_MAXDFN+1) && (tab[i] == avail))
2868       newsta0 = i;
2869     else
2870       newsta0 = -1;
2871 
2872    /* ###------------------------------------------------------### */
2873    /*    Analysing new command               */
2874    /* ###------------------------------------------------------### */
2875 
2876     switch (newsta0)
2877       {
2878       case (VHD__UPDFN):
2879         current_pnt        = stk[--stk_pnt] ;
2880         break;
2881 
2882       case (VHD__BKDFN):
2883         while ((--stk_pnt != 0) && (stk[stk_pnt].mark != 1));
2884         current_pnt        = stk[stk_pnt] ;
2885         break;
2886 
2887       case (VHD__SPDFN):
2888         current_pnt.mark   = 1;
2889         break;
2890 
2891       case (VHD__TPDFN):
2892         current_pnt        = stk[0] ;
2893         stk_pnt        = 0 ;
2894         break;
2895 
2896       case (VHD__XTDFN):
2897         current_pnt.data   = NULL;
2898         current_pnt.type   = VHD__XTDFN;
2899         current_pnt.mark   = 0;
2900         break;
2901 
2902       case (VHD_ERRDFN):
2903         break;
2904 
2905       default:
2906         stk[stk_pnt++] = current_pnt;
2907         current_pnt.type   = typ[newsta0];
2908         current_pnt.mark   = 0;
2909         current_pnt.data   = nxt[newsta0];
2910         break;
2911 
2912       }
2913 
2914     state  = current_pnt.type;
2915     }
2916   }
2917 
2918 
vhd_getcmd(prvcmd)2919 static int vhd_getcmd (prvcmd)
2920 
2921 char prvcmd[3][20];
2922 
2923   {
2924   char readstr[60];
2925   char comd0[20];
2926   char comd1[20];
2927   char comd2[20];
2928   int  code;
2929 
2930   (void)printf ("\n\n\n COMMAND >> ");
2931   comd0[0] = '\0';
2932   comd1[0] = '\0';
2933   comd2[0] = '\0';
2934   (void)fgets( readstr, 60, stdin );
2935   (void)sscanf (readstr,"%19s%19s%19s",comd0,comd1,comd2);
2936 
2937   if (strcmp(comd0,"."))
2938     {
2939     (void)strcpy (prvcmd[0], comd0);
2940     (void)strcpy (prvcmd[1], comd1);
2941     (void)strcpy (prvcmd[2], comd2);
2942     }
2943   code = vhd_hash (prvcmd[0]);
2944 
2945   (void)printf ("\n\n\n\n\n");
2946   return (code);
2947   }
2948 
2949 
2950 
vhd_hash(str)2951 static int vhd_hash (str)
2952 
2953 char *str;
2954 
2955   {
2956   int code = 0;
2957 
2958   while(*str != '\0')
2959     code =  code<<1 ^ *str++;
2960 
2961   return (code);
2962   }
2963 
2964 /*##------------------------------------------------------------------##*/
2965 /*  Author : VUONG H.N.                   */
2966 /*  Date   : Dec 11 1991                  */
2967 /*  Cont.  : Essentially functions to duplicate lofig structures  */
2968 /*           such a complete LOFIG or just a chain_list.    */
2969 /*##------------------------------------------------------------------##*/
2970 
2971 /*##------------------------------------------------------------------##*/
2972 /*  Function : dupchainlst()                 */
2973 /*  contents : duplicate a chain list and return a pointer on the new   */
2974 /*             structure.                 */
2975 /*  called func. : reverse(), mbkalloc(),          */
2976 /*##------------------------------------------------------------------##*/
2977 
dupchainlst(chain_ptr)2978 chain_list *dupchainlst(chain_ptr)
2979 chain_list *chain_ptr;
2980   {
2981   chain_list *chain_rpt = NULL;     /* Returned chain pointer  */
2982 
2983   while(chain_ptr != NULL)
2984     {
2985     chain_rpt = addchain(chain_rpt, chain_ptr->DATA);
2986     chain_ptr     = chain_ptr->NEXT;
2987     }
2988   chain_rpt = reverse(chain_rpt);
2989   return(chain_rpt);
2990   }
2991 
2992 /*##------------------------------------------------------------------##*/
2993 /*  Function : duploconlst()                 */
2994 /*  contents : duplicate a locon list and return a pointer on the new   */
2995 /*             structure.                 */
2996 /*  called func. : duplocon(), reverse(),          */
2997 /*##------------------------------------------------------------------##*/
2998 
duploconlst(locon_ptr)2999 locon_list *duploconlst(locon_ptr)
3000 locon_list *locon_ptr;
3001   {
3002   locon_list *locon_rpt = NULL;     /* Returned locon pointer  */
3003   locon_list *locon_tmpptr = NULL;  /* Temporary pointer       */
3004 
3005   while(locon_ptr != NULL)
3006     {
3007     locon_tmpptr       = duplocon(locon_ptr);
3008     locon_tmpptr->NEXT = locon_rpt;
3009     locon_rpt          = locon_tmpptr;
3010 
3011     locon_ptr          = locon_ptr->NEXT;
3012     }
3013   locon_rpt = (locon_list *)reverse((chain_list *)locon_rpt);
3014   return(locon_rpt);
3015   }
3016 
3017 /*##------------------------------------------------------------------##*/
3018 /*  Function : duplocon()                 */
3019 /*  contents : duplicate a locon and return a pointer on the new  */
3020 /*        structure.                      */
3021 /*  called func. : mbkalloc(),                  */
3022 /*  note : the ROOT and the SIG pointer are also duplicated    */
3023 /*##------------------------------------------------------------------##*/
3024 
duplocon(locon_ptr)3025 locon_list *duplocon(locon_ptr)
3026 locon_list *locon_ptr;
3027   {
3028   locon_list *locon_rpt = NULL;     /* Returned locon pointer  */
3029   num_list   *sn;
3030   ptype_list *ptnodename;
3031 
3032   locon_rpt             = (locon_list *)(mbkalloc(sizeof(locon_list)));
3033   locon_rpt->NEXT       = NULL;
3034   locon_rpt->NAME    = locon_ptr->NAME;
3035   locon_rpt->SIG        = locon_ptr->SIG;
3036   locon_rpt->ROOT       = locon_ptr->ROOT;
3037   locon_rpt->DIRECTION  = locon_ptr->DIRECTION;
3038   locon_rpt->TYPE       = locon_ptr->TYPE;
3039 
3040   locon_rpt->PNODE = NULL;
3041   for( sn = locon_ptr->PNODE ; sn ; sn = sn->NEXT )
3042     locon_rpt->PNODE = addnum( locon_rpt->PNODE, sn->DATA );
3043   locon_rpt->PNODE = (num_list*)reverse( (chain_list*)locon_rpt->PNODE );
3044 
3045   locon_rpt->USER       = NULL;     /* The ptype_list is not duplicated */
3046 
3047   if( ( ptnodename = getptype( locon_ptr->USER, PNODENAME ) ) )
3048     locon_rpt->USER = addptype( locon_rpt->USER,
3049                                 PNODENAME,
3050                                 dupchainlst( ptnodename->DATA )
3051                               );
3052 
3053   return(locon_rpt);
3054   }
3055 
3056 /*##------------------------------------------------------------------##*/
3057 /*  Function : duploinslst()                 */
3058 /*  contents : duplicate a loins list and return a pointer on the new   */
3059 /*             structure.                 */
3060 /*  called func. : duploins(), reverse(),          */
3061 /*##------------------------------------------------------------------##*/
3062 
duploinslst(loins_ptr)3063 loins_list *duploinslst(loins_ptr)
3064 loins_list *loins_ptr;
3065   {
3066   loins_list *loins_rpt = NULL;     /* Returned loins pointer  */
3067   loins_list *loins_tmpptr = NULL;  /* Temporary pointer       */
3068 
3069   while(loins_ptr != NULL)
3070     {
3071     loins_tmpptr       = duploins(loins_ptr);
3072     loins_tmpptr->NEXT = loins_rpt;
3073     loins_rpt          = loins_tmpptr;
3074 
3075     loins_ptr          = loins_ptr->NEXT;
3076     }
3077   loins_rpt = (loins_list *)reverse((chain_list *)loins_rpt);
3078   return(loins_rpt);
3079   }
3080 
3081 /*##------------------------------------------------------------------##*/
3082 /*  Function : duploins()                 */
3083 /*  contents : duplicate a loins and return a pointer on the new  */
3084 /*        structure.                      */
3085 /*  called func. : mbkalloc(),                  */
3086 /*  note : the LOCON pointer is also duplicated          */
3087 /*##------------------------------------------------------------------##*/
3088 
duploins(loins_ptr)3089 loins_list *duploins(loins_ptr)
3090 loins_list *loins_ptr;
3091   {
3092   loins_list *loins_rpt = NULL;     /* Returned loins pointer  */
3093 
3094   loins_rpt             = (loins_list *)(mbkalloc(sizeof(loins_list)));
3095   loins_rpt->NEXT       = NULL;
3096   loins_rpt->LOCON   = loins_ptr->LOCON;
3097   loins_rpt->INSNAME    = loins_ptr->INSNAME;
3098   loins_rpt->FIGNAME    = loins_ptr->FIGNAME;
3099   loins_rpt->USER       = NULL;     /* The ptype_list is not duplicated */
3100 
3101   return(loins_rpt);
3102   }
3103 
3104 /*##------------------------------------------------------------------##*/
3105 /*  Function : duplotrslst()                 */
3106 /*  contents : duplicate a lotrs list and return a pointer on the new   */
3107 /*             structure.                 */
3108 /*  called func. : duplotrs(), reverse(),          */
3109 /*##------------------------------------------------------------------##*/
3110 
duplotrslst(lotrs_ptr)3111 lotrs_list *duplotrslst(lotrs_ptr)
3112 lotrs_list *lotrs_ptr;
3113   {
3114   lotrs_list *lotrs_rpt = NULL;     /* Returned lotrs pointer  */
3115   lotrs_list *lotrs_tmpptr = NULL;  /* Temporary pointer       */
3116 
3117   while(lotrs_ptr != NULL)
3118     {
3119     lotrs_tmpptr       = duplotrs(lotrs_ptr);
3120     lotrs_tmpptr->NEXT = lotrs_rpt;
3121     lotrs_rpt          = lotrs_tmpptr;
3122 
3123     lotrs_ptr          = lotrs_ptr->NEXT;
3124     }
3125   lotrs_rpt = (lotrs_list *)reverse((chain_list *)lotrs_rpt);
3126   return(lotrs_rpt);
3127   }
3128 
3129 /*##------------------------------------------------------------------##*/
3130 /*  Function : duplotrs()                 */
3131 /*  contents : duplicate a lotrs and return a pointer on the new  */
3132 /*        structure.                      */
3133 /*  called func. : mbkalloc(), duplocon()             */
3134 /*  note : the DRAIN, SOURCE, GRID, BULK pointers are also duplicated   */
3135 /*##------------------------------------------------------------------##*/
3136 
duplotrs(lotrs_ptr)3137 lotrs_list *duplotrs(lotrs_ptr)
3138 lotrs_list *lotrs_ptr;
3139   {
3140   lotrs_list *lotrs_rpt = NULL;     /* Returned lotrs pointer  */
3141 
3142   lotrs_rpt             = (lotrs_list *)mbkalloc(sizeof(lotrs_list));
3143   lotrs_rpt->NEXT       = NULL;
3144   lotrs_rpt->TRNAME             = lotrs_ptr->TRNAME;
3145   lotrs_rpt->DRAIN   = lotrs_ptr->DRAIN;
3146   lotrs_rpt->GRID       = lotrs_ptr->GRID;
3147   lotrs_rpt->SOURCE     = lotrs_ptr->SOURCE;
3148   lotrs_rpt->BULK       = lotrs_ptr->BULK;
3149   lotrs_rpt->WIDTH      = lotrs_ptr->WIDTH;
3150   lotrs_rpt->LENGTH     = lotrs_ptr->LENGTH;
3151   lotrs_rpt->PS         = lotrs_ptr->PS;
3152   lotrs_rpt->PD         = lotrs_ptr->PD;
3153   lotrs_rpt->XS         = lotrs_ptr->XS;
3154   lotrs_rpt->XD         = lotrs_ptr->XD;
3155   lotrs_rpt->X          = lotrs_ptr->X;
3156   lotrs_rpt->Y          = lotrs_ptr->Y;
3157   lotrs_rpt->TYPE       = lotrs_ptr->TYPE;
3158   lotrs_rpt->USER       = NULL;     /* The ptype_list is not duplicated */
3159 
3160   return(lotrs_rpt);
3161   }
3162 
3163 /*##------------------------------------------------------------------##*/
3164 /*  Function : duplosiglst()                 */
3165 /*  contents : duplicate a losig_list and return a pointer on the new   */
3166 /*             structure, a pointer on BKSIG must be given.    */
3167 /*  called func. :duplosig(), reverse(),           */
3168 /*##------------------------------------------------------------------##*/
3169 
duplosiglst(losig_ptr,BKSIG_ptr,sigsize)3170 losig_list *duplosiglst(losig_ptr,BKSIG_ptr,sigsize)
3171 losig_list *losig_ptr;
3172 ptype_list **BKSIG_ptr;
3173 int sigsize;
3174   {
3175   losig_list *losig_rpt = NULL;     /* Returned losig pointer  */
3176   losig_list *losig_tmpptr = NULL;  /* Temporary pointer       */
3177   ptype_list *BKSIG_rpt = NULL;        /* Returned BKSIG pointer  */
3178 
3179   while(losig_ptr != NULL)
3180     {
3181     losig_tmpptr       = duplosig(losig_ptr, &BKSIG_rpt, sigsize);
3182     losig_tmpptr->NEXT = losig_rpt;
3183     losig_rpt          = losig_tmpptr;
3184 
3185     losig_ptr          = losig_ptr->NEXT;
3186     }
3187   losig_rpt = (losig_list *)reverse((chain_list *)losig_rpt);
3188   *BKSIG_ptr = BKSIG_rpt;
3189   return(losig_rpt);
3190   }
3191 
3192 /*##------------------------------------------------------------------##*/
3193 /*  Function : duplosig()                                               */
3194 /*  contents : duplicate a losig and return a pointer on the new        */
3195 /*             structure, a pointer on the BKSIG must be given.         */
3196 /*  called func. : mbkalloc, addptype, dupchainlst       */
3197 /*##------------------------------------------------------------------##*/
3198 
duplosig(losig_ptr,BKSIG_ptr,sigsize)3199 losig_list *duplosig(losig_ptr, BKSIG_ptr, sigsize)
3200 losig_list *losig_ptr;
3201 ptype_list **BKSIG_ptr;
3202 int sigsize;
3203   {
3204   ptype_list *ptype_ptr = NULL;
3205   ptype_list *pt = NULL;
3206   long index = losig_ptr->INDEX;
3207   int i;
3208   int low, high;
3209   losig_list *ptsig = NULL;
3210   losig_list *pthead = NULL;
3211 
3212   ptype_ptr = *BKSIG_ptr;
3213   low = (index % sigsize);
3214   high = (index / sigsize);
3215   for (pt = ptype_ptr; pt; pt = pt->NEXT)
3216     if (pt->TYPE == high)
3217       break;
3218   if (pt == NULL)
3219     {
3220     /* Initialization of the array of losig */
3221     pthead = (losig_list *)mbkalloc(sigsize * sizeof(losig_list));
3222     ptsig = pthead;
3223     for (i = 0; i < sigsize; i++)
3224       {
3225       ptsig->INDEX = 0;
3226       ptsig++;
3227       }
3228     pt = ptype_ptr = (ptype_list *)addptype(ptype_ptr,(long)high,(void *)pthead);
3229     }
3230   ptsig = (losig_list *)(pt->DATA) + low;
3231 
3232   /* check index  unicity */
3233   if (ptsig->INDEX != 0L)
3234     {
3235    (void)fflush(stdout);
3236     (void)fprintf(stderr, "*** mbk error ***\n");
3237     (void)fprintf(stderr, "duplosig impossible :\n");
3238     (void)fprintf(stderr, "signal %ld already exist\n",
3239            index);
3240     EXIT(1);
3241     }
3242 
3243   ptsig->NEXT      = NULL;
3244   ptsig->NAMECHAIN = dupchainlst(losig_ptr->NAMECHAIN);
3245   ptsig->PRCN      = NULL;
3246   ptsig->INDEX     = losig_ptr->INDEX;
3247   ptsig->USER      = NULL;
3248   ptsig->PRCN      = NULL;    /* The rc data is not duplicated    */
3249   ptsig->TYPE      = losig_ptr->TYPE;  /* The ptype_list is not duplicated */
3250 
3251   if (TRACE_MODE == 'Y') {
3252     (void)fprintf(stdout, "--- mbk --- duplosig : %ld ", index);
3253     if (ptsig->NAMECHAIN)
3254       if (ptsig->NAMECHAIN->DATA)
3255    (void)fprintf(stdout, "name : %s",
3256                       (char *)((chain_list *)(ptsig->NAMECHAIN))->DATA);
3257     (void)fprintf(stdout, "\n");
3258     }
3259 
3260   *BKSIG_ptr = ptype_ptr;
3261   return ptsig;
3262   }
3263 
3264 /*##------------------------------------------------------------------##*/
3265 /*  Function : duplofiglst()                 */
3266 /*  contents : duplicate a lofig list and return a pointer on the new   */
3267 /*             structure.                 */
3268 /*  called func. : duplofig(), reverse(),          */
3269 /*##------------------------------------------------------------------##*/
3270 
duplofiglst(lofig_ptr)3271 lofig_list *duplofiglst(lofig_ptr)
3272 lofig_list *lofig_ptr;
3273   {
3274   lofig_list *lofig_rpt = NULL;     /* Returned lofig pointer  */
3275   lofig_list *lofig_tmpptr = NULL;  /* Temporary pointer       */
3276 
3277   while(lofig_ptr != NULL)
3278     {
3279     lofig_tmpptr       = duplofig(lofig_ptr);
3280     lofig_tmpptr->NEXT = lofig_rpt;
3281     lofig_rpt          = lofig_tmpptr;
3282 
3283     lofig_ptr          = lofig_ptr->NEXT;
3284     }
3285   lofig_rpt = (lofig_list *)reverse((chain_list *)lofig_rpt);
3286   return(lofig_rpt);
3287   }
3288 
3289 /*##------------------------------------------------------------------##*/
3290 /*  Function : duplofig()                 */
3291 /*  contents : duplicate a lofig and return a pointer on the new  */
3292 /*        structure.                      */
3293 /*  called func. : mbkalloc(), dupchainlst(),            */
3294 /*  note : the LOCON, LOSIG, BKSIG, LOINS, LOTRS, LOCAP, LORES, LOSELF pointers are     */
3295 /*         also duplicated                */
3296 /*##------------------------------------------------------------------##*/
3297 
duplofig(lofig_ptr)3298 lofig_list *duplofig(lofig_ptr)
3299 lofig_list *lofig_ptr;
3300   {
3301   lofig_list *lofig_rpt = NULL;     /* Returned lofig pointer  */
3302 
3303   lofig_rpt             = (lofig_list *)(mbkalloc(sizeof(lofig_list)));
3304   lofig_rpt->BKSIG      = NULL;
3305   lofig_rpt->USER       = NULL;     /* The ptype_list is not duplicated */
3306   setsigsize( lofig_rpt, getsigsize( lofig_ptr ));
3307   lofig_rpt->NEXT       = NULL;
3308   lofig_rpt->MODELCHAIN = dupchainlst(lofig_ptr->MODELCHAIN);
3309   lofig_rpt->LOCON      = lofig_ptr->LOCON;
3310   lofig_rpt->LOSIG      = lofig_ptr->LOSIG;
3311   lofig_rpt->BKSIG      = lofig_ptr->BKSIG;
3312   lofig_rpt->LOINS      = lofig_ptr->LOINS;
3313   lofig_rpt->LOTRS      = lofig_ptr->LOTRS;
3314   lofig_rpt->LOCAP      = lofig_ptr->LOCAP;
3315   lofig_rpt->LORES      = lofig_ptr->LORES;
3316   lofig_rpt->LOSELF     = lofig_ptr->LOSELF;
3317   lofig_rpt->NAME       = lofig_ptr->NAME;
3318   lofig_rpt->MODE       = lofig_ptr->MODE;
3319 
3320   return(lofig_rpt);
3321   }
3322 
3323 /*##------------------------------------------------------------------##*/
3324 /*  Function : rduplofig()                */
3325 /*  contents : recursively duplicate a lofig and return a pointer on    */
3326 /*             the new structure. This structure is the entirely  */
3327 /*             double of the lofig duplicated. Except, that all the  */
3328 /*             USER fields are empty.                 */
3329 /*  called func. : mbkalloc(),                  */
3330 /*##------------------------------------------------------------------##*/
3331 
rduplofig(lofig_ptr)3332 lofig_list *rduplofig(lofig_ptr)
3333 lofig_list *lofig_ptr;
3334   {
3335   lofig_list *lofig_rpt = NULL;     /* Returned lofig pointer  */
3336   ptype_list *ptype_ptr = NULL;
3337   locon_list *locon_pt = NULL;
3338   loins_list *loins_pt = NULL;
3339   lotrs_list *lotrs_pt = NULL;
3340   locap_list *locap_pt = NULL;
3341   lores_list *lores_pt = NULL;
3342   loself_list *loself_pt = NULL;
3343   losig_list *losig_pt = NULL;
3344   chain_list *headctc;
3345   chain_list *scanchain;
3346   loctc_list *ptctc;
3347   long index = 0;
3348 
3349   lofig_rpt             = duplofig(lofig_ptr);
3350   lofig_rpt->LOSIG      = duplosiglst(lofig_rpt->LOSIG, &ptype_ptr,getsigsize(lofig_rpt));
3351   lofig_rpt->BKSIG      = ptype_ptr;
3352   lofig_rpt->LOCON      = duploconlst(lofig_rpt->LOCON);
3353   lofig_rpt->LOINS      = duploinslst(lofig_rpt->LOINS);
3354   lofig_rpt->LOTRS      = duplotrslst(lofig_rpt->LOTRS);
3355 
3356   lofig_rpt->LOCAP      = duplocaplst(lofig_rpt->LOCAP);
3357   lofig_rpt->LORES      = duploreslst(lofig_rpt->LORES);
3358   lofig_rpt->LOSELF     = duploselflst(lofig_rpt->LOSELF);
3359 
3360   /* Now verify and restitute the coherence of the figure   */
3361 
3362   /* Restitute coherence in the LOTRS List */
3363   lotrs_pt = lofig_rpt->LOTRS;
3364   while(lotrs_pt != NULL)
3365     {
3366     lotrs_pt->GRID   = duplocon(lotrs_pt->GRID);
3367     locon_pt = lotrs_pt->GRID;
3368     while(locon_pt != NULL)
3369       {
3370       index       = (locon_pt->SIG)->INDEX;
3371       locon_pt->SIG  = getlosig(lofig_rpt, index);
3372       locon_pt->ROOT = (void *)lotrs_pt;
3373 
3374       locon_pt = locon_pt->NEXT;
3375       }
3376 
3377     lotrs_pt->DRAIN  = duplocon(lotrs_pt->DRAIN);
3378     locon_pt = lotrs_pt->DRAIN;
3379     while(locon_pt != NULL)
3380       {
3381       index       = (locon_pt->SIG)->INDEX;
3382       locon_pt->SIG  = getlosig(lofig_rpt, index);
3383       locon_pt->ROOT = (void *)lotrs_pt;
3384 
3385       locon_pt = locon_pt->NEXT;
3386       }
3387 
3388     lotrs_pt->SOURCE    = duplocon(lotrs_pt->SOURCE);
3389     locon_pt = lotrs_pt->SOURCE;
3390     while(locon_pt != NULL)
3391       {
3392       index       = (locon_pt->SIG)->INDEX;
3393       locon_pt->SIG  = getlosig(lofig_rpt, index);
3394       locon_pt->ROOT = (void *)lotrs_pt;
3395 
3396       locon_pt = locon_pt->NEXT;
3397       }
3398 
3399     lotrs_pt->BULK   = duplocon(lotrs_pt->BULK);
3400     locon_pt = lotrs_pt->BULK;
3401     while(locon_pt != NULL)
3402       {
3403       if( locon_pt->SIG )
3404         {
3405         index     = (locon_pt->SIG)->INDEX;
3406         locon_pt->SIG   = getlosig(lofig_rpt, index);
3407    }
3408       else
3409         {
3410    locon_pt->SIG   = NULL;
3411    }
3412       locon_pt->ROOT = (void *)lotrs_pt;
3413 
3414       locon_pt = locon_pt->NEXT;
3415       }
3416 
3417     lotrs_pt = lotrs_pt->NEXT;
3418     }
3419 
3420 
3421   /* Restitute coherence in the LOCAP List */
3422   locap_pt = lofig_rpt->LOCAP;
3423   while(locap_pt != NULL)
3424     {
3425     locap_pt->TCON   = duplocon(locap_pt->TCON);
3426     locon_pt = locap_pt->TCON;
3427     while(locon_pt != NULL)
3428       {
3429       index       = (locon_pt->SIG)->INDEX;
3430       locon_pt->SIG  = getlosig(lofig_rpt, index);
3431       locon_pt->ROOT = (void *)locap_pt;
3432 
3433       locon_pt = locon_pt->NEXT;
3434       }
3435 
3436     locap_pt->BCON  = duplocon(locap_pt->BCON);
3437     locon_pt = locap_pt->BCON;
3438     while(locon_pt != NULL)
3439       {
3440       index       = (locon_pt->SIG)->INDEX;
3441       locon_pt->SIG  = getlosig(lofig_rpt, index);
3442       locon_pt->ROOT = (void *)locap_pt;
3443 
3444       locon_pt = locon_pt->NEXT;
3445       }
3446 
3447     while(locon_pt != NULL)
3448       {
3449       if( locon_pt->SIG )
3450         {
3451         index     = (locon_pt->SIG)->INDEX;
3452         locon_pt->SIG   = getlosig(lofig_rpt, index);
3453    }
3454       else
3455         {
3456    locon_pt->SIG   = NULL;
3457    }
3458       locon_pt->ROOT = (void *)locap_pt;
3459 
3460       locon_pt = locon_pt->NEXT;
3461       }
3462 
3463     locap_pt = locap_pt->NEXT;
3464     }
3465 
3466 
3467   /* Restitute coherence in the LORES List */
3468   lores_pt = lofig_rpt->LORES;
3469   while(lores_pt != NULL)
3470     {
3471     lores_pt->RCON1   = duplocon(lores_pt->RCON1);
3472     locon_pt = lores_pt->RCON1;
3473     while(locon_pt != NULL)
3474       {
3475       index       = (locon_pt->SIG)->INDEX;
3476       locon_pt->SIG  = getlosig(lofig_rpt, index);
3477       locon_pt->ROOT = (void *)lores_pt;
3478 
3479       locon_pt = locon_pt->NEXT;
3480       }
3481 
3482     lores_pt->RCON2  = duplocon(lores_pt->RCON2);
3483     locon_pt = lores_pt->RCON2;
3484     while(locon_pt != NULL)
3485       {
3486       index       = (locon_pt->SIG)->INDEX;
3487       locon_pt->SIG  = getlosig(lofig_rpt, index);
3488       locon_pt->ROOT = (void *)lores_pt;
3489 
3490       locon_pt = locon_pt->NEXT;
3491       }
3492 
3493     while(locon_pt != NULL)
3494       {
3495       if( locon_pt->SIG )
3496         {
3497         index     = (locon_pt->SIG)->INDEX;
3498         locon_pt->SIG   = getlosig(lofig_rpt, index);
3499    }
3500       else
3501         {
3502    locon_pt->SIG   = NULL;
3503    }
3504       locon_pt->ROOT = (void *)lores_pt;
3505 
3506       locon_pt = locon_pt->NEXT;
3507       }
3508 
3509     lores_pt = lores_pt->NEXT;
3510     }
3511 
3512 
3513   /* Selftitute coherence in the LOSELF List */
3514   loself_pt = lofig_rpt->LOSELF;
3515   while(loself_pt != NULL)
3516     {
3517     loself_pt->SCON1   = duplocon(loself_pt->SCON1);
3518     locon_pt = loself_pt->SCON1;
3519     while(locon_pt != NULL)
3520       {
3521       index       = (locon_pt->SIG)->INDEX;
3522       locon_pt->SIG  = getlosig(lofig_rpt, index);
3523       locon_pt->ROOT = (void *)loself_pt;
3524 
3525       locon_pt = locon_pt->NEXT;
3526       }
3527 
3528     loself_pt->SCON2  = duplocon(loself_pt->SCON2);
3529     locon_pt = loself_pt->SCON2;
3530     while(locon_pt != NULL)
3531       {
3532       index       = (locon_pt->SIG)->INDEX;
3533       locon_pt->SIG  = getlosig(lofig_rpt, index);
3534       locon_pt->ROOT = (void *)loself_pt;
3535 
3536       locon_pt = locon_pt->NEXT;
3537       }
3538 
3539     while(locon_pt != NULL)
3540       {
3541       if( locon_pt->SIG )
3542         {
3543         index     = (locon_pt->SIG)->INDEX;
3544         locon_pt->SIG   = getlosig(lofig_rpt, index);
3545    }
3546       else
3547         {
3548    locon_pt->SIG   = NULL;
3549    }
3550       locon_pt->ROOT = (void *)loself_pt;
3551 
3552       locon_pt = locon_pt->NEXT;
3553       }
3554 
3555     loself_pt = loself_pt->NEXT;
3556     }
3557 
3558 
3559 
3560   /* Restitute coherence in the LOINS List */
3561   loins_pt = lofig_rpt->LOINS;
3562   while(loins_pt != NULL)
3563     {
3564     loins_pt->LOCON  = duploconlst(loins_pt->LOCON);
3565     locon_pt = loins_pt->LOCON;
3566     while(locon_pt != NULL)
3567       {
3568       index       = (locon_pt->SIG)->INDEX;
3569       locon_pt->SIG  = getlosig(lofig_rpt, index);
3570       locon_pt->ROOT = (void *)loins_pt;
3571 
3572       locon_pt = locon_pt->NEXT;
3573       }
3574     loins_pt = loins_pt->NEXT;
3575     }
3576 
3577   /* Restitute coherence in the LOCON List */
3578   locon_pt = lofig_rpt->LOCON;
3579   while(locon_pt != NULL)
3580     {
3581     index      = (locon_pt->SIG)->INDEX;
3582     locon_pt->SIG    = getlosig(lofig_rpt, index);
3583     locon_pt->ROOT   = (void *)lofig_rpt;
3584 
3585     locon_pt = locon_pt->NEXT;
3586     }
3587 
3588   /* Duplicate rc data */
3589   for( losig_pt = lofig_ptr->LOSIG ; losig_pt ; losig_pt = losig_pt->NEXT )
3590      duplorcnet( getlosig( lofig_rpt, losig_pt->INDEX ), losig_pt );
3591 
3592   headctc = getallctc( lofig_ptr );
3593   for( scanchain = headctc ; scanchain ; scanchain = scanchain->NEXT )
3594   {
3595     ptctc = (loctc_list*)scanchain->DATA;
3596     addloctc( getlosig( lofig_rpt, ptctc->SIG1->INDEX ), ptctc->NODE1,
3597               getlosig( lofig_rpt, ptctc->SIG2->INDEX ), ptctc->NODE2,
3598               ptctc->CAPA );
3599   }
3600   freechain( headctc );
3601 
3602   return(lofig_rpt);
3603   }
3604 
3605 /* sort routines :
3606    connectors and signals may have to be sorted by name for some
3607    language purposes. */
3608 
3609 static char Buffer0[255]; /* may be of use for other functions */
3610 
3611 static int
connectorcmp(flc,slc)3612    connectorcmp(flc, slc)
3613 locon_list **flc, **slc;
3614 {
3615    return naturalstrcmp((*slc)->NAME, (*flc)->NAME);
3616 }
3617 
3618 void
sortlocon(connectors)3619    sortlocon(connectors)
3620 locon_list **connectors;
3621 {
3622 long n, i;
3623 locon_list *lc, **tc;
3624 
3625    if (!connectors || !(*connectors))
3626       return;
3627 
3628    /* first :
3629       count connectors. */
3630    for (n = 0, lc = *connectors; lc; lc = lc->NEXT)
3631       n++;
3632    tc = (locon_list **)mbkalloc(n * sizeof(locon_list *));
3633    for (n = 0, lc = *connectors; lc; lc = lc->NEXT)
3634       tc[n++] = lc;
3635    /* second :
3636       sort them. */
3637    qsort((void *)tc, n, sizeof(locon_list *), connectorcmp);
3638    /* tables :
3639       the last element of the table is t[n - 1].
3640       relink the list in the sorted order. */
3641    n--;
3642    *connectors = tc[0];
3643    for (i = 0; i < n; i++)
3644       tc[i]->NEXT = tc[i + 1];
3645    tc[n]->NEXT = (locon_list *)NULL;
3646    mbkfree((void *)tc);
3647 }
3648 
3649 static int
signalcmp(fls,sls)3650    signalcmp(fls, sls)
3651 losig_list **fls, **sls;
3652 {
3653    return naturalstrcmp(getsigname(*fls), getsigname(*sls));
3654 }
3655 
3656 void
sortlosig(signals)3657    sortlosig(signals)
3658 losig_list **signals;
3659 {
3660 long n, i;
3661 losig_list *lc, **tc;
3662 
3663    if (!signals || !(*signals))
3664       return;
3665 
3666    /* first :
3667       count signals. */
3668    for (n = 0, lc = *signals; lc; lc = lc->NEXT)
3669       n++;
3670    tc = (losig_list **)mbkalloc(n * sizeof(losig_list *));
3671    for (n = 0, lc = *signals; lc; lc = lc->NEXT)
3672       tc[n++] = lc;
3673    /* second :
3674       sort them. */
3675    qsort((void *)tc, n, sizeof(losig_list *), signalcmp);
3676    /* tables :
3677       the last element of the table is t[n - 1].
3678       relink the list in the sorted order. */
3679    n--;
3680    *signals = tc[0];
3681    for (i = 0; i < n; i++)
3682       tc[i]->NEXT = tc[i + 1];
3683    tc[n]->NEXT = (losig_list *)NULL;
3684    mbkfree((void *)tc);
3685 }
3686 
3687 /* checking :
3688    the validity of a list of connectors for vectorization purposes
3689    is to be checked for some file formats, so let's do it.
3690    The algorithm checks that :
3691       vectorized radical do not appear on themselves
3692       vectorized connectors are all together and ordered properly */
3693 #define HTSIZE 200
3694 int
checkloconorder(c)3695    checkloconorder(c)
3696 locon_list *c;
3697 {
3698 char *s=NULL, *t=NULL;
3699 ht *table;
3700 int first = 1, previous=0, delta=0, current=0;
3701 
3702    table = addht(HTSIZE);
3703    while (c) {
3704       /* vectorized ?
3705          no. */
3706       if ((s = strchr(c->NAME, ' ')) == NULL) {
3707 avoid_redundancy :
3708          if (sethtitem(table, (void *)c->NAME, 0)) {
3709             (void)fflush(stdout);
3710             (void)fprintf(stderr, "*** mbk error ***\n");
3711             (void)fprintf(stderr,
3712                            "the radical %s is already used in a vector\n",
3713                            c->NAME);
3714             delht(table);
3715             EXIT(1);
3716             return 1;
3717          }
3718          first = 1;
3719          c = c->NEXT;
3720       } else {
3721          while (c) {
3722          int i = 1;
3723             /* redundancy :
3724                I'ven't found an elegant way to do that, too bad. */
3725             if (!s)
3726                if ((s = strchr(c->NAME, ' ')) == NULL)
3727                   goto avoid_redundancy;
3728             /* Temporary change :
3729                alter the string contents just a microsecond. */
3730             *s = '\0';
3731             strcpy(Buffer0, c->NAME);
3732             *s = ' ';
3733             while (*(s + i) && isdigit((int)*(s + i)))
3734                i++;
3735             if (*(s + i)) {
3736                (void)fflush(stdout);
3737                (void)fprintf(stderr, "*** mbk error ***\n");
3738                (void)fprintf(stderr,
3739                      "the radical %s has a spurious vectorized value %s (%s)\n",
3740                      Buffer0, s + 1, c->NAME);
3741                delht(table);
3742                EXIT(1);
3743                return 1;
3744             }
3745             current = atoi(s + 1);
3746             s = NULL;
3747             /* first :
3748                the name is not yet known. so I store it.
3749                we do that each time a new vector is encountered. */
3750             if (first) {
3751 its_first:
3752                if (sethtitem(table, (void *)(t = namealloc(Buffer0)), 0)) {
3753                   (void)fflush(stdout);
3754                   (void)fprintf(stderr, "*** mbk error ***\n");
3755                   (void)fprintf(stderr,
3756                                  "the radical %s is already used in a vector\n",
3757                                  Buffer0);
3758                   delht(table);
3759                   EXIT(1);
3760                   return 1;
3761                }
3762                delta = first = 0;
3763                previous = current;
3764                c = c->NEXT;
3765             } else { /* let's see if it's a good vhdl legal vector */
3766                /* its a new vector :
3767                   in fact this vector follows an other vector! */
3768                if (t != namealloc(Buffer0))
3769                   goto its_first;
3770                if (!delta)
3771                   delta = previous - current;
3772                else if (delta != previous - current) {
3773                   (void)fflush(stdout);
3774                   (void)fprintf(stderr, "*** mbk error ***\n");
3775                   (void)fprintf(stderr,
3776                               "the radical %s is not vectorized properly,",
3777                               Buffer0);
3778                   (void)fprintf(stderr,
3779                               " %s %d follows %s %d\n", Buffer0, previous,
3780                                                          Buffer0, current);
3781                   delht(table);
3782                   EXIT(1);
3783                   return 1;
3784                }
3785                if (delta != 1 && delta != -1) {
3786                   (void)fflush(stdout);
3787                   (void)fprintf(stderr, "*** mbk error ***\n");
3788                   (void)fprintf(stderr,
3789                               "the radical %s is not vectorized properly,",
3790                               c->NAME);
3791                   (void)fprintf(stderr,
3792                               " %s %d follows %s %d\n", Buffer0, previous,
3793                                                          Buffer0, current);
3794                   delht(table);
3795                   EXIT(1);
3796                   return 1;
3797                }
3798                previous = current;
3799                c = c->NEXT;
3800             }
3801          }
3802       }
3803    }
3804    delht(table);
3805    return 0;
3806 }
3807 
3808 /*************************** Analogical world ***************************************/
3809 
3810 /*##------------------------------------------------------------------##*/
3811 /*  Function : duplocaplst()                 */
3812 /*  contents : duplicate a locap list and return a pointer on the new   */
3813 /*             structure.                 */
3814 /*  called func. : duplocap(), reverse(),          */
3815 /*##------------------------------------------------------------------##*/
3816 
duplocaplst(locap_ptr)3817 locap_list *duplocaplst(locap_ptr)
3818 locap_list *locap_ptr;
3819   {
3820   locap_list *locap_rpt = NULL;     /* Returned locap pointer  */
3821   locap_list *locap_tmpptr = NULL;  /* Temporary pointer       */
3822 
3823   while(locap_ptr != NULL)
3824     {
3825     locap_tmpptr       = duplocap(locap_ptr);
3826     locap_tmpptr->NEXT = locap_rpt;
3827     locap_rpt          = locap_tmpptr;
3828 
3829     locap_ptr          = locap_ptr->NEXT;
3830     }
3831   locap_rpt = (locap_list *)reverse((chain_list *)locap_rpt);
3832   return(locap_rpt);
3833   }
3834 
3835 /*##------------------------------------------------------------------##*/
3836 /*  Function : duplocap()                 */
3837 /*  contents : duplicate a locap and return a pointer on the new  */
3838 /*        structure.                      */
3839 /*  called func. : mbkalloc(), duplocon()             */
3840 /*  note : the TCON, BCON pointers are also duplicated   */
3841 /*##------------------------------------------------------------------##*/
3842 
duplocap(locap_ptr)3843 locap_list *duplocap(locap_ptr)
3844 locap_list *locap_ptr;
3845   {
3846   locap_list *locap_rpt = NULL;     /* Returned locap pointer  */
3847 
3848   locap_rpt             = (locap_list *)mbkalloc(sizeof(locap_list));
3849   locap_rpt->NEXT       = NULL;
3850   locap_rpt->NAME       = locap_ptr->NAME;
3851   locap_rpt->TCON       = locap_ptr->TCON;
3852   locap_rpt->BCON       = locap_ptr->BCON;
3853   locap_rpt->TYPE       = locap_ptr->TYPE;
3854   locap_rpt->CAPA       = locap_ptr->CAPA;
3855   locap_rpt->USER       = NULL;     /* The ptype_list is not duplicated */
3856 
3857   return(locap_rpt);
3858   }
3859 
3860 
3861 /*##------------------------------------------------------------------##*/
3862 /*  Function : duploreslst()                 */
3863 /*  contents : duplicate a lores list and return a pointer on the new   */
3864 /*             structure.                 */
3865 /*  called func. : duplores(), reverse(),          */
3866 /*##------------------------------------------------------------------##*/
3867 
duploreslst(lores_ptr)3868 lores_list *duploreslst(lores_ptr)
3869 lores_list *lores_ptr;
3870   {
3871   lores_list *lores_rpt = NULL;     /* Returned lores pointer  */
3872   lores_list *lores_tmpptr = NULL;  /* Temporary pointer       */
3873 
3874   while(lores_ptr != NULL)
3875     {
3876     lores_tmpptr       = duplores(lores_ptr);
3877     lores_tmpptr->NEXT = lores_rpt;
3878     lores_rpt          = lores_tmpptr;
3879 
3880     lores_ptr          = lores_ptr->NEXT;
3881     }
3882   lores_rpt = (lores_list *)reverse((chain_list *)lores_rpt);
3883   return(lores_rpt);
3884   }
3885 
3886 /*##------------------------------------------------------------------##*/
3887 /*  Function : duplores()                 */
3888 /*  contents : duplicate a lores and return a pointer on the new  */
3889 /*        structure.                      */
3890 /*  called func. : mbkalloc(), duplocon()             */
3891 /*  note : the RCON1, RCON2 pointers are also duplicated   */
3892 /*##------------------------------------------------------------------##*/
3893 
duplores(lores_ptr)3894 lores_list *duplores(lores_ptr)
3895 lores_list *lores_ptr;
3896   {
3897   lores_list *lores_rpt = NULL;     /* Returned lores pointer  */
3898 
3899   lores_rpt             = (lores_list *)mbkalloc(sizeof(lores_list));
3900   lores_rpt->NEXT       = NULL;
3901   lores_rpt->NAME       = lores_ptr->NAME;
3902   lores_rpt->RCON1      = lores_ptr->RCON1;
3903   lores_rpt->RCON2      = lores_ptr->RCON2;
3904   lores_rpt->TYPE       = lores_ptr->TYPE;
3905   lores_rpt->RESI       = lores_ptr->RESI;
3906   lores_rpt->USER       = NULL;     /* The ptype_list is not duplicated */
3907 
3908   return(lores_rpt);
3909   }
3910 
3911 
3912 /*##------------------------------------------------------------------##*/
3913 /*  Function : duploselflst()                 */
3914 /*  contents : duplicate a loself list and return a pointer on the new   */
3915 /*             structure.                 */
3916 /*  called func. : duploself(), reverse(),          */
3917 /*##------------------------------------------------------------------##*/
3918 
duploselflst(loself_ptr)3919 loself_list *duploselflst(loself_ptr)
3920 loself_list *loself_ptr;
3921   {
3922   loself_list *loself_rpt = NULL;     /* Returned loself pointer  */
3923   loself_list *loself_tmpptr = NULL;  /* Temporary pointer       */
3924 
3925   while(loself_ptr != NULL)
3926     {
3927     loself_tmpptr       = duploself(loself_ptr);
3928     loself_tmpptr->NEXT = loself_rpt;
3929     loself_rpt          = loself_tmpptr;
3930 
3931     loself_ptr          = loself_ptr->NEXT;
3932     }
3933   loself_rpt = (loself_list *)reverse((chain_list *)loself_rpt);
3934   return(loself_rpt);
3935   }
3936 
3937 /*##------------------------------------------------------------------##*/
3938 /*  Function : duploself()                 */
3939 /*  contents : duplicate a loself and return a pointer on the new  */
3940 /*        structure.                      */
3941 /*  called func. : mbkalloc(), duplocon()             */
3942 /*  note : the RCON1, RCON2 pointers are also duplicated   */
3943 /*##------------------------------------------------------------------##*/
3944 
duploself(loself_ptr)3945 loself_list *duploself(loself_ptr)
3946 loself_list *loself_ptr;
3947   {
3948   loself_list *loself_rpt = NULL;     /* Returned loself pointer  */
3949 
3950   loself_rpt             = (loself_list *)mbkalloc(sizeof(loself_list));
3951   loself_rpt->NEXT       = NULL;
3952   loself_rpt->NAME       = loself_ptr->NAME;
3953   loself_rpt->SCON1      = loself_ptr->SCON1;
3954   loself_rpt->SCON2      = loself_ptr->SCON2;
3955   loself_rpt->TYPE       = loself_ptr->TYPE;
3956   loself_rpt->SELF       = loself_ptr->SELF;
3957   loself_rpt->USER       = NULL;     /* The ptype_list is not duplicated */
3958 
3959   return(loself_rpt);
3960   }
3961 
3962 
3963 
3964 
3965 
3966