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