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