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