home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / diffh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  4.0 KB  |  263 lines

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