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 #ident "$Author: alliance $ $Date: 2012/05/14 14:20:25 $ $Revision: 1.7 $"
25 
26 /*******************************************************************************
27 *                                                                              *
28 *  Tool        : Spice parser / driver v 7.00                                  *
29 *  Author(s)   : Gregoire AVOT                                                 *
30 *  Updates     : March, 18th 1998                                              *
31 *                                                                              *
32 *******************************************************************************/
33 
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <math.h>
38 #include <ctype.h>
39 
40 #include <mut.h>
41 #include <mlo.h>
42 #include <rcn.h>
43 #include "msl.h"
44 #include "spi_int.h"
45 #include "spi_hash.h"
46 #include "spi_parse.h"
47 #include "spi_msg.h"
48 #include "spi_global.h"
49 
50 /* Fonctions dynamiques */
51 static int	 (*ext_handler)() = NULL;
52 static int	 (*cmp_handler)() = NULL;
53 
54 /* Variables globales MSL */
55 lofig_list	*msl_ptfig;
56 int		 msl_figloaded;
57 char*		 msl_figname;
58 char*		 msl_subckt;
59 int              msl_line;
60 
61 char              SPI_SEPAR           ;
62 static char      *SPI_NETNAME         ;
63 char              SPI_ONE_NODE_NORC   ;
64 char              SPI_MERGE           ;
65 char              SPI_VERBOSE         ;
66 char              SPI_FILE            ;
67 char              SPI_CHECK_NAME      ;
68 char              SPI_AUTO_LOAD       ;
69 char              SPI_NODE_EQUI_DRIVE ;
70 char              SPI_AFF_UNK         ;
71 
72 /******************************************************************************/
73 
spiceloadlofig(ptfig,name,mode)74 void		spiceloadlofig(ptfig, name, mode)
75 lofig_list      *ptfig;
76 char            *name;
77 char             mode;
78 {
79   char		*env;
80   ginterf	*teteinterf;
81   ginterf	*effinterf;
82   ginterf	*scaninterf;
83   chain_list	*scanchain;
84   char          *spicename;
85 
86   /* Comportement par defaut */
87 
88   SPI_SEPAR            = '.'   ;
89   SPI_NETNAME          = "NET" ;
90   SPI_MERGE            = 1     ;
91   SPI_VERBOSE          = 0     ;
92   SPI_FILE             = 0     ;
93   SPI_ONE_NODE_NORC    = 0     ;
94   SPI_CHECK_NAME       = 0     ;
95   SPI_AUTO_LOAD        = 0     ;
96   SPI_NODE_EQUI_DRIVE  = 0     ;
97   SPI_AFF_UNK          = 1     ;
98 
99   spi_init_lang();
100 
101   env = mbkgetenv( "MBK_SPI_NETNAME" );
102 
103   if( env )
104     SPI_NETNAME = env;
105 
106   env = mbkgetenv( "MBK_SPI_SEPAR" );
107 
108   if( env )
109   {
110     switch( strlen( env ) )
111     {
112       case 0:
113         SPI_SEPAR = 0;
114         SPI_MERGE = 0;
115         break;
116       case 1:
117         SPI_SEPAR = *env;
118         break;
119       default :
120         fflush( stdout );
121         fprintf( stderr, "%s.\n", SPIMSG(7) );
122         EXIT(1);
123         break;
124     }
125   }
126 
127   env = mbkgetenv( "MBK_SPI_CHECK_NAME" );
128 
129   if( env )
130     SPI_CHECK_NAME = 1;
131 
132   env = mbkgetenv( "MBK_SPI_AUTO_LOAD" );
133 
134   if( env )
135     SPI_AUTO_LOAD = 1;
136 
137   /* Variables d'environnement cachees */
138 
139   /* MBK_SPI_MERGE. Si positionnee, on n'effectue pas
140    * de regroupement de locon sur les noms toto, toto.1, toto.2, toto.3...
141    */
142 
143   env = mbkgetenv( "MBK_SPI_MERGE" );
144 
145   if( env )
146     SPI_MERGE = 0;
147 
148   env = mbkgetenv( "MBK_SPI_FILE" );
149 
150   if( env )
151     SPI_FILE = 1;
152 
153   env = mbkgetenv( "MBK_SPI_VERBOSE" );
154 
155   if( env )
156     SPI_VERBOSE = 1;
157 
158   env = mbkgetenv( "MBK_SPI_ONE_NODE_NORC" );
159 
160   if( env )
161     SPI_ONE_NODE_NORC = 1;
162 
163   env = mbkgetenv( "MBK_SPI_NODE_EQUI_DRIVE" );
164 
165   if( env )
166     SPI_NODE_EQUI_DRIVE = 1;
167 
168   env = mbkgetenv( "MBK_SPI_NO_AFF_UNK" );
169 
170   if( env )
171     SPI_AFF_UNK = 0;
172 
173   if( SPI_VERBOSE )
174   {
175     printf( "Parser Spice compile le %s a %s\n", __DATE__, __TIME__ );
176     printf( "Revision     : %s\n", "$Revision: 1.7 $" );
177     printf( "Date         : %s\n", "$Date: 2012/05/14 14:20:25 $"     );
178 
179     printf( "Separateur   : '%c'\n", SPI_SEPAR  );
180     printf( "Nom de noeud : %s\n", SPI_NETNAME  );
181     printf( "Regroupement : %s\n", SPI_MERGE ? "Oui" : "Non" );
182     printf( "Noms         : %s\n", SPI_CHECK_NAME ? "Oui" : "Non" );
183     printf(
184  "Ne cree pas les vues RC sur les reseaux ne contenant qu'un seul noeud : %s\n",
185             SPI_ONE_NODE_NORC ? "Oui" : "Non"
186           );
187   }
188 
189   if( mode != 'A'  )
190   {
191     fflush( stdout );
192     fprintf( stderr, "%s\n", SPIMSG(0) );
193     fprintf( stderr, "%s : '%c'\n", SPIMSG(8), mode );
194     EXIT(1);
195   }
196 
197   spicename = (char*)mbkalloc( sizeof(char)*( strlen(name)+5 ));
198   sprintf( spicename, "%s.%s", name, IN_LO );
199 
200   msl_figname = name;
201   msl_ptfig   = NULL;
202 
203   teteinterf  = NULL;
204 
205   teteinterf = spiceloading( ptfig, spicename, mode, teteinterf );
206 
207   if( teteinterf )
208   {
209     effinterf = NULL;
210     for( scaninterf = teteinterf; scaninterf ; scaninterf = scaninterf->SUIV )
211     {
212       if( effinterf )
213       {
214 	free( effinterf->NOM );
215         for( scanchain = effinterf->GINTERF ;
216   	     scanchain ;
217   	     scanchain = scanchain->NEXT )
218           mbkfree( scanchain->DATA );
219 	freechain( effinterf->GINTERF );
220         mbkfree( effinterf );
221       }
222       effinterf = scaninterf;
223     }
224     if( effinterf )
225     {
226       free( effinterf->NOM );
227       for( scanchain = effinterf->GINTERF ;
228         scanchain ;
229   	scanchain = scanchain->NEXT )
230       mbkfree( scanchain->DATA );
231       freechain( effinterf->GINTERF );
232       mbkfree( effinterf );
233     }
234   }
235 
236   mbkfree( spicename );
237 }
238 
spifileopen(name)239 spifile*         spifileopen( name )
240 char            *name;
241 {
242   spifile       *pt;
243 
244   if( SPI_FILE )
245   {
246     fflush( stdout );
247     fprintf( stderr, "%s : %s\n", SPIMSG(53), name );
248   }
249 
250   pt          = mbkalloc( sizeof( *pt ) );
251   pt->df      = mbkfopen( name, NULL, READ_TEXT );
252   pt->decomp1 = NULL;
253   pt->decomp2 = NULL;
254   pt->filename = name;
255   pt->msl_line = -1;
256   *(pt->file_line) = '\0';
257 
258 
259   if( ! pt->df )
260   {
261     fflush( stdout );
262     fprintf( stderr, "%s\n", SPIMSG(0) );
263     fprintf( stderr, "%s %s.\n", SPIMSG(9), name );
264     EXIT(1);
265   }
266 
267   return( pt );
268 }
269 
spifileclose(pt)270 void             spifileclose( pt )
271 spifile         *pt;
272 {
273   fclose( pt->df );
274 
275   if( pt->decomp1 || pt->decomp2 )
276   {
277     fflush( stdout );
278     fprintf( stderr, "%s\n", SPIMSG(0) );
279     fprintf( stderr, "%s.\n", SPIMSG(10) );
280     EXIT(1);
281   }
282 
283   mbkfree( pt );
284 }
285 
spiceloading(ptfig,name,mode,teteinterf)286 ginterf*	spiceloading(ptfig, name, mode, teteinterf )
287 lofig_list	*ptfig;
288 char		*name;
289 char             mode;
290 ginterf         *teteinterf;
291 {
292   circuit	        *ptcir;
293   spifile               *df;
294   lofig_list	        *newfig;
295 
296   df = spifileopen( name );
297 
298 
299   while( ( ptcir = lirecircuit( df, &teteinterf ) ) )
300   {
301     constequi( ptcir, teteinterf );
302     teteinterf = constinterf( ptcir, teteinterf );
303 
304     if( SPI_VERBOSE )
305       taillevuespice( ptcir );
306 
307     if( ptfig && strcasecmp( ptcir->NOM, ptfig->NAME ) == 0 )
308     {
309       if( SPI_VERBOSE )
310         printf( "Construction figure pere.\n" );
311 
312       constlofig( ptcir, ptfig, teteinterf, mode );
313       msl_ptfig = ptfig;
314       ptfig->USER = constphinterf( ptfig->USER, teteinterf );
315     }
316     else
317     {
318       lofig_list *lf;
319       const char *name = namealloc(ptcir->NOM);
320       /* Check that a model has not yet been read, otherwise (wrongly)
321        * assumes that the models having the same name are identical.
322        * I issue a warning because this suck.
323        * I should preprend a prefix and use the prefixed name, but
324        * since it is the first and probably last time that I hack this
325        * code, I'll live with this on my conscience ;-) */
326       for (lf = HEAD_LOFIG; lf ; lf = lf->NEXT) {
327          if (lf->NAME == name) {
328             fprintf(stderr, "Warning: skipping model '%s' as it has already"
329                             " been loaded\n", name);
330             goto skip;
331          }
332       }
333 
334       /* Si la figure est vide, on ne construit pas la lofig correspondante */
335       if( ptcir->RESI  ||
336           ptcir->VALIM ||
337           ptcir->TRANS ||
338           ptcir->CAPA  ||
339           ptcir->INST
340         )
341       {
342         if( SPI_VERBOSE )
343           printf( "Construction figure fille %s.\n", ptcir->NOM );
344 
345         /* figure fille ou n'ayant rien a voir avec ptfig */
346         newfig = addlofig( ptcir->NOM );
347 
348         constlofig( ptcir, newfig, teteinterf, mode );
349         msl_ptfig = newfig;
350         newfig->USER = constphinterf( newfig->USER, teteinterf );
351       }
352       else
353 skip:   if( SPI_VERBOSE )
354           printf( "Ne construit pas la figure %s.\n", ptcir->NOM );
355     }
356 
357     if( SPI_VERBOSE )
358       printf( "Taille memoire occupee par le subckt %s : %ld\n",
359               ptcir->NOM,
360               ptcir->TAILLE
361             );
362 
363     liberecircuit( ptcir );
364   }
365 
366   spifileclose( df );
367 
368   if( cmp_handler )
369   {
370     msl_figloaded = FALSE;
371     msl_subckt    = NULL;
372     msl_line      = df->msl_line;
373     cmp_handler();
374   }
375 
376   return( teteinterf );
377 }
378 
379 /******************************************************************************/
380 
constphinterf(pt,interface)381 ptype_list*      constphinterf( pt, interface )
382 ptype_list      *pt;
383 ginterf         *interface;
384 {
385   chain_list    *tete_ph_interf;
386   chain_list    *scan;
387   char          *nomdevec;
388 
389   tete_ph_interf=NULL;
390 
391   for( scan = interface->GINTERF ; scan ; scan = scan->NEXT )
392   {
393     nomdevec = spi_devect( (char*)(scan->DATA) );
394     tete_ph_interf = addchain( tete_ph_interf, namealloc( nomdevec ) );
395     mbkfree( nomdevec );
396   }
397 
398   return( addptype( pt, PH_INTERF, reverse( tete_ph_interf )) );
399 }
400 
401 /******************************************************************************/
402 
constinterf(ptcir,teteinterf)403 ginterf*	constinterf( ptcir, teteinterf )
404 circuit		*ptcir;
405 ginterf		*teteinterf;
406 {
407   ginterf	*ninterf;
408   chain_list	*scaninterf;
409   char		**tabnom;
410   int		 i;
411   int		 nb;
412   noeud		*ptnoeud;
413   noeud		*scannoeud;
414   char		nom[80];
415 
416   ninterf = (ginterf*) mbkalloc( sizeof( ginterf ) );
417   ninterf->NOM = mbkstrdup( ptcir->NOM );
418 
419   ninterf->SUIV = teteinterf;
420 
421   /* On cree pour chaque signal de l'interface une chain_list contenant tous
422    * les noms possibles pour un signal. Pour chaque signal, le nom retenu en
423    * priorite est le premier nomm� sur l'interface */
424 
425   /* Calcul du nombre d'elements */
426   nb = 0;
427   for( scaninterf = ptcir->CINTERF ;
428        scaninterf ;
429        scaninterf = scaninterf->NEXT
430      )
431   {
432     ptnoeud = (noeud*) scaninterf->DATA;
433 
434     if( ptnoeud->SIGNAL > nb )
435       nb = ptnoeud->SIGNAL;
436   }
437 
438   /* Creation du tableau */
439   tabnom = (char**) mbkalloc( sizeof(char*) * nb );
440   for( i = 0 ; i < nb ; i++ )
441     tabnom[ i ] = NULL;
442 
443   /* Remplissage du tableau */
444   /* On regarde d'abord l'interface */
445   for( scaninterf = ptcir->CINTERF ;
446        scaninterf ;
447        scaninterf = scaninterf->NEXT
448      )
449   {
450     ptnoeud = (noeud*) scaninterf->DATA;
451     if( ptnoeud->NOM && ! tabnom[ ptnoeud->SIGNAL - 1 ] )
452     {
453       tabnom[ ptnoeud->SIGNAL - 1 ] = ptnoeud->NOM;
454     }
455   }
456   /* Puis les noeuds constituant les signaux */
457 
458   for( scaninterf = ptcir->CINTERF ;
459        scaninterf ;
460        scaninterf = scaninterf->NEXT
461      )
462   {
463     ptnoeud = (noeud*) scaninterf->DATA;
464     if( ! tabnom[ ptnoeud->SIGNAL - 1 ] )
465     {
466       for( scannoeud = ptcir->NOEUD ; scannoeud ; scannoeud = scannoeud->SUIV )
467       {
468         if( scannoeud->SIGNAL == ptnoeud->SIGNAL && scannoeud->NOM )
469         {
470           /* Il est possible que le nom de signal soit deja utilise :
471 	   * on le verifie*/
472           for( i = 0 ; i < nb ; i++ )
473             if( tabnom[ i ] == scannoeud->NOM )
474  	      break;
475 
476           if( i == nb )
477 	  {
478             tabnom[ ptnoeud->SIGNAL - 1 ] = scannoeud->NOM;
479 	    break;
480 	  }
481 	}
482       }
483     }
484   }
485 
486   /* finallement on cree un nom de connecteurs */
487   i=0;
488   for( scaninterf = ptcir->CINTERF ;
489        scaninterf ;
490        scaninterf = scaninterf->NEXT
491      )
492   {
493     ptnoeud = (noeud*) scaninterf->DATA;
494     if( tabnom[ ptnoeud->SIGNAL - 1 ] == NULL )
495     {
496       sprintf( nom, "SPICE_C_%d",i++);
497       tabnom[ ptnoeud->SIGNAL - 1 ] = spicenamealloc( ptcir, nom );
498     }
499   }
500 
501   /* On cree la chainlist de interf */
502 
503   ninterf->GINTERF = NULL;
504   for( scaninterf = ptcir->CINTERF ;
505        scaninterf ;
506        scaninterf = scaninterf->NEXT
507      )
508   {
509     ptnoeud = (noeud*) scaninterf->DATA;
510     strcpy( nom, tabnom[ ptnoeud->SIGNAL -1 ] );
511 
512     if( SPI_MERGE )
513       stopchainsepar( nom );
514 
515     ninterf->GINTERF = addchain( ninterf->GINTERF,
516                                  mbkstrdup( nom )
517                                );
518   }
519 
520   ninterf->GINTERF = reverse( ninterf->GINTERF );
521 
522   mbkfree( tabnom );
523 
524   return( ninterf );
525 }
526 
527 /******************************************************************************/
528 
lirecircuit(df,teteinterf)529 circuit*	lirecircuit( df, teteinterf )
530 spifile		*df;
531 ginterf         **teteinterf;
532 {
533   char		complet;
534   chain_list	*ligne;
535   chain_list	*elem, *elem1, *elem2;
536   float		valeur;
537   circuit	*ptcir;
538   noeud		*ptnoeud;
539   chain_list	*sc1, *sc2, *prev;
540   resi		*ptresi, *scanresi;
541   capa		*ptcapa, *scancapa;
542   trans		*pttrans, *scantrans;
543   inst		*ptinst, *scaninst;
544   valim         *ptvalim, *scanvalim;
545   int		nbelem;
546   int		status;
547   int		i;
548   int		traitecomment;
549   float         com_x,com_y;
550   ginterf      *scaninterf;
551   char          buf[1024];
552   char          tt;
553 
554   complet = 0;
555   ptcir   = NULL;
556 
557   while( !complet )
558   {
559     ligne = lireligne( df );
560     traitecomment = TRUE;
561 
562     if( !ligne ) /* fin de fichier */
563       break;
564 
565     com_x = 0.0;
566     com_y = 0.0;
567 
568     /* On r�cup�re les param�tres non standards : $X, $Y */
569     for( sc1 = ligne; sc1; sc1 = sc1->NEXT )
570     {
571       if( strcasecmp( (char*)(sc1->DATA), "$X" ) == 0 &&
572           sc1->NEXT &&
573           sc1->NEXT->NEXT
574         )
575       {
576         if( strcmp( (char*)(sc1->NEXT->DATA), "=" ) )
577           continue;
578         valeur = spicefloat( (char*)(sc1->NEXT->NEXT->DATA) ,&status );
579         if( status == -1 )
580           continue;
581         com_x = valeur;
582       }
583       else
584       if( strcasecmp( (char*)(sc1->DATA), "$Y" ) == 0 &&
585           sc1->NEXT &&
586           sc1->NEXT->NEXT
587         )
588       {
589         if( strcmp( (char*)(sc1->NEXT->DATA), "=" ) )
590           continue;
591         valeur = spicefloat( (char*)(sc1->NEXT->NEXT->DATA) ,&status );
592         if( status == -1 )
593           continue;
594         com_y = valeur;
595       }
596     }
597 
598     prev = NULL;
599 
600     for( sc1 = ligne; sc1; sc1 = sc1->NEXT )
601     {
602       if( *((char*)(sc1->DATA)) == '$' )
603         break;
604       prev = sc1;
605     }
606 
607     if( sc1 )
608     {
609       for( sc2 = sc1 ; sc2 ; sc2 = sc2->NEXT )
610         mbkfree( sc2->DATA );
611 
612       if( prev )
613         prev->NEXT = NULL;
614 
615       freechain( sc1 );
616     }
617 
618     if( ! prev )
619       ligne = NULL;
620 
621     if( !ligne )
622     {
623     }
624     else
625     if( strcasecmp( (char*)ligne->DATA, ".INCLUDE" ) == 0 )
626     {
627       if( ptcir )
628         spierror( 2, df->filename, df->msl_line );
629 
630       elem = ligne->NEXT;
631 
632       if( !elem )
633         spierror( 13, df->filename, df->msl_line );
634 
635       if( elem->NEXT )
636         spierror( 14, df->filename, df->msl_line );
637 
638       *teteinterf = traiteinclude( *teteinterf, (char*)elem->DATA );
639     }
640     else
641     if( strcasecmp( (char*)ligne->DATA, ".SUBCKT" ) == 0 )
642     {
643       if( ptcir )
644         spierror( 15, df->filename, df->msl_line );
645 
646       ptcir            = (circuit*)mbkalloc( sizeof( circuit ) );
647       ptcir->NOEUD     = NULL;
648       ptcir->TRANS     = NULL;
649       ptcir->RESI      = NULL;
650       ptcir->CAPA      = NULL;
651       ptcir->INST      = NULL;
652       ptcir->NOM       = NULL;
653       ptcir->CINTERF   = NULL;
654       ptcir->FREE      = NULL;
655       ptcir->VALIM     = NULL;
656       ptcir->INT_NOEUD = creattableint();
657       ptcir->NOM_NOEUD = creatthash( );
658       ptcir->HASHGNAME = creatthash( );
659       ptcir->HASHCAPA  = creatthash( );
660       ptcir->HASHRESI  = creatthash( );
661       ptcir->HASHVALIM = creatthash( );
662       ptcir->HASHINST  = creatthash( );
663       ptcir->HASHTRAN  = creatthash( );
664       ptcir->TAILLE    = sizeof( circuit );
665       ptcir->RESTENOM  = 0;
666 
667       elem = ligne->NEXT;
668 
669       if( !elem )
670         spierror( 16, df->filename, df->msl_line );
671 
672       ptcir->NOM = (char*)spiciralloue( ptcir,
673                            sizeof(char)*( strlen( (char*)(elem->DATA) ) + 1 )
674                                        );
675       strcpy( ptcir->NOM, (char*)( elem->DATA ) );
676 
677       /* Pour verifier qu'on a pas plusieurs fois le meme noeud, on
678        * met un 1 dans le champs RCN */
679       for( elem = elem->NEXT; elem; elem = elem->NEXT )
680       {
681         ptnoeud       = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
682 
683         if( ptnoeud->RCN )
684         {
685           fflush( stdout );
686           fprintf( stderr, "%s.\n", SPIMSG(0) );
687           fprintf( stderr, "%s : %s - %d\n", SPIMSG(6),
688                                              ptnoeud->NOM,
689                                              ptnoeud->SPICE
690                  );
691           fprintf( stderr, "%s : %s, %s : %d\n", SPIMSG(11), df->filename,
692                                                  SPIMSG(12), df->msl_line
693                  );
694           exit( 1 );
695         }
696         ptnoeud->RCN = 1;
697 
698         ptcir->CINTERF = addchain( ptcir->CINTERF, ptnoeud );
699       }
700 
701       for( sc1 = ptcir->CINTERF ; sc1 ; sc1 = sc1->NEXT )
702         ((noeud*)(sc1->DATA))->SPICE = -1;
703 
704       ptcir->CINTERF = reverse( ptcir->CINTERF );
705 
706     }
707     else
708     if( *( (char*)(ligne->DATA) ) == '*' )
709     {
710       traitecomment = FALSE;
711 
712       elem = ligne->NEXT;
713 
714       if( ptcir && elem )
715       {
716 
717         if( strcasecmp( (char*)(elem->DATA), SPI_NETNAME ) == 0 )
718         {
719 	  traitecomment = TRUE;
720           elem = elem->NEXT;
721           sc1  = elem;
722           sc2  = NULL;
723 
724           for( ; elem && strcasecmp( (char*)(elem->DATA), "=" ) != 0;
725                elem = elem->NEXT )
726           {
727             for( i=0; ((char*)(elem->DATA))[i] >= '0' &&
728                       ((char*)(elem->DATA))[i] <= '9'     ; i++ ) ;
729 
730             if( ((char*)(elem->DATA))[i] != 0 )
731               spierror( 17, df->filename, df->msl_line );
732 
733             ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
734             sc2     = addchain( sc2, ptnoeud );
735           }
736 
737           if( !elem )
738             spierror( 18, df->filename, df->msl_line );
739 
740           if( elem == sc1 )
741             spierror( 19, df->filename, df->msl_line );
742 
743           elem = elem->NEXT;	/* on passe le = */
744 
745           if( !elem )
746             spierror( 20, df->filename, df->msl_line );
747 
748           for( sc1 = sc2; sc1; sc1 = sc1->NEXT)
749             nomenoeud( ptcir, (noeud*)(sc1->DATA), (char*)(elem->DATA), df );
750           freechain(sc2);
751 
752           elem = elem->NEXT;
753           if( elem )
754             spierror( 21, df->filename, df->msl_line );
755         }
756       }
757 
758       if( ext_handler && ! traitecomment )
759       {
760         msl_figloaded = ( ptcir ? TRUE : FALSE );
761 	msl_subckt    = ( ptcir ? ptcir->NOM : NULL );
762         msl_line      = df->msl_line;
763         ext_handler( df->file_line1 );
764       }
765     }
766     else
767     if( strcasecmp( (char*)(ligne->DATA), ".ENDS" ) == 0 )
768     {
769       if( !ptcir )
770         spierror( 22, df->filename, df->msl_line );
771 
772       if( !ligne->NEXT )
773       {
774         /*spierror( 23, df->filename, df->msl_line );*/
775       }
776       else
777       {
778         if( strcasecmp( (char*)(ligne->NEXT->DATA), ptcir->NOM ) != 0 )
779           spierror( 24, df->filename, df->msl_line );
780 
781         if( ligne->NEXT->NEXT )
782           spierror( 14, df->filename, df->msl_line );
783       }
784       complet = 1;
785 
786       /* V�rification de l'existance des mod�les pour les instances */
787       if( SPI_AUTO_LOAD )
788       {
789         for( scaninst = ptcir->INST ; scaninst ; scaninst = scaninst->SUIV )
790         {
791           for( scaninterf = *teteinterf ;
792                scaninterf ;
793                scaninterf = scaninterf->SUIV
794              )
795           {
796             if( strcasecmp( scaninterf->NOM, scaninst->MODELE )==0 )
797               break;
798           }
799 
800           if( !scaninterf )
801           {
802             sprintf( buf,"%s.%s", scaninst->MODELE, IN_LO );
803             *teteinterf = traiteinclude( *teteinterf, buf );
804           }
805         }
806       }
807     }
808     else
809     if( ( *((char*)ligne->DATA)=='M' || *((char*)ligne->DATA)=='m' ) && ptcir )
810     {
811       pttrans        = (trans*) spiciralloue( ptcir, sizeof( trans ) );
812       pttrans->L     = 0.0;
813       pttrans->W     = 0.0;
814       pttrans->AS    = 0.0;
815       pttrans->AD    = 0.0;
816       pttrans->PS    = 0.0;
817       pttrans->PD    = 0.0;
818 
819       if( *( (char*)( ligne->DATA ) + 1 ) == 0 )
820         spierror( 25, df->filename, df->msl_line );
821 
822       pttrans->NOM = spicenamealloc( ptcir, (char*)(ligne->DATA) + 1  );
823 
824       scantrans = getthashelem( pttrans->NOM, ptcir->HASHTRAN, NULL );
825 
826       if( scantrans )
827       {
828         if( SPI_CHECK_NAME )
829           spierror( 26, df->filename, df->msl_line );
830       }
831       else
832         addthashelem( pttrans->NOM, pttrans, ptcir->HASHTRAN );
833 
834       pttrans->SUIV  = ptcir->TRANS;
835       ptcir->TRANS   = pttrans;
836 
837       elem = ligne->NEXT;	/* drain */
838 
839       if( !elem )
840         spierror( 27, df->filename, df->msl_line );
841 
842       ptnoeud        = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
843       pttrans->DRAIN = ptnoeud;
844 
845       elem = elem->NEXT;	/* grille */
846 
847       if( !elem )
848         spierror( 28, df->filename, df->msl_line );
849 
850       ptnoeud         = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
851       pttrans->GRILLE = ptnoeud;
852 
853       elem = elem->NEXT;	/* source */
854 
855       if( !elem )
856         spierror( 29, df->filename, df->msl_line );
857 
858       ptnoeud         = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
859       pttrans->SOURCE = ptnoeud;
860 
861       elem = elem->NEXT;	/* bulk ou type du transistor */
862 
863       if( !elem )
864         spierror( 30, df->filename, df->msl_line );
865 
866       tt = spitranstype( (char*)(elem->DATA) );
867       if( tt != SPI_UNK_TRANS_TYPE )
868       {
869         pttrans->TYPE = tt;
870         pttrans->SUBST  = NULL;
871       }
872       else
873       {
874         ptnoeud         = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
875         pttrans->SUBST  = ptnoeud;
876 
877         elem = elem->NEXT;	/* type du transistor */
878 
879         if( !elem )
880           spierror( 31, df->filename, df->msl_line );
881 
882         tt = spitranstype( (char*)(elem->DATA) );
883         if( tt != SPI_UNK_TRANS_TYPE )
884           pttrans->TYPE = tt;
885         else
886           spierror( 32, df->filename, df->msl_line );
887       }
888 
889       /* Le reste des parametres est de la forme xxx = yyy */
890 
891       while( (elem = elem->NEXT ) )
892       {
893         elem1 = elem->NEXT;
894         elem2 = ( elem1 ? elem1->NEXT : NULL );
895 
896         if( !elem2 )
897           spierror( 33, df->filename, df->msl_line );
898 
899         if( strcmp( (char*)(elem1->DATA), "=" ) )
900           spierror( 33, df->filename, df->msl_line );
901 
902         valeur = spicefloat( (char*)(elem2->DATA) ,&status );
903         if( status == -1 )
904           spierror( 34, df->filename, df->msl_line );
905 
906         if( strcasecmp( (char*)(elem->DATA), "L" ) == 0 )
907           pttrans->L  = valeur;
908         else
909         if( strcasecmp( (char*)(elem->DATA), "W" ) == 0 )
910           pttrans->W  = valeur;
911         else
912         if( strcasecmp( (char*)(elem->DATA), "AS" ) == 0 )
913           pttrans->AS = valeur;
914         else
915         if( strcasecmp( (char*)(elem->DATA), "AD" ) == 0 )
916           pttrans->AD = valeur;
917         else
918         if( strcasecmp( (char*)(elem->DATA), "PS" ) == 0 )
919           pttrans->PS = valeur;
920         else
921         if( strcasecmp( (char*)(elem->DATA), "PD" ) == 0 )
922           pttrans->PD = valeur;
923         else
924         {
925           fflush( stdout );
926           fprintf( stderr, "%s.\n", SPIMSG(0) );
927           fprintf( stderr, "%s. %s %s. %s %d.\n",
928                    SPIMSG(1),
929                    SPIMSG(11),
930                    df->filename,
931                    SPIMSG(12),
932                    df->msl_line
933                  );
934           fprintf( stderr, "%s : %s.\n", SPIMSG(35), (char*)(elem->DATA) );
935           EXIT(1);
936         }
937         elem = elem->NEXT->NEXT;
938       }
939       pttrans->X = com_x;
940       pttrans->Y = com_y;
941     }
942     else
943     if( ( *((char*)ligne->DATA)=='R' || *((char*)ligne->DATA)=='r' ) && ptcir )
944     {
945       ptresi       = (resi*) spiciralloue( ptcir, sizeof(resi) );
946 
947       if( *( (char*)( ligne->DATA ) +1 ) == 0 )
948         spierror( 36, df->filename, df->msl_line );
949 
950       ptresi->NOM = spicenamealloc( ptcir, (char*)(ligne->DATA) + 1  );
951 
952       scanresi = getthashelem( ptresi->NOM, ptcir->HASHRESI, NULL );
953 
954       if( scanresi )
955       {
956         if( SPI_CHECK_NAME )
957           spierror( 37, df->filename, df->msl_line );
958       }
959       else
960         addthashelem( ptresi->NOM, ptresi, ptcir->HASHRESI );
961 
962       ptresi->SUIV = ptcir->RESI;
963       ptcir->RESI  = ptresi;
964 
965       elem = ligne->NEXT;	/* first node */
966 
967       if( !elem )
968         spierror( 13, df->filename, df->msl_line );
969 
970       ptnoeud        = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
971       ptresi->N1     = ptnoeud;
972 
973       elem = elem->NEXT;	/* second node */
974 
975       if( !elem )
976         spierror( 13, df->filename, df->msl_line );
977 
978       ptnoeud        = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
979       ptresi->N2     = ptnoeud;
980 
981       elem = elem->NEXT;	/* R value */
982       if( !elem )
983         spierror( 13, df->filename, df->msl_line );
984 
985       valeur = spicefloat( (char*)(elem->DATA) ,&status );
986       if( status == -1 )
987         spierror( 34, df->filename, df->msl_line );
988 
989       ptresi->RESI = valeur;
990 
991       elem = elem->NEXT;	/* no more parameters */
992       if( elem )
993         spierror( 14, df->filename, df->msl_line );
994     }
995     else
996     if( ( *((char*)ligne->DATA)=='C' || *((char*)ligne->DATA)=='c' ) && ptcir )
997     {
998       ptcapa     = (capa*) spiciralloue( ptcir, sizeof(capa) );
999 
1000       if( *( (char*)( ligne->DATA ) +1 ) == 0 )
1001         spierror( 38, df->filename, df->msl_line );
1002 
1003       ptcapa->NOM = spicenamealloc( ptcir, (char*)(ligne->DATA) + 1  );
1004 
1005       scancapa = getthashelem( ptcapa->NOM, ptcir->HASHCAPA, NULL );
1006       if( scancapa )
1007       {
1008         if( SPI_CHECK_NAME )
1009           spierror( 39, df->filename, df->msl_line );
1010       }
1011       else
1012         addthashelem( ptcapa->NOM, ptcapa, ptcir->HASHCAPA);
1013 
1014 
1015       ptcapa->SUIV = ptcir->CAPA;
1016       ptcir->CAPA  = ptcapa;
1017 
1018       elem = ligne->NEXT;	/* first node */
1019 
1020       if( !elem )
1021         spierror( 13, df->filename, df->msl_line );
1022 
1023       ptnoeud        = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
1024       ptcapa->N1     = ptnoeud;
1025 
1026       elem = elem->NEXT;	/* second node */
1027 
1028       if( !elem )
1029         spierror( 13, df->filename, df->msl_line );
1030 
1031       ptnoeud        = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
1032       ptcapa->N2     = ptnoeud;
1033 
1034       elem = elem->NEXT;	/* C value */
1035       if( !elem )
1036         spierror( 13, df->filename, df->msl_line );
1037 
1038       valeur = spicefloat( (char*)(elem->DATA) ,&status );
1039 
1040       if( status == -1 )
1041         spierror( 34, df->filename, df->msl_line );
1042 
1043       /* Les valeurs dans Alliance sont en pif */
1044       ptcapa->CAPA = valeur * 1e12 ;
1045 
1046       elem = elem->NEXT;	/* no more parameters */
1047 
1048       if( elem )
1049         spierror( 14, df->filename, df->msl_line );
1050     }
1051     else
1052     if( ( *((char*)ligne->DATA)=='V' || *((char*)ligne->DATA)=='v' ) && ptcir )
1053     {
1054       ptvalim       = (valim*) spiciralloue( ptcir, sizeof(valim) );
1055 
1056       if( *( (char*)( ligne->DATA ) +1 ) == 0 )
1057         spierror( 36, df->filename, df->msl_line );
1058 
1059       ptvalim->NOM = spicenamealloc( ptcir, (char*)(ligne->DATA) + 1  );
1060 
1061       scanvalim = getthashelem( ptvalim->NOM, ptcir->HASHVALIM, NULL );
1062 
1063       if( scanvalim )
1064       {
1065         if( SPI_CHECK_NAME )
1066           spierror( 37, df->filename, df->msl_line );
1067       }
1068       else
1069         addthashelem( ptvalim->NOM, ptvalim, ptcir->HASHVALIM );
1070 
1071       ptvalim->SUIV = ptcir->VALIM;
1072       ptcir->VALIM  = ptvalim;
1073 
1074       elem = ligne->NEXT;	/* first node */
1075 
1076       if( !elem )
1077         spierror( 13, df->filename, df->msl_line );
1078 
1079       ptnoeud        = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
1080       ptvalim->N1     = ptnoeud;
1081 
1082       elem = elem->NEXT;	/* second node */
1083 
1084       if( !elem )
1085         spierror( 13, df->filename, df->msl_line );
1086 
1087       ptnoeud        = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
1088       ptvalim->N2     = ptnoeud;
1089 
1090       elem = elem->NEXT;	/* R value */
1091       if( !elem )
1092         spierror( 13, df->filename, df->msl_line );
1093 
1094       valeur = spicefloat( (char*)(elem->DATA) ,&status );
1095       if( status == -1 )
1096         spierror( 34, df->filename, df->msl_line );
1097 
1098       ptvalim->TENSION = valeur;
1099 
1100       elem = elem->NEXT;	/* no more parameters */
1101       if( elem )
1102         spierror( 14, df->filename, df->msl_line );
1103     }
1104     else
1105     if( ( *(char*)(ligne->DATA) == 'X' || *(char*)(ligne->DATA) == 'x' ) &&
1106         ptcir                                                               )
1107     {
1108       ptinst          = (inst*)spiciralloue( ptcir, sizeof(inst) );
1109       ptinst->IINTERF = NULL;
1110 
1111       if( *( ((char*)(ligne->DATA)) + 1) == 0 )
1112         spierror( 40, df->filename, df->msl_line );
1113 
1114       ptinst->NOM = spicenamealloc( ptcir, ((char*)(ligne->DATA)) + 1 );
1115 
1116 
1117       scaninst = getthashelem( ptinst->NOM, ptcir->HASHINST, NULL );
1118       if( scaninst )
1119         spierror( 41, df->filename, df->msl_line );
1120 
1121       ptinst->SUIV   = ptcir->INST;
1122       ptcir->INST    = ptinst;
1123       addthashelem( ptinst->NOM, ptinst, ptcir->HASHINST );
1124 
1125       for( nbelem=0, elem = ligne->NEXT ; elem ; elem = elem->NEXT, nbelem++ );
1126 
1127       if( nbelem <= 1 )
1128         spierror( 13, df->filename, df->msl_line );
1129 
1130       for( elem = ligne->NEXT; elem->NEXT; elem = elem->NEXT )
1131       {
1132         ptnoeud         = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
1133         ptinst->IINTERF = addchain( ptinst->IINTERF, ptnoeud );
1134       }
1135       ptinst->IINTERF = reverse( ptinst->IINTERF );
1136 
1137       ptinst->MODELE = spicenamealloc( ptcir, (char*)elem->DATA );
1138     }
1139     else
1140     {
1141       if( SPI_AFF_UNK )
1142       {
1143         fflush( stdout );
1144         fprintf( stderr, "%s\n", SPIMSG(0) );
1145         fprintf( stderr, "%s. %s %s. %s %d :\n",
1146                  SPIMSG(42),
1147                  SPIMSG(11),
1148                  df->filename,
1149                  SPIMSG(12),
1150                  df->msl_line
1151                );
1152         fprintf( stderr, "%s\n", (char*)ligne->DATA );
1153       }
1154     }
1155 
1156     if( ligne )
1157     {
1158       for( sc1 = ligne; sc1; sc1 = sc1->NEXT )
1159         mbkfree( sc1->DATA );
1160 
1161       freechain( ligne );
1162     }
1163   }
1164 
1165 
1166   return( ptcir );
1167 }
1168 
1169 /******************************************************************************/
1170 
traiteinclude(instance,nom)1171 ginterf*	traiteinclude( instance, nom )
1172 ginterf		*instance;
1173 char            *nom;
1174 {
1175   ginterf	*sci;
1176   ginterf	*nouvinterf;
1177 
1178   for( sci = instance ; sci ; sci = sci->SUIV )
1179   {
1180     if( strcasecmp( sci->NOM, nom ) == 0 )
1181     {
1182       fflush( stdout );
1183       fprintf( stderr, "%s\n", SPIMSG(0) );
1184       fprintf( stderr, "%s : %s.\n", SPIMSG(41), nom );
1185       EXIT( 1 );
1186     }
1187   }
1188 
1189   nouvinterf = spiceloading( NULL, nom, 'A', instance );
1190 
1191   return( nouvinterf );
1192 }
1193 
1194 /******************************************************************************/
1195 
loconinterf(ptfig,tete)1196 void            loconinterf( ptfig, tete )
1197 lofig_list      *ptfig;
1198 chain_list      *tete;
1199 {
1200   chain_list    *sc1;
1201   chain_list    *sc2;
1202   char          *nomdevec;
1203   /*int           sigidx;
1204   losig_list    *ptsig;
1205 
1206   sigidx = 0;*/
1207 
1208   for( sc1 = tete ; sc1 ; sc1 = sc1->NEXT )
1209   {
1210     for( sc2 = tete; sc2 != sc1 ; sc2 = sc2->NEXT )
1211       if( strcasecmp( sc1->DATA, sc2->DATA ) == 0 )
1212         break;
1213     if( sc1 == sc2 )
1214     {
1215       /*
1216       sigidx++;
1217       ptsig = addlosig( ptfig, sigidx, NULL, 'E' );
1218       */
1219       nomdevec = spi_devect( (char*)(sc1->DATA) );
1220       addlocon( ptfig, namealloc(nomdevec), /*ptsig*/ NULL, 'X' );
1221       mbkfree( nomdevec );
1222     }
1223   }
1224 
1225   ptfig->LOCON = (locon_list*)reverse( (chain_list*)ptfig->LOCON );
1226 }
1227 
1228 /******************************************************************************/
1229 
constequi(ptcir,instances)1230 void		constequi( ptcir, instances )
1231 circuit		*ptcir;
1232 ginterf		*instances;
1233 {
1234   inst		*scaninst;
1235   chain_list	*sc1, *sc2, *sc3, *sc4, *sc5 ;
1236   ptype_list	*pt, *pt2;
1237   int		idsig = 0 ; /* Warning a la compil */
1238   int		signal;
1239   ptype_list	*headsig;
1240   int		nb;
1241   int		t;
1242   ptype_list	*spt;
1243   noeud		*scannoeud;
1244   resi		*scanresi;
1245   valim		*scanvalim;
1246   ginterf	*sci;
1247   char		*vdd;
1248   char		*vss;
1249   int		vuevss;
1250   int		vuevdd;
1251   int		cirvss;
1252   int		cirvdd;
1253   chain_list    *scanchain;
1254   noeud         *node1;
1255   noeud         *node2;
1256 
1257   signal  = 1;
1258   headsig = NULL;
1259 
1260   /*	traite les instances						*/
1261 
1262   for( scaninst = ptcir->INST; scaninst; scaninst = scaninst->SUIV )
1263   {
1264     for( sci = instances; sci; sci = sci->SUIV )
1265     {
1266       if( strcasecmp( sci->NOM, scaninst->MODELE ) == 0 )
1267         break;
1268     }
1269 
1270     if( !sci )
1271     {
1272       fflush( stdout );
1273       fprintf( stderr, "%s\n", SPIMSG(0) );
1274       fprintf( stderr, "%s %s.\n", SPIMSG( 43 ), scaninst->MODELE );
1275       EXIT(1);
1276     }
1277 
1278     for( sc1 = sci->GINTERF, sc2 = scaninst->IINTERF ;
1279          sc1 && sc2 ;
1280          sc1 = sc1->NEXT, sc2 = sc2->NEXT )
1281     {
1282       /* On verifie qu'on a une nouvelle equipotentielle */
1283 
1284       for( sc3 = sci->GINTERF ; sc3 != sc1 ; sc3 = sc3->NEXT )
1285         if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 )
1286           break;
1287       if( sc3 != sc1 )
1288         continue;
1289 
1290       nb = 0;	/* nombre d'equipotentielle deja existant sur l'interface */
1291 
1292       for( sc3 = sc1, sc4 = sc2 ; sc3 && sc4 ; sc3 = sc3->NEXT, sc4 = sc4->NEXT)
1293         if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 &&
1294             ( (noeud*)( sc4->DATA ) )->SIGNAL != 0        )
1295         {
1296           nb ++;
1297           idsig = ( (noeud*)( sc4->DATA ) )->SIGNAL;
1298         }
1299 
1300       switch( nb )
1301       {
1302         case 0 :	/* creation d'une nouvelle equi */
1303 
1304         headsig = addptype( headsig, signal, NULL );
1305 
1306 	for( sc3 = sc1, sc4 = sc2 ;
1307 	     sc3 && sc4 ;
1308 	     sc3 = sc3->NEXT, sc4 = sc4->NEXT)
1309 	  if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 )
1310 	  {
1311             ((noeud*)(sc4->DATA))->SIGNAL = signal;
1312             headsig->DATA = addchain( headsig->DATA, sc4->DATA );
1313           }
1314 
1315           signal++;
1316 
1317           break;
1318 
1319 	case 1:         /* On reutilise l'equi existante */
1320 
1321         pt = getptype( headsig, idsig );
1322 
1323 	for( sc3 = sc1, sc4 = sc2 ;
1324 	     sc3 && sc4 ;
1325 	     sc3 = sc3->NEXT, sc4 = sc4->NEXT)
1326 	  if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 )
1327 	  {
1328             if( ! ((noeud*)(sc4->DATA))->SIGNAL )
1329 	    {
1330 	      ((noeud*)( sc4->DATA ))->SIGNAL = idsig;
1331 	      pt->DATA = addchain( pt->DATA, sc4->DATA );
1332 	    }
1333           }
1334 
1335 	break;
1336 
1337 	default :       /* Il y a plus de deux equi existante : il faut
1338 			   les regrouper en une seule */
1339         pt = getptype( headsig, idsig );
1340 
1341 	for( sc3 = sc1, sc4 = sc2 ;
1342 	     sc3 && sc4 ;
1343 	     sc3 = sc3->NEXT, sc4 = sc4->NEXT)
1344 	  if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 )
1345 	  {
1346 	    /* Pas de signal sur le noeud sc4 */
1347             if( ! ( (noeud*)( sc4->DATA ) )->SIGNAL )
1348 	    {
1349 	      ((noeud*)( sc4->DATA ))->SIGNAL = idsig;
1350 	      pt->DATA = addchain( pt->DATA, sc4->DATA );
1351 	    }
1352 	    else
1353 	    /* Si on se trouve sur un autre signal */
1354             if( ( (noeud*)( sc4->DATA ) )->SIGNAL != idsig )
1355 	    {
1356 	      /* t : index signal source */
1357 	      t   = ( (noeud*)( sc4->DATA ) )->SIGNAL;
1358 	      pt2 = getptype( headsig, t );
1359 
1360 	      /* on change ne numero de signal de tous les noeuds du signal
1361 	       * source */
1362 	      for( sc5 = pt2->DATA ; sc5 ; sc5 = sc5->NEXT )
1363 	        ( (noeud*)( sc5->DATA ) )->SIGNAL = idsig;
1364 
1365 	      /* on ajoute la chain_list source a la fin de la chain_list
1366 	       * destination */
1367 	      for( sc5 = (chain_list*)( pt->DATA ) ;
1368 		   sc5->NEXT ;
1369 		   sc5 = sc5->NEXT );
1370 	      sc5->NEXT = (chain_list*)pt2->DATA;
1371 
1372 	      /* On libere le signal source */
1373               headsig = delptype( headsig, t );
1374 
1375 	    }
1376 	    /* Cas o� on est sur le meme signal : on ne fait rien */
1377 	  }
1378 
1379 	break;
1380       }
1381     }
1382 
1383     if( sc1 || sc2 )
1384     {
1385       fflush( stdout );
1386       fprintf( stderr, "%s\n", SPIMSG(0) );
1387       fprintf( stderr, "%s :\n%s %s. %s %s. %s %s.\n", SPIMSG( 44 ),
1388                                                        SPIMSG( 54 ),
1389                                                        ptcir->NOM,
1390                                                        SPIMSG( 55 ),
1391                                                        scaninst->NOM,
1392                                                        SPIMSG( 56 ),
1393                                                        scaninst->MODELE
1394              );
1395       EXIT(1);
1396     }
1397   }
1398 
1399   /*	traite les resistances : Ca peut s'ameliorer pour aller + vite	*/
1400 
1401   for( scanresi = ptcir->RESI ; scanresi ; scanresi = scanresi->SUIV )
1402   {
1403     if( scanresi->N1->SIGNAL == 0 && scanresi->N2->SIGNAL == 0 )
1404     {
1405       headsig = addptype( headsig, signal, NULL );
1406       scanresi->N1->SIGNAL = signal;
1407       scanresi->N2->SIGNAL = signal;
1408       headsig->DATA = addchain( headsig->DATA, scanresi->N1 );
1409       headsig->DATA = addchain( headsig->DATA, scanresi->N2 );
1410       signal++;
1411     }
1412     else
1413     if( scanresi->N1->SIGNAL != 0 && scanresi->N2->SIGNAL == 0 )
1414     {
1415       pt = getptype( headsig, scanresi->N1->SIGNAL );
1416       pt->DATA = addchain( pt->DATA, scanresi->N2 );
1417       scanresi->N2->SIGNAL = pt->TYPE;
1418     }
1419     else
1420     if( scanresi->N1->SIGNAL == 0 && scanresi->N2->SIGNAL != 0 )
1421     {
1422       pt = getptype( headsig, scanresi->N2->SIGNAL );
1423       pt->DATA = addchain( pt->DATA, scanresi->N1 );
1424       scanresi->N1->SIGNAL = pt->TYPE;
1425     }
1426     else
1427     if( scanresi->N1->SIGNAL != scanresi->N2->SIGNAL )
1428     {
1429       pt  = getptype( headsig, scanresi->N1->SIGNAL );
1430       pt2 = getptype( headsig, scanresi->N2->SIGNAL );
1431 
1432       for( sc1 = pt2->DATA ; sc1 ; sc1 = sc1->NEXT )
1433         ((noeud*)(sc1->DATA))->SIGNAL = pt->TYPE;
1434       for( sc1 = pt->DATA ; sc1->NEXT ; sc1 = sc1->NEXT ) ;
1435       sc1->NEXT = pt2->DATA;
1436       headsig = delptype( headsig, pt2->TYPE );
1437     }
1438   }
1439 
1440   for( scanvalim = ptcir->VALIM ; scanvalim ; scanvalim = scanvalim->SUIV )
1441   {
1442     if( scanvalim->N1->SIGNAL == 0 && scanvalim->N2->SIGNAL == 0 )
1443     {
1444       headsig = addptype( headsig, signal, NULL );
1445       scanvalim->N1->SIGNAL = signal;
1446       scanvalim->N2->SIGNAL = signal;
1447       headsig->DATA = addchain( headsig->DATA, scanvalim->N1 );
1448       headsig->DATA = addchain( headsig->DATA, scanvalim->N2 );
1449       signal++;
1450     }
1451     else
1452     if( scanvalim->N1->SIGNAL != 0 && scanvalim->N2->SIGNAL == 0 )
1453     {
1454       pt = getptype( headsig, scanvalim->N1->SIGNAL );
1455       pt->DATA = addchain( pt->DATA, scanvalim->N2 );
1456       scanvalim->N2->SIGNAL = pt->TYPE;
1457     }
1458     else
1459     if( scanvalim->N1->SIGNAL == 0 && scanvalim->N2->SIGNAL != 0 )
1460     {
1461       pt = getptype( headsig, scanvalim->N2->SIGNAL );
1462       pt->DATA = addchain( pt->DATA, scanvalim->N1 );
1463       scanvalim->N1->SIGNAL = pt->TYPE;
1464     }
1465     else
1466     if( scanvalim->N1->SIGNAL != scanvalim->N2->SIGNAL )
1467     {
1468       pt  = getptype( headsig, scanvalim->N1->SIGNAL );
1469       pt2 = getptype( headsig, scanvalim->N2->SIGNAL );
1470 
1471       for( sc1 = pt2->DATA ; sc1 ; sc1 = sc1->NEXT )
1472         ((noeud*)(sc1->DATA))->SIGNAL = pt->TYPE;
1473       for( sc1 = pt->DATA ; sc1->NEXT ; sc1 = sc1->NEXT ) ;
1474       sc1->NEXT = pt2->DATA;
1475       headsig = delptype( headsig, pt2->TYPE );
1476     }
1477   }
1478 
1479   if( SPI_MERGE == 1 )
1480   {
1481     for( sc1 = ptcir->CINTERF ; sc1 ; sc1 = sc1->NEXT )
1482     {
1483       node1 = ( noeud* )( sc1->DATA );
1484 
1485       for( sc2 = ptcir->CINTERF ; sc2 != sc1 ; sc2 = sc2->NEXT )
1486       {
1487         node2 = ( noeud* )( sc2->DATA );
1488         if( nodenameisequi( node1->NOM, node2->NOM ) )
1489           break;
1490       }
1491 
1492       if( sc1 != sc2 )
1493         continue;
1494 
1495       for( sc2 = sc1->NEXT ; sc2 ; sc2 = sc2->NEXT )
1496       {
1497         node2 = ( noeud* )( sc2->DATA );
1498 
1499         if( nodenameisequi( node1->NOM, node2->NOM ) )
1500         {
1501           if( node1->SIGNAL == 0 && node2->SIGNAL == 0 )
1502           {
1503             headsig = addptype( headsig, signal, NULL );
1504             node1->SIGNAL = signal;
1505             node2->SIGNAL = signal;
1506             headsig->DATA = addchain( headsig->DATA, node1 );
1507             headsig->DATA = addchain( headsig->DATA, node2 );
1508             signal++;
1509           }
1510           else
1511           if( node1->SIGNAL != 0 && node2->SIGNAL == 0 )
1512           {
1513             pt = getptype( headsig, node1->SIGNAL );
1514             pt->DATA = addchain( pt->DATA, node2 );
1515             node2->SIGNAL = node1->SIGNAL;
1516           }
1517           else
1518           if( node1->SIGNAL == 0 && node2->SIGNAL != 0 )
1519           {
1520             pt = getptype( headsig, node2->SIGNAL );
1521             pt->DATA = addchain( pt->DATA, node1 );
1522             node1->SIGNAL = node2->SIGNAL;
1523           }
1524           else
1525           if( node1->SIGNAL != node2->SIGNAL )
1526           {
1527             pt  = getptype( headsig, node1->SIGNAL );
1528             pt2 = getptype( headsig, node2->SIGNAL );
1529 
1530             for( sc3 = pt2->DATA ; sc3 ; sc3 = sc3->NEXT )
1531               ((noeud*)(sc3->DATA))->SIGNAL = node1->SIGNAL;
1532             for( sc3 = pt->DATA ; sc3->NEXT ; sc3 = sc3->NEXT ) ;
1533             sc3->NEXT = pt2->DATA;
1534             headsig = delptype( headsig, pt2->TYPE );
1535           }
1536           else
1537           {
1538             /* rien a faire : node1->SIGNAL == node2->SIGNAL */
1539           }
1540         }
1541       }
1542     }
1543   }
1544 
1545   /*	On s'occupe des noeuds libres					*/
1546 
1547   for( scannoeud = ptcir->NOEUD; scannoeud; scannoeud = scannoeud->SUIV )
1548   {
1549     if( scannoeud->SIGNAL == 0 )
1550     {
1551       headsig = addptype( headsig, signal, addchain( NULL, scannoeud ) );
1552       scannoeud->SIGNAL = signal++;
1553 
1554     }
1555   }
1556 
1557   /*	Remplie le champ RCN de chaque noeud				*/
1558 
1559   for( spt = headsig ; spt ; spt = spt->NEXT )
1560   {
1561     sc1 = (chain_list*)(spt->DATA);
1562 
1563     if( sc1->NEXT || SPI_ONE_NODE_NORC == 0 )
1564     {
1565       nb = 1;
1566       for( ; sc1 ; sc1 = sc1->NEXT )
1567         ((noeud*)(sc1->DATA))->RCN = nb++ ;
1568     }
1569     else
1570     {
1571       ((noeud*)(sc1->DATA))->RCN = 0;
1572     }
1573   }
1574 
1575   /*	Tous les noeuds d'un signal VSS ou VDD ont le nom VSS ou VDD	*/
1576 
1577   vss    = spicenamealloc( ptcir, VSS );
1578   vdd    = spicenamealloc( ptcir, VDD );
1579   cirvss = 0;
1580   cirvdd = 0;
1581 
1582   for( spt = headsig ; spt ; spt = spt->NEXT )
1583   {
1584     vuevss = vuevdd = 0;
1585 
1586     for( sc1 = spt->DATA ; sc1 ; sc1 = sc1->NEXT )
1587     {
1588       if( ( ( noeud* )( sc1->DATA ) )->NOM == vss )
1589         vuevss = 1;
1590 
1591       if( ( ( noeud* )( sc1->DATA ) )->NOM == vdd )
1592         vuevdd = 1;
1593     }
1594 
1595     if( vuevss && vuevdd )
1596     {
1597       fflush( stdout );
1598       fprintf( stderr, "%s\n", SPIMSG(0) );
1599       fprintf( stderr, "%s : %s\n", SPIMSG(45), ptcir->NOM );
1600       EXIT( 1 );
1601     }
1602 
1603     if( vuevss && cirvss )
1604     {
1605       fflush( stdout );
1606       fprintf( stderr, "%s\n", SPIMSG(0) );
1607       fprintf( stderr, "%s : %s\n", SPIMSG(46), ptcir->NOM );
1608       EXIT( 1 );
1609     }
1610 
1611     if( vuevss )
1612     {
1613       for( sc1 = spt->DATA ; sc1 ; sc1 = sc1->NEXT )
1614          ( ( noeud* )( sc1->DATA ) )->NOM = vss;
1615       cirvss = 1;
1616     }
1617 
1618     if( vuevdd && cirvdd )
1619     {
1620       fflush( stdout );
1621       fprintf( stderr, "%s\n", SPIMSG(0) );
1622       fprintf( stderr, "%s : %s\n", SPIMSG(47), ptcir->NOM );
1623       EXIT( 1 );
1624     }
1625 
1626     if( vuevdd )
1627     {
1628       for( sc1 = spt->DATA ; sc1 ; sc1 = sc1->NEXT )
1629          ( ( noeud* )( sc1->DATA ) )->NOM = vdd;
1630       cirvdd = 1;
1631     }
1632   }
1633 
1634   /*
1635   if( !cirvss || !cirvdd )
1636   {
1637     fflush( stdout );
1638     fprintf( stderr,
1639              "*** mbkspi error *** : No vdd or vss nodes in %s\n",
1640              ptcir->NOM
1641 	   );
1642     EXIT( 1 );
1643   }
1644   */
1645 
1646   /* On renumerote les signaux en partant de 1, c'est plus propre.      */
1647   idsig = 1;
1648   for(spt = headsig ; spt ; spt = spt->NEXT )
1649   {
1650     if( spt->DATA )
1651     {
1652       for( scanchain = (chain_list*)(spt->DATA) ;
1653            scanchain ;
1654            scanchain = scanchain->NEXT
1655          )
1656       {
1657         scannoeud = (noeud*)(scanchain->DATA);
1658         scannoeud->SIGNAL = idsig;
1659       }
1660       idsig++;
1661     }
1662   }
1663 
1664   if( SPI_NODE_EQUI_DRIVE )
1665     spi_dump_equi( ptcir->NOM, headsig );
1666 
1667   /*	libere la liste des noeuds par signal				*/
1668 
1669   for(spt = headsig; spt; spt = spt->NEXT )
1670     if( spt->DATA )
1671       freechain( (chain_list*)(spt->DATA) );
1672   freeptype( headsig );
1673 
1674 }
1675 
1676 /******************************************************************************/
spi_dump_equi(char * figname,ptype_list * headsig)1677 void spi_dump_equi( char *figname, ptype_list *headsig )
1678 {
1679   ptype_list *spt;
1680   chain_list *scan;
1681   FILE       *ptf;
1682   noeud      *node;
1683 
1684   ptf = mbkfopen( figname, "equi", WRITE_TEXT );
1685   if( !ptf )
1686     return;
1687 
1688   for( spt = headsig ; spt ; spt = spt->NEXT )
1689   {
1690     if( spt->DATA )
1691     {
1692       scan = (chain_list*)spt->DATA ;
1693       fprintf( ptf, "Signal %d.\n", ((noeud*)(scan->DATA))->SIGNAL );
1694       for( ; scan ; scan = scan->NEXT )
1695       {
1696         node = ((noeud*)scan->DATA );
1697         fprintf( ptf,
1698                  "  %5d %5d %s\n",
1699                  node->SPICE,
1700                  node->RCN,
1701                  node->NOM ? node->NOM : "-"
1702                );
1703       }
1704     }
1705   }
1706   fclose( ptf );
1707 }
1708 
1709 /******************************************************************************/
1710 
nodenameisequi(name1,name2)1711 int             nodenameisequi( name1, name2 )
1712 /* Renvoie 1 si les deux noms sont sur la meme equipotentielle */
1713 char            *name1;
1714 char            *name2;
1715 {
1716   int           end1;
1717   int           end2;
1718   int           end1x;
1719   int           end2x;
1720 
1721   if( name1 == NULL || name2 == NULL )
1722     return(0);
1723 
1724   /*modif karim pour passer les fichier ck1 ck1.1 ck1.2*/
1725   /*end1 = strlen( name1 ) - 1 ;*/
1726   end1x = end1 = strlen( name1 ) - 1 ;
1727 
1728   /* on passe les chiffres */
1729 
1730   while( end1 > 0 && isdigit( (int)name1[ end1 ] ) )
1731     end1--;
1732 
1733   /* on passe le '.' */
1734 
1735   /*modif karim pour passer les fichier ck1 ck1.1 ck1.2*/
1736   if( name1[ end1 ] == SPI_SEPAR )
1737     end1--;
1738   else
1739     end1 = end1x ;
1740 
1741   /*modif karim pour passer les fichier ck1 ck1.1 ck1.2*/
1742   /*end2 = strlen( name2 ) - 1 ;*/
1743   end2x = end2 = strlen( name2 ) - 1 ;
1744 
1745   /* on passe les chiffres */
1746 
1747   while( end2 > 0 && isdigit( (int)name2[ end2 ] ) )
1748     end2--;
1749 
1750   /* on passe le '.' */
1751 
1752   /*modif karim pour passer les fichier ck1 ck1.1 ck1.2*/
1753   if( name2[ end2 ] == SPI_SEPAR )
1754     end2--;
1755   else
1756     end2 = end2x ;
1757 
1758   end1++;
1759   end2++;
1760 
1761   if( end1 == end2 )
1762     if( strncmp( name1, name2, end1 ) == 0 )
1763       return( 1 );
1764 
1765   return( 0 );
1766 }
1767 
1768 /******************************************************************************/
1769 
constlofig(ptcir,ptfig,instances,mode)1770 void		constlofig( ptcir, ptfig, instances, mode )
1771 circuit		*ptcir;
1772 lofig_list	*ptfig;
1773 ginterf		*instances;
1774 char		mode;
1775 {
1776   noeud		*scannoeud;
1777   noeud		*ptnoeud;
1778   chain_list	*sc1, *sc2, *sc3, *sc4, *sc5;
1779   locon_list	*scanlocon;
1780   losig_list	*ptsig;
1781   int		nbsig;
1782   int		i;
1783   losig_list	**tabsig;
1784   num_list	*interf;
1785   chain_list	*connec_sig;
1786   chain_list	*connec_noeud;
1787   chain_list    *connec_nom;
1788   chain_list    *connec_con;
1789   trans		*scantrans;
1790   inst		*scaninst;
1791   char		*nom;
1792   lotrs_list	*pttrs;
1793   locon_list	*scancon;
1794   capa		*scancapa;
1795   loins_list	*ptinst;
1796   resi		*scanresi;
1797   valim		*scanvalim;
1798   ginterf	*sci;
1799   lofig_list	*modele;
1800   lofig_list	*tetemodele;
1801   loctc_list    *ptctc;
1802   char          *devect;
1803   ptype_list    *ptnodename;
1804 
1805 
1806   tetemodele = NULL;
1807 
1808   /* Cr�ation du tableau des signaux */
1809 
1810   nbsig = 0;
1811   for( scannoeud = ptcir->NOEUD; scannoeud ; scannoeud = scannoeud->SUIV )
1812     if( scannoeud->SIGNAL > nbsig )
1813       nbsig = scannoeud->SIGNAL;
1814 
1815   tabsig = (losig_list**)mbkalloc( sizeof(losig_list*)*nbsig );
1816   for( i = 0 ; i < nbsig ; i++ )
1817     tabsig[i] = NULL;
1818 
1819   /* Cr�ation des signaux */
1820 
1821   setsigsize( ptfig, nbsig > 1024 ? 1024 : nbsig );
1822 
1823   for( scannoeud = ptcir->NOEUD; scannoeud ; scannoeud = scannoeud->SUIV )
1824   {
1825     if( !(ptsig = tabsig[ scannoeud->SIGNAL - 1 ]) )
1826     {
1827       ptsig = addlosig( ptfig, scannoeud->SIGNAL, NULL, INTERNAL );
1828       tabsig[ scannoeud->SIGNAL - 1 ] = ptsig;
1829     }
1830 
1831     if( scannoeud->NOM )
1832     {
1833       devect = spi_devect( scannoeud->NOM );
1834 
1835       nom = namealloc( devect );
1836       mbkfree( devect );
1837 
1838       for( sc1 = ptsig->NAMECHAIN; sc1 ; sc1 = sc1->NEXT )
1839         if( sc1->DATA == nom )
1840           break;
1841 
1842       if( ! sc1 )
1843         ptsig->NAMECHAIN = addchain( ptsig->NAMECHAIN, nom );
1844     }
1845   }
1846 
1847   /* On construit les vues RCN et/ou CTC */
1848   /*
1849   for( ptsig = ptfig->LOSIG ; ptsig ; ptsig = ptsig->NEXT )
1850     if( ! ptsig->PRCN )
1851       addlorcnet( ptsig );
1852   */
1853 
1854   triecapa( ptcir );
1855 
1856   for( scancapa = ptcir->CAPA ; scancapa ; scancapa = scancapa->SUIV )
1857   {
1858     if( !tabsig[ scancapa->N1->SIGNAL -1 ]->PRCN )
1859       addlorcnet( tabsig[ scancapa->N1->SIGNAL -1 ] );
1860 
1861     if( !tabsig[ scancapa->N2->SIGNAL -1 ]->PRCN )
1862       addlorcnet( tabsig[ scancapa->N2->SIGNAL -1 ] );
1863 
1864     tabsig[ scancapa->N1->SIGNAL -1 ]->PRCN->CAPA += scancapa->CAPA;
1865     tabsig[ scancapa->N2->SIGNAL -1 ]->PRCN->CAPA += scancapa->CAPA;
1866   }
1867 
1868   for( scanresi = ptcir->RESI ; scanresi ; scanresi = scanresi->SUIV )
1869   {
1870     if( !tabsig[ scanresi->N1->SIGNAL - 1 ]->PRCN )
1871       addlorcnet( tabsig[ scanresi->N1->SIGNAL - 1 ] );
1872 
1873     addlowire( tabsig[ scanresi->N1->SIGNAL - 1 ],
1874                RCN_WIRE_UNKNOW,
1875                0,
1876                scanresi->RESI,
1877                scanresi->CAPA,
1878                0l,
1879                0l,
1880                0l,
1881                0l,
1882                scanresi->N1->RCN,
1883                scanresi->N2->RCN
1884              );
1885   }
1886 
1887   for( scanvalim = ptcir->VALIM ; scanvalim ; scanvalim = scanvalim->SUIV )
1888   {
1889     if( !tabsig[ scanvalim->N1->SIGNAL - 1 ]->PRCN )
1890       addlorcnet( tabsig[ scanvalim->N1->SIGNAL - 1 ] );
1891 
1892     addlowire( tabsig[ scanvalim->N1->SIGNAL - 1 ],
1893                RCN_WIRE_UNKNOW,
1894                0,
1895                0.0,
1896                0.0,
1897                0l,
1898                0l,
1899                0l,
1900                0l,
1901                scanvalim->N1->RCN,
1902                scanvalim->N2->RCN
1903              );
1904   }
1905 
1906   for( scancapa = ptcir->CAPA ; scancapa ; scancapa = scancapa->SUIV )
1907   {
1908     if( !tabsig[ scancapa->N1->SIGNAL - 1 ]->PRCN )
1909       addlorcnet( tabsig[ scancapa->N1->SIGNAL - 1 ] );
1910 
1911     if( !tabsig[ scancapa->N2->SIGNAL - 1 ]->PRCN )
1912       addlorcnet( tabsig[ scancapa->N2->SIGNAL - 1 ] );
1913 
1914     if( scancapa->NOM != NULL && scancapa->N1 != scancapa->N2 )
1915     {
1916       ptctc = getloctc( tabsig[ scancapa->N1->SIGNAL - 1 ],
1917                         scancapa->N1->RCN ? scancapa->N1->RCN : 1,
1918                         tabsig[ scancapa->N2->SIGNAL - 1 ],
1919                         scancapa->N2->RCN ? scancapa->N2->RCN : 1
1920                       );
1921 
1922       if( ptctc )
1923         ptctc->CAPA = ptctc->CAPA + scancapa->CAPA;
1924       else
1925         addloctc( tabsig[ scancapa->N1->SIGNAL - 1 ],
1926                   scancapa->N1->RCN ? scancapa->N1->RCN : 1,
1927                   tabsig[ scancapa->N2->SIGNAL - 1 ],
1928                   scancapa->N2->RCN ? scancapa->N2->RCN : 1,
1929                   scancapa->CAPA
1930                 );
1931     }
1932   }
1933 
1934   /* Connecteurs de l'interface */
1935 
1936   for( sc1 = ptcir->CINTERF, sc2 = instances->GINTERF ;
1937        sc1 && sc2 ;
1938        sc1 = sc1->NEXT, sc2 = sc2->NEXT
1939      )
1940   {
1941     ptnoeud = (noeud*)(sc1->DATA);
1942 
1943     for( scanlocon = ptfig->LOCON ; scanlocon ; scanlocon = scanlocon->NEXT )
1944       if( scanlocon->SIG->INDEX == ptnoeud->SIGNAL )
1945         break;
1946 
1947     if( !scanlocon )
1948     {
1949       ptsig       = tabsig[ ptnoeud->SIGNAL - 1 ];
1950       ptsig->TYPE = 'E';
1951 
1952       devect = spi_devect( (char*)(sc2->DATA) );
1953 
1954       if( SPI_MERGE == 1 )
1955         stopchainsepar( devect );
1956 
1957       nom = namealloc( devect );
1958       mbkfree( devect );
1959 
1960       scanlocon = addlocon( ptfig, nom, ptsig, UNKNOWN );
1961       scanlocon->USER = addptype( scanlocon->USER, PNODENAME, NULL );
1962     }
1963 
1964     if( ptnoeud->RCN )
1965     {
1966       if( !scanlocon->SIG->PRCN )
1967         addlorcnet( scanlocon->SIG );
1968 
1969       setloconnode( scanlocon, ptnoeud->RCN );
1970       ptnodename = getptype( scanlocon->USER, PNODENAME );
1971 
1972       if( ptnoeud->NOM )
1973         ptnodename->DATA = addchain( ((chain_list*)(ptnodename->DATA)), namealloc( ptnoeud->NOM ) );
1974       else
1975         ptnodename->DATA = addchain( ((chain_list*)(ptnodename->DATA)), NULL );
1976     }
1977   }
1978 
1979   if( sc1 || sc2 )
1980   {
1981     fflush( stdout );
1982     fprintf( stderr,"sc1 ou sc2.\n" );
1983     EXIT(-1);
1984   }
1985 
1986   for( scanlocon = ptfig->LOCON ; scanlocon ; scanlocon = scanlocon->NEXT )
1987   {
1988     scanlocon->PNODE = (struct num *)reverse( (chain_list*)scanlocon->PNODE );
1989 
1990     ptnodename = getptype( scanlocon->USER, PNODENAME );
1991     for( sc1 = (chain_list*)( ptnodename->DATA ) ; sc1 ; sc1 = sc1->NEXT )
1992       if( sc1->DATA )
1993         break;
1994     if( sc1 )
1995       ptnodename->DATA = reverse( ((chain_list*)(ptnodename->DATA)) );
1996     else
1997     {
1998       freechain( (chain_list*)ptnodename->DATA );
1999       scanlocon->USER = delptype( scanlocon->USER, PNODENAME );
2000     }
2001   }
2002 
2003   ptfig->LOCON = (locon_list *)reverse( (chain_list*)ptfig->LOCON );
2004 
2005   /* On cree les transistors */
2006 
2007   for( scantrans = ptcir->TRANS; scantrans; scantrans = scantrans->SUIV )
2008   {
2009     pttrs = addlotrs(
2010                  ptfig,
2011                  scantrans->TYPE,
2012                  float2long( scantrans->X ),
2013                  float2long( scantrans->Y ),
2014                  float2long( scantrans->W  * SCALE_X * 1e6 ),
2015                  float2long( scantrans->L  * SCALE_X * 1e6 ),
2016                  float2long( scantrans->PS * SCALE_X * 1e6 ),
2017                  float2long( scantrans->PD * SCALE_X * 1e6 ),
2018                  float2long( scantrans->AS * SCALE_X * 1e6 / scantrans->W ),
2019                  float2long( scantrans->AD * SCALE_X * 1e6 / scantrans->W ),
2020                  tabsig[ scantrans->GRILLE->SIGNAL - 1 ],
2021                  tabsig[ scantrans->SOURCE->SIGNAL - 1 ],
2022                  tabsig[ scantrans->DRAIN->SIGNAL  - 1 ],
2023                  scantrans->SUBST ?
2024                    tabsig[ scantrans->SUBST->SIGNAL  - 1 ] :
2025                    NULL,
2026                  scantrans->NOM
2027                     );
2028 
2029     if( scantrans->DRAIN->RCN )
2030     {
2031       if( !pttrs->DRAIN->SIG->PRCN )
2032         addlorcnet( pttrs->DRAIN->SIG );
2033       setloconnode(pttrs->DRAIN,  scantrans->DRAIN->RCN  );
2034       if( scantrans->DRAIN->NOM )
2035         pttrs->DRAIN->USER = addptype( pttrs->DRAIN->USER,
2036                                        PNODENAME,
2037                                        addchain( NULL,
2038                                                namealloc( scantrans->DRAIN->NOM)
2039                                                )
2040                                      );
2041     }
2042 
2043     if( scantrans->GRILLE->RCN )
2044     {
2045       if( !pttrs->GRID->SIG->PRCN )
2046         addlorcnet( pttrs->GRID->SIG );
2047       setloconnode(pttrs->GRID,   scantrans->GRILLE->RCN );
2048       if( scantrans->GRILLE->NOM )
2049         pttrs->GRID->USER = addptype( pttrs->GRID->USER,
2050                                       PNODENAME,
2051                                       addchain( NULL,
2052                                               namealloc( scantrans->GRILLE->NOM)
2053                                               )
2054                                     );
2055     }
2056 
2057     if( scantrans->SOURCE->RCN )
2058     {
2059       if( !pttrs->SOURCE->SIG->PRCN )
2060         addlorcnet( pttrs->SOURCE->SIG );
2061       setloconnode(pttrs->SOURCE, scantrans->SOURCE->RCN );
2062       if( scantrans->SOURCE->NOM )
2063         pttrs->SOURCE->USER = addptype( pttrs->SOURCE->USER,
2064                                         PNODENAME,
2065                                         addchain( NULL,
2066                                               namealloc( scantrans->SOURCE->NOM)
2067                                                 )
2068                                       );
2069     }
2070 
2071     if( scantrans->SUBST )
2072     {
2073       if( scantrans->SUBST->RCN )
2074       {
2075         if( !pttrs->BULK->SIG->PRCN )
2076           addlorcnet( pttrs->BULK->SIG );
2077         setloconnode(pttrs->BULK,   scantrans->SUBST->RCN   );
2078         if( scantrans->SUBST->NOM )
2079           pttrs->BULK->USER = addptype( pttrs->BULK->USER,
2080                                         PNODENAME,
2081                                         addchain( NULL,
2082                                                namealloc( scantrans->SUBST->NOM)
2083                                                 )
2084                                       );
2085       }
2086     }
2087   }
2088 
2089   /* On cree les instances */
2090 
2091 
2092   for( scaninst = ptcir->INST ; scaninst ; scaninst = scaninst->SUIV )
2093   {
2094     connec_sig   = NULL;
2095     connec_noeud = NULL;
2096     connec_nom   = NULL;
2097     connec_con   = NULL;
2098 
2099     for( sci = instances ; sci ; sci = sci->SUIV )
2100     {
2101       if( strcasecmp( sci->NOM, scaninst->MODELE ) == 0 )
2102         break;
2103     }
2104 
2105     if( !sci )
2106     {
2107       fflush( stdout );
2108       fprintf( stderr,
2109                "Internal error : can't find model %s.\n",
2110                scaninst->MODELE
2111              );
2112       EXIT( 1 );
2113     }
2114 
2115     /* Constitue la liste des signaux */
2116     for( sc1 = sci->GINTERF, sc2 = scaninst->IINTERF ;
2117          sc1 && sc2 ;
2118          sc1 = sc1->NEXT, sc2 = sc2->NEXT
2119        )
2120     {
2121       for( sc3 = sci->GINTERF ; sc3 != sc1 ; sc3 = sc3->NEXT )
2122         if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 )
2123           break;
2124 
2125       if( sc3 == sc1 ) /* Creation d'un nouveau locon */
2126       {
2127         connec_sig = addchain( connec_sig,
2128                                tabsig[ ((noeud*)(sc2->DATA))->SIGNAL - 1 ]
2129                              );
2130         connec_noeud = addchain( connec_noeud,
2131                                  addnum( NULL, ((noeud*)(sc2->DATA))->RCN )
2132                                );
2133         connec_nom = addchain( connec_nom,
2134                                addchain( NULL,
2135                                          namealloc( ((noeud*)(sc2->DATA))->NOM )
2136                                        )
2137                              );
2138         connec_con = addchain( connec_con, sc1->DATA );
2139       }
2140       else /* On complete des noeuds d'un locon */
2141       {
2142         for ( sc3 = connec_con, sc4 = connec_noeud, sc5 = connec_nom ;
2143               strcasecmp( (char*)sc3->DATA, (char*)sc1->DATA ) != 0 ;
2144               sc3 = sc3->NEXT, sc4 = sc4->NEXT, sc5 = sc5->NEXT
2145             ) ;
2146 
2147         sc4->DATA = addnum( sc4->DATA, ((noeud*)(sc2->DATA))->RCN );
2148         sc5->DATA = addchain( sc5->DATA, namealloc (
2149                                                     ((noeud*)(sc2->DATA))->NOM
2150                                                    )
2151                             );
2152       }
2153     }
2154 
2155     freechain( connec_con );
2156     connec_sig   = reverse( connec_sig   );
2157     connec_noeud = reverse( connec_noeud );
2158     connec_nom   = reverse( connec_nom   );
2159 
2160     nom = namealloc( sci->NOM );
2161 
2162     modele = getlomodel( tetemodele, nom );
2163     if( !modele )
2164       modele = tetemodele = recuperemodele( tetemodele, nom, sci->GINTERF );
2165 
2166     ptinst = addloins( ptfig, "*", modele, connec_sig );
2167     ptinst->INSNAME = namealloc( scaninst->NOM ) ;
2168 
2169     ptinst->USER = constphinterf( ptinst->USER, sci );
2170 
2171     for( scancon = ptinst->LOCON, sc1 = connec_noeud, sc2 = connec_nom ;
2172          scancon ;
2173          scancon = scancon->NEXT, sc1 = sc1->NEXT, sc2 = sc2->NEXT
2174        )
2175     {
2176       interf = (num_list*)sc1->DATA;
2177       scancon->USER = addptype( scancon->USER, PNODENAME, NULL );
2178       ptnodename = scancon->USER;
2179 
2180       if( interf->DATA )
2181       {
2182         if( !scancon->SIG->PRCN )
2183           addlorcnet( scancon->SIG );
2184 
2185         for( ; interf ; interf = interf->NEXT )
2186           setloconnode( scancon, interf->DATA );
2187 
2188         sc3 = (chain_list*)sc2->DATA;
2189         for( ; sc3 ; sc3 = sc3->NEXT )
2190           ptnodename->DATA = addchain(((chain_list*)(ptnodename->DATA)),
2191                                                         sc3->DATA
2192                                                       );
2193 
2194       }
2195     }
2196 
2197     freechain( connec_sig   );
2198     for( sc1 = connec_noeud ; sc1 ; sc1 = sc1->NEXT )
2199       freenum( sc1->DATA );
2200     freechain( connec_noeud );
2201     for( sc1 = connec_nom ; sc1 ; sc1 = sc1->NEXT )
2202       freechain( sc1->DATA );
2203     freechain( connec_nom );
2204 
2205     for( scancon = ptinst->LOCON ; scancon ; scancon = scancon->NEXT )
2206     {
2207       ptnodename = getptype( scancon->USER, PNODENAME );
2208       for( sc1 = (chain_list*)( ptnodename->DATA ) ; sc1 ; sc1 = sc1->NEXT )
2209         if( sc1->DATA )
2210           break;
2211       if( !sc1 )
2212       {
2213         freechain( (chain_list*)ptnodename->DATA );
2214         scancon->USER = delptype( scancon->USER, PNODENAME );
2215       }
2216     }
2217   }
2218 
2219   ptfig->MODE = mode;
2220   mbkfree( tabsig );
2221   freelomodel( tetemodele );
2222 
2223   ptfig->LOTRS = ( lotrs_list* ) reverse( (chain_list*) ptfig->LOTRS );
2224 
2225   lofigchain( ptfig );
2226 }
2227 
2228 /******************************************************************************/
2229 
lireligne(df)2230 chain_list*	lireligne( df )
2231 spifile		*df;
2232 {
2233   chain_list		*sc;
2234   chain_list		*eff;
2235 
2236   if( df->decomp2 == NULL )
2237   {
2238     df->decomp1 = decompligne(df);
2239     strcpy( df->file_line1, df->file_line );
2240   }
2241   else
2242   {
2243     df->decomp1 = df->decomp2;
2244     strcpy( df->file_line1, df->file_line2 );
2245   }
2246 
2247   if( df->decomp1 == NULL ) /* cas d'un fichier vide */
2248     return(NULL);
2249 
2250   while( TRUE )
2251   {
2252     df->decomp2 = decompligne(df);
2253     strcpy( df->file_line2, df->file_line );
2254 
2255     if( df->decomp2 == NULL )
2256       break;
2257 
2258     /*
2259     if( strcmp( (char*)df->decomp2->DATA, "+" ) != 0 )
2260     */
2261     if( ((char*)(df->decomp2->DATA))[0] != '+' ||
2262         ((char*)(df->decomp2->DATA))[1] != 0      )
2263       break;
2264 
2265     /* On reforme les lignes s�par�es par des + */
2266 
2267     eff = df->decomp2;
2268     df->decomp2 = df->decomp2->NEXT;
2269     eff->NEXT = NULL;
2270     mbkfree( eff->DATA );
2271     freechain(eff);
2272 
2273     for( sc = df->decomp1; sc->NEXT; sc = sc->NEXT );
2274     sc->NEXT = df->decomp2;
2275   }
2276   return( df->decomp1 );
2277 }
2278 
2279 /******************************************************************************/
2280 
decompligne(df)2281 chain_list*	decompligne( df )
2282 spifile		*df;
2283 {
2284   char		mot[LONG_LIGNE];
2285   int		lg;
2286   chain_list	*decomp;
2287   char		motencours;
2288   char		*element;
2289   int		i, j=0 ; /* Warning a la compilation */
2290 
2291   do
2292   {
2293     df->msl_line++;
2294     decomp = NULL;
2295 
2296     fgets( df->file_line, LONG_LIGNE, df->df );
2297 
2298     if( feof(df->df) )
2299       return( NULL );
2300 
2301     lg = strlen(df->file_line);
2302 
2303     if( lg == LONG_LIGNE-1 )
2304       spierror( 48, df->filename, df->msl_line );
2305 
2306     motencours = 0;
2307 
2308     /* Un cas particulier : si le premier caractere de la ligne est
2309      * un '+'. Sur la suite de la ligne, le '+' sera considere comme un
2310      * caractere standard. */
2311 
2312     i=0;
2313     while( df->file_line[i] == ' ' )
2314       i++;
2315 
2316     if( df->file_line[i] == '+' )
2317     {
2318       element  = (char*)mbkalloc( 2 * sizeof(char) );
2319       element[0] = df->file_line[i];
2320       element[1] = 0;
2321       decomp = addchain( decomp, element );
2322       i++;
2323     }
2324 
2325     /* On traite le reste de la ligne */
2326 
2327     for( ; i<lg; i++ )
2328     {
2329       if( ( df->file_line[i] >= 'A' && df->file_line[i] <= 'Z' ) ||
2330           ( df->file_line[i] >= 'a' && df->file_line[i] <= 'z' ) ||
2331           ( df->file_line[i] >= '0' && df->file_line[i] <= '9' ) ||
2332           strchr( ":/$<>[]._-|+@", df->file_line[i] )               )
2333       {
2334         if( !motencours )
2335         {
2336           motencours = 1;
2337           j = 0;
2338         }
2339         mot[j++] = df->file_line[i];
2340       }
2341       else
2342       {
2343         if( motencours )
2344         {
2345           mot[j++] = 0;
2346 
2347           element  = (char*)mbkalloc( j * sizeof(char) );
2348           memcpy( element, mot, j );
2349           decomp = addchain( decomp, element );
2350 
2351           motencours = 0;
2352         }
2353 
2354         if( strchr( "=*$", df->file_line[i] ) )
2355         {
2356           element  = (char*)mbkalloc( 2 * sizeof(char) );
2357           element[0] = df->file_line[i];
2358           element[1] = 0;
2359           decomp = addchain( decomp, element );
2360         }
2361       }
2362     }
2363   }
2364   while(!decomp);
2365 
2366   return(reverse(decomp));
2367 }
2368 
2369 /******************************************************************************/
2370 
liberecircuit(ptcir)2371 void		liberecircuit( ptcir )
2372 circuit		*ptcir;
2373 {
2374   chain_list	*scanchain;
2375   inst          *scaninst;
2376 
2377   for( scaninst = ptcir->INST ; scaninst ; scaninst = scaninst->SUIV )
2378     freechain( scaninst->IINTERF );
2379 
2380   for( scanchain = ptcir->FREE ; scanchain ; scanchain = scanchain->NEXT )
2381     mbkfree( scanchain->DATA );
2382 
2383   freechain( ptcir->FREE   );
2384   freechain( ptcir->CINTERF );
2385   freetableint( ptcir->INT_NOEUD );
2386   freethash( ptcir->HASHGNAME );
2387   freethash( ptcir->HASHCAPA );
2388   freethash( ptcir->HASHRESI );
2389   freethash( ptcir->HASHVALIM );
2390   freethash( ptcir->HASHINST );
2391   freethash( ptcir->HASHTRAN );
2392   freethash( ptcir->NOM_NOEUD );
2393   mbkfree( ptcir );
2394 }
2395 
2396 /******************************************************************************/
2397 
ajoutenoeud(ptcir,index,df)2398 noeud*		ajoutenoeud( ptcir, index, df )
2399 circuit		*ptcir;
2400 char		*index;
2401 spifile         *df;
2402 {
2403   int		val;
2404   char		*fin;
2405   noeud		*sn;
2406   char		*nom = NULL;
2407 
2408   val = strtol( index, &fin, 10 );
2409 
2410   if( fin != index ) /* Ca commence par un nombre */
2411   {
2412     if( *fin!=0 )
2413     {
2414       fflush( stdout );
2415       fprintf( stderr, "%s\n", SPIMSG(0) );
2416       fprintf( stderr, "%s : %s\n", SPIMSG(49), index );
2417       fprintf( stderr, "%s %s. %s %d :\n",
2418                SPIMSG(11),
2419                df->filename,
2420                SPIMSG(12),
2421                df->msl_line
2422              );
2423       EXIT( 1 );
2424     }
2425 
2426     sn = (noeud*) tsttableint( ptcir->INT_NOEUD, val );
2427     if( sn )
2428       return( sn );
2429   }
2430   else
2431   {
2432     if(!(( index[0] >= 'A' && index[0] <= 'Z' ) ||
2433          ( index[0] >= 'a' && index[0] <= 'z' ) ||
2434          ( index[0] == '_' || index[0] == '@' )    ) )
2435     {
2436       fflush( stdout );
2437       fprintf( stderr, "%s\n", SPIMSG(0) );
2438       fprintf( stderr, "%s : %s\n", SPIMSG(50), index );
2439       fprintf( stderr, "%s %s. %s %d :\n",
2440                SPIMSG(11),
2441                df->filename,
2442                SPIMSG(12),
2443                df->msl_line
2444              );
2445       EXIT( 1 );
2446     }
2447 
2448     nom = spicenamealloc( ptcir, index );
2449 
2450     sn = getthashelem( nom, ptcir->NOM_NOEUD, NULL );
2451     if( sn )
2452       return( sn );
2453   }
2454 
2455   sn           = (noeud*)spiciralloue( ptcir, sizeof(noeud) );
2456   sn->SUIV     = ptcir->NOEUD;
2457   ptcir->NOEUD = sn;
2458 
2459   sn->NOM      = nom;
2460   sn->SIGNAL   = 0;
2461   sn->RCN      = 0;
2462   sn->SPICE    = val;
2463 
2464   if( val != -1 )
2465     settableint( ptcir->INT_NOEUD, val, sn );
2466   if( nom )
2467     addthashelem( nom, sn, ptcir->NOM_NOEUD );
2468 
2469   return(sn);
2470 }
2471 
2472 /******************************************************************************/
2473 
nomenoeud(ptcir,ptnoeud,ptnom,df)2474 void		nomenoeud( ptcir, ptnoeud, ptnom, df )
2475 circuit		*ptcir;
2476 noeud		*ptnoeud;
2477 char		*ptnom;
2478 spifile         *df;
2479 {
2480   if( ptnoeud->NOM )
2481   {
2482     fflush( stdout );
2483     fprintf( stderr, "%s\n", SPIMSG(0) );
2484     fprintf( stderr, "%s : %s\n", SPIMSG(51), ptnoeud->NOM );
2485     fprintf( stderr, "%s %s. %s %d :\n",
2486              SPIMSG(11),
2487              df->filename,
2488              SPIMSG(12),
2489              df->msl_line
2490            );
2491     EXIT( 1 );
2492   }
2493 
2494   ptnoeud->NOM = spicenamealloc( ptcir, ptnom );
2495   addthashelem( ptnoeud->NOM, ptnoeud, ptcir->NOM_NOEUD );
2496 }
2497 
2498 /******************************************************************************/
2499 
spicenamealloc(ptcir,ptnom)2500 char*		spicenamealloc( ptcir, ptnom )
2501 circuit		*ptcir;
2502 char		*ptnom;
2503 {
2504   char		*elem;
2505   char		tmp[LONG_LIGNE];
2506   int           l;
2507 
2508   downstr( ptnom, tmp );
2509   /* Bug dans la fonction downstr : il ne recopie pas le 0 de fin de chaine */
2510   tmp[ strlen(ptnom) ] = 0;
2511 
2512   elem = getthashelem( tmp, ptcir->HASHGNAME, NULL );
2513   if( elem )
2514     return( elem );
2515 
2516   l = sizeof(char) * (strlen( tmp ) + 1 );
2517   if( ptcir->RESTENOM < l )
2518   {
2519     ptcir->ALLOUENOM = (char*)spiciralloue( ptcir, TAILLENOM );
2520     ptcir->RESTENOM = TAILLENOM;
2521   }
2522 
2523   elem = strcpy( ptcir->ALLOUENOM + ( TAILLENOM - ptcir->RESTENOM ), tmp );
2524   ptcir->RESTENOM = ptcir->RESTENOM - l;
2525   addthashelem( elem, elem, ptcir->HASHGNAME );
2526   return( elem );
2527 }
2528 
2529 /******************************************************************************/
2530 
spiciralloue(cir,taille)2531 void*		spiciralloue( cir, taille )
2532 circuit		*cir;
2533 int		 taille;
2534 {
2535   void		*pt;
2536 
2537   if(!cir)
2538   {
2539     fflush( stdout );
2540     fprintf( stderr, "*** mbkspi internal error *** : spiciralloue()\n" );
2541     EXIT(1);
2542   }
2543 
2544   pt = mbkalloc( taille );
2545   cir->FREE = addchain( cir->FREE, pt );
2546   cir->TAILLE = cir->TAILLE + taille ;
2547   return( pt );
2548 }
2549 
2550 /******************************************************************************/
2551 
spicefloat(nombre,status)2552 float		spicefloat( nombre, status )
2553 char		*nombre;
2554 int		*status;
2555 {
2556   float		valeur;
2557   char		*fin;
2558 
2559   /* Les caract�res suivant une unit� sont ignor�s */
2560 
2561   *status = -1 ;
2562 
2563   valeur = (float)strtod( nombre, &fin );
2564 
2565   if( *fin == 0 )
2566     *status = 1;
2567   else
2568   if( strncasecmp( fin, "F", 1 ) == 0 )
2569   {
2570     *status = 1;
2571     valeur = valeur * 1e-15 ;
2572   }
2573   else
2574   if( strncasecmp( fin, "P", 1 ) == 0 )
2575   {
2576     *status = 1;
2577     valeur = valeur * 1e-12 ;
2578   }
2579   else
2580   if( strncasecmp( fin, "N", 1 ) == 0 )
2581   {
2582     *status = 1;
2583     valeur = valeur * 1e-9 ;
2584   }
2585   else
2586   if( strncasecmp( fin, "U", 1 ) == 0 )
2587   {
2588     *status = 1;
2589     valeur = valeur * 1e-6 ;
2590   }
2591   else
2592   if( strncasecmp( fin, "M", 1 ) == 0 )
2593   {
2594     *status = 1;
2595     valeur = valeur * 1e-3 ;
2596   }
2597   else
2598   if( strncasecmp( fin, "K", 1 ) == 0 )
2599   {
2600     *status = 1;
2601     valeur = valeur * 1e+3 ;
2602   }
2603   else
2604   if( strncasecmp( fin, "MEG", 3 ) == 0 )
2605   {
2606     *status = 1;
2607     valeur = valeur * 1e+6 ;
2608   }
2609   else
2610   if( strncasecmp( fin, "MI", 2 ) == 0 )
2611   {
2612     *status = 1;
2613     valeur = valeur * 25.4e+6 ;
2614   }
2615   else
2616   if( strncasecmp( fin, "G", 1 ) == 0 )
2617   {
2618     *status = 1;
2619     valeur = valeur * 1e+9 ;
2620   }
2621   else /*unit values*/
2622   if( strncasecmp( fin, "V", 1 ) == 0 )
2623   {
2624     *status = 1;
2625     valeur = valeur * 1e+9 ;
2626   }
2627 
2628   return( valeur);
2629 }
2630 
2631 /******************************************************************************/
2632 
triecapa(ptcir)2633 void		triecapa( ptcir )
2634 circuit		*ptcir;
2635 {
2636   resi		*scanresi;
2637   char		*n1, *n2;
2638   capa		*c1, *c2;
2639   noeud		*tmp;
2640   char		*vss;
2641 
2642   vss = spicenamealloc( ptcir, VSS);
2643 
2644   for( scanresi = ptcir->RESI ; scanresi ; scanresi = scanresi->SUIV )
2645   {
2646     n1 = mbkalloc( sizeof( char ) * ( strlen(scanresi->NOM) + 2 ) );
2647     n2 = mbkalloc( sizeof( char ) * ( strlen(scanresi->NOM) + 2 ) );
2648 
2649     sprintf( n1 , "%s1", scanresi->NOM );
2650     sprintf( n2 , "%s2", scanresi->NOM );
2651 
2652     c1 = NULL;
2653     c2 = NULL;
2654 
2655     c1 = getthashelem( n1, ptcir->HASHCAPA, NULL );
2656     c2 = getthashelem( n2, ptcir->HASHCAPA, NULL );
2657 
2658     if( !c1 || !c2 )
2659     {
2660       scanresi->CAPA = 0.0;
2661       mbkfree( n1 );
2662       mbkfree( n2 );
2663       continue;
2664     }
2665 
2666     if( c1->N2->NOM == vss )
2667     {
2668       tmp = c1->N2;
2669       c1->N2 = c1->N1;
2670       c1->N1 = tmp;
2671     }
2672     else
2673     if( c1->N1->NOM != vss )
2674     {
2675       scanresi->CAPA = 0.0;
2676       mbkfree( n1 );
2677       mbkfree( n2 );
2678       continue;
2679     }
2680 
2681     if( c2->N2->NOM == vss )
2682     {
2683       tmp = c2->N2;
2684       c2->N2 = c2->N1;
2685       c2->N1 = tmp;
2686     }
2687     else
2688     if( c2->N1->NOM != vss )
2689     {
2690       scanresi->CAPA = 0.0;
2691       mbkfree( n1 );
2692       mbkfree( n2 );
2693       continue;
2694     }
2695 
2696     if( c1->CAPA != c2->CAPA )
2697     {
2698       scanresi->CAPA = 0.0;
2699       mbkfree( n1 );
2700       mbkfree( n2 );
2701       continue;
2702     }
2703 
2704     if( ( c1->N2 == scanresi->N1 && c2->N2 == scanresi->N2 )  ||
2705         ( c2->N2 == scanresi->N1 && c1->N2 == scanresi->N1 )     )
2706     {
2707       /* On ne prendra plus ces capacites en compte */
2708 
2709       c1->NOM = NULL;
2710       c2->NOM = NULL;
2711 
2712       scanresi->CAPA = c1->CAPA+c1->CAPA;
2713     }
2714     else
2715     {
2716       scanresi->CAPA = 0.0;
2717       mbkfree( n1 );
2718       mbkfree( n2 );
2719       continue;
2720     }
2721 
2722     mbkfree( n1 );
2723     mbkfree( n2 );
2724 
2725   }
2726 }
2727 
2728 /******************************************************************************/
2729 
float2long(v)2730 long            float2long( v )
2731 float		v;
2732 {
2733   long  i;
2734   float	r;
2735 
2736   i = v;
2737   r = v-i;
2738 
2739   if( r >= 0.5 )
2740     return ( i+1 );
2741   return(i);
2742 }
2743 
2744 /******************************************************************************/
2745 
taillevuespice(ptcir)2746 void            taillevuespice( ptcir )
2747 circuit         *ptcir;
2748 {
2749   int nb_noeud   = 0;
2750   int nb_resi    = 0;
2751   int nb_capa    = 0;
2752   int nb_inst    = 0;
2753   int nb_alim    = 0;
2754   int nb_trans   = 0;
2755   int total;
2756   noeud         *scannoeud;
2757   resi          *scanresi;
2758   capa          *scancapa;
2759   trans         *scantrans;
2760   inst          *scaninst;
2761   valim         *scanalim;
2762 
2763   for( scannoeud = ptcir->NOEUD ; scannoeud ; scannoeud = scannoeud->SUIV )
2764     nb_noeud++;
2765 
2766   for( scantrans = ptcir->TRANS ; scantrans ; scantrans = scantrans->SUIV )
2767     nb_trans++;
2768 
2769   for( scanresi = ptcir->RESI ; scanresi ; scanresi = scanresi->SUIV )
2770     nb_resi++;
2771 
2772   for( scancapa = ptcir->CAPA ; scancapa ; scancapa = scancapa->SUIV )
2773     nb_capa++;
2774 
2775   for( scaninst = ptcir->INST ; scaninst ; scaninst = scaninst->SUIV )
2776     nb_inst++;
2777 
2778   for( scanalim = ptcir->VALIM ; scanalim ; scanalim = scanalim->SUIV )
2779     nb_alim++;
2780 
2781   printf( "Data size structure :\n" );
2782   printf( "  noeud : %7dx%3d = %9d\n",
2783           nb_noeud,
2784           sizeof( noeud ),
2785           nb_noeud * sizeof(noeud)
2786         );
2787   printf( "  trans : %7dx%3d = %9d\n",
2788           nb_trans,
2789           sizeof(trans),
2790           nb_trans * sizeof(trans)
2791         );
2792   printf( "  resi  : %7dx%3d = %9d\n",
2793           nb_resi,
2794           sizeof(resi),
2795           nb_resi * sizeof(resi)
2796         );
2797   printf( "  capa  : %7dx%3d = %9d\n",
2798           nb_capa,
2799           sizeof(capa),
2800           nb_capa * sizeof(capa)
2801         );
2802   printf( "  inst  : %7dx%3d = %9d\n",
2803           nb_inst,
2804           sizeof(inst),
2805           nb_inst * sizeof(inst)
2806         );
2807   printf( "  alim  : %7dx%3d = %9d\n",
2808           nb_alim,
2809           sizeof(valim),
2810           nb_alim * sizeof(valim)
2811         );
2812 
2813   total = nb_noeud * sizeof(noeud) +
2814           nb_trans * sizeof(trans) +
2815           nb_resi * sizeof(resi)   +
2816           nb_capa * sizeof(capa)   +
2817           nb_inst * sizeof(inst)   +
2818           nb_alim * sizeof(valim);
2819 
2820   printf( "Total : %d.\n", total );
2821   printf( "Real size : %ld\n", ptcir->TAILLE );
2822 
2823 }
2824 
2825 /******************************************************************************/
2826 
affvuespice(ptcir)2827 void		affvuespice( ptcir )
2828 circuit		*ptcir;
2829 {
2830   chain_list	*sc;
2831   inst		*scaninst;
2832   trans		*scantrans;
2833   resi		*scanresi;
2834   capa		*scancapa;
2835 
2836   printf("Circuit : %s\n", ptcir->NOM );
2837 
2838   printf("Interface :\n");
2839   for( sc = ptcir->CINTERF; sc; sc = sc->NEXT )
2840     printf("  %ld %4d %4d %4d %s\n",
2841            ((unsigned long)(sc->DATA)),
2842            ((noeud*)(sc->DATA))->SPICE,
2843            ((noeud*)(sc->DATA))->SIGNAL,
2844            ((noeud*)(sc->DATA))->RCN,
2845            ((noeud*)(sc->DATA))->NOM ? ((noeud*)(sc->DATA))->NOM : "" );
2846 
2847   for(scantrans = ptcir->TRANS; scantrans; scantrans = scantrans->SUIV)
2848   {
2849     printf("Transitor : %s\n",scantrans->NOM);
2850     printf("  DRAIN   %ld %4d %4d %4d %s\n",
2851             (unsigned long)scantrans->DRAIN,
2852             scantrans->DRAIN->SPICE,
2853             scantrans->DRAIN->SIGNAL,
2854             scantrans->DRAIN->RCN,
2855             scantrans->DRAIN->NOM ? scantrans->DRAIN->NOM : "" );
2856     printf("  GRILLE  %ld %4d %4d %4d %s\n",
2857             (unsigned long)scantrans->GRILLE,
2858             scantrans->GRILLE->SPICE,
2859             scantrans->GRILLE->SIGNAL,
2860             scantrans->GRILLE->RCN,
2861             scantrans->GRILLE->NOM ? scantrans->GRILLE->NOM : ""    );
2862     printf("  SOURCE  %ld %4d %4d %4d %s\n",
2863             (unsigned long)scantrans->SOURCE,
2864             scantrans->SOURCE->SPICE,
2865             scantrans->SOURCE->SIGNAL,
2866             scantrans->SOURCE->RCN,
2867             scantrans->SOURCE->NOM ? scantrans->SOURCE->NOM : ""    );
2868     if( scantrans->SUBST )
2869     {
2870       printf("  SUBST   %ld %4d %4d %4d %s\n",
2871               (unsigned long)scantrans->SUBST,
2872               scantrans->SUBST->SPICE,
2873               scantrans->SUBST->SIGNAL,
2874               scantrans->SUBST->RCN,
2875               scantrans->SUBST->NOM ? scantrans->SUBST->NOM : ""     );
2876       printf("  TYPE    %c\n",scantrans->TYPE );
2877       printf("  L=%g W=%g AS=%g AD=%g PS=%g PD=%g\n",scantrans->L,
2878                                                      scantrans->W,
2879                                                      scantrans->AS,
2880                                                      scantrans->AD,
2881                                                      scantrans->PS,
2882                                                      scantrans->PD      );
2883     }
2884   }
2885 
2886   for(scanresi = ptcir->RESI ; scanresi; scanresi = scanresi->SUIV )
2887   {
2888     printf("Resistance : %s\n",scanresi->NOM);
2889     printf("  N1   %ld %4d %4d %4d %s\n",
2890             (unsigned long)scanresi->N1,
2891             scanresi->N1->SPICE,
2892             scanresi->N1->SIGNAL,
2893             scanresi->N1->RCN,
2894             scanresi->N1->NOM ? scanresi->N1->NOM : ""    );
2895     printf("  N2   %ld %4d %4d %4d %s\n",
2896             (unsigned long)scanresi->N2,
2897             scanresi->N2->SPICE,
2898             scanresi->N2->SIGNAL,
2899             scanresi->N2->RCN,
2900             scanresi->N2->NOM ? scanresi->N2->NOM : ""    );
2901     printf("  R=%g\n",scanresi->RESI);
2902   }
2903 
2904   for(scancapa = ptcir->CAPA ; scancapa; scancapa = scancapa->SUIV )
2905   {
2906     printf("Capacite : %s\n",scancapa->NOM);
2907     printf("  N1   %ld %4d %4d %4d %s\n",
2908             (unsigned long)scancapa->N1,
2909             scancapa->N1->SPICE,
2910             scancapa->N1->SIGNAL,
2911             scancapa->N1->RCN,
2912             scancapa->N1->NOM ? scancapa->N1->NOM : ""    );
2913     printf("  N2   %ld %4d %4d %4d %s\n",
2914             (unsigned long)scancapa->N2,
2915             scancapa->N2->SPICE,
2916             scancapa->N2->SIGNAL,
2917             scancapa->N2->RCN,
2918             scancapa->N2->NOM ? scancapa->N2->NOM : ""    );
2919     printf("  C=%g\n",scancapa->CAPA);
2920   }
2921 
2922   for( scaninst = ptcir->INST; scaninst; scaninst = scaninst->SUIV)
2923   {
2924     printf("Instance %s basee sur %s\n",scaninst->NOM, scaninst->MODELE);
2925     for( sc = scaninst->IINTERF; sc; sc = sc->NEXT )
2926       printf("  %ld %4d %4d %4d %s\n",
2927              ((unsigned long)(sc->DATA)),
2928              ((noeud*)(sc->DATA))->SPICE,
2929              ((noeud*)(sc->DATA))->SIGNAL,
2930              ((noeud*)(sc->DATA))->RCN,
2931              ((noeud*)(sc->DATA))->NOM ? ((noeud*)(sc->DATA))->NOM : ""    );
2932   }
2933 }
2934 
2935 /******************************************************************************/
2936 
retireextention(nom)2937 char*		retireextention( nom )
2938 char		*nom;
2939 {
2940   char		*pt;
2941   int		i;
2942 
2943   pt = mbkstrdup( nom );
2944 
2945   /* On retire l'extention du nom, c'est a dire qu'on arrete la chaine au
2946    * dernier point rencontr� */
2947   /* >0 : On laisse quand meme 1 caractere si le nom commence par un point */
2948   for( i = strlen( pt ) - 1 ; i > 0 ; i-- )
2949     if( pt[i] == '.' )
2950     {
2951       pt[i] = 0;
2952       break;
2953     }
2954 
2955   return( pt );
2956 }
2957 
2958 /******************************************************************************/
2959 
recuperemodele(tetemodel,nom,interf)2960 lofig_list*	recuperemodele( tetemodel, nom, interf )
2961 lofig_list	*tetemodel;
2962 char		*nom;
2963 chain_list	*interf;
2964 {
2965   lofig_list	*ptmod;
2966   chain_list	*sc1, *sc2;
2967   char          *nomdevec;
2968 
2969   ptmod = addlomodel( tetemodel, nom );
2970 
2971   for( sc1 = interf ; sc1 ; sc1 = sc1->NEXT )
2972   {
2973     for( sc2 = interf; sc1 != sc2 ; sc2 = sc2->NEXT )
2974       if( strcasecmp( sc1->DATA, sc2->DATA ) == 0 )
2975         break;
2976 
2977     if( sc1 != sc2 )
2978       continue;
2979 
2980     nomdevec = spi_devect( (char*)(sc1->DATA) );
2981     ptmod->LOCON = addlocon( ptmod, namealloc( nomdevec ), NULL, 'X' );
2982     mbkfree( nomdevec );
2983   }
2984 
2985   ptmod->LOCON = (locon_list*)reverse( (chain_list*) ptmod->LOCON );
2986   return( ptmod );
2987 }
2988 
2989 /******************************************************************************/
2990 
2991 void		mslAddExtension(mslExtHandler)
2992 int		(*mslExtHandler)();
2993 {
2994   ext_handler = mslExtHandler;
2995 }
2996 
2997 /******************************************************************************/
2998 
mslRmvExtension()2999 void		mslRmvExtension()
3000 {
3001   ext_handler = NULL;
3002 }
3003 
3004 /******************************************************************************/
3005 
3006 void		mslAddCompletion(mslCmpHandler)
3007 int             (*mslCmpHandler)();
3008 {
3009   cmp_handler = mslCmpHandler;
3010 }
3011 
3012 /******************************************************************************/
3013 
mslRmvCompletion()3014 void		mslRmvCompletion()
3015 {
3016   cmp_handler = NULL;
3017 }
3018 
3019 /******************************************************************************/
3020 
spi_devect(nom)3021 char*           spi_devect( nom )
3022 char            *nom;
3023 {
3024   int           taille;
3025   int           i;
3026   int           j;
3027   char         *nouv;
3028   int           fin;
3029   int           modif;
3030 
3031   taille = strlen( nom );
3032   if( taille == 0 )
3033   {
3034     /* message */
3035     EXIT(1);
3036   }
3037 
3038   nouv  = (char*)mbkalloc( sizeof(char) * (taille+1) );
3039   fin   = taille - 1 ;
3040   modif = 0;
3041 
3042   if( nom[fin] == ']' )
3043   {
3044     /* Retrouve le crochet ouvrant */
3045     for( i = fin-1 ; i >= 0 && isdigit( (int)nom[i] ) ; i-- );
3046 
3047     if( nom[i] == '[' )
3048     {
3049       if( i == 0 || i == fin - 1 )
3050       {
3051         /* nom de variable bizare, de la forme [43] ou toto[] */
3052         fflush( stdout );
3053         fprintf( stderr, "%s : \"%s\"\n", SPIMSG(52), nom );
3054         EXIT(1);
3055       }
3056       else
3057       {
3058         /* bon vecteur : toto[32] */
3059         for( j = 0 ; j < fin ; j++ )
3060           if( i != j )
3061             nouv[j] = nom[j];
3062           else
3063             nouv[i] = ' ';
3064         nouv[j] = 0;
3065 
3066         modif = 1;
3067       }
3068     }
3069     else
3070     {
3071       /* Nom de variable bizarre, de la forme toto32], toto] ou 32] */
3072       fflush( stdout );
3073       fprintf( stderr, "%s : \"%s\"\n", SPIMSG(52), nom );
3074       EXIT(1);
3075     }
3076   }
3077 
3078   if( ! modif )
3079     strcpy( nouv, nom );
3080 
3081   return(nouv);
3082 }
3083 
3084 /******************************************************************************/
3085 
spierror(mesg,file,line)3086 void spierror( mesg, file, line )
3087 int      mesg;
3088 char    *file;
3089 int      line;
3090 {
3091   fflush( stdout );
3092   fprintf( stderr, "%s.\n", SPIMSG(0) );
3093   fprintf( stderr, "%s. %s %s. %s %d.\n",
3094            SPIMSG(1),
3095            SPIMSG(11),
3096            file,
3097            SPIMSG(12),
3098            line
3099          );
3100   fprintf( stderr, "%s.\n",SPIMSG(mesg));
3101   EXIT(1);
3102 }
3103 
3104 /******************************************************************************/
3105 
stopchainsepar(chaine)3106 void    stopchainsepar( chaine )
3107 char    *chaine;
3108 {
3109   int i;
3110 
3111   /* On retire le nombre en fin de nom et le SPI_SEPAR */
3112   for( i = strlen( chaine ) - 1 ; i >= 0 ; i-- )
3113     if( ! isdigit( (int)chaine[i] ) )
3114       break;
3115 
3116   if( i > 0 )
3117     if( chaine[i] == SPI_SEPAR )
3118       chaine[i] = '\0' ;
3119 }
3120