/************************************************************************
*       MBK : Parser alliance logic                                     *
*                                                                       *
*	version : 4.01					                                    *
*	date	: 23/07/92				                                    *
************************************************************************/

#include <ctype.h>
#include <string.h>
#include "generic_target.h"
#include MUT_H
#include MLO_H
#include MLU_H

#define TAILLE_CHAINE BUFSIZE

/************************************************************************
*                  alc_typecode()                                       *
************************************************************************/
char alc_typedecode(type)
char * type;
{
	switch (type[0])
	{
		case 'E' :
			return EXTERNAL;
		default :
		case 'I' :
			return INTERNAL;
	}
}

/************************************************************************
*                  alcloadlofig4()                                      *
************************************************************************/

void alcloadlofig4(pfig,fname,mode,in)
lofig_list * pfig;
char * fname;
char mode;
FILE * in;
{
	chain_list * pchains;
	lofig_list * ptfigmodele;
	lofig_list * tetemodele = NULL;
	losig_list * psig;
	char ligne[TAILLE_CHAINE];
	char nomtmp[TAILLE_CHAINE], * paux, *ptemp;
	char * type, decodedtype, * name, insname[TAILLE_CHAINE], figname[TAILLE_CHAINE], inst_avant, nomodele;
	long i, index, l, w, x, y, ps, pd, xs, xd, equig, equid, equis;
	float capa;
/* to check signal name unicity */
	ht * h;

/* Analyse de la ligne d'entete H */
	(void)fgets(ligne,TAILLE_CHAINE,in);
	if (ligne[0]!='H')
	{
		(void)fprintf(stderr,"\n*** mbk error *** line 2 unexpected, header needed\n");
		EXIT(1);
	}
	if ((paux=(char *)strchr(ligne,',')) == NULL)
	{
		(void)fprintf(stderr,"\n*** mbk error *** syntax error line : 2\n");
		EXIT(1);
	}
	*paux='\0';
/* controle du nom */
	if (strcmp(ligne+2,fname)!=0)
	{
		(void)fprintf(stderr,"\n*** mbk error *** invalid name, line : 2\n");
		EXIT(1);
	}
	paux++;
/*controle du type de fichier */
	if (*paux!='L')
	{
		(void)fprintf(stderr,"\n*** mbk error *** bad file type\n");
		EXIT(1);
	}
/* boucle de lecture */
	inst_avant  = nomodele = 0;
	h = addht (100); /* create Hash Table for signal name unicity */
	for(i=3;;i++)
	{
		if (fgets(ligne,TAILLE_CHAINE,in)==NULL)
		{
			(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
			EXIT(1);
		}
		if (strncmp(ligne,"EOF",3)==0)
			break;
		switch(ligne[0])
		{
			case 'C' :
				if ((mode == 'C') && (!inst_avant))
					continue;
				name = ligne + 2;
				if ((paux=(char *)strchr(ligne+2,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				type = ptemp;
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				decodedtype = alc_typedecode(ptemp);
				ptemp=paux+1;
				index = atol(ptemp);
				if (inst_avant)
				{
					if (decodedtype != INTERNAL)
					{
						(void)fprintf(stderr,"\n*** mbk Warning *** loadlofig (al) bad connector direction line : %d\n",i);
					}
					psig = givelosig(ptfigmodele,index);
					psig->TYPE = 'E';
					if (nomodele)
						(void)addlocon(ptfigmodele,name,psig,alc_directiondecode(type));
					pchains = addchain(pchains,(void *)givelosig(pfig,index));
				}
				else
				{
					if (decodedtype != EXTERNAL)
					{
						(void)fprintf(stderr,"\n*** mbk Warning *** loadlofig (al) bad connector direction line : %d\n",i);
					}
					psig = givelosig(pfig,index);
					psig->TYPE = 'E';
					(void)addlocon(pfig,name,psig,alc_directiondecode(type));
				}
				break;
			case 'T' :
				if (mode == 'P')
					goto end_lopars;
				if (inst_avant)
				{
					(void)addloins(pfig,insname,ptfigmodele,pchains);
					freechain(pchains);
				}
				inst_avant = 0;
				pchains = NULL;
				if ((paux=(char *)strchr(ligne+2,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				ptemp=paux+1;
				type = ligne+2;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				l = (long)(atof(ptemp) * (float)SCALE_X);
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				w = (long)(atof(ptemp) * (float)SCALE_X);
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				equid = atol(ptemp);
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				equig = atol(ptemp);
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				equis = atol(ptemp);
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				xs = (long)(atof(ptemp) * (float)SCALE_X);
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				xd = (long)(atof(ptemp) * (float)SCALE_X);
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				ps = (long)(atof(ptemp) * (float)SCALE_X);
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				pd = (long)(atof(ptemp) * (float)SCALE_X);
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				x = (long)(atof(ptemp) * (float)SCALE_X);
				ptemp=paux+1;
				y = (long)(atof(ptemp) * (float)SCALE_X);
				(void)addlotrs(pfig, (*type == 'N') ? TRANSN : TRANSP, x, y, w, l, ps, pd, xs, xd, givelosig(pfig,equig), givelosig(pfig,equis), givelosig(pfig,equid));
				break;
			case 'I' :
				if (mode == 'P')
					goto end_lopars;
				if (inst_avant)
				{
					(void)addloins(pfig,insname,ptfigmodele,pchains);
					freechain(pchains);
				}
				pchains = NULL;
				inst_avant = 1;
				if ((paux=(char *)strchr(ligne+2,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				(void)strcpy(figname,ligne+2);
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,'\n')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				(void)strcpy(insname,ptemp);
				if ((ptfigmodele = getlomodel(tetemodele,figname)) == NULL)
				{
					nomodele = 1;
					ptfigmodele = tetemodele = addlomodel(tetemodele,figname);
				}
				else
					nomodele = 0;
				break;
			case 'S' :
				if (mode == 'P')
					goto end_lopars;
				if (inst_avant)
				{
					(void)addloins(pfig,insname,ptfigmodele,pchains);
					freechain(pchains);
				}
				pchains = NULL;
				inst_avant = 0;
				if ((paux=(char *)strchr(ligne+2,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				index = atol(ligne+2);
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				decodedtype = alc_typedecode(ptemp);
				psig = givelosig(pfig,index);
				psig->TYPE = decodedtype;
				ptemp=paux+1;
				if ((paux=(char *)strchr(ptemp,',')) == NULL)
				{
					capa = atof(ptemp);
					addcapa(psig,capa);
					(void)sprintf(nomtmp,"mbk_sig%d", index);
					if (sethtitem(h, namealloc (nomtmp), 0))
					{
						for (paux = nomtmp; *paux != '\0'; paux++);
						*(paux + 11) = '\0';
						for (x = (long)'a'; x <= (long)'z'; x++)
						for (y = (long)'a'; y <= (long)'z'; y++)
						for (l = (long)'a'; l <= (long)'z'; l++)
						for (w = (long)'a'; w <= (long)'z'; w++)
						for (ps = (long)'a'; ps <= (long)'z'; ps++)
						for (pd = (long)'a'; pd <= (long)'z'; pd++)
						for (xs = (long)'a'; xs <= (long)'z'; xs++)
						for (xd = (long)'a'; xd <= (long)'z'; xd++)
						for (equig = (long)'a'; equig <= (long)'z'; equig++)
						for (equid = (long)'a'; equid <= (long)'z'; equid++)
						for (equis = (long)'a'; equis <= (long)'z'; equis++)
						{
							*paux = (char)x;
							*(paux + 1) = (char)y;
							*(paux + 2) = (char)l;
							*(paux + 3) = (char)w;
							*(paux + 4) = (char)ps;
							*(paux + 5) = (char)pd;
							*(paux + 6) = (char)xs;
							*(paux + 7) = (char)xd;
							*(paux + 8) = (char)equig;
							*(paux + 9) = (char)equid;
							*(paux + 10) = (char)equis;
							
							if (!sethtitem(h, namealloc(nomtmp), 0))
							{
								goto break_11_for;
								
							}
						}
					}
break_11_for:					
					psig->NAMECHAIN = addchain(psig->NAMECHAIN,(void *)namealloc(nomtmp));
					break; /* case 'S' : */
				}
				*paux='\0';
				capa = atof(ptemp);
				addcapa(psig,capa);
				/* restore NAMECHAIN */
				x = 1;
				ptemp=paux+1;
				while ((paux=(char *)strchr(ptemp,',')) != NULL)
				{
					*paux='\0';
					if ((*ptemp != '\0') && (strcmp(ptemp,"*") != 0))
					{
						x++;
						psig->NAMECHAIN = addchain(psig->NAMECHAIN,(void *)namealloc(ptemp));
					}
					ptemp=paux+1;
				}
				if ((paux=(char *)strchr(ptemp,'\n')) == NULL)
				{
					(void)fprintf(stderr,"\n*** mbk error *** syntax error line : %d\n",i);
					EXIT(1);
				}
				*paux='\0';
				if ((*ptemp != '\0') && (strcmp(ptemp,"*") != 0))
				{
					x++;
					psig->NAMECHAIN = addchain(psig->NAMECHAIN,(void *)namealloc(ptemp));
				}
				/* set only one valid name for the signal */
				while (x > 0)
				{
					paux = getsigname(psig);
					if (sethtitem(h, paux, 0)) /* check unicity */
					{ /* name is not unique */
						for (pchains = psig->NAMECHAIN; pchains; pchains = pchains->NEXT)
							if (paux == ((char *)(pchains->DATA)))
								break;
						if (pchains)
							psig->NAMECHAIN = delchain (psig->NAMECHAIN, pchains);
						pchains = NULL;
						x --;
					}
					else
						break;
				}
				freechain (psig->NAMECHAIN);
				psig->NAMECHAIN = NULL;

				if (x <= 0)
				{ /* no unique name is found in the list, generate one */
					(void)sprintf(nomtmp,"mbk_sig%d", index);
					if (sethtitem(h, namealloc(nomtmp), 0))
					{
						for (paux = nomtmp; *paux != '\0'; paux++);
						*(paux + 11) = '\0';
						for (x = (long)'a'; x <= (long)'z'; x++)
						for (y = (long)'a'; y <= (long)'z'; y++)
						for (l = (long)'a'; l <= (long)'z'; l++)
						for (w = (long)'a'; w <= (long)'z'; w++)
						for (ps = (long)'a'; ps <= (long)'z'; ps++)
						for (pd = (long)'a'; pd <= (long)'z'; pd++)
						for (xs = (long)'a'; xs <= (long)'z'; xs++)
						for (xd = (long)'a'; xd <= (long)'z'; xd++)
						for (equig = (long)'a'; equig <= (long)'z'; equig++)
						for (equid = (long)'a'; equid <= (long)'z'; equid++)
						for (equis = (long)'a'; equis <= (long)'z'; equis++)
						{
							*paux = (char)x;
							*(paux + 1) = (char)y;
							*(paux + 2) = (char)l;
							*(paux + 3) = (char)w;
							*(paux + 4) = (char)ps;
							*(paux + 5) = (char)pd;
							*(paux + 6) = (char)xs;
							*(paux + 7) = (char)xd;
							*(paux + 8) = (char)equig;
							*(paux + 9) = (char)equid;
							*(paux + 10) = (char)equis;
							
							if (!sethtitem(h, namealloc(nomtmp), 0))
							{
								goto break_11_for2;
								
							}
						}
					}
break_11_for2:
					paux = nomtmp;
				}
				psig->NAMECHAIN = addchain(psig->NAMECHAIN,(void *)namealloc(paux));
				break;
			default :
				(void)fprintf(stderr,"\n*** mbk error *** line %d unexpected\n",i);
				EXIT(1);
				
		}
	}
end_lopars :
	if (inst_avant)
	{
		(void)addloins(pfig,insname,ptfigmodele,pchains);
		freechain(pchains);
	}
	delht(h); /* delete the Hash Table */
	freelomodel(tetemodele);
}

