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 progam is  free software; you can redistribute it  and/or modify it
10  * under the  terms of the GNU  General Public License as  published by the
11  * Free Software Foundation;  either version 2 of the License,  or (at your
12  * option) any later version.
13  *
14  * Alliance VLSI  CAD System  is distributed  in the hope  that it  will be
15  * useful, but WITHOUT  ANY WARRANTY; without even the  implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17  * Public License for more details.
18  *
19  * You should have received a copy  of the GNU General Public License along
20  * with the GNU C Library; see the  file COPYING. If not, write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 /***************************************************************/
25 /* module   : libpat_l.c                                       */
26 /* date     : 28/07/93                                         */
27 /* auteurs  : RENAUD & VENOT & PITON                           */
28 /***************************************************************/
29 
30 #ident "$Id: libpat_l.c,v 1.3 2012/05/14 14:20:14 alliance Exp $"
31 
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include <sys/signal.h>
37 
38 #include "mut.h"
39 #include "pat.h"
40 #include "libpat_l.h"
41 
42 /*------------------------------------------------------------
43  *      Numero de ligne dans le fichier source
44  *------------------------------------------------------------*/
45 unsigned int GNP_LINE = 1;
46 
47 /*------------------------------------------------------------
48  *      STRUCTURE PAT
49  *------------------------------------------------------------*/
50 struct  paseq  *racine_paseq;
51 
52 /*------------------------------------------------------------
53  *      LABEL
54  *------------------------------------------------------------*/
55 unsigned int    MAX_LABEL = 7;
56 
57 /*------------------------------------------------------------
58  *      NUMERO DE PATTERN COURANT
59  *------------------------------------------------------------*/
60 unsigned long   GNP_PATTERN_COURANT;
61 
62 /*------------------------------------------------------------
63  *      TABLE DES PAIOLs
64  *------------------------------------------------------------*/
65 struct paiol *tab_paiol[GNP_MAXTAB_PAIOL];
66 int      GNP_PAIOL_INDEX=0;
67 int      GNP_TAB_PAIOL_CREE;
68 
69 /*------------------------------------------------------------
70  *      TABLE DES IDENTIFICATEURS
71  *------------------------------------------------------------*/
72 Tptab_ident tab_ident[GNP_MAXTAB_IDENT];
73 int     ind_tab_ident;
74 
75 /*------------------------------------------------------------
76  *      GESTION DES PARAMETRES A NOMBRE INDETERMINE
77  *------------------------------------------------------------*/
78 char    *pile_param[GNP_MAXPILE_PARAM];
79 int      sp_pile_param ;
80 int      sp_file_param ;
81 
82 /*-------------------------------------------------------------------*/
83 /*      TABLES DE HACHAGE                                            */
84 /*-------------------------------------------------------------------*/
85 elt    *hash_paiol[GNP_HASHSIZE];
86 elt    *hash_pagrp[GNP_HASHSIZE];
87 
88 /* ###--------------------------------------------------------------### */
89 /* function     : Erreur						*/
90 /* description  : print error message & exit 				*/
91 /* called func. : none							*/
92 /* ###--------------------------------------------------------------### */
93 
Erreur(chaine)94 void Erreur (chaine)
95 char *chaine;
96 {
97   fprintf (stderr, "GENPAT : line %u : %s\n", GNP_LINE, chaine);
98 
99 #ifdef DEBUG
100   EXIT(1);
101 #else
102   exit(1);
103 #endif
104 
105 }
106 
107 /*-------------------------------------------------------------------*/
Hash(nom)108 static int Hash(nom)
109 char *nom;
110 {
111 int code = 0;
112 char *p;
113   p = nom;
114   while (*p)
115      code = (code << 1) ^ *p++;
116   if ( code < 0)
117      code =- code;
118   code %= GNP_HASHSIZE;
119   return( code);
120 }
121 /*-------------------------------------------------------------------*/
InitHash(tab)122 void InitHash(tab)
123 elt *tab[];
124 {
125 int i;
126   for (i=0;i< GNP_HASHSIZE ; i++)
127     tab[i] = NULL ;
128 }
129 /*-------------------------------------------------------------------
130  * retourne le pointeur sur la structure ELT
131  * le champ name est mis a jour
132  * le champs num_index n'est pas mis  a jour
133  * il vaut -1
134  */
135 /*-------------------------------------------------------------------*/
SymbAlloc(ident,tab)136 elt *SymbAlloc(ident,tab)
137 char *ident;
138 elt  *tab[] ;
139 {
140 int num_case;
141 elt *ptr_aux;
142 char *allocname;
143    allocname = (char *)namealloc (ident);
144    num_case = Hash(allocname);
145    ptr_aux = tab[num_case];
146    while (ptr_aux != NULL)
147       if ( strcmp( ptr_aux->name , allocname ) == 0 )
148           return(ptr_aux);
149       else
150           ptr_aux = ptr_aux->next;
151    ptr_aux = (elt*) mbkalloc ( sizeof (elt) );
152    ptr_aux->name = allocname;
153    ptr_aux->num_index = -1;
154    ptr_aux->sens = 0;
155    ptr_aux->next = tab[num_case] ;
156    tab[num_case] = ptr_aux ;
157    return ( ptr_aux );
158 }
159 /*-------------------------------------------------------------------*/
ExisteIdent(ident,tab)160 elt *ExisteIdent(ident,tab)
161 char *ident;
162 elt  *tab[] ;
163 {
164 elt *ptr_aux;
165 char *allocname;
166    allocname = (char *)namealloc (ident);
167    for(ptr_aux = tab[Hash(allocname)];
168        (ptr_aux==NULL) || ( strcmp( ptr_aux->name , allocname ) != 0 );
169        ptr_aux = ptr_aux->next
170        );
171    if ( ptr_aux == NULL)
172        Erreur ("identifier not found");
173    return (ptr_aux);
174 }
175 /*-------------------------------------------------------------------
176  * retourne soit -1 si le nom n'existe pas
177  *          soit le champ num_index si le nom est trouve dans la table
178  */
FindIdent(ident,tab)179 int FindIdent(ident,tab)
180 char *ident;
181 elt  *tab[] ;
182 {
183 int num_case;
184 elt *ptr_aux;
185 char *allocname;
186    allocname = (char *)namealloc (ident);
187     num_case = Hash(allocname);
188     ptr_aux = tab[num_case] ;
189     while (ptr_aux != NULL)
190     if ( strcmp( ptr_aux->name , allocname ) == 0 )
191       return (ptr_aux->num_index);
192     else
193       ptr_aux = ptr_aux->next;
194     return(-1);
195 }
196 
197 /* ###--------------------------------------------------------------### */
198 /* function     : namei							*/
199 /* description  : add a number to a name				*/
200 /* called func. : none							*/
201 /* ###--------------------------------------------------------------### */
202 
namei(str,n)203 char *namei(str,n)
204 char *str;
205 int n;
206 {
207 	char *p;
208 
209 	if (str == NULL)
210 	  return (NULL);
211 	p = (char *)malloc((strlen(str)+11) * sizeof(char));
212 	sprintf(p,"%s_%d",str,n);
213 	return(p);
214 }
215 
216 /* ###--------------------------------------------------------------### */
217 /* function     : KillEsp                                               */
218 /* description  : remove every space character of a string              */
219 /* called func. : isspace                                               */
220 /* ###--------------------------------------------------------------### */
221 
KillEsp(name)222 void KillEsp (name)
223 char *name;
224 {
225 int i = 0;
226 int j = 0;
227 
228    while (name [i] != '\0')
229    {
230       name [j] = name [i];
231       if (isspace (name[i]) == 0)
232         j++;
233       i++;
234    }
235    name [j] = '\0';
236 }
237 
238 /* ###--------------------------------------------------------------### */
239 /* function     : CheckIdent                                            */
240 /* description  : Check if ident is of type IDENT                       */
241 /* called func. : isspace, isalpha, isalnum, isupper, Erreur            */
242 /* ###--------------------------------------------------------------### */
243 
CheckIdent(ident)244 void    CheckIdent (ident)
245 char *ident;
246 {
247 char  *cpt;
248 int i;
249    cpt = ident;
250    while ( isspace (*cpt) != 0 )
251        cpt ++;
252    if (isalpha(*cpt++) == 0)
253          Erreur ("IDENT error not an identifier");
254    for (i = strlen(cpt); i >0; i--)
255    {
256       if (isalnum(*cpt) == 0)
257         if ((*cpt != '_') && (*cpt != '.'))
258            Erreur ("IDENT error not an identifier");
259       cpt ++;
260    }
261 }
262 
263 
264 /* ###--------------------------------------------------------------### */
265 /* function     : CheckSeparate                                         */
266 /* description  : Check `# of blank between value` string declaration   */
267 /* called func. : isdigit                                               */
268 /* ###--------------------------------------------------------------### */
269 
CheckSeparate(chn_blk)270 char CheckSeparate(chn_blk)
271 char *chn_blk;
272 {
273    char *pt = chn_blk;
274 
275    if (*pt == ':')
276    {
277      pt++;
278      if  (strlen (pt) == 1 )
279      {
280        if (isdigit (*pt))
281           return (*pt);
282      }
283      if  (strlen (pt) == 0 )
284           return ('0');
285    }
286    Erreur ("SEPARATOR error in paiol declaration");
287    return (*pt);
288 }
289 
290 /* ###--------------------------------------------------------------### */
291 /* function     : CheckFormat						*/
292 /* description  : Check if format is : x, X, o, O, b, B			*/
293 /* called func. : KillEsp, Erreur					*/
294 /* ###--------------------------------------------------------------### */
295 
CheckFormat(format)296 char CheckFormat (format)
297 
298 char *format;
299 {
300 char value = '-';
301 
302   KillEsp (format);
303   if (strlen (format) > 1 )
304     Erreur ("FORMAT format error");
305 
306   switch (*format)
307     {
308     case 'x':
309     case 'X':
310       value = 'X';
311       break;
312 
313     case 'o':
314     case 'O':
315       value = 'O';
316       break;
317 
318     case 'b':
319     case 'B':
320       value = 'B';
321       break;
322 
323     default:
324       Erreur ("FORMAT error");
325     }
326 
327   return (value);
328   }
329 
330 /* ###--------------------------------------------------------------### */
331 /* function     : CheckType						*/
332 /* description  : Check connector type					*/
333 /* called func. : KillEsp, Erreur					*/
334 /* ###--------------------------------------------------------------### */
335 
CheckType(type)336 char CheckType (type)
337 char *type;
338 {
339     char t = '-';
340 
341     KillEsp (type);
342     if (strlen (type) > 1 )
343         Erreur ("TYPE error");
344     switch (*type)
345     {
346       case 'O':case 'o': t = 'O'; break;
347       case 'I':case 'i': t = 'I'; break;
348       case 'T':case 't': t = 'T'; break;
349       case 'S':case 's': t = 'S'; break;
350       case 'R':case 'r': t = 'R'; break;
351       default:
352            Erreur ("MODE error");
353     }
354     return(t);
355 }
356 
357 
358 /* ###--------------------------------------------------------------### */
359 /* function     : CheckOption						*/
360 /* description  : Check connector option				*/
361 /* called func. : KillEsp, Erreur					*/
362 /* ###--------------------------------------------------------------### */
363 
CheckOption(option)364 char CheckOption (option)
365 char *option;
366 {
367     char flg = 0;
368 
369     KillEsp (option);
370     if (strlen (option) > 1 )
371         Erreur ("OPTION error");
372     if (strlen (option) == 0)
373     {
374       flg = 0;
375     }
376     else
377     {
378       switch (*option)
379       {
380         case 'S': case 's': flg |= PAT_IOL__SPY; break;
381         default:
382              Erreur ("OPTION error");
383       }
384     }
385     return(flg);
386 }
387 
388 
389 /* ###--------------------------------------------------------------### */
390 /* function     : CheckPattern                                          */
391 /* description  : Check if string "pattern" describe a pattern number   */
392 /* called func. : KillEsp, isdigit, Erreur                              */
393 /* ###--------------------------------------------------------------### */
394 
CheckPattern(pattern)395 void CheckPattern (pattern)
396 char *pattern;
397 {
398 int lg,i;
399 
400      KillEsp (pattern);
401      lg = strlen (pattern);
402      if ( lg == 0)
403          Erreur("PATTERN NUMBER syntax error");
404      if ( (*pattern != '+') && (isdigit(*pattern )== 0) )
405          Erreur("PATTERN NUMBER syntax error");
406      for (i = 1; i< lg ; i++)
407      {
408         pattern ++;
409         if ( isdigit(*pattern)  == 0  )
410          Erreur("PATTERN NUMBER syntax error");
411      }
412 }
413 
414 /* ###--------------------------------------------------------------### */
415 /* function     : CheckWidth                                            */
416 /* description  : Check vector field descriptor                         */
417 /* called func. : atoi, Erreur                                          */
418 /* ###--------------------------------------------------------------### */
419 
CheckWidth(chaine)420 void  CheckWidth (chaine)
421 struct alpha_num *chaine;
422 {
423 int gauche, droite, lg_gauche, lg_droite, lg_alpha;
424 
425    lg_gauche = strlen (chaine->gauche);
426    gauche    = atoi(chaine->gauche);
427    lg_droite = strlen (chaine->droite);
428    droite    = atoi(chaine->droite);
429    lg_alpha  = strlen (chaine->alpha);
430 
431    if ( ( lg_alpha  == 0 &&  lg_droite != 0 ) ||
432         ( lg_alpha  != 0 &&  lg_droite == 0 ) ||
433         ( lg_gauche == 0 && ( lg_alpha != 0   ||  lg_droite != 0) ) )
434       Erreur ("CheckWidth :VECTOR field descriptor error, missing argument");
435 
436    if ( (( strcmp (chaine->alpha,"DOWNTO")==0) ||
437          ( strcmp (chaine->alpha,"downto")==0)   ) && (gauche < droite))
438       Erreur ("CheckWidth :VECTOR field descriptor error, incorrect direction");
439 
440    if ( ( (strcmp (chaine->alpha,"TO")==0) ||
441           (strcmp (chaine->alpha,"to")==0)   ) &&  (droite < gauche) )
442       Erreur ("CheckWidth :VECTOR field descriptor error, incorrect direction");
443 }
444 
445 
446 
447 /* ###--------------------------------------------------------------### */
448 /* function     : SplitIdent                                            */
449 /* description  : Split Ident (ident) in two strings :                  */
450 /*               Ident name (ident) and Ident number (chaine)           */
451 /* called func. : isspace                                               */
452 /* ###--------------------------------------------------------------### */
453 
454 
SplitIdent(ident,chaine)455 void  SplitIdent (ident,chaine)
456 char *chaine;
457 char *ident;
458 {
459 char idtmp[30],reste[30], *cpt;
460 int i,j =0,k =0, flag1=0,flag2=0;
461    cpt = ident;
462    for (i = strlen(ident); i >0; i--)
463    {
464        if (flag1 == 0)
465        {
466            if (isspace(*cpt) == 0  &&  *cpt != '(' )
467 	   {
468                flag2 = 1;
469                idtmp[j++] = *cpt;
470            }
471            else
472 	   {
473 	     if (flag2 ==  1 )
474 	     {
475 	      flag1      = 1;
476 	      if (*cpt  == '(')  reste[k++] = *cpt;
477 	     }
478 	     else idtmp[j++] = *cpt;
479            }
480        }
481        else
482        {
483             reste[k++] = *cpt;
484        }
485        cpt ++;
486    }
487    idtmp[j] = '\0';
488    reste[k] = '\0';
489    strcpy (chaine,reste);
490    strcpy (ident,idtmp);
491 }
492 
493 /* ###--------------------------------------------------------------### */
494 /* function     : TraiterChaine                                         */
495 /* description  : find out left & right bound and direction of an array */
496 /* called func. : isdigit, isalpha, isspace                             */
497 /* ###--------------------------------------------------------------### */
498 
TraiterChaine(chaine,traite)499 void TraiterChaine (chaine,traite)
500 char * chaine;
501 struct alpha_num *traite;
502 {
503 char *cpt;
504 int i=0,j=0,k=0,l=0,flag=0,f=0;
505 
506    KillEsp(chaine);
507 
508    if ( *chaine == '(')
509    {
510      f = 1;
511      chaine++;
512    }
513 
514    cpt = chaine;
515    for (i = strlen(chaine); i >0; i--)
516    {
517      switch (flag)
518      {
519       case 0:
520       {
521           if (isdigit(*cpt) )
522               traite->gauche[j++] = *cpt;
523           if (isalpha (*cpt))
524 	  {
525               traite->alpha[k++] = *cpt;
526               flag = 1;
527           }
528 	  if (*cpt == ')' && f == 0)
529 	    Erreur ("BIT descriptor error");
530           break;
531       }
532       case 1:
533       {
534           if (isalpha (*cpt))
535 	  {
536               traite->alpha[k++] = *cpt;
537               flag = 1;
538 	      break;
539           }
540 	  if (isdigit(*cpt))
541 	  {
542 	     traite->droite[l++] = *cpt;
543 	     flag = 2;
544 	     break;
545 	  }
546 	  if ( ! ( (*cpt == ')') && (f==1) && (i==1) ) )
547 	      Erreur("TraiterChaine : VECTOR field descriptor error");
548           break;
549       }
550       case 2:
551       {
552           if (isdigit(*cpt))
553               traite->droite[l++] = *cpt;
554 	  else
555 	     if( ! ( (*cpt == ')') && (f==1) && (i==1) ) )
556               Erreur ("TraiterChaine  :VECTOR field descriptor error");
557           break;
558       }
559      }
560      cpt++;
561    }
562    traite->gauche[j] = '\0';
563    traite->alpha[k] = '\0';
564    traite->droite[l] = '\0';
565 
566    return ;
567 }
568 /* ###--------------------------------------------------------------### */
569 /* function     : CreatePagrp                                           */
570 /* description  : add a new PAGRP, set hash tab and ident tab & index   */
571 /* called func. : SymbAlloc, pat_addpagrp, Erreur			*/
572 /* ###--------------------------------------------------------------### */
573 
CreatePagrp(ident,length,sens,type_vecteur)574 void CreatePagrp(ident,length,sens,type_vecteur)
575 char *ident;
576 int length,sens;
577 short type_vecteur;
578 {
579 int index;
580 elt *tmp_elt;
581 
582      index = GNP_PAIOL_INDEX - length;
583      if (index < 0 )
584          Erreur ( "PAGRP length doesnt match");
585 
586      if (ind_tab_ident >= GNP_MAXTAB_IDENT)
587          Erreur ("PAGRP too much declared identifiers");
588 
589      tmp_elt = SymbAlloc(ident,hash_pagrp);
590      racine_pagrp = pat_addpagrp(racine_pagrp,
591                               tmp_elt->name,
592                               length,
593                               index,
594 			      type_vecteur);
595 
596      tmp_elt->num_index = ind_tab_ident;
597      tmp_elt->sens = sens;
598      tab_ident[ind_tab_ident].duplicate  =ind_tab_ident;
599      tab_ident[ind_tab_ident++].pointeur =(void *)racine_pagrp;
600 }
601 
602 
603 /* ###--------------------------------------------------------------### */
604 /* function     : DupPaiol						*/
605 /* description  : Create (duplicate = -1) or duplicate a PAIOL struct	*/
606 /*	set PASEQ struct. and ident tab & index				*/
607 /* called func. : SymbAlloc, pat_addpaiol, ExisteIdent, Erreur		*/
608 /* ###--------------------------------------------------------------### */
609 
DupPaiol(duplicate,format,param_effectif,param_virtuel,i_o,blk,flg)610 void DupPaiol (duplicate,format,param_effectif,param_virtuel,i_o,blk,flg)
611 int duplicate;
612 char format;
613 char *param_effectif;
614 char *param_virtuel;
615 char i_o, blk, flg;
616 {
617 elt *tmp_elt_effectif;
618 elt *tmp_elt_virtuel;
619 
620      tmp_elt_virtuel = SymbAlloc (param_virtuel,hash_paiol);
621 
622      if (duplicate == GNP_NO_DUPLICATE)
623 	  tmp_elt_effectif = SymbAlloc(param_effectif,hash_paiol);
624      else
625           tmp_elt_effectif = ExisteIdent (param_effectif,hash_paiol);
626 
627      if (duplicate != tmp_elt_effectif->num_index)
628 	Erreur ("DupPaiol error unconstistent paiol references");
629 
630      if (ind_tab_ident >= GNP_MAXTAB_IDENT)
631          Erreur ("too mutch declared identifiers");
632 
633      tmp_elt_virtuel->num_index = ind_tab_ident;
634 
635      racine_paiol = pat_addpaiol(racine_paiol,
636                               tmp_elt_effectif->name,
637                               format,
638                               i_o,
639                               (char)((int)blk - (int)'0'));
640 
641      racine_paiol->FLAG = flg;
642 
643      IOLNUMBER++;
644 
645      if (duplicate != GNP_NO_DUPLICATE)
646      {
647          tab_ident[ind_tab_ident].duplicate = tab_ident[duplicate].duplicate;
648          tab_ident[duplicate].duplicate = ind_tab_ident;
649      }
650      else
651      {
652          tmp_elt_effectif->num_index = ind_tab_ident;
653          tab_ident[ind_tab_ident].duplicate = ind_tab_ident;
654      }
655 
656      tab_ident[ind_tab_ident].num_paiol = GNP_PAIOL_INDEX++;
657      tab_ident[ind_tab_ident++].pointeur =(void *)racine_paiol;
658 }
659 
660 
661 /* ###--------------------------------------------------------------### */
662 /* function     : CreatePaiol                                           */
663 /* description  : add a new PAIOL, set hash tab and ident tab & index   */
664 /* called func. : SymbAlloc, pat_addpaiol, Erreur                       */
665 /* ###--------------------------------------------------------------### */
666 
CreatePaiol(format,ident,mode,blk,flg)667 void CreatePaiol (format,ident,mode,blk,flg)
668 char format;
669 char *ident;
670 char mode,blk,flg;
671 {
672 elt *tmp_elt;
673 
674      if (ind_tab_ident >= GNP_MAXTAB_IDENT)
675          Erreur ("too mutch declared identifiers");
676 
677      tmp_elt = SymbAlloc(ident,hash_paiol);
678 
679      racine_paiol = pat_addpaiol(racine_paiol,
680                               tmp_elt->name,
681                               format,
682                               mode,
683                               (char)((int)blk - (int)'0'));
684 
685      racine_paiol->FLAG = flg;
686 
687      IOLNUMBER++;
688 
689      tmp_elt->num_index = ind_tab_ident;
690      tab_ident[ind_tab_ident].duplicate = ind_tab_ident;
691      tab_ident[ind_tab_ident].num_paiol = GNP_PAIOL_INDEX++;
692      tab_ident[ind_tab_ident++].pointeur =(void *)racine_paiol;
693 }
694 
695 
696 /* ###--------------------------------------------------------------### */
697 /* function     : EmpileParam                                           */
698 /* description  : push parameter in parameter stack			*/
699 /* called func. : Erreur						*/
700 /* ###--------------------------------------------------------------### */
701 
EmpileParam(param)702 void EmpileParam(param)
703 char *param;
704 {
705     if ( sp_pile_param >= GNP_MAXPILE_PARAM )
706 	Erreur (" no more place in param stack");
707 
708     pile_param[sp_pile_param ++] = param ;
709 }
710 
711 /* ###--------------------------------------------------------------### */
712 /* function     : DefileParam                                           */
713 /* description  : unchain parameter					*/
714 /* called func. : Erreur						*/
715 /* ###--------------------------------------------------------------### */
716 
DefileParam()717 char *DefileParam()
718 {
719     if (  sp_file_param > sp_pile_param )
720 	Erreur("empty parameter file");
721 
722     return ( pile_param[sp_file_param++] ) ;
723 }
724 
725 
726 
727 
728 /* ###--------------------------------------------------------------### */
729 /* function     : FusionPaevt                                           */
730 /* description  : add a list of PAEVT at the and of a PAEVT list        */
731 /* called func. : FusionPaevt, Erreur                                   */
732 /* ###--------------------------------------------------------------### */
733 
FusionPaevt(lst_event,tete_event)734 struct paevt *FusionPaevt (lst_event,tete_event)
735 struct paevt *lst_event;
736 struct paevt *tete_event;
737 {
738 struct paevt *tmp_paevt = tete_event;
739 
740   if (tete_event == NULL) return(lst_event);
741   if (lst_event == NULL) return(tete_event);
742 
743   while ( (tmp_paevt->NEXT) != NULL )
744     tmp_paevt = tmp_paevt->NEXT;
745 
746   tmp_paevt->NEXT = lst_event;
747 
748   return (tete_event);
749 }
750 
751 
752 
753 /* ###--------------------------------------------------------------### */
754 /* function     : CreateAction                                          */
755 /* description  : Change ACTFLAG flag in PAPAT 				*/
756 /* called func. : none                                                  */
757 /* ###--------------------------------------------------------------### */
758 
CreateAction(act_type)759 void CreateAction (act_type)
760 char *act_type;
761 {
762 char car_act;
763 struct papat *tmp_papat;
764 
765    tmp_papat = racine_papat;
766 
767 /* recherche de l'emplacement du papat dans la liste des papat */
768 
769    if (tmp_papat == NULL)
770       Erreur("CreateAction error not yet created pattern");
771 
772    while ((tmp_papat != NULL) && (tmp_papat->TIME > GNP_PATTERN_COURANT))
773       tmp_papat = tmp_papat->NEXT;
774 
775    if (tmp_papat == NULL)
776       Erreur("CreateAction error not yet created pattern");
777 
778    if (tmp_papat->TIME != GNP_PATTERN_COURANT)
779      Erreur ("CreateAction  : error in data structure");
780 
781    car_act = *act_type;
782    tmp_papat->ACTFLAG = car_act;
783 }
784 
785 
786 /* ###--------------------------------------------------------------### */
787 /* function     : FusionPaini                                           */
788 /* description  : merge two initialization lists			*/
789 /* called func. : none							*/
790 /* ###--------------------------------------------------------------### */
791 
FusionPaini(fst_ini,scd_ini)792 struct paini *FusionPaini (fst_ini, scd_ini)
793 
794 struct paini *fst_ini;
795 struct paini *scd_ini;
796 
797   {
798   struct paini *res_ini;
799 
800   if (fst_ini == NULL)
801     res_ini = scd_ini;
802   else
803     {
804     res_ini = fst_ini;
805     while (res_ini->NEXT != NULL)
806       res_ini = res_ini->NEXT;
807 
808     res_ini->NEXT = scd_ini;
809     res_ini       = fst_ini;
810     }
811 
812   return (res_ini);
813   }
814 
815 
816 /* ###--------------------------------------------------------------### */
817 /* function     : CreatePapat                                           */
818 /* description  : add  or set a PAPAT struct in PAPAT list              */
819 /* called func. : pat_addpacom, TriFusion				*/
820 /* ###--------------------------------------------------------------### */
821 
CreatePapat(label,lst_event,lst_ini)822 void CreatePapat (label,lst_event,lst_ini)
823 
824 char         *label;
825 struct paevt *lst_event;
826 struct paini *lst_ini;
827 
828   {
829   struct papat *fils_papat;
830   struct papat *pere_papat;
831   struct papat *tmp_papat;
832   int           size;
833 
834 
835   if (racine_papat == NULL)
836     {
837 
838 /* first PAPAT to be created */
839 
840     racine_papat = pat_addpapat (NULL, namei (label,GNP_PATTERN_COURANT),
841                                  GNP_PATTERN_COURANT);
842     racine_papat->TIME = GNP_PATTERN_COURANT;
843     racine_papat->PAEVT = lst_event;
844     racine_papat->PAINI = lst_ini;
845     PATNUMBER = 1;
846     }
847   else
848     {
849 
850 /* putting fils_papat after or on the good papat */
851 
852     pere_papat = racine_papat;
853     fils_papat = racine_papat;
854 
855     while ((fils_papat != NULL) && (fils_papat->TIME > GNP_PATTERN_COURANT))
856       {
857       pere_papat = fils_papat;
858       fils_papat = fils_papat->NEXT;
859       }
860 
861     if ( (fils_papat == NULL) || (fils_papat->TIME < GNP_PATTERN_COURANT) )
862       {
863 
864 /* fils_papat is after the good papat or NULL*/
865 
866 
867       tmp_papat = pat_addpapat (fils_papat, namei(label, GNP_PATTERN_COURANT),
868                                 GNP_PATTERN_COURANT);
869       tmp_papat->TIME = GNP_PATTERN_COURANT;
870       tmp_papat->PAEVT = lst_event;
871       tmp_papat->PAINI = lst_ini;
872       PATNUMBER++;
873 
874       if (pere_papat == fils_papat )
875         racine_papat     = tmp_papat;
876       else
877         pere_papat->NEXT = tmp_papat;
878 
879       }
880     else
881       {
882 
883 /* fils_papat is on the good papat */
884 
885 
886       fils_papat->PAEVT = FusionPaevt (lst_event, fils_papat->PAEVT);
887       fils_papat->PAINI = FusionPaini (lst_ini  , fils_papat->PAINI);
888       if (label != NULL)
889         fils_papat->LABEL = namei(label,GNP_PATTERN_COURANT);
890       }
891     }
892 
893   if ( label != NULL)
894     {
895     size = strlen (namei (label, GNP_PATTERN_COURANT));
896     if (MAX_LABEL < size)
897     MAX_LABEL = size;
898     }
899   }
900 
901 
902 /* ###--------------------------------------------------------------### */
903 /* function     : CreatePaevt                                           */
904 /* description  : add a PAEVT struct at the end of a PAEVT list         */
905 /* warning	: parameters validity is not tested			*/
906 /* called func. : pat_addpacom, TriFusion				*/
907 /* ###--------------------------------------------------------------### */
908 
CreatePaevt(tete_paevt,num_ident,valeur)909 struct paevt *CreatePaevt(tete_paevt,num_ident,valeur)
910 struct paevt *tete_paevt;
911 int num_ident;
912 char valeur;
913 {
914 struct paevt *tmp_paevt ;
915 
916   tmp_paevt = pat_addpaevt(NULL,tab_ident[num_ident].num_paiol,valeur);
917   tete_paevt = FusionPaevt(tmp_paevt,tete_paevt);
918   return (tete_paevt);
919 }
920 
921 
922 /* ###--------------------------------------------------------------### */
923 /* function     : MajPatternCourrant                                    */
924 /* description  : Set current pattern number 				*/
925 /* called func. : atoi                                                  */
926 /* ###--------------------------------------------------------------### */
927 
MajPatternCourant(pattern)928 void MajPatternCourant(pattern)
929 char *pattern;
930 {
931 unsigned long relatif = 0, valeur;
932 
933      if(*pattern == '+')
934      {
935          relatif = 1;
936          pattern++;
937      }
938      valeur = atoi (pattern);
939      GNP_PATTERN_COURANT = (GNP_PATTERN_COURANT * relatif) + valeur;
940 }
941 
942 
943 /* ###--------------------------------------------------------------### */
944 /* function     : FormatValue						*/
945 /* description  : change inout value to binary according to format      */
946 /* called func. : Erreur						*/
947 /* ###--------------------------------------------------------------### */
948 
FormatValue(ret_val,value,nb_car,sens,i_o)949 void FormatValue (ret_val,value,nb_car,sens,i_o)
950 char *ret_val;
951 char *value;
952 int nb_car, sens;
953 int i_o;
954 {
955 char *valeur;
956 char *res;
957 int lg,i,li;
958 char  tmp [64];
959 char flg =' ';
960 
961    valeur = value ;
962    if (i_o == 0)
963      {
964         lg = strlen (valeur);
965         for (i = 0; i< lg ; i++)
966         {
967            if (*valeur == '*')
968 	    Erreur ("AFFECT/INIT incorrect input or init-value syntax");
969            valeur ++;
970         }
971 	valeur = value;
972      }
973 
974    if (strlen (valeur) >1)
975      valeur++;
976    switch (*valeur)
977    {
978      case 'b': case 'B':
979      {
980         valeur++;
981         lg = strlen (valeur);
982         strcpy (ret_val,"\0");
983         for (i = 0 ; i < lg ; i++)
984         {
985             switch (*valeur)
986             {
987                case '0': { strcat (ret_val,"-");  break; }
988                case '1': { strcat (ret_val,"+");  break; }
989                case '*': { strcat (ret_val,"*");
990 			   flg='*';
991 			   break; }
992                default :
993                   Erreur ("AFFECT/INIT incorrect binary format");
994             }
995             valeur++;
996         }
997         break;
998      }
999      case 'o': case 'O':
1000      {
1001         valeur++;
1002         lg = strlen (valeur);
1003         strcpy (ret_val,"\0");
1004         for (i = 0 ; i < lg ; i++)
1005         {
1006             switch (*valeur)
1007             {
1008                case '0': { strcat (ret_val,"---");  break; }
1009                case '1': { strcat (ret_val,"--+");  break; }
1010                case '2': { strcat (ret_val,"-+-");  break; }
1011                case '3': { strcat (ret_val,"-++");  break; }
1012                case '4': { strcat (ret_val,"+--");  break; }
1013                case '5': { strcat (ret_val,"+-+");  break; }
1014                case '6': { strcat (ret_val,"++-");  break; }
1015                case '7': { strcat (ret_val,"+++");  break; }
1016                case '*': { strcat (ret_val,"***");
1017 			   flg='*';
1018 			   break; }
1019                default :  Erreur ("AFFECT/INIT incorrect octal format");
1020             }
1021             valeur++;
1022         }
1023         break;
1024      }
1025      case 'x': case 'X':
1026      {
1027 	valeur++;
1028         lg = strlen (valeur);
1029         strcpy (ret_val,"\0");
1030         for (i = 0 ; i < lg ; i++)
1031         {
1032             switch (*valeur)
1033             {
1034                 case '0': { strcat (ret_val,"----"); break; }
1035                 case '1': { strcat (ret_val,"---+"); break; }
1036                 case '2': { strcat (ret_val,"--+-"); break; }
1037                 case '3': { strcat (ret_val,"--++"); break; }
1038                 case '4': { strcat (ret_val,"-+--"); break; }
1039                 case '5': { strcat (ret_val,"-+-+"); break; }
1040                 case '6': { strcat (ret_val,"-++-"); break; }
1041                 case '7': { strcat (ret_val,"-+++"); break; }
1042                 case '8': { strcat (ret_val,"+---"); break; }
1043                 case '9': { strcat (ret_val,"+--+"); break; }
1044                 case 'A': case 'a': { strcat (ret_val,"+-+-"); break; }
1045                 case 'B': case 'b': { strcat (ret_val,"+-++"); break; }
1046                 case 'C': case 'c': { strcat (ret_val,"++--"); break; }
1047                 case 'D': case 'd': { strcat (ret_val,"++-+"); break; }
1048                 case 'E': case 'e': { strcat (ret_val,"+++-"); break; }
1049                 case 'F': case 'f': { strcat (ret_val,"++++"); break; }
1050                 case '*': { strcat (ret_val,"****");
1051 			    flg='*';
1052 			    break; }
1053                 default : Erreur ("AFFECT/INIT incorrect hexad. format");
1054             }
1055             valeur++;
1056         }
1057         break;
1058      }
1059      default :
1060      {
1061 	valeur = value;
1062         lg = strlen (valeur);
1063         for (i = 0; i< lg ; i++)
1064         {
1065            if ( isdigit(*valeur)  == 0  )
1066 	    Erreur ("AFFECT/INIT incorrect decimal format");
1067            valeur ++;
1068         }
1069 	li = atoi(value);
1070 
1071 	valeur = ret_val;
1072 	while(li != 0)
1073 	{
1074 	   if ( (li & 0x01) == 1)
1075 	     *valeur++ = '+';
1076 	   else
1077 	     *valeur++ = '-';
1078 	   li = li >> 1;
1079 
1080 	}
1081 	if ( valeur == ret_val )
1082 	  *valeur++ = '-';
1083 	*valeur = '\0';
1084 
1085 	valeur = ret_val;
1086 	lg = strlen(ret_val);
1087 	for(i = lg-1; i>=0; i--) tmp[i]=*valeur++;
1088 	tmp[lg]= '\0';
1089 	strcpy(ret_val,tmp);
1090 	break;
1091      }
1092    }
1093 /* ajuster la longueur de la chaine en moins */
1094    lg = strlen (ret_val);
1095    if (lg > nb_car)
1096    {
1097        valeur = res = ret_val ;
1098        printf ("line %u :VALUE too large value: MSB are truncated\n",GNP_LINE);
1099        for (i = 0; i< (lg - nb_car) ; i++,res++);
1100        while ( *res != '\0')
1101        {
1102          *valeur = *res;
1103           valeur++;
1104 	  res++;
1105        }
1106        *valeur = '\0';
1107    }
1108 /* ajuster la longueur de la chaine en + avec des 0 */
1109    if (lg < nb_car)
1110    {
1111       valeur = ret_val;
1112       for (i = 0 ; i < (nb_car - lg) ; i ++) tmp[i] = '-';
1113 
1114       for (i = i ; i < nb_car ; i ++)  tmp[i] = *valeur++;
1115 
1116       tmp[i] = '\0';
1117       strcpy (ret_val,(char *)tmp);
1118    }
1119    if (sens == GNP_UP)
1120    {
1121 /* inverser la chaine */
1122       valeur = ret_val;
1123       for (i = nb_car-1 ; i >=0 ; i--)  tmp[i] = *valeur++;
1124       tmp[nb_car] = '\0';
1125       strcpy (ret_val,(char *)tmp);
1126    }
1127 /* ajuster le format */
1128    if ((i_o == 0) || (flg == '*'))
1129    {
1130     valeur = ret_val;
1131     for (i = nb_car-1 ; i>= 0 ; i--)
1132      if (flg == '*')
1133 	*valeur++ = '*';
1134      else
1135      {
1136         *valeur = ( (*valeur == '-') ? '0' : '1' );
1137 	valeur++;
1138      }
1139    }
1140 }
1141