1*17603Sralph static char sccsid[] = "@(#)diffh.c 4.3 01/02/85"; 21324Sbill 31324Sbill #include <stdio.h> 41324Sbill #include <ctype.h> 51324Sbill #include <sys/types.h> 61324Sbill #include <sys/stat.h> 71324Sbill 81324Sbill #define C 3 91324Sbill #define RANGE 30 101324Sbill #define LEN 255 111324Sbill #define INF 16384 121324Sbill 131324Sbill char *text[2][RANGE]; 141324Sbill long lineno[2] = {1, 1}; /*no. of 1st stored line in each file*/ 151324Sbill int ntext[2]; /*number of stored lines in each*/ 161324Sbill long n0,n1; /*scan pointer in each*/ 171324Sbill int bflag; 181324Sbill int debug = 0; 191324Sbill FILE *file[2]; 201324Sbill 211324Sbill /* return pointer to line n of file f*/ 221324Sbill char *getl(f,n) 231324Sbill long n; 241324Sbill { 251324Sbill register char *t; 261324Sbill char *malloc(); 271324Sbill register delta, nt; 281324Sbill again: 291324Sbill delta = n - lineno[f]; 301324Sbill nt = ntext[f]; 311324Sbill if(delta<0) 321324Sbill progerr("1"); 331324Sbill if(delta<nt) 341324Sbill return(text[f][delta]); 351324Sbill if(delta>nt) 361324Sbill progerr("2"); 371324Sbill if(nt>=RANGE) 381324Sbill progerr("3"); 391324Sbill if(feof(file[f])) 401324Sbill return(NULL); 411324Sbill t = text[f][nt]; 421324Sbill if(t==0) { 431324Sbill t = text[f][nt] = malloc(LEN+1); 441324Sbill if(t==NULL) 451324Sbill if(hardsynch()) 461324Sbill goto again; 471324Sbill else 481324Sbill progerr("5"); 491324Sbill } 501324Sbill t = fgets(t,LEN,file[f]); 511324Sbill if(t!=NULL) 521324Sbill ntext[f]++; 531324Sbill return(t); 541324Sbill } 551324Sbill 561324Sbill /*remove thru line n of file f from storage*/ 571324Sbill clrl(f,n) 581324Sbill long n; 591324Sbill { 601324Sbill register i,j; 611324Sbill j = n-lineno[f]+1; 621324Sbill for(i=0;i+j<ntext[f];i++) 631324Sbill movstr(text[f][i+j],text[f][i]); 641324Sbill lineno[f] = n+1; 651324Sbill ntext[f] -= j; 661324Sbill } 671324Sbill 681324Sbill movstr(s,t) 691324Sbill register char *s, *t; 701324Sbill { 711324Sbill while(*t++= *s++) 721324Sbill continue; 731324Sbill } 741324Sbill 751324Sbill main(argc,argv) 761324Sbill char **argv; 771324Sbill { 781324Sbill char *s0,*s1; 791324Sbill FILE *dopen(); 80*17603Sralph register int status = 0; 81*17603Sralph 821324Sbill while(*argv[1]=='-') { 831324Sbill argc--; 841324Sbill argv++; 851324Sbill while(*++argv[0]) 861324Sbill if(*argv[0]=='b') 871324Sbill bflag++; 881324Sbill } 891324Sbill if(argc!=3) 901324Sbill error("must have 2 file arguments",""); 911324Sbill file[0] = dopen(argv[1],argv[2]); 921324Sbill file[1] = dopen(argv[2],argv[1]); 931324Sbill for(;;) { 941324Sbill s0 = getl(0,++n0); 951324Sbill s1 = getl(1,++n1); 961324Sbill if(s0==NULL||s1==NULL) 971324Sbill break; 981324Sbill if(cmp(s0,s1)!=0) { 991324Sbill if(!easysynch()&&!hardsynch()) 1001324Sbill progerr("5"); 101*17603Sralph status = 1; 1021324Sbill } else { 1031324Sbill clrl(0,n0); 1041324Sbill clrl(1,n1); 1051324Sbill } 1061324Sbill } 1071324Sbill if(s0==NULL&&s1==NULL) 108*17603Sralph return(status); 1091324Sbill if(s0==NULL) 1101324Sbill output(-1,INF); 1111324Sbill if(s1==NULL) 1121324Sbill output(INF,-1); 113*17603Sralph return(1); 1141324Sbill } 1151324Sbill 1161324Sbill /* synch on C successive matches*/ 1171324Sbill easysynch() 1181324Sbill { 1191324Sbill int i,j; 1201324Sbill register k,m; 1211324Sbill char *s0,*s1; 1221324Sbill for(i=j=1;i<RANGE&&j<RANGE;i++,j++) { 1231324Sbill s0 = getl(0,n0+i); 1241324Sbill if(s0==NULL) 1251324Sbill return(output(INF,INF)); 1261324Sbill for(k=C-1;k<j;k++) { 1271324Sbill for(m=0;m<C;m++) 1281324Sbill if(cmp(getl(0,n0+i-m), 1291324Sbill getl(1,n1+k-m))!=0) 1301324Sbill goto cont1; 1311324Sbill return(output(i-C,k-C)); 1321324Sbill cont1: ; 1331324Sbill } 1341324Sbill s1 = getl(1,n1+j); 1351324Sbill if(s1==NULL) 1361324Sbill return(output(INF,INF)); 1371324Sbill for(k=C-1;k<=i;k++) { 1381324Sbill for(m=0;m<C;m++) 1391324Sbill if(cmp(getl(0,n0+k-m), 1401324Sbill getl(1,n1+j-m))!=0) 1411324Sbill goto cont2; 1421324Sbill return(output(k-C,j-C)); 1431324Sbill cont2: ; 1441324Sbill } 1451324Sbill } 1461324Sbill return(0); 1471324Sbill } 1481324Sbill 1491324Sbill output(a,b) 1501324Sbill { 1511324Sbill register i; 1521324Sbill char *s; 1531324Sbill if(a<0) 1541324Sbill change(n0-1,0,n1,b,"a"); 1551324Sbill else if(b<0) 1561324Sbill change(n0,a,n1-1,0,"d"); 1571324Sbill else 1581324Sbill change(n0,a,n1,b,"c"); 1591324Sbill for(i=0;i<=a;i++) { 1601324Sbill s = getl(0,n0+i); 1611324Sbill if(s==NULL) 1621324Sbill break; 1631324Sbill printf("< %s",s); 1641324Sbill clrl(0,n0+i); 1651324Sbill } 1661324Sbill n0 += i-1; 1671324Sbill if(a>=0&&b>=0) 1681324Sbill printf("---\n"); 1691324Sbill for(i=0;i<=b;i++) { 1701324Sbill s = getl(1,n1+i); 1711324Sbill if(s==NULL) 1721324Sbill break; 1731324Sbill printf("> %s",s); 1741324Sbill clrl(1,n1+i); 1751324Sbill } 1761324Sbill n1 += i-1; 1771324Sbill return(1); 1781324Sbill } 1791324Sbill 1801324Sbill change(a,b,c,d,s) 1811324Sbill long a,c; 1821324Sbill char *s; 1831324Sbill { 1841324Sbill range(a,b); 1851324Sbill printf("%s",s); 1861324Sbill range(c,d); 1871324Sbill printf("\n"); 1881324Sbill } 1891324Sbill 1901324Sbill range(a,b) 1911324Sbill long a; 1921324Sbill { 1931324Sbill if(b==INF) 1941324Sbill printf("%ld,$",a); 1951324Sbill else if(b==0) 1961324Sbill printf("%ld",a); 1971324Sbill else 1981324Sbill printf("%ld,%ld",a,a+b); 1991324Sbill } 2001324Sbill 2011324Sbill cmp(s,t) 2021324Sbill char *s,*t; 2031324Sbill { 2041324Sbill if(debug) 2051324Sbill printf("%s:%s\n",s,t); 2061324Sbill for(;;){ 2071324Sbill if(bflag&&isspace(*s)&&isspace(*t)) { 2081324Sbill while(isspace(*++s)) ; 2091324Sbill while(isspace(*++t)) ; 2101324Sbill } 2111324Sbill if(*s!=*t||*s==0) 2121324Sbill break; 2131324Sbill s++; 2141324Sbill t++; 2151324Sbill } 2161324Sbill return(*s-*t); 2171324Sbill } 2181324Sbill 2191324Sbill FILE *dopen(f1,f2) 2201324Sbill char *f1,*f2; 2211324Sbill { 2221324Sbill FILE *f; 2231324Sbill char b[100],*bptr,*eptr; 2241324Sbill struct stat statbuf; 2251324Sbill if(cmp(f1,"-")==0) 2261324Sbill if(cmp(f2,"-")==0) 2271324Sbill error("can't do - -",""); 2281324Sbill else 2291324Sbill return(stdin); 2301324Sbill if(stat(f1,&statbuf)==-1) 2311324Sbill error("can't access ",f1); 2321324Sbill if((statbuf.st_mode&S_IFMT)==S_IFDIR) { 2331324Sbill for(bptr=b;*bptr= *f1++;bptr++) ; 2341324Sbill *bptr++ = '/'; 2351324Sbill for(eptr=f2;*eptr;eptr++) 2361324Sbill if(*eptr=='/'&&eptr[1]!=0&&eptr[1]!='/') 2371324Sbill f2 = eptr+1; 2381324Sbill while(*bptr++= *f2++) ; 2391324Sbill f1 = b; 2401324Sbill } 2411324Sbill f = fopen(f1,"r"); 2421324Sbill if(f==NULL) 2431324Sbill error("can't open",f1); 2441324Sbill return(f); 2451324Sbill } 2461324Sbill 2471324Sbill 2481324Sbill progerr(s) 2491324Sbill char *s; 2501324Sbill { 2511324Sbill error("program error ",s); 2521324Sbill } 2531324Sbill 2541324Sbill error(s,t) 2551324Sbill char *s,*t; 2561324Sbill { 2571324Sbill fprintf(stderr,"diffh: %s%s\n",s,t); 258*17603Sralph exit(2); 2591324Sbill } 2601324Sbill 2611324Sbill /*stub for resychronization beyond limits of text buf*/ 2621324Sbill hardsynch() 2631324Sbill { 2641324Sbill change(n0,INF,n1,INF,"c"); 2651324Sbill printf("---change record omitted\n"); 2661324Sbill error("can't resynchronize",""); 2671324Sbill return(0); 2681324Sbill } 269