1: static char sccsid[] = "@(#)diffh.c 4.4 11/27/85"; 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: register int status = 0; 81: 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: status = 1; 102: } else { 103: clrl(0,n0); 104: clrl(1,n1); 105: } 106: } 107: if(s0==NULL&&s1==NULL) 108: exit(status); 109: if(s0==NULL) 110: output(-1,INF); 111: if(s1==NULL) 112: output(INF,-1); 113: exit(1); 114: } 115: 116: /* synch on C successive matches*/ 117: easysynch() 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)); 132: cont1: ; 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)); 143: cont2: ; 144: } 145: } 146: return(0); 147: } 148: 149: output(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: 180: change(a,b,c,d,s) 181: long a,c; 182: char *s; 183: { 184: range(a,b); 185: printf("%s",s); 186: range(c,d); 187: printf("\n"); 188: } 189: 190: range(a,b) 191: long 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: 201: cmp(s,t) 202: char *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: 219: FILE *dopen(f1,f2) 220: char *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: 248: progerr(s) 249: char *s; 250: { 251: error("program error ",s); 252: } 253: 254: error(s,t) 255: char *s,*t; 256: { 257: fprintf(stderr,"diffh: %s%s\n",s,t); 258: exit(2); 259: } 260: 261: /*stub for resychronization beyond limits of text buf*/ 262: hardsynch() 263: { 264: change(n0,INF,n1,INF,"c"); 265: printf("---change record omitted\n"); 266: error("can't resynchronize",""); 267: return(0); 268: }