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: }