/*				pfl.c

	kontextsensitive substitution von charakteren in buffern
	
	(c) jaenner 1993 by ingo kloeckl jr.

*/

#define TEST 0

#include <stdio.h>
#define MAX_S 		20
#define MAX_ENTRY	20
#define BUF_SIZE	32767

FILE *fopen(), *in, *out;

typedef struct subs 
{
	char	sub[MAX_S], 
			ins[MAX_S];
	int		from,
			to;
};

struct subs sub_table[MAX_ENTRY];

char *buffer, *buf_end;
int sub_cnt = 0;

main(int argc, char **argv)
{
	char i_file[80], o_file[80];
	char *ps, *rindex(), *buf;
	int gen;
	
	printf("**** pflc - (c) 1993 by IK ****\n\n");
	if ( argc<3 )
	{
		printf("\007usage : pflc infile gen_int\n\n");
	    exit(1);
	}
	strcpy(i_file, *++argv);
	strcpy(o_file, i_file); 
	if ( (ps = rindex(o_file, '.')) )
	{
		*ps = '_';
	}
	strcat(o_file,".pre");
	printf("Gen=%d\n",gen = atoi(*++argv));
	printf("Files : -%s-\n-%s-\n",i_file,o_file);
	buf = buffer = (char *)malloc(BUF_SIZE);

	printf("reading subsitutions...\n");
	in = fopen(i_file,"r");
	read_subs();
	while ( !feof(in)) 
	{
		printf("%d\n",*++buf = fgetc(in));
	}
	fclose(in);
	*(--buf) = '\0';
	buf_end = buf;
	printf("%d chars read to buffer\n",buf-buffer);
	printf("\n\nbuffer: -%s-\n",buffer);

	out = fopen(o_file,"w");
	substitue(gen);
	for ( ; buffer<=buf_end; buffer++)
	{
		fputc((int)*buffer,out);
	}
	fclose(out);
}

substitue(int gen)
{
	int i, j, cntrl, delta, from, to, l;
	char *ptr, *h1_ptr, *h2_ptr;

	for (i=gen; i; i--)
	{
		ptr = buffer;
	    printf("Gen. %d\n",i);
	    while ( ptr <= buf_end )
	    {
			j = 1;
			while ( j<=sub_cnt && ( cntrl = strncmp(ptr, sub_table[j].sub, l = strlen(sub_table[j].sub)) ) )
			{
				j++;
			}
			if ( !cntrl )
		    {
				from = sub_table[j].from;
				to = sub_table[j].to;
				delta = strlen(sub_table[j].ins);
				replace(ptr, sub_table[j].ins, 1+from, to-from+1);
				ptr += delta + l - (to-from+1);
				buf_end += delta -(to-from+1);
		    }
			else
			{
				ptr++;
			}
		}
	    printf("%s\nLaenge : %d\n--------\n",buffer,buf_end-buffer);
	}
}


read_subs()
{
	int i, j;
	char *ptr, c;

	while ( ( c = fgetc(in)) == '&' )
	{
		for(i=6; i; fgetc(in), i--);  /*  skip 'define'  */
		while ( ( c = fgetc(in) ) == ' ');
		*(ptr = sub_table[++sub_cnt].sub) = c;
		while ( ( *++ptr = fgetc(in) ) != ' ');
		*ptr = '\0';
		ptr = sub_table[sub_cnt].ins;
	    while ( ( *ptr++ = fgetc(in) ) != ' ');
	    *--ptr = '\0';
	    fscanf(in,"%d",&sub_table[sub_cnt].from);
	    fscanf(in,"%d",&sub_table[sub_cnt].to);
	    fgetc(in);
	    printf("cnt = %d\n",sub_cnt);
	    printf("%s replaced by %s\n",sub_table[sub_cnt].sub,sub_table[sub_cnt].ins);
	    printf("  kontext switches %d %d\n",sub_table[sub_cnt].from,sub_table[sub_cnt].to);

	}
	printf("\n buffer : -%c-\n",*buffer = c);
}


char *rindex(char *str, char c)
{
	char *hlp;

	hlp = str+strlen(str);
	while ( hlp >= str  &&  ( *hlp != c ) ) 
	{
		hlp--;
	}
	return( (hlp<str) ? 0 : hlp );
}


replace(char *scr, char *instr, int pos, int repanz)
{
	int inlen, scrlen;
	char *temp, *memo = scr;

	scrlen = strlen(scr);
	if ( pos > scrlen ) return(0);
	inlen = strlen(instr);
	if ( inlen<repanz )
	{
		temp = scr+pos-1+repanz;
	    scr += pos-1+inlen;
	    while ( *scr++ = *temp++ );
	    *scr = '\0';
	}
	else if ( inlen>repanz )
	{
		register int i;
	    temp = scr + scrlen;
	    scr += scrlen-repanz+inlen;
	    for ( i=scrlen-pos-repanz+1; i>=0; *scr-- = *temp--, i--);
	}
	scr = memo + pos - 1;
	while ( *instr )
	{
		*scr++ = *instr++;
	}
	scr = memo;
}
