xref: /csrg-svn/usr.bin/diff/diffh/diffh.c (revision 1324)
1*1324Sbill static	char sccsid[] = "@(#)diffh.c 4.1 10/09/80";
2*1324Sbill 
3*1324Sbill #include <stdio.h>
4*1324Sbill #include <ctype.h>
5*1324Sbill #include <sys/types.h>
6*1324Sbill #include <sys/stat.h>
7*1324Sbill 
8*1324Sbill #define C 3
9*1324Sbill #define RANGE 30
10*1324Sbill #define LEN 255
11*1324Sbill #define INF 16384
12*1324Sbill 
13*1324Sbill char *text[2][RANGE];
14*1324Sbill long lineno[2] = {1, 1};	/*no. of 1st stored line in each file*/
15*1324Sbill int ntext[2];		/*number of stored lines in each*/
16*1324Sbill long n0,n1;		/*scan pointer in each*/
17*1324Sbill int bflag;
18*1324Sbill int debug = 0;
19*1324Sbill FILE *file[2];
20*1324Sbill 
21*1324Sbill 	/* return pointer to line n of file f*/
22*1324Sbill char *getl(f,n)
23*1324Sbill long n;
24*1324Sbill {
25*1324Sbill 	register char *t;
26*1324Sbill 	char *malloc();
27*1324Sbill 	register delta, nt;
28*1324Sbill again:
29*1324Sbill 	delta = n - lineno[f];
30*1324Sbill 	nt = ntext[f];
31*1324Sbill 	if(delta<0)
32*1324Sbill 		progerr("1");
33*1324Sbill 	if(delta<nt)
34*1324Sbill 		return(text[f][delta]);
35*1324Sbill 	if(delta>nt)
36*1324Sbill 		progerr("2");
37*1324Sbill 	if(nt>=RANGE)
38*1324Sbill 		progerr("3");
39*1324Sbill 	if(feof(file[f]))
40*1324Sbill 		return(NULL);
41*1324Sbill 	t = text[f][nt];
42*1324Sbill 	if(t==0) {
43*1324Sbill 		t = text[f][nt] = malloc(LEN+1);
44*1324Sbill 		if(t==NULL)
45*1324Sbill 			if(hardsynch())
46*1324Sbill 				goto again;
47*1324Sbill 			else
48*1324Sbill 				progerr("5");
49*1324Sbill 	}
50*1324Sbill 	t = fgets(t,LEN,file[f]);
51*1324Sbill 	if(t!=NULL)
52*1324Sbill 		ntext[f]++;
53*1324Sbill 	return(t);
54*1324Sbill }
55*1324Sbill 
56*1324Sbill 	/*remove thru line n of file f from storage*/
57*1324Sbill clrl(f,n)
58*1324Sbill long n;
59*1324Sbill {
60*1324Sbill 	register i,j;
61*1324Sbill 	j = n-lineno[f]+1;
62*1324Sbill 	for(i=0;i+j<ntext[f];i++)
63*1324Sbill 		movstr(text[f][i+j],text[f][i]);
64*1324Sbill 	lineno[f] = n+1;
65*1324Sbill 	ntext[f] -= j;
66*1324Sbill }
67*1324Sbill 
68*1324Sbill movstr(s,t)
69*1324Sbill register char *s, *t;
70*1324Sbill {
71*1324Sbill 	while(*t++= *s++)
72*1324Sbill 		continue;
73*1324Sbill }
74*1324Sbill 
75*1324Sbill main(argc,argv)
76*1324Sbill char **argv;
77*1324Sbill {
78*1324Sbill 	char *s0,*s1;
79*1324Sbill 	FILE *dopen();
80*1324Sbill 	extern char _sobuf[];
81*1324Sbill 	setbuf(stdout, _sobuf);
82*1324Sbill 	while(*argv[1]=='-') {
83*1324Sbill 		argc--;
84*1324Sbill 		argv++;
85*1324Sbill 		while(*++argv[0])
86*1324Sbill 			if(*argv[0]=='b')
87*1324Sbill 				bflag++;
88*1324Sbill 	}
89*1324Sbill 	if(argc!=3)
90*1324Sbill 		error("must have 2 file arguments","");
91*1324Sbill 	file[0] = dopen(argv[1],argv[2]);
92*1324Sbill 	file[1] = dopen(argv[2],argv[1]);
93*1324Sbill 	for(;;) {
94*1324Sbill 		s0 = getl(0,++n0);
95*1324Sbill 		s1 = getl(1,++n1);
96*1324Sbill 		if(s0==NULL||s1==NULL)
97*1324Sbill 			break;
98*1324Sbill 		if(cmp(s0,s1)!=0) {
99*1324Sbill 			if(!easysynch()&&!hardsynch())
100*1324Sbill 				progerr("5");
101*1324Sbill 		} else {
102*1324Sbill 			clrl(0,n0);
103*1324Sbill 			clrl(1,n1);
104*1324Sbill 		}
105*1324Sbill 	}
106*1324Sbill 	if(s0==NULL&&s1==NULL)
107*1324Sbill 		return;
108*1324Sbill 	if(s0==NULL)
109*1324Sbill 		output(-1,INF);
110*1324Sbill 	if(s1==NULL)
111*1324Sbill 		output(INF,-1);
112*1324Sbill }
113*1324Sbill 
114*1324Sbill 	/* synch on C successive matches*/
115*1324Sbill easysynch()
116*1324Sbill {
117*1324Sbill 	int i,j;
118*1324Sbill 	register k,m;
119*1324Sbill 	char *s0,*s1;
120*1324Sbill 	for(i=j=1;i<RANGE&&j<RANGE;i++,j++) {
121*1324Sbill 		s0 = getl(0,n0+i);
122*1324Sbill 		if(s0==NULL)
123*1324Sbill 			return(output(INF,INF));
124*1324Sbill 		for(k=C-1;k<j;k++) {
125*1324Sbill 			for(m=0;m<C;m++)
126*1324Sbill 				if(cmp(getl(0,n0+i-m),
127*1324Sbill 					getl(1,n1+k-m))!=0)
128*1324Sbill 					goto cont1;
129*1324Sbill 			return(output(i-C,k-C));
130*1324Sbill cont1:			;
131*1324Sbill 		}
132*1324Sbill 		s1 = getl(1,n1+j);
133*1324Sbill 		if(s1==NULL)
134*1324Sbill 			return(output(INF,INF));
135*1324Sbill 		for(k=C-1;k<=i;k++) {
136*1324Sbill 			for(m=0;m<C;m++)
137*1324Sbill 				if(cmp(getl(0,n0+k-m),
138*1324Sbill 					getl(1,n1+j-m))!=0)
139*1324Sbill 					goto cont2;
140*1324Sbill 			return(output(k-C,j-C));
141*1324Sbill cont2:			;
142*1324Sbill 		}
143*1324Sbill 	}
144*1324Sbill 	return(0);
145*1324Sbill }
146*1324Sbill 
147*1324Sbill output(a,b)
148*1324Sbill {
149*1324Sbill 	register i;
150*1324Sbill 	char *s;
151*1324Sbill 	if(a<0)
152*1324Sbill 		change(n0-1,0,n1,b,"a");
153*1324Sbill 	else if(b<0)
154*1324Sbill 		change(n0,a,n1-1,0,"d");
155*1324Sbill 	else
156*1324Sbill 		change(n0,a,n1,b,"c");
157*1324Sbill 	for(i=0;i<=a;i++) {
158*1324Sbill 		s = getl(0,n0+i);
159*1324Sbill 		if(s==NULL)
160*1324Sbill 			break;
161*1324Sbill 		printf("< %s",s);
162*1324Sbill 		clrl(0,n0+i);
163*1324Sbill 	}
164*1324Sbill 	n0 += i-1;
165*1324Sbill 	if(a>=0&&b>=0)
166*1324Sbill 		printf("---\n");
167*1324Sbill 	for(i=0;i<=b;i++) {
168*1324Sbill 		s = getl(1,n1+i);
169*1324Sbill 		if(s==NULL)
170*1324Sbill 			break;
171*1324Sbill 		printf("> %s",s);
172*1324Sbill 		clrl(1,n1+i);
173*1324Sbill 	}
174*1324Sbill 	n1 += i-1;
175*1324Sbill 	return(1);
176*1324Sbill }
177*1324Sbill 
178*1324Sbill change(a,b,c,d,s)
179*1324Sbill long a,c;
180*1324Sbill char *s;
181*1324Sbill {
182*1324Sbill 	range(a,b);
183*1324Sbill 	printf("%s",s);
184*1324Sbill 	range(c,d);
185*1324Sbill 	printf("\n");
186*1324Sbill }
187*1324Sbill 
188*1324Sbill range(a,b)
189*1324Sbill long a;
190*1324Sbill {
191*1324Sbill 	if(b==INF)
192*1324Sbill 		printf("%ld,$",a);
193*1324Sbill 	else if(b==0)
194*1324Sbill 		printf("%ld",a);
195*1324Sbill 	else
196*1324Sbill 		printf("%ld,%ld",a,a+b);
197*1324Sbill }
198*1324Sbill 
199*1324Sbill cmp(s,t)
200*1324Sbill char *s,*t;
201*1324Sbill {
202*1324Sbill 	if(debug)
203*1324Sbill 		printf("%s:%s\n",s,t);
204*1324Sbill 	for(;;){
205*1324Sbill 		if(bflag&&isspace(*s)&&isspace(*t)) {
206*1324Sbill 			while(isspace(*++s)) ;
207*1324Sbill 			while(isspace(*++t)) ;
208*1324Sbill 		}
209*1324Sbill 		if(*s!=*t||*s==0)
210*1324Sbill 			break;
211*1324Sbill 		s++;
212*1324Sbill 		t++;
213*1324Sbill 	}
214*1324Sbill 	return(*s-*t);
215*1324Sbill }
216*1324Sbill 
217*1324Sbill FILE *dopen(f1,f2)
218*1324Sbill char *f1,*f2;
219*1324Sbill {
220*1324Sbill 	FILE *f;
221*1324Sbill 	char b[100],*bptr,*eptr;
222*1324Sbill 	struct stat statbuf;
223*1324Sbill 	if(cmp(f1,"-")==0)
224*1324Sbill 		if(cmp(f2,"-")==0)
225*1324Sbill 			error("can't do - -","");
226*1324Sbill 		else
227*1324Sbill 			return(stdin);
228*1324Sbill 	if(stat(f1,&statbuf)==-1)
229*1324Sbill 		error("can't access ",f1);
230*1324Sbill 	if((statbuf.st_mode&S_IFMT)==S_IFDIR) {
231*1324Sbill 		for(bptr=b;*bptr= *f1++;bptr++) ;
232*1324Sbill 		*bptr++ = '/';
233*1324Sbill 		for(eptr=f2;*eptr;eptr++)
234*1324Sbill 			if(*eptr=='/'&&eptr[1]!=0&&eptr[1]!='/')
235*1324Sbill 				f2 = eptr+1;
236*1324Sbill 		while(*bptr++= *f2++) ;
237*1324Sbill 		f1 = b;
238*1324Sbill 	}
239*1324Sbill 	f = fopen(f1,"r");
240*1324Sbill 	if(f==NULL)
241*1324Sbill 		error("can't open",f1);
242*1324Sbill 	return(f);
243*1324Sbill }
244*1324Sbill 
245*1324Sbill 
246*1324Sbill progerr(s)
247*1324Sbill char *s;
248*1324Sbill {
249*1324Sbill 	error("program error ",s);
250*1324Sbill }
251*1324Sbill 
252*1324Sbill error(s,t)
253*1324Sbill char *s,*t;
254*1324Sbill {
255*1324Sbill 	fprintf(stderr,"diffh: %s%s\n",s,t);
256*1324Sbill 	exit(1);
257*1324Sbill }
258*1324Sbill 
259*1324Sbill 	/*stub for resychronization beyond limits of text buf*/
260*1324Sbill hardsynch()
261*1324Sbill {
262*1324Sbill 	change(n0,INF,n1,INF,"c");
263*1324Sbill 	printf("---change record omitted\n");
264*1324Sbill 	error("can't resynchronize","");
265*1324Sbill 	return(0);
266*1324Sbill }
267