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