xref: /csrg-svn/usr.bin/diff/diffh/diffh.c (revision 17603)
1*17603Sralph static	char sccsid[] = "@(#)diffh.c 4.3 01/02/85";
21324Sbill 
31324Sbill #include <stdio.h>
41324Sbill #include <ctype.h>
51324Sbill #include <sys/types.h>
61324Sbill #include <sys/stat.h>
71324Sbill 
81324Sbill #define C 3
91324Sbill #define RANGE 30
101324Sbill #define LEN 255
111324Sbill #define INF 16384
121324Sbill 
131324Sbill char *text[2][RANGE];
141324Sbill long lineno[2] = {1, 1};	/*no. of 1st stored line in each file*/
151324Sbill int ntext[2];		/*number of stored lines in each*/
161324Sbill long n0,n1;		/*scan pointer in each*/
171324Sbill int bflag;
181324Sbill int debug = 0;
191324Sbill FILE *file[2];
201324Sbill 
211324Sbill 	/* return pointer to line n of file f*/
221324Sbill char *getl(f,n)
231324Sbill long n;
241324Sbill {
251324Sbill 	register char *t;
261324Sbill 	char *malloc();
271324Sbill 	register delta, nt;
281324Sbill again:
291324Sbill 	delta = n - lineno[f];
301324Sbill 	nt = ntext[f];
311324Sbill 	if(delta<0)
321324Sbill 		progerr("1");
331324Sbill 	if(delta<nt)
341324Sbill 		return(text[f][delta]);
351324Sbill 	if(delta>nt)
361324Sbill 		progerr("2");
371324Sbill 	if(nt>=RANGE)
381324Sbill 		progerr("3");
391324Sbill 	if(feof(file[f]))
401324Sbill 		return(NULL);
411324Sbill 	t = text[f][nt];
421324Sbill 	if(t==0) {
431324Sbill 		t = text[f][nt] = malloc(LEN+1);
441324Sbill 		if(t==NULL)
451324Sbill 			if(hardsynch())
461324Sbill 				goto again;
471324Sbill 			else
481324Sbill 				progerr("5");
491324Sbill 	}
501324Sbill 	t = fgets(t,LEN,file[f]);
511324Sbill 	if(t!=NULL)
521324Sbill 		ntext[f]++;
531324Sbill 	return(t);
541324Sbill }
551324Sbill 
561324Sbill 	/*remove thru line n of file f from storage*/
571324Sbill clrl(f,n)
581324Sbill long n;
591324Sbill {
601324Sbill 	register i,j;
611324Sbill 	j = n-lineno[f]+1;
621324Sbill 	for(i=0;i+j<ntext[f];i++)
631324Sbill 		movstr(text[f][i+j],text[f][i]);
641324Sbill 	lineno[f] = n+1;
651324Sbill 	ntext[f] -= j;
661324Sbill }
671324Sbill 
681324Sbill movstr(s,t)
691324Sbill register char *s, *t;
701324Sbill {
711324Sbill 	while(*t++= *s++)
721324Sbill 		continue;
731324Sbill }
741324Sbill 
751324Sbill main(argc,argv)
761324Sbill char **argv;
771324Sbill {
781324Sbill 	char *s0,*s1;
791324Sbill 	FILE *dopen();
80*17603Sralph 	register int status = 0;
81*17603Sralph 
821324Sbill 	while(*argv[1]=='-') {
831324Sbill 		argc--;
841324Sbill 		argv++;
851324Sbill 		while(*++argv[0])
861324Sbill 			if(*argv[0]=='b')
871324Sbill 				bflag++;
881324Sbill 	}
891324Sbill 	if(argc!=3)
901324Sbill 		error("must have 2 file arguments","");
911324Sbill 	file[0] = dopen(argv[1],argv[2]);
921324Sbill 	file[1] = dopen(argv[2],argv[1]);
931324Sbill 	for(;;) {
941324Sbill 		s0 = getl(0,++n0);
951324Sbill 		s1 = getl(1,++n1);
961324Sbill 		if(s0==NULL||s1==NULL)
971324Sbill 			break;
981324Sbill 		if(cmp(s0,s1)!=0) {
991324Sbill 			if(!easysynch()&&!hardsynch())
1001324Sbill 				progerr("5");
101*17603Sralph 			status = 1;
1021324Sbill 		} else {
1031324Sbill 			clrl(0,n0);
1041324Sbill 			clrl(1,n1);
1051324Sbill 		}
1061324Sbill 	}
1071324Sbill 	if(s0==NULL&&s1==NULL)
108*17603Sralph 		return(status);
1091324Sbill 	if(s0==NULL)
1101324Sbill 		output(-1,INF);
1111324Sbill 	if(s1==NULL)
1121324Sbill 		output(INF,-1);
113*17603Sralph 	return(1);
1141324Sbill }
1151324Sbill 
1161324Sbill 	/* synch on C successive matches*/
1171324Sbill easysynch()
1181324Sbill {
1191324Sbill 	int i,j;
1201324Sbill 	register k,m;
1211324Sbill 	char *s0,*s1;
1221324Sbill 	for(i=j=1;i<RANGE&&j<RANGE;i++,j++) {
1231324Sbill 		s0 = getl(0,n0+i);
1241324Sbill 		if(s0==NULL)
1251324Sbill 			return(output(INF,INF));
1261324Sbill 		for(k=C-1;k<j;k++) {
1271324Sbill 			for(m=0;m<C;m++)
1281324Sbill 				if(cmp(getl(0,n0+i-m),
1291324Sbill 					getl(1,n1+k-m))!=0)
1301324Sbill 					goto cont1;
1311324Sbill 			return(output(i-C,k-C));
1321324Sbill cont1:			;
1331324Sbill 		}
1341324Sbill 		s1 = getl(1,n1+j);
1351324Sbill 		if(s1==NULL)
1361324Sbill 			return(output(INF,INF));
1371324Sbill 		for(k=C-1;k<=i;k++) {
1381324Sbill 			for(m=0;m<C;m++)
1391324Sbill 				if(cmp(getl(0,n0+k-m),
1401324Sbill 					getl(1,n1+j-m))!=0)
1411324Sbill 					goto cont2;
1421324Sbill 			return(output(k-C,j-C));
1431324Sbill cont2:			;
1441324Sbill 		}
1451324Sbill 	}
1461324Sbill 	return(0);
1471324Sbill }
1481324Sbill 
1491324Sbill output(a,b)
1501324Sbill {
1511324Sbill 	register i;
1521324Sbill 	char *s;
1531324Sbill 	if(a<0)
1541324Sbill 		change(n0-1,0,n1,b,"a");
1551324Sbill 	else if(b<0)
1561324Sbill 		change(n0,a,n1-1,0,"d");
1571324Sbill 	else
1581324Sbill 		change(n0,a,n1,b,"c");
1591324Sbill 	for(i=0;i<=a;i++) {
1601324Sbill 		s = getl(0,n0+i);
1611324Sbill 		if(s==NULL)
1621324Sbill 			break;
1631324Sbill 		printf("< %s",s);
1641324Sbill 		clrl(0,n0+i);
1651324Sbill 	}
1661324Sbill 	n0 += i-1;
1671324Sbill 	if(a>=0&&b>=0)
1681324Sbill 		printf("---\n");
1691324Sbill 	for(i=0;i<=b;i++) {
1701324Sbill 		s = getl(1,n1+i);
1711324Sbill 		if(s==NULL)
1721324Sbill 			break;
1731324Sbill 		printf("> %s",s);
1741324Sbill 		clrl(1,n1+i);
1751324Sbill 	}
1761324Sbill 	n1 += i-1;
1771324Sbill 	return(1);
1781324Sbill }
1791324Sbill 
1801324Sbill change(a,b,c,d,s)
1811324Sbill long a,c;
1821324Sbill char *s;
1831324Sbill {
1841324Sbill 	range(a,b);
1851324Sbill 	printf("%s",s);
1861324Sbill 	range(c,d);
1871324Sbill 	printf("\n");
1881324Sbill }
1891324Sbill 
1901324Sbill range(a,b)
1911324Sbill long a;
1921324Sbill {
1931324Sbill 	if(b==INF)
1941324Sbill 		printf("%ld,$",a);
1951324Sbill 	else if(b==0)
1961324Sbill 		printf("%ld",a);
1971324Sbill 	else
1981324Sbill 		printf("%ld,%ld",a,a+b);
1991324Sbill }
2001324Sbill 
2011324Sbill cmp(s,t)
2021324Sbill char *s,*t;
2031324Sbill {
2041324Sbill 	if(debug)
2051324Sbill 		printf("%s:%s\n",s,t);
2061324Sbill 	for(;;){
2071324Sbill 		if(bflag&&isspace(*s)&&isspace(*t)) {
2081324Sbill 			while(isspace(*++s)) ;
2091324Sbill 			while(isspace(*++t)) ;
2101324Sbill 		}
2111324Sbill 		if(*s!=*t||*s==0)
2121324Sbill 			break;
2131324Sbill 		s++;
2141324Sbill 		t++;
2151324Sbill 	}
2161324Sbill 	return(*s-*t);
2171324Sbill }
2181324Sbill 
2191324Sbill FILE *dopen(f1,f2)
2201324Sbill char *f1,*f2;
2211324Sbill {
2221324Sbill 	FILE *f;
2231324Sbill 	char b[100],*bptr,*eptr;
2241324Sbill 	struct stat statbuf;
2251324Sbill 	if(cmp(f1,"-")==0)
2261324Sbill 		if(cmp(f2,"-")==0)
2271324Sbill 			error("can't do - -","");
2281324Sbill 		else
2291324Sbill 			return(stdin);
2301324Sbill 	if(stat(f1,&statbuf)==-1)
2311324Sbill 		error("can't access ",f1);
2321324Sbill 	if((statbuf.st_mode&S_IFMT)==S_IFDIR) {
2331324Sbill 		for(bptr=b;*bptr= *f1++;bptr++) ;
2341324Sbill 		*bptr++ = '/';
2351324Sbill 		for(eptr=f2;*eptr;eptr++)
2361324Sbill 			if(*eptr=='/'&&eptr[1]!=0&&eptr[1]!='/')
2371324Sbill 				f2 = eptr+1;
2381324Sbill 		while(*bptr++= *f2++) ;
2391324Sbill 		f1 = b;
2401324Sbill 	}
2411324Sbill 	f = fopen(f1,"r");
2421324Sbill 	if(f==NULL)
2431324Sbill 		error("can't open",f1);
2441324Sbill 	return(f);
2451324Sbill }
2461324Sbill 
2471324Sbill 
2481324Sbill progerr(s)
2491324Sbill char *s;
2501324Sbill {
2511324Sbill 	error("program error ",s);
2521324Sbill }
2531324Sbill 
2541324Sbill error(s,t)
2551324Sbill char *s,*t;
2561324Sbill {
2571324Sbill 	fprintf(stderr,"diffh: %s%s\n",s,t);
258*17603Sralph 	exit(2);
2591324Sbill }
2601324Sbill 
2611324Sbill 	/*stub for resychronization beyond limits of text buf*/
2621324Sbill hardsynch()
2631324Sbill {
2641324Sbill 	change(n0,INF,n1,INF,"c");
2651324Sbill 	printf("---change record omitted\n");
2661324Sbill 	error("can't resynchronize","");
2671324Sbill 	return(0);
2681324Sbill }
269