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 *                                                                              *
26 *  Tool        : Parser al                                                     *
27 *  Author(s)   : Gregoire AVOT                                                 *
28 *  Updates     : June, 12th 1998                                               *
29 *  Updates     : June, 30th 1998  Create unique name on losig where no one     *
30 *                                 is provided.                                 *
31 *  Updates     : AUGUST, 12th 2002, Pierre Nguyen Tuong                        *
32 *  $Log: alc_pars_l6.c,v $
33 *  Revision 1.10  2012/05/14 14:20:24  alliance
34 *  Updated GNU/FSF address (patch from Thibault North).
35 *
36 *  Revision 1.9  2003/09/11 15:08:50  fred
37 *  Correction on stdarg
38 *
39 *  Revision 1.8  2003/09/11 13:07:06  fred
40 *  Changing varargs into stdarg, and updating the sources accordingly.
41 *
42 *  Revision 1.7  2003/03/22 16:35:04  ludo
43 *  Bug fixing: core dump under Solaris 8 64 bits
44 *
45 *  Revision 1.6  2003/01/14 12:02:23  fred
46 *  Corrected a bug in electrical dimensions of the transistors when
47 *  parsing al file: eg a 0.35 in al became a 0.34 in spice! Argh!
48 *
49 *  Revision 1.5  2002/10/09 09:18:37  xtof
50 *  Dans la fonction read_line, deux buffers de 524288 caracteres etaient
51 *  declares. En fonction de la taille max de la pile, dans certains
52 *  cas cela peut faire mal ... Je mets donc la taille � 1024,
53 *  ce qui me semble plus raisonnable et suffisant.
54 *
55 *  Revision 1.4  2002/09/30 16:20:52  czo
56 *  support/users
57 *
58 *  Revision 1.3  2002/08/14 19:10:20  pnt
59 *  Inversion de l'ordre d'ecriture des parametres pour les capacites, les
60 *  resistances et les inductances. Le genere .al contient desormais
61 *
62 *  P type capa tcon bcon name node_tcon node_bcon           ---capacite
63 *  R type resi rcon1 rcon2 name node_rcon1 node_rcon2       ---resistance
64 *  L type self scon1 scon2 name node_scon1 node_scon2       ---inductance
65 *
66 *  et non
67 *
68 *  P type capa name tcon bcon node_tcon node_bcon           ---capacite
69 *  R type resi name rcon1 rcon2 node_rcon1 node_rcon2       ---resistance
70 *  L type self name scon1 scon2 node_scon1 node_scon2       ---inductance
71 *
72 *  Revision 1.2  2002/08/13 16:40:14  pnt
73 *  Suite de l'introduction des objets analogiques capacite, resistance et self.
74 *
75 *  Modification du parser et du driver al.
76 *
77 *  Syntaxe:
78 *  P type capa name tcon bcon node_tcon node_bcon           ---capacite
79 *  R type resi name rcon1 rcon2 node_rcon1 node_rcon2       ---resistance
80 *  L type self name scon1 scon2 node_scon1 node_scon2       ---inductance
81 *
82 *  Note:
83 *  Q existe deja pour les capacites de type RC (rcn). On utilise P a la place.
84 *
85 *  Revision 1.1.1.1  2002/03/13 10:19:11  fred
86 *  Importing MBKAL sources into the new CVS tree
87 *
88 *                                                                              *
89 *******************************************************************************/
90 
91 #include <stdlib.h>
92 #include <stdio.h>
93 #include <string.h>
94 #include <unistd.h>
95 #include <stdarg.h>
96 #include <math.h>
97 
98 #include <mut.h>
99 #include <mlo.h>
100 #include <rcn.h>
101 #include <mlu.h>
102 
103 /******************************************************************************/
104 
105 #define MAL_CON	0x00000001
106 #define MAL_INS	0x00000002
107 #define MAL_TRS	0x00000004
108 #define MAL_WIR	0x00000008
109 #define MAL_CAP	0x00000010
110 #define MAL_CTC	0x00000020
111 #define MAL_SIG	0x00000040
112 #define MAL_EOF	0x00000080
113 #define MAL_HEA 0x00000100
114 
115 #define MAL_LOCAP  0x00000200
116 #define MAL_LORES  0x00000400
117 #define MAL_LOSELF 0x00000800
118 
119 /* Tampon de lecture */
120 #define	MALBUFMAX 8192
121 
122 /* ptype sur losig -> verification unicite du signal */
123 #define MALDEFINED 11223344
124 
125 /* ptype sur losig -> nom unique */
126 #define SIGHT 199806301
127 
128 typedef struct
129 {
130   char		*name;
131   char		 type;
132   char		 dir;
133   losig_list	*ptsig;
134   num_list	*phcon;
135 } data_locon;
136 
137 typedef struct
138 {
139   char		*insname;	/* namealloc */
140   char		*modelename;	/* namealloc */
141   chain_list	*interface;
142 } data_loins;
143 
144 /******************************************************************************/
145 
146 int		nbitem        __P(( chain_list* ));
147 char		decode_dir    __P(( char*, char*, int ));
148 char		decode_type   __P(( char*, char*, int ));
149 losig_list*	decode_sig    __P(( lofig_list*, chain_list*, char*, int,
150                                     int
151                                  ));
152 lotrs_list*	decode_trs    __P(( lofig_list*, chain_list*, char*, int,
153                                     int
154                                  ));
155 
156 locap_list *decode_locap(lofig_list *ptfig,chain_list *line,char *fname,int mal_line,int version) ;
157 
158 /*
159 locap_list*	decode_locap    __P(( lofig_list*, chain_list*, char*, int,
160                                     int
161                                  ));
162 */
163 
164 lores_list*	decode_lores    __P(( lofig_list*, chain_list*, char*, int,
165                                     int
166                                  ));
167 
168 loself_list*	decode_loself    __P(( lofig_list*, chain_list*, char*, int,
169                                     int
170                                  ));
171 
172 int		decode_int    __P(( char*, char*, int ));
173 double		decode_float  __P(( char*, char*, int ));
174 data_locon*	decode_locon  __P(( lofig_list*, chain_list*, char*, int ));
175 lowire_list*	decode_lowire __P(( losig_list*, chain_list*, char*, int ));
176 loctc_list*	decode_loctc  __P(( lofig_list*, chain_list*, char*, int ));
177 float		decode_capa   __P(( losig_list*, chain_list*, char*, int ));
178 int		type_line     __P(( chain_list*, char*, int ));
179 chain_list*	read_line     __P(( FILE*, char*, int ));
180 void		free_line     __P(( chain_list* ));
181 void		mal_error     __P(( char *, ...));
182 void		chk_header    __P(( chain_list*, char*, int ));
183 unsigned char	decode_layer  __P(( char*, char*, int ));
184 data_loins*	decode_ins    __P(( chain_list*, char*, int ));
185 loins_list*	end_ins       __P(( lofig_list*, lofig_list**, data_loins*,
186                                     char*, int
187                                  ));
188 void		complete_ins  __P(( lofig_list*, data_loins*, chain_list*,
189                                     char*, int
190 				 ));
191 
192 /*** Macro and function for debug *********************************************/
193 
194 /* Set the define 'ALDEBUG' will ENABLE debug mode */
195 /*
196 #define ALDEBUG
197 */
198 
199 #ifdef ALDEBUG
200 
201 chain_list*     al_dbg_addchain
202                               __P(( chain_list*, void*, int ));
203 void            al_dbg_freechain
204                               __P(( chain_list* ));
205 void            al_dbg_chkchain
206                               __P(( void ));
207 void            al_dbg_init   __P(( void ));
208 
209 #define ALMAXCHAIN 1024
210 
211 chain_list*     al_chain_pt[ALMAXCHAIN];
212 int             al_chain_lg[ALMAXCHAIN];
213 
214 #define al_addchain( a, b )    al_dbg_addchain( a, b, __LINE__ )
215 #define al_freechain( a )      al_dbg_freechain( a )
216 
217 #else
218 
219 #define al_addchain( a, b )    addchain( a, b )
220 #define al_freechain( a )      freechain( a )
221 
222 #endif
223 
224 /******************************************************************************/
225 
nbitem(head)226 int		nbitem( head )
227 chain_list	*head;
228 {
229   chain_list	*scan;
230   int		 count;
231 
232   for( scan = head, count = 0 ; scan ; scan = scan->NEXT, count++ );
233   return( count );
234 }
235 
236 /******************************************************************************/
237 
decode_layer(elem,fname,mal_line)238 unsigned char	decode_layer( elem, fname, mal_line )
239 char		*elem;
240 char		*fname;
241 int		 mal_line;
242 {
243   if( strcmp( elem, "X"  ) == 0 ) return RCN_WIRE_UNKNOW;
244   if( strcmp( elem, "PY" ) == 0 ) return RCN_WIRE_POLY;
245   if( strcmp( elem, "A1" ) == 0 ) return RCN_WIRE_ALU1;
246   if( strcmp( elem, "A2" ) == 0 ) return RCN_WIRE_ALU2;
247   if( strcmp( elem, "CY" ) == 0 ) return RCN_WIRE_CONT_POLY;
248   if( strcmp( elem, "CN" ) == 0 ) return RCN_WIRE_CONT_DIF_N;
249   if( strcmp( elem, "CP" ) == 0 ) return RCN_WIRE_CONT_DIF_P;
250   if( strcmp( elem, "CV" ) == 0 ) return RCN_WIRE_CONT_VIA;
251   if( strcmp( elem, "CW" ) == 0 ) return RCN_WIRE_CONT_VIA2;
252 
253   mal_error( fname,
254              mal_line,
255              "decode_layer()",
256              "invalid wire type [%s].",
257              elem
258            );
259 
260   /* Never reach */
261   return 0;
262 }
263 
264 /******************************************************************************/
265 
decode_dir(elem,fname,mal_line)266 char		decode_dir( elem, fname, mal_line )
267 char		*elem;
268 char		*fname;
269 int		 mal_line;
270 {
271   if( strcasecmp( elem, "IN"       ) == 0 ) return( 'I' );
272   if( strcasecmp( elem, "OUT"      ) == 0 ) return( 'O' );
273   if( strcasecmp( elem, "INOUT"    ) == 0 ) return( 'B' );
274   if( strcasecmp( elem, "UNKNOWN"  ) == 0 ) return( 'X' );
275   if( strcasecmp( elem, "TRISTATE" ) == 0 ) return( 'Z' );
276   if( strcasecmp( elem, "TRANSCV"  ) == 0 ) return( 'T' );
277 
278   mal_error( fname,
279              mal_line,
280              "decode_dir",
281              "Bad direction [%s] for connector.\n",
282              elem
283            );
284 
285   /* Never reach */
286   return 0;
287 }
288 
289 /******************************************************************************/
290 
decode_type(elem,fname,mal_line)291 char		decode_type( elem, fname, mal_line )
292 char		*elem;
293 char		*fname;
294 int		mal_line;
295 {
296   if( strcasecmp( elem, "INTERNAL" ) == 0 ) return( 'I' );
297   if( strcasecmp( elem, "EXTERNAL" ) == 0 ) return( 'E' );
298 
299   mal_error( fname,
300              mal_line,
301              "decode_type()",
302              "Bad type [%s] for connector.\n",
303              elem
304            );
305 
306   /* Never reach */
307   return 0;
308 }
309 
310 /******************************************************************************/
311 
decode_capa(ptsig,line,fname,mal_line)312 float		decode_capa( ptsig, line, fname, mal_line )
313 losig_list	*ptsig;
314 chain_list	*line;
315 char		*fname;
316 int		 mal_line;
317 {
318   float		capa;
319 
320   if( nbitem( line ) != 1 )
321     mal_error( fname,
322                mal_line,
323                "decode_capa()",
324                "Bad number of argument.\n"
325              );
326 
327   if(!ptsig->PRCN)
328     addlorcnet( ptsig );
329 
330   capa = (float)decode_float( (char*) line->DATA, fname, mal_line );
331   addcapa( ptsig, capa );
332 
333   return capa;
334 }
335 
336 /******************************************************************************/
337 
decode_ins(line,fname,mal_line)338 data_loins*	decode_ins( line, fname, mal_line )
339 chain_list	*line;
340 char		*fname;
341 int		 mal_line;
342 {
343   data_loins	*newins;
344 
345   if( nbitem( line ) != 2 )
346     mal_error( fname, mal_line, "decode_ins()", "Bad number of argument.\n");
347 
348   newins             = (data_loins*) mbkalloc( sizeof( data_loins ) );
349   newins->modelename = namealloc( (char*) line->DATA       );
350   newins->insname    = namealloc( (char*) line->NEXT->DATA );
351   newins->interface  = NULL;
352 
353   return( newins );
354 }
355 
356 /******************************************************************************/
357 
decode_trs(ptfig,line,fname,mal_line,version)358 lotrs_list*	decode_trs( ptfig, line, fname, mal_line, version )
359 lofig_list	*ptfig;
360 chain_list	*line;
361 char		*fname;
362 int		 mal_line;
363 int              version;
364 {
365   char		 type;
366   long           w;
367   long           l;
368   losig_list	*drain;
369   losig_list	*grid;
370   losig_list	*source;
371   losig_list	*bulk;
372   long           xs;
373   long           xd;
374   long           ps;
375   long           pd;
376   long		 x;
377   long		 y;
378   int		 phsource;
379   int		 phdrain;
380   int		 phgrid;
381   int		 phbulk;
382   lotrs_list	*pttrs;
383   int		 n;
384   char		*name;
385 
386   n = nbitem( line );
387 
388   /* Version 4 :  type L W D G S XS XD PS PD X Y
389    * Version 5 :  type L W D G S XS XD PS PD X Y [ nd ng ns ]
390    * Version 6 :  type L W D G S B XS XD PS PD X Y [ nd ng ns nb ] nom
391    */
392 
393   if( ( version == 6 && n != 14 && n != 18   ) ||
394       ( version == 5 && n != 12 && n != 15   ) ||
395       ( version == 4 && n != 12              )    )
396     mal_error( fname,
397                mal_line,
398                "decode_trs()",
399                "Bad number of element (%d).\n",
400                n
401              );
402 
403   type = -1;
404   if( strcasecmp( (char*)line->DATA, "P" ) == 0 ) type = TRANSP;
405   if( strcasecmp( (char*)line->DATA, "N" ) == 0 ) type = TRANSN;
406   if( type == -1 )
407     mal_error( fname,
408                mal_line,
409                "decode_trs()",
410 	       "Unknown transistor type [%s].\n",
411 	       (char*)line->DATA
412 	     );
413   line   = line->NEXT;
414 
415   l      = .5 + decode_float( (char*)line->DATA, fname, mal_line ) * (double)SCALE_X ;
416   line   = line->NEXT;
417 
418   w      = .5 + decode_float( (char*)line->DATA, fname, mal_line ) * (double)SCALE_X ;
419   line   = line->NEXT;
420 
421   drain  = givelosig( ptfig, decode_int( (char*)line->DATA, fname, mal_line ) );
422   line   = line->NEXT;
423 
424   grid   = givelosig( ptfig, decode_int( (char*)line->DATA, fname, mal_line ) );
425   line   = line->NEXT;
426 
427   source = givelosig( ptfig, decode_int( (char*)line->DATA, fname, mal_line ) );
428   line   = line->NEXT;
429 
430   bulk = NULL;
431 
432   if( version == 6 )
433   {
434     n      = decode_int( (char*)line->DATA, fname, mal_line );
435     if( n )
436       bulk = givelosig( ptfig, n );
437 
438     line   = line->NEXT;
439   }
440 
441   xs   = .5 + decode_float( (char*)line->DATA, fname, mal_line ) * (double)SCALE_X ;
442   line = line->NEXT;
443 
444   xd   = .5 + decode_float( (char*)line->DATA, fname, mal_line ) * (double)SCALE_X ;
445   line = line->NEXT;
446 
447   ps   = .5 + decode_float( (char*)line->DATA, fname, mal_line ) * (double)SCALE_X ;
448   line = line->NEXT;
449 
450   pd   = .5 + decode_float( (char*)line->DATA, fname, mal_line ) * (double)SCALE_X ;
451   line = line->NEXT;
452 
453   x    = .5 + decode_float( (char*)line->DATA, fname, mal_line ) * (double)SCALE_X ;
454   line = line->NEXT;
455 
456   y    = .5 + decode_float( (char*)line->DATA, fname, mal_line ) * (double)SCALE_X ;
457   line = line->NEXT;
458 
459   phdrain  = 0;
460   phgrid   = 0;
461   phsource = 0;
462   phbulk   = 0;
463 
464   if( version == 5 || version == 6 )
465   {
466     if( line && line->NEXT )	/* 3 or 4 physicals node are coming */
467     {
468       phdrain  = decode_int( (char*)line->DATA, fname, mal_line );
469       line     = line->NEXT;
470 
471       phgrid   = decode_int( (char*)line->DATA, fname, mal_line );
472       line     = line->NEXT;
473 
474       phsource = decode_int( (char*)line->DATA, fname, mal_line );
475       line     = line->NEXT;
476 
477       if( version == 6 )
478       {
479         phbulk   = decode_int( (char*)line->DATA, fname, mal_line );
480         line     = line->NEXT;
481       }
482     }
483   }
484 
485   name = NULL;
486   if( version == 6 )
487   {
488     name   = namealloc( (char*)line->DATA );
489   }
490 
491   pttrs  = addlotrs( ptfig, type, x, y, w, l, ps, pd, xs, xd,
492                      grid, source, drain, bulk,
493                      name
494 	 	   );
495 
496   if( phdrain )
497   {
498     if( !pttrs->DRAIN->SIG->PRCN )
499       addlorcnet( pttrs->DRAIN->SIG );
500 
501     setloconnode( pttrs->DRAIN, phdrain );
502   }
503 
504   if( phgrid )
505   {
506     if( !pttrs->GRID->SIG->PRCN )
507       addlorcnet( pttrs->GRID->SIG );
508 
509     setloconnode( pttrs->GRID, phgrid );
510   }
511 
512   if( phsource )
513   {
514     if( !pttrs->SOURCE->SIG->PRCN )
515       addlorcnet( pttrs->SOURCE->SIG );
516 
517     setloconnode( pttrs->SOURCE, phsource );
518   }
519 
520   if( phbulk )
521   {
522     if( !pttrs->BULK->SIG->PRCN )
523       addlorcnet( pttrs->BULK->SIG );
524 
525     setloconnode( pttrs->BULK, phbulk );
526   }
527 
528   return( pttrs );
529 }
530 
531 /******************************************************************************/
532 
decode_locap(lofig_list * ptfig,chain_list * line,char * fname,int mal_line,int version)533 locap_list *decode_locap(lofig_list *ptfig,chain_list *line,char *fname,int mal_line,int version)
534 {
535   char       type   = -1   ;
536   losig_list *tcon  = NULL ;
537   losig_list *bcon  = NULL ;
538   int	     phtcon = 0    ;
539   int	     phbcon = 0    ;
540   locap_list *ptcap = NULL ;
541   char	     *name  = NULL ;
542   float      capa   = 0.0  ;
543 
544   /* Version 6 :  P type capa name tcon bcon node_tcon node_bcon */
545 
546   /***** type *****/
547 
548   if(strcasecmp((char *)line -> DATA, "MIM") == 0)
549    {
550      type = CAPMIM ;
551    }
552 
553   if(strcasecmp((char *)line -> DATA, "POLY_NWELL") == 0)
554    {
555      type = CAPPNWELL ;
556    }
557 
558   if(type == -1)
559     {
560       mal_error(fname,
561                 mal_line,
562                 "decode_locap()",
563 	        "Unknown capacitor type [%s].\n",
564 	        (char *)line -> DATA) ;
565     }
566 
567   line   = line -> NEXT ;
568 
569   /***** capa *****/
570 
571   capa   = decode_float((char *)line -> DATA,fname,mal_line) ;
572   line   = line -> NEXT ;
573 
574   /***** tcon bcon *****/
575 
576   tcon   = givelosig(ptfig,decode_int((char *)line -> DATA,fname,mal_line)) ;
577   line   = line -> NEXT ;
578 
579   bcon   = givelosig(ptfig,decode_int((char *)line -> DATA,fname,mal_line)) ;
580   line   = line -> NEXT ;
581 
582   /***** name *****/
583 
584   name   = namealloc((char *)line -> DATA) ;
585   line   = line -> NEXT ;
586 
587   /***** node_tcon node_bcon *****/
588 
589   phtcon  = decode_int((char *)line -> DATA,fname,mal_line) ;
590   line    = line -> NEXT ;
591 
592   phbcon  = decode_int((char *)line -> DATA,fname,mal_line) ;
593 
594   ptcap  = addlocap(ptfig,type,capa,tcon,bcon,name) ;
595 
596   if(phtcon)
597     {
598       if(!ptcap -> TCON -> SIG -> PRCN)
599 	{
600           addlorcnet(ptcap -> TCON -> SIG) ;
601 	}
602 
603       setloconnode(ptcap -> TCON,phtcon) ;
604   }
605 
606   if(phbcon)
607     {
608       if(!ptcap -> BCON -> SIG -> PRCN)
609         {
610           addlorcnet(ptcap -> BCON -> SIG) ;
611         }
612 
613       setloconnode(ptcap -> BCON,phbcon) ;
614     }
615 
616   return(ptcap) ;
617 }
618 
619 /******************************************************************************/
620 
decode_lores(lofig_list * ptfig,chain_list * line,char * fname,int mal_line,int version)621 lores_list *decode_lores(lofig_list *ptfig,chain_list *line,char *fname,int mal_line,int version)
622 {
623   char       type    = -1   ;
624   losig_list *rcon1  = NULL ;
625   losig_list *rcon2  = NULL ;
626   int	     phrcon1 = 0    ;
627   int	     phrcon2 = 0    ;
628   lores_list *ptres  = NULL ;
629   char	     *name   = NULL ;
630   float      resi    = 0.0  ;
631 
632   /* Version 6 :  R type resi name rcon1 rcon2 node_rcon1 node_rcon2 */
633 
634   if(strcasecmp((char *)line -> DATA, "MIM") == 0)
635    {
636      type = RESMIM ;
637    }
638 
639   if(strcasecmp((char *)line -> DATA, "MIM") == 0)
640    {
641      type = RESMIM ;
642    }
643 
644   if(type == -1)
645     {
646       mal_error(fname,
647                 mal_line,
648                 "decode_lores()",
649 	        "Unknown resistor type [%s].\n",
650 	        (char *)line -> DATA) ;
651     }
652 
653   line   = line -> NEXT ;
654 
655   /***** resi *****/
656 
657   resi   = decode_float((char *)line -> DATA,fname,mal_line) ;
658   line   = line -> NEXT ;
659 
660   /***** rcon1 rcon2 *****/
661 
662   rcon1   = givelosig(ptfig,decode_int((char *)line -> DATA,fname,mal_line)) ;
663   line   = line -> NEXT ;
664 
665   rcon2   = givelosig(ptfig,decode_int((char *)line -> DATA,fname,mal_line)) ;
666   line   = line -> NEXT ;
667 
668   /***** name *****/
669 
670   name   = namealloc((char *)line -> DATA) ;
671   line   = line -> NEXT ;
672 
673   /***** node_rcon1 node_rcon2 *****/
674 
675   phrcon1  = decode_int((char *)line -> DATA,fname,mal_line) ;
676   line    = line -> NEXT ;
677 
678   phrcon2  = decode_int((char *)line -> DATA,fname,mal_line) ;
679 
680   ptres  = addlores(ptfig,type,resi,rcon1,rcon2,name) ;
681 
682   if(phrcon1)
683     {
684       if(!ptres -> RCON1 -> SIG -> PRCN)
685 	{
686           addlorcnet(ptres -> RCON1 -> SIG) ;
687 	}
688 
689       setloconnode(ptres -> RCON1,phrcon1) ;
690   }
691 
692   if(phrcon2)
693     {
694       if(!ptres -> RCON2 -> SIG -> PRCN)
695         {
696           addlorcnet(ptres -> RCON2 -> SIG) ;
697         }
698 
699       setloconnode(ptres -> RCON2,phrcon2) ;
700     }
701 
702   return(ptres) ;
703 }
704 
705 /******************************************************************************/
706 
decode_loself(lofig_list * ptfig,chain_list * line,char * fname,int mal_line,int version)707 loself_list *decode_loself(lofig_list *ptfig,chain_list *line,char *fname,int mal_line,int version)
708 {
709   char        type     = -1   ;
710   losig_list  *scon1   = NULL ;
711   losig_list  *scon2   = NULL ;
712   int	      phscon1  = 0    ;
713   int	      phscon2  = 0    ;
714   loself_list *ptself = NULL ;
715   char	      *name    = NULL ;
716   float       self     = 0.0  ;
717 
718   /* Version 6 :  L type self name scon1 scon2 node_scon1 node_scon2 */
719 
720   if(strcasecmp((char *)line -> DATA, "MIM") == 0)
721    {
722      type = SELFMIM ;
723    }
724 
725   if(strcasecmp((char *)line -> DATA, "MIM") == 0)
726    {
727      type = SELFMIM ;
728    }
729 
730   if(type == -1)
731     {
732       mal_error(fname,
733                 mal_line,
734                 "decode_loself()",
735 	        "Unknown inductor type [%s].\n",
736 	        (char *)line -> DATA) ;
737     }
738 
739   line   = line -> NEXT ;
740 
741   /***** self *****/
742 
743   self   = decode_float((char *)line -> DATA,fname,mal_line) ;
744   line   = line -> NEXT ;
745 
746   /***** scon1 scon2 *****/
747 
748   scon1   = givelosig(ptfig,decode_int((char *)line -> DATA,fname,mal_line)) ;
749   line   = line -> NEXT ;
750 
751   scon2   = givelosig(ptfig,decode_int((char *)line -> DATA,fname,mal_line)) ;
752   line   = line -> NEXT ;
753 
754   /***** name *****/
755 
756   name   = namealloc((char *)line -> DATA) ;
757   line   = line -> NEXT ;
758 
759   /***** node_scon1 node_scon2 *****/
760 
761   phscon1  = decode_int((char *)line -> DATA,fname,mal_line) ;
762   line    = line -> NEXT ;
763 
764   phscon2  = decode_int((char *)line -> DATA,fname,mal_line) ;
765 
766   ptself  = addloself(ptfig,type,self,scon1,scon2,name) ;
767 
768   if(phscon1)
769     {
770       if(!ptself -> SCON1 -> SIG -> PRCN)
771 	{
772           addlorcnet(ptself -> SCON1 -> SIG) ;
773 	}
774 
775       setloconnode(ptself -> SCON1,phscon1) ;
776   }
777 
778   if(phscon2)
779     {
780       if(!ptself -> SCON2 -> SIG -> PRCN)
781         {
782           addlorcnet(ptself -> SCON2 -> SIG) ;
783         }
784 
785       setloconnode(ptself -> SCON2,phscon2) ;
786     }
787 
788   return(ptself) ;
789 }
790 
791 /******************************************************************************/
792 
complete_ins(ptfig,ins,line,fname,mal_line)793 void		complete_ins( ptfig, ins, line, fname, mal_line )
794 lofig_list	*ptfig;
795 data_loins	*ins;
796 chain_list	*line;
797 char		*fname;
798 int		 mal_line;
799 {
800   data_locon	*ptcon;
801 
802   ptcon       = decode_locon( ptfig, line, fname, mal_line );
803   ptcon->name = namealloc( ptcon->name );
804 
805   ins->interface = al_addchain( ins->interface, ptcon );
806 }
807 
808 /******************************************************************************/
809 
decode_loctc(ptfig,line,fname,mal_line)810 loctc_list*	decode_loctc( ptfig, line, fname, mal_line )
811 lofig_list	*ptfig;
812 chain_list	*line;
813 char		*fname;
814 int		 mal_line;
815 {
816   float		 capa;
817   int		 idxsig1;
818   int		 idxsig2;
819   losig_list    *ptsig1;
820   losig_list    *ptsig2;
821   int            node1;
822   int            node2;
823 
824   if( nbitem( line ) != 5 )
825     mal_error( fname, mal_line, "decode_loctc()", "Bad number of argument.\n");
826 
827   capa    = (float)decode_float( (char*)line->DATA, fname, mal_line );
828   line    = line->NEXT;
829 
830   idxsig1 = decode_int( (char*)line->DATA, fname, mal_line );
831   line    = line->NEXT;
832 
833   node1   = decode_int( (char*)line->DATA, fname, mal_line );
834   line    = line->NEXT;
835 
836   idxsig2 = decode_int( (char*)line->DATA, fname, mal_line );
837   line    = line->NEXT;
838 
839   node2   = decode_int( (char*)line->DATA, fname, mal_line );
840 
841   ptsig1  = givelosig( ptfig, idxsig1 );
842   ptsig2  = givelosig( ptfig, idxsig2 );
843 
844   if( !ptsig1->PRCN )
845     addlorcnet( ptsig1 );
846 
847   if( !ptsig2->PRCN )
848     addlorcnet( ptsig2 );
849 
850   return( addloctc( ptsig1, node1, ptsig2, node2, capa ) );
851 }
852 
853 /******************************************************************************/
854 
decode_lowire(ptsig,line,fname,mal_line)855 lowire_list*	decode_lowire( ptsig, line, fname, mal_line )
856 losig_list	*ptsig;
857 chain_list	*line;
858 char		*fname;
859 int		 mal_line;
860 {
861   int		n1;
862   int		n2;
863   int		layer;
864   float		r;
865   float		c;
866   float		x;
867   float		y;
868   float		dx;
869   float		dy;
870   /* long		lx; */
871   /* long		ly; */
872   /* long		ldx; */
873   /* long		ldy; */
874 
875   if( nbitem( line ) != 9 )
876     mal_error( fname, mal_line,"decode_lowire()","Bad number of argument.\n" );
877 
878   if( !ptsig->PRCN )
879     addlorcnet( ptsig );
880 
881   n1    = decode_int( line->DATA, fname, mal_line );
882   line  = line->NEXT;
883 
884   n2    = decode_int( line->DATA, fname, mal_line );
885   line  = line->NEXT;
886 
887   layer = decode_layer( line->DATA, fname, mal_line );
888   line  = line->NEXT;
889 
890   r     = (float)decode_float( line->DATA, fname, mal_line );
891   line  = line->NEXT;
892 
893   c     = (float)decode_float( line->DATA, fname, mal_line );
894   line  = line->NEXT;
895 
896   x     = (float)decode_float( line->DATA, fname, mal_line );
897   line  = line->NEXT;
898 
899   y     = (float)decode_float( line->DATA, fname, mal_line );
900   line  = line->NEXT;
901 
902   dx    = (float)decode_float( line->DATA, fname, mal_line );
903   line  = line->NEXT;
904 
905   dy    = (float)decode_float( line->DATA, fname, mal_line );
906 
907   /* lx    = x  * SCALE_X; */
908   /* ly    = y  * SCALE_X; */
909   /* ldx   = dx * SCALE_X; */
910   /* ldy   = dy * SCALE_X; */
911 
912   return( addlowire( ptsig, layer, 0, r, c, x, y, dx, dy, n1, n2 ) );
913 }
914 
915 /******************************************************************************/
916 
decode_sig(ptfig,line,fname,mal_line,version)917 losig_list*	decode_sig( ptfig, line, fname, mal_line, version )
918 lofig_list	*ptfig;
919 chain_list	*line;
920 char		*fname;
921 int          mal_line;
922 int          version;
923 {
924   int            idx;
925   losig_list	*ptsig;
926   char           type;
927   float          capa;
928   char           signame[256];
929   ht            *htsigname;
930   long           index;
931   char          *ptallocsigname;
932   long           i;
933   long           j;
934   long           k;
935 
936   if( ( nbitem( line ) < 2 && version == 6 ) ||
937       ( nbitem( line ) < 3 && version == 5 ) ||
938       ( nbitem( line ) < 3 && version == 4 )
939     )
940     mal_error( fname, mal_line, "decode_sig()", "Incomplete line.\n" );
941 
942   idx   = decode_int( (char*)line->DATA, fname, mal_line );
943   line  = line->NEXT;
944   ptsig = givelosig( ptfig, idx );
945 
946   if( getptype( ptsig->USER, MALDEFINED ) )
947     mal_error( fname, mal_line, "decode_sig()","Signal %d yet defined.\n", idx);
948 
949   type  = decode_type( (char*)line->DATA, fname, mal_line );
950   line  = line->NEXT;
951 
952   ptsig->TYPE = type;
953 
954   if( version == 5 || version == 4 )
955   {
956     if(!ptsig->PRCN)
957       addlorcnet( ptsig );
958 
959     capa = (float)decode_float( (char*) line->DATA, fname, mal_line );
960     addcapa( ptsig, capa );
961 
962     line = line->NEXT;
963   }
964 
965   htsigname = (ht*) ( getptype( ptfig->USER, SIGHT )->DATA );
966 
967   if( line )
968   {
969     for( ; line ; line = line->NEXT )
970     {
971       ptsig->NAMECHAIN = addchain( ptsig->NAMECHAIN,
972                                    namealloc( (char*) line->DATA )
973                                  );
974       addhtitem( htsigname, ptsig->NAMECHAIN->DATA, 1 );
975     }
976   }
977   else
978   {
979     /* Le parser al ajoute un nom si le signal n'en possede pas deja.
980      * Bizare : ce n'est pas au parser de faire ce boulot.
981      */
982 
983     sprintf( signame, "mbk_sig%ld", ptsig->INDEX );
984     ptallocsigname = namealloc( signame ) ;
985 
986     if( gethtitem( htsigname, ptallocsigname ) != EMPTYHT )
987     {
988       /* En theorie, sur 11 caracteres, on arrive a 3E15 pour index.
989        * En pratique, on s'en fout.
990        */
991 
992       index = 0;
993 
994       do
995       {
996         sprintf( signame, "mbk_sig012345" );
997         j = 26*26*26*26*26 ;
998         k = index;
999         for( i = 5 ; i >= 0 ; i-- )
1000         {
1001           signame[12-i] = k / j + 'a' ;
1002           k = k - ( ( k / j ) * j ) ;
1003           j = j / 26 ;
1004         }
1005         ptallocsigname = namealloc( signame ) ;
1006         index++;
1007       }
1008       while( gethtitem( htsigname, ptallocsigname ) != EMPTYHT );
1009     }
1010 
1011     ptsig->NAMECHAIN = addchain( ptsig->NAMECHAIN, ptallocsigname );
1012     addhtitem( htsigname, ptsig->NAMECHAIN->DATA, 1 );
1013   }
1014 
1015   ptsig->USER = addptype( ptsig->USER, MALDEFINED, (void*)1 );
1016   return( ptsig );
1017 }
1018 
1019 /******************************************************************************/
1020 
decode_int(elem,fname,mal_line)1021 int		decode_int( elem, fname, mal_line )
1022 char		*elem;
1023 char		*fname;
1024 int		 mal_line;
1025 {
1026   long		 v;
1027   char		*stop;
1028 
1029   v = strtol( elem, &stop, 10 );
1030 
1031   if( *stop != '\0' )
1032     mal_error( fname, mal_line, "decode_int()","Not an integer [%s].\n", elem );
1033 
1034   return( (int) v );
1035 }
1036 
1037 /******************************************************************************/
1038 
decode_float(elem,fname,mal_line)1039 double		decode_float( elem, fname, mal_line )
1040 char		*elem;
1041 char		*fname;
1042 int		 mal_line;
1043 {
1044   double  	v;
1045   char		*stop;
1046 
1047   v = strtod( elem, &stop );
1048 
1049   if( *stop != '\0' )
1050     mal_error( fname, mal_line, "decode_float()", "Not a float [%s].\n", elem );
1051 
1052   return( v );
1053 }
1054 
1055 /******************************************************************************/
1056 
decode_locon(ptfig,line,fname,mal_line)1057 data_locon*	decode_locon( ptfig, line, fname, mal_line )
1058 lofig_list	*ptfig;
1059 chain_list	*line;
1060 char		*fname;
1061 int		 mal_line;
1062 {
1063   data_locon	*newcon;
1064 
1065   newcon = (data_locon*) mbkalloc( sizeof( data_locon ) );
1066 
1067   if( nbitem( line ) < 4 )
1068     mal_error( fname,
1069                mal_line,
1070                "decode_locon()",
1071                "Bad description of connector.\n"
1072              );
1073 
1074   newcon->name   = (char*) line->DATA;
1075   line           = line->NEXT;
1076 
1077   newcon->dir    = decode_dir( (char*) line->DATA, fname, mal_line );
1078   line           = line->NEXT;
1079 
1080   newcon->type   = decode_type( (char*) line->DATA, fname, mal_line );
1081   line           = line->NEXT;
1082 
1083   /*
1084   if( ptfig->MODE != 'C' )
1085   {
1086   */
1087     newcon->ptsig = givelosig( ptfig, decode_int( (char*) line->DATA,
1088                                                   fname,
1089   						  mal_line
1090     					        )
1091                              );
1092 
1093     newcon->ptsig->TYPE = 'E';
1094   /*
1095   }
1096   */
1097 
1098   line           = line->NEXT;
1099 
1100   newcon->phcon  = NULL;
1101   for( ; line ; line = line->NEXT )
1102     newcon->phcon = addnum( newcon->phcon,
1103                             decode_int( (char*) line->DATA, fname, mal_line )
1104 			  );
1105 
1106   return( newcon );
1107 }
1108 
1109 /******************************************************************************/
1110 
type_line(head,fname,mal_line)1111 int		type_line( head, fname, mal_line )
1112 chain_list	*head;
1113 char		*fname;
1114 int		 mal_line;
1115 {
1116   char		*type;
1117 
1118   type = (char*) head->DATA;
1119 
1120   if( strcasecmp( type, "H"   ) == 0 ) return ( MAL_HEA );
1121   if( strcasecmp( type, "S"   ) == 0 ) return ( MAL_SIG );
1122   if( strcasecmp( type, "I"   ) == 0 ) return ( MAL_INS );
1123   if( strcasecmp( type, "C"   ) == 0 ) return ( MAL_CON );
1124   if( strcasecmp( type, "W"   ) == 0 ) return ( MAL_WIR );
1125   if( strcasecmp( type, "Q"   ) == 0 ) return ( MAL_CAP );
1126   if( strcasecmp( type, "K"   ) == 0 ) return ( MAL_CTC );
1127   if( strcasecmp( type, "T"   ) == 0 ) return ( MAL_TRS );
1128 
1129   /* Trucs analogiques. Q et K sont deja pris */
1130   if( strcasecmp( type, "P"   ) == 0 ) return ( MAL_LOCAP );
1131   if( strcasecmp( type, "R"   ) == 0 ) return ( MAL_LORES );
1132   if( strcasecmp( type, "L"   ) == 0 ) return ( MAL_LOSELF);
1133 
1134   if( strcasecmp( type, "EOF" ) == 0 ) return ( MAL_EOF );
1135 
1136   mal_error( fname, mal_line, "type_line()", "Unknown element [%s].\n", type );
1137 
1138   /* Never reach */
1139   return 0;
1140 }
1141 
1142 /******************************************************************************/
1143 
read_line(df,fname,mal_line)1144 chain_list*	read_line( df, fname, mal_line )
1145 FILE		*df;
1146 char		*fname;
1147 int		 mal_line;
1148 {
1149   char		buffer[MALBUFMAX];
1150   char		word[MALBUFMAX];
1151   int		lg;
1152   int		onword;
1153   int		i;
1154   int		j=0;
1155   char		*elem;
1156   chain_list	*decomp;
1157 
1158   decomp = NULL;
1159 
1160   if( fgets( buffer, MALBUFMAX, df ) == NULL )
1161     mal_error( fname,
1162                mal_line,
1163                "read_line()",
1164                "Error when reading input file.\n"
1165              );
1166 
1167   if( feof(df) )
1168     mal_error( fname,
1169                mal_line,
1170                "read_line()",
1171                "End of file before end of parsing.\n"
1172              );
1173 
1174   lg = strlen( buffer );
1175 
1176   if( lg == MALBUFMAX-1 )
1177     mal_error( fname,
1178                mal_line,
1179                "read_line()",
1180                "Line exceed %d characters.\n",
1181                MALBUFMAX
1182              );
1183 
1184   if( lg > 0 )
1185   {
1186     if( buffer[lg-1] != '\n' )
1187     {
1188       fflush( stdout );
1189       fprintf( stderr, "Ligne non terminee par '\\n'.\n" );
1190       fprintf( stderr, "\"%s\"\n", buffer );
1191     }
1192   }
1193 
1194   onword  = 0;
1195 
1196   /* En tete de ligne : soit 'EOF', soit 'X '. L'espace apres le X est le
1197    * seul qui doit etre pris en compte comme separateur. */
1198   if( lg == 4 && strcmp( "EOF\n", buffer )==0 )
1199   {
1200     elem = (char*)mbkalloc( sizeof(char) * 4 );
1201     strncpy( elem, buffer, 3 );
1202     elem[3] = 0;
1203     decomp = al_addchain( decomp, elem );
1204     return( decomp );
1205   }
1206 
1207   /* decode le premier argument de type 'X ' */
1208   if( buffer[1] != ' ' )
1209     mal_error( fname, mal_line, "read_line()", "Bad type of line.\n" );
1210 
1211   elem = (char*)mbkalloc( sizeof(char) * 2 );
1212   elem[0] = buffer[0];
1213   elem[1] = 0;
1214   decomp = al_addchain( decomp, elem );
1215 
1216   /* Decode le reste de la ligne */
1217 
1218   for( i=2; i<lg; i++ )
1219   {
1220     if( ( buffer[i] >= 'A' && buffer[i] <= 'Z' ) ||
1221         ( buffer[i] >= 'a' && buffer[i] <= 'z' ) ||
1222         ( buffer[i] >= '0' && buffer[i] <= '9' ) ||
1223         strchr( " <>[]._-|/+", buffer[i] )               )
1224     {
1225       if( !onword )
1226       {
1227         onword = 1;
1228         j = 0;
1229       }
1230       word[j++] = buffer[i];
1231     }
1232     else
1233     {
1234       if( onword ) /* On vient de terminer un mot */
1235       {
1236         word[j++] = 0;
1237 
1238         elem  = (char*)mbkalloc( j * sizeof(char) );
1239         memcpy( elem, word, j );
1240         decomp = al_addchain( decomp, elem );
1241 
1242         onword = 0;
1243       }
1244 
1245       /* Ici si des symbols sont consid�r�s comme des mots � part enti�re */
1246     }
1247   }
1248 
1249   if( decomp == NULL )
1250     mal_error( fname, mal_line, "read_line()", "Blank line.\n" );
1251 
1252   return( reverse( decomp ) );
1253 }
1254 
1255 /******************************************************************************/
1256 
free_line(head)1257 void		free_line( head )
1258 chain_list	*head;
1259 {
1260   chain_list	*trashing;
1261 
1262   for( trashing = head ; trashing ; trashing = trashing->NEXT )
1263     mbkfree( trashing->DATA );
1264 
1265   al_freechain( head );
1266 }
1267 
1268 /******************************************************************************/
1269 
mal_error(char * fname,...)1270 void		mal_error( char *fname, ... )
1271 {
1272   va_list	 index;
1273   int		 line;
1274   char          *func;
1275   char          *fmt;
1276 
1277   va_start( index, fname );
1278   fname = va_arg( index, char* );
1279   line  = va_arg( index, int   );
1280   func  = va_arg( index, char* );
1281   fmt   = va_arg( index, char* );
1282 
1283   fflush( stdout );
1284 
1285   fprintf( stderr,
1286          "*** mbk error in loadlofig ( al, function %s ) file %s line %d ***\n",
1287            func,
1288            fname,
1289 	   line
1290 	 );
1291   vfprintf( stderr, fmt, index );
1292 
1293   va_end( index );
1294 
1295   EXIT(1);
1296 }
1297 
1298 /******************************************************************************/
1299 
chk_header(line,fname,mal_line)1300 void		chk_header( line, fname, mal_line )
1301 chain_list	*line;
1302 char		*fname;
1303 int		 mal_line;
1304 {
1305   int		 type;
1306 
1307   type = type_line( line, fname, mal_line );
1308 
1309   if( type != MAL_HEA )
1310     mal_error( fname, mal_line, "chk_header()", "Can't find header.\n" );
1311 
1312   if( ! line->NEXT || ! line->NEXT->NEXT )
1313     mal_error( fname, mal_line, "chk_header()", "Incomplete header.\n" );
1314 
1315   if( strcasecmp( (char*) line->NEXT->DATA, fname ) != 0 )
1316     mal_error( fname,
1317                mal_line,
1318                "chk_header()",
1319 	       "Bad circuit name : %s insteated of %s.\n",
1320                (char*) line->NEXT->DATA,
1321 	       fname
1322 	     );
1323 
1324   if( strcasecmp( (char*) line->NEXT->NEXT->DATA, "L" ) != 0 )
1325     mal_error( fname,
1326                mal_line,
1327                "chk_header()",
1328                "Bad type of view (not logical).\n"
1329              );
1330 }
1331 
1332 /******************************************************************************/
1333 
end_ins(ptfig,tetemodele,newins,fname,mal_line)1334 loins_list*	end_ins( ptfig, tetemodele, newins, fname, mal_line )
1335 lofig_list	*ptfig;
1336 lofig_list	**tetemodele;
1337 data_loins	*newins;
1338 char		*fname;
1339 int		 mal_line;
1340 {
1341   lofig_list	*ptmodele;
1342   chain_list	*scan;
1343   chain_list	*headsig;
1344   locon_list	*scancon;
1345   num_list	*scannum;
1346   loins_list	*ins;
1347   data_locon	*dtcon;
1348   ht            *htcon;
1349   int            nb;
1350 
1351   ptmodele = getlomodel( *tetemodele, newins->modelename );
1352   if( !ptmodele )
1353   {
1354     *tetemodele = addlomodel( *tetemodele, newins->modelename );
1355     ptmodele   = *tetemodele;
1356 
1357     /* Building connectors for new model */
1358     for( scan = newins->interface ; scan ; scan = scan->NEXT )
1359       addlocon( *tetemodele, ((data_locon*)scan->DATA)->name, NULL, 'X');
1360   }
1361 
1362   headsig = NULL;
1363   /* Create losig in the same order of the locon in the model */
1364 
1365   for( scancon = ptmodele->LOCON, nb = 0 ;
1366        scancon ;
1367        scancon = scancon->NEXT, nb++
1368      );
1369 
1370   htcon = addht( nb/10+1 );
1371 
1372   for( scan = newins->interface; scan ; scan = scan->NEXT )
1373     addhtitem( htcon, ((data_locon*)scan->DATA)->name, (long)(scan) );
1374 
1375   for( scancon = ptmodele->LOCON ; scancon ; scancon = scancon->NEXT )
1376   {
1377     scan = (chain_list*)gethtitem( htcon, scancon->NAME );
1378     if( ((long)(scan)) != EMPTYHT )
1379       headsig = al_addchain( headsig, ((data_locon*)scan->DATA)->ptsig );
1380     else
1381     {
1382       mal_error( fname,
1383                  mal_line,
1384                  "end_ins()",
1385                  "Bad interface for instance %s of model %s.\n",
1386                  newins->insname,
1387                  newins->modelename
1388                );
1389 
1390     }
1391   }
1392 
1393   delht( htcon );
1394 
1395   headsig = reverse( headsig );
1396 
1397   ins = addloins( ptfig, newins->insname, ptmodele, headsig );
1398 
1399   newins->interface = reverse( newins->interface );
1400   for( scan = newins->interface, scancon = ins->LOCON ;
1401        scan ;
1402        scan = scan->NEXT, scancon = scancon->NEXT
1403      )
1404   {
1405     dtcon = (data_locon*)scan->DATA;
1406     scancon->DIRECTION = dtcon->dir;
1407 
1408     if( dtcon->phcon && !scancon->SIG->PRCN )
1409       addlorcnet( scancon->SIG );
1410 
1411 
1412     for( scannum = dtcon->phcon ; scannum ; scannum = scannum->NEXT )
1413       setloconnode( scancon, scannum->DATA );
1414   }
1415 
1416   al_freechain( headsig );
1417 
1418   for( scan = newins->interface; scan ; scan = scan->NEXT )
1419   {
1420     freenum( ((data_locon*)(scan->DATA))->phcon );
1421     mbkfree( scan->DATA );
1422   }
1423 
1424   al_freechain( newins->interface );
1425 
1426   mbkfree( newins );
1427 
1428   return( ins );
1429 }
1430 
1431 /******************************************************************************/
1432 
alcloadlofig6(ptfig,fname,mode,in,version)1433 void		alcloadlofig6( ptfig, fname, mode, in, version )
1434 lofig_list	*ptfig;
1435 char		*fname;
1436 char		 mode;
1437 FILE		*in;
1438 int              version;
1439 {
1440   chain_list	*line;		/* line read from file			*/
1441   int		 type;		/* type of line				*/
1442   int		 mal_line;	/* line number in file			*/
1443   data_locon	*newcon;	/* data extract from object 'C'		*/
1444   locon_list	*newlocon;	/* new locon				*/
1445   losig_list	*newlosig;	/* new losig				*/
1446   num_list	*scannum;	/* to scan phcon			*/
1447   int		 compose=0;	/* Valid elements for currents object	*/
1448   lofig_list	*tetemodele;	/* model list used			*/
1449   data_loins	*newins;	/* new instance				*/
1450   losig_list	*scansig;	/* to clean the USER field of losig	*/
1451   locon_list	*figcon;	/* for mode c : connector of lofig	*/
1452   ht            *htsigname;     /* create an unique name on losig       */
1453 
1454 #ifdef ALDEBUG
1455   al_dbg_init();
1456 #endif
1457 
1458   mal_line   = 1;
1459   line       = NULL;
1460   tetemodele = NULL;
1461 
1462 
1463   ptfig->MODE = mode;
1464   htsigname   = addht( 1024 );
1465   ptfig->USER = addptype( ptfig->USER, SIGHT, htsigname   );
1466 
1467 
1468   /* check the name							*/
1469 
1470   mal_line++;
1471   line = read_line( in, fname, mal_line );
1472   chk_header( line, fname, mal_line );
1473   free_line( line );
1474 
1475   /* externals connectors						*/
1476 
1477   figcon = ptfig->LOCON;
1478 
1479   do
1480   {
1481     mal_line++;
1482     line = read_line( in, fname, mal_line );
1483     type = type_line( line, fname, mal_line );
1484 
1485     if( type == MAL_CON )
1486     {
1487       newcon = decode_locon( ptfig, line->NEXT, fname, mal_line );
1488 
1489       if( mode != 'C' )
1490         newlocon = addlocon( ptfig, newcon->name, newcon->ptsig, newcon->dir );
1491       else
1492       {
1493         newlocon = figcon;
1494 	/*newlocon->SIG = newcon->ptsig;*/
1495 	figcon = figcon->NEXT;
1496       }
1497 
1498       if( mode != 'C' && newcon->phcon )
1499       {
1500         if( !newcon->ptsig->PRCN )
1501           addlorcnet( newcon->ptsig );
1502 
1503         for( scannum = newcon->phcon ; scannum ; scannum = scannum->NEXT )
1504           setloconnode( newlocon, scannum->DATA );
1505       }
1506 
1507       /* del the newcon */
1508       freenum( newcon->phcon );
1509       mbkfree( newcon );
1510 
1511       free_line( line );
1512 
1513     }
1514   }
1515   while( type == MAL_CON );
1516 
1517 
1518   /* Internal description of figure */
1519 
1520   if( mode != 'P' )
1521   {
1522     while( type != MAL_EOF && type != MAL_CTC )
1523     {
1524       newlosig = NULL;
1525       newins   = NULL;
1526 
1527       switch( type )
1528       {
1529       case MAL_INS :
1530         compose  = MAL_CON;
1531         newins = decode_ins( line->NEXT, fname, mal_line );
1532         break;
1533 
1534       case MAL_TRS :
1535         compose = 0;
1536         decode_trs( ptfig, line->NEXT, fname, mal_line, version );
1537         break;
1538 
1539       case MAL_LOCAP :
1540         compose = 0;
1541         decode_locap( ptfig, line->NEXT, fname, mal_line, version );
1542         break;
1543 
1544       case MAL_LORES :
1545         compose = 0;
1546         decode_lores( ptfig, line->NEXT, fname, mal_line, version );
1547         break;
1548 
1549       case MAL_LOSELF :
1550         compose = 0;
1551         decode_loself( ptfig, line->NEXT, fname, mal_line, version );
1552         break;
1553 
1554       case MAL_SIG:
1555         if( version == 6 )
1556           compose = MAL_WIR | MAL_CAP ;
1557         else
1558         if( version == 5 )
1559           compose = MAL_WIR ;
1560         else
1561           compose = 0;
1562         newlosig = decode_sig( ptfig, line->NEXT, fname, mal_line, version );
1563         break;
1564 
1565       default:
1566         /* erreur : element non reconnu. */
1567         mal_error( fname,
1568                    mal_line,
1569                    "alcloadlofig6()",
1570                    "Incorrect file structure.\n"
1571                  );
1572       }
1573 
1574       free_line( line );
1575 
1576       mal_line++;
1577       line = read_line( in, fname, mal_line );
1578       type = type_line( line, fname, mal_line );
1579 
1580       while ( type & compose )
1581       {
1582         if( newins )
1583         {
1584           complete_ins( ptfig, newins, line->NEXT, fname, mal_line );
1585         }
1586         else
1587         if( newlosig )
1588         {
1589           switch( type )
1590           {
1591           case MAL_WIR:
1592 	    decode_lowire( newlosig, line->NEXT, fname, mal_line );
1593 	    break;
1594 	case   MAL_CAP:
1595 	    decode_capa( newlosig, line->NEXT, fname, mal_line );
1596 	    break;
1597           }
1598         }
1599 
1600         free_line( line );
1601         mal_line++;
1602         line = read_line( in, fname, mal_line );
1603         type = type_line( line, fname, mal_line );
1604       }
1605 
1606       /* terminate current element */
1607       if( newins )
1608         end_ins( ptfig, &tetemodele, newins, fname, mal_line );
1609     }
1610 
1611     if( version == 6 )
1612     {
1613       while( type == MAL_CTC )
1614       {
1615         decode_loctc(  ptfig, line->NEXT, fname, mal_line );
1616 
1617         free_line( line );
1618         mal_line++;
1619         line = read_line( in, fname, mal_line );
1620         type = type_line( line, fname, mal_line );
1621       }
1622     }
1623 
1624     if( type != MAL_EOF )
1625       mal_error( fname,
1626                  mal_line,
1627                  "alcloadlofig6()",
1628                  "Incorrect file structure.\n"
1629                );
1630 
1631     freelomodel( tetemodele );
1632     for( scansig = ptfig->LOSIG ; scansig ; scansig = scansig->NEXT )
1633       scansig->USER = delptype( scansig->USER, MALDEFINED );
1634   }
1635 
1636   free_line( line );
1637 
1638   delht( htsigname );
1639   ptfig->USER = delptype( ptfig->USER, SIGHT );
1640 
1641 #ifdef ALDEBUG
1642   al_dbg_chkchain();
1643 #endif
1644 
1645   lofigchain( ptfig );
1646 }
1647 
1648 
1649 /******* Function for debug ***************************************************/
1650 
1651 #ifdef ALDEBUG
1652 
al_dbg_addchain(head,data,ligne)1653 chain_list* al_dbg_addchain( head, data, ligne )
1654 chain_list      *head;
1655 void            *data;
1656 int              ligne;
1657 {
1658   int i;
1659 
1660   for( i=0 ; i < ALMAXCHAIN ; i++ )
1661     if( al_chain_lg[i] == 0 )
1662       break;
1663 
1664   if( i == ALMAXCHAIN )
1665   {
1666     printf( "\n*** Debuggage AL : tableau al_chain plein.\n" );
1667     exit(1);
1668   }
1669 
1670   al_chain_lg[i] = ligne;
1671   al_chain_pt[i] = addchain( head, data );
1672 
1673   return( al_chain_pt[i] );
1674 }
1675 
al_freechain(head)1676 void al_freechain( head )
1677 chain_list      *head;
1678 {
1679   int i;
1680   chain_list    *scan;
1681 
1682   for( scan = head ; scan ; scan = scan->NEXT )
1683   {
1684     for( i = 0 ; i < ALMAXCHAIN ; i++ )
1685       if( al_chain_pt[i] == scan )
1686         break;
1687     if( i == ALMAXCHAIN )
1688     {
1689       printf( "\n*** Debuggage AL : chain_list a liberer non trouvee.\n" );
1690       exit(1);
1691     }
1692     al_chain_lg[i] = 0;
1693   }
1694   freechain( head );
1695 }
1696 
al_dbg_chkchain(void)1697 void al_dbg_chkchain( void )
1698 {
1699   int i;
1700 
1701   for( i=0 ; i < ALMAXCHAIN ; i++ )
1702   {
1703     if( al_chain_lg[i] )
1704       printf( "*** Debuggage AL : Element alloue ligne %d non libere.\n",
1705               al_chain_lg[i]
1706             );
1707   }
1708 }
1709 
al_dbg_init(void)1710 void al_dbg_init( void )
1711 {
1712   int i;
1713 
1714   printf( "*** Parser al v6.03. Debug\n" );
1715   for( i=0 ; i<ALMAXCHAIN ; i++ )
1716     al_chain_lg[i]=0;
1717 }
1718 #endif
1719 
1720 
1721 
1722