1 static char sccsid[] = "@(#)diffh.c 4.1 10/09/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 } 267