#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAXLINE 256

int input(FILE *fp, char **mass)
	{
	char word0[MAX];
	int i = 0, j = 0;
	
	while ((c = gets(fp)) != EOF)
		{
		while ((c != ' ') || (c != EOF))
			{
			word0[j++] = c;
			c = gets(fp);
			}
		if (j != 0) 
			{
			word0[j] = '\0';
			*mass[++i] = (char*)malloc(sizeof(char) * j);
			strcpy(mass[i],word0);
			}
		j = 0;
		}
	if (i == 0) 
		{
		fprintf(stderr, "diff.input: file is empty");
		}
	return i;
	}

void Print-LSC(char *strel, char **f2, int i, int j, int m, int *l,int *pr)
	{
	while ((i != 0) && (j != 0))
		{
		switch (strel[i*m+j])
			{
			case -1 :
				{
				++(*l);
				Print-LSC(strel, f2, --i, --j, m, l, pr);
				printf("*%d\n",*l);
				*l = 0;
				break;
				}
			case  0 :
				{
				Print-LSC(strel, f2, --i, j, m, l, pr);
				printf("+%s\n",*f2[++i]);
				break;
				}
			case  1 :
				{
				++(*pr);
				Print-LSC(strel, f2, i, --j, m, l, pr);
				printf("-%s\n",*pr);
				*pr = 0;
				break;
				}
			}
		}
	 return;
	}
	
void LCS-Length(char **f1, char **f2, int n, int m)
	{
	int i, j, *l = 0, *pr = 0, *mass;
	char  *strel;
	
	mass = (int*)malloc(sizeof(int) * m * n);
	strel = (char*)malloc(sizeof(char) * m * n);
	for(i = 1;i <= n; i++) mass[i*m] = 0;
	for(j = 0;j <= m; j++) mass[j] = 0;
	for(i = 1;i <= n; i++) 
		{
		for(j = 1;j <= m; j++)
			{
			if (strcmp(*f1[j],*f2[i]))
				{
				mass[i*m+j] = mass[(i-1)*m+(j-1)] + 1;
				strel[i*m+j] = 0;
				}
			else if (mass[(i-1)*m+j] >= mass[i*m+(j-1)])
					{
					mass[i*m+j] = mass[(i-1)*m+j];
					strel[i*m+j] = 1;
					}
				else
					{
					mass[i*m+j] = mass[i*m+(j-1)];
					strel[i*m+j] = -1;
					}
			}
		}
	Print-LSC(strel, f2, i, j, m, l, pr)
	
	return;
	}

void compare(FILE *fp1, FILE *fp2)
	{
	int m, n;
	char **f1, **f2;
	
	m = input(fp1, f1);
	if (m != 0)
		{
		n = input(fp2, f2);
		if (n != 0)
			{
			LCS-Length(f1, f2, n, m);
			}
		}
	return;
	}
	
void patch(FILE *fp1, FILE **fp2, char *name)
	{
	int m, i = 1;
	char **f2, c, word[MAX];
	
	m = input(*fp2, f2);
	fclose(*fp2);
	*fp2 = fopen(name, "w");
	if (m != 0)
		{
		c = gets(fp1);
		while (c != EOF)
			{
			switch (c)
				{
				case '-' : 
					{
					c = gets(fp1);
					if ((isdigit(c) || (c != EOF))
						i += atoi(c);
					else 
						{
						fprintf(stderr, "diff.patch: script is incorrect");
						return;
						}
					c = gets(fp1);
					break;
					}
				case '+' :
					{
					i = 0;
					c = gets(fp1);
					while ((c != '-') || (c != EOF)) || (c != '-') || (c != '-'))
						{
						word[i++] = c;
						c = gets(fp1);
						}
					if (i != 0) 
						{
						word[i] = '\0';
						fprintf(fp2,"%s",*word);
						}
					else fprintf(stderr, "diff.patch: script is incorrect");
					if (c != EOF) return;
					break;
					}
				case '*' :
					{
					c = gets(fp1);
					if ((isdigit(c) || (c != EOF))
						for (i = 1;i <= atoi(c); i++) 
							fprintf(fp2,"%s",*f2[i]);
					else 
						{
						fprintf(stderr, "diff.patch: script is incorrect");
						return;
						}
					c = gets(fp1);
					break;
					}
				default : fprintf(stderr, "diff.patch: script is incorrect");
				}
			}
		
		}
	return;
	}

int main(int argc, char *argv[])
	{
	char *prog = argv[0];
	FILE *fp1, *fp2;
	
	if (argc == 3)
		{
		fp1 = fopen(argv[2], "r");
		fp2 = fopen(argv[3], "r");
		if (strcmp(argv[1], "--patch")) patch(fp1, &fp2, argv[1]);
		else if (strcmp(argv[1], "--compare")) compare(fp1, fp2);
			else fprintf(stderr, "diff.main: error in mode");
		fclose(fp1);
		fclose(fp2);
		}
	else fprintf(stderr, "diff.main: error in number of arguments");
	
	return 0;
	}
	
	