|
|
1.1 root 1: static char sccsid[] = "@(#)diffh.c 4.1 10/9/80";
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:
13: char *text[2][RANGE];
14: long lineno[2] = {1, 1}; /*no. of 1st stored line in each file*/
15: int ntext[2]; /*number of stored lines in each*/
16: long n0,n1; /*scan pointer in each*/
17: int bflag;
18: int debug = 0;
19: FILE *file[2];
20:
21: /* return pointer to line n of file f*/
22: char *getl(f,n)
23: long n;
24: {
25: register char *t;
26: char *malloc();
27: register delta, nt;
28: again:
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*/
57: clrl(f,n)
58: long 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:
68: movstr(s,t)
69: register char *s, *t;
70: {
71: while(*t++= *s++)
72: continue;
73: }
74:
75: main(argc,argv)
76: char **argv;
77: {
78: char *s0,*s1;
79: FILE *dopen();
80: extern char _sobuf[];
81: setbuf(stdout, _sobuf);
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");
101: } else {
102: clrl(0,n0);
103: clrl(1,n1);
104: }
105: }
106: if(s0==NULL&&s1==NULL)
107: return;
108: if(s0==NULL)
109: output(-1,INF);
110: if(s1==NULL)
111: output(INF,-1);
112: }
113:
114: /* synch on C successive matches*/
115: easysynch()
116: {
117: int i,j;
118: register k,m;
119: char *s0,*s1;
120: for(i=j=1;i<RANGE&&j<RANGE;i++,j++) {
121: s0 = getl(0,n0+i);
122: if(s0==NULL)
123: return(output(INF,INF));
124: for(k=C-1;k<j;k++) {
125: for(m=0;m<C;m++)
126: if(cmp(getl(0,n0+i-m),
127: getl(1,n1+k-m))!=0)
128: goto cont1;
129: return(output(i-C,k-C));
130: cont1: ;
131: }
132: s1 = getl(1,n1+j);
133: if(s1==NULL)
134: return(output(INF,INF));
135: for(k=C-1;k<=i;k++) {
136: for(m=0;m<C;m++)
137: if(cmp(getl(0,n0+k-m),
138: getl(1,n1+j-m))!=0)
139: goto cont2;
140: return(output(k-C,j-C));
141: cont2: ;
142: }
143: }
144: return(0);
145: }
146:
147: output(a,b)
148: {
149: register i;
150: char *s;
151: if(a<0)
152: change(n0-1,0,n1,b,"a");
153: else if(b<0)
154: change(n0,a,n1-1,0,"d");
155: else
156: change(n0,a,n1,b,"c");
157: for(i=0;i<=a;i++) {
158: s = getl(0,n0+i);
159: if(s==NULL)
160: break;
161: printf("< %s",s);
162: clrl(0,n0+i);
163: }
164: n0 += i-1;
165: if(a>=0&&b>=0)
166: printf("---\n");
167: for(i=0;i<=b;i++) {
168: s = getl(1,n1+i);
169: if(s==NULL)
170: break;
171: printf("> %s",s);
172: clrl(1,n1+i);
173: }
174: n1 += i-1;
175: return(1);
176: }
177:
178: change(a,b,c,d,s)
179: long a,c;
180: char *s;
181: {
182: range(a,b);
183: printf("%s",s);
184: range(c,d);
185: printf("\n");
186: }
187:
188: range(a,b)
189: long a;
190: {
191: if(b==INF)
192: printf("%ld,$",a);
193: else if(b==0)
194: printf("%ld",a);
195: else
196: printf("%ld,%ld",a,a+b);
197: }
198:
199: cmp(s,t)
200: char *s,*t;
201: {
202: if(debug)
203: printf("%s:%s\n",s,t);
204: for(;;){
205: if(bflag&&isspace(*s)&&isspace(*t)) {
206: while(isspace(*++s)) ;
207: while(isspace(*++t)) ;
208: }
209: if(*s!=*t||*s==0)
210: break;
211: s++;
212: t++;
213: }
214: return(*s-*t);
215: }
216:
217: FILE *dopen(f1,f2)
218: char *f1,*f2;
219: {
220: FILE *f;
221: char b[100],*bptr,*eptr;
222: struct stat statbuf;
223: if(cmp(f1,"-")==0)
224: if(cmp(f2,"-")==0)
225: error("can't do - -","");
226: else
227: return(stdin);
228: if(stat(f1,&statbuf)==-1)
229: error("can't access ",f1);
230: if((statbuf.st_mode&S_IFMT)==S_IFDIR) {
231: for(bptr=b;*bptr= *f1++;bptr++) ;
232: *bptr++ = '/';
233: for(eptr=f2;*eptr;eptr++)
234: if(*eptr=='/'&&eptr[1]!=0&&eptr[1]!='/')
235: f2 = eptr+1;
236: while(*bptr++= *f2++) ;
237: f1 = b;
238: }
239: f = fopen(f1,"r");
240: if(f==NULL)
241: error("can't open",f1);
242: return(f);
243: }
244:
245:
246: progerr(s)
247: char *s;
248: {
249: error("program error ",s);
250: }
251:
252: error(s,t)
253: char *s,*t;
254: {
255: fprintf(stderr,"diffh: %s%s\n",s,t);
256: exit(1);
257: }
258:
259: /*stub for resychronization beyond limits of text buf*/
260: hardsynch()
261: {
262: change(n0,INF,n1,INF,"c");
263: printf("---change record omitted\n");
264: error("can't resynchronize","");
265: return(0);
266: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.