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