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