text: /* Copyright (c) 1991 Sun Wu and Udi Manber.  All Rights Reserved. */
  #include "agrep.h"
  
  extern unsigned Init1, Init[], Mask[], endposition, D_endpos, AND, NO_ERR_MASK;
  extern int DELIMITER, FILENAMEONLY, INVERSE;
  extern CHAR CurrentFileName[];
  extern int I, num_of_matched, TRUNCATE;
  
  extern int fill_buf(int fd, unsigned char *buf, int record_size);
  extern void output(register CHAR *buffer, int i1, int i2, int j);
  
  void asearch0(CHAR old_D_pat[], int text, register unsigned D)
  {
    register unsigned i, c, r1, r2, CMask, r_NO_ERR, r_Init1,  end, endpos; 
    unsigned A[MaxError+2], B[MaxError+2];
    unsigned D_Mask;
    int D_length, FIRSTROUND, ResidueSize, lasti, l, k, j=0;
    int printout_end;
    CHAR buffer[BlockSize+Max_record+1];
    
    D_length = strlen(old_D_pat);
    buffer[Max_record-1] = '\n';
    D_Mask = D_endpos;
    for ( i=1; i<D_length; i++) D_Mask = (D_Mask<<1) | D_Mask;
    D_Mask = ~D_Mask;
  
    r_Init1 = Init1; /* put Init1 in register */
    r_NO_ERR = NO_ERR_MASK; /* put NO_ERR_MASK in register */
    endpos = D_endpos;    
    FIRSTROUND = ON;
    for(k=0; k<=D; k++) A[k] = B[k] = Init[0];
    lasti = Max_record;
  
    while ((l = fill_buf(text, buffer + Max_record, Max_record)) > 0)
    { i = Max_record; end = Max_record + l ;
      if (FIRSTROUND) { 
          i = Max_record - 1;
          FIRSTROUND = OFF; }
      if (l < BlockSize) {
          strncpy(buffer+end, old_D_pat, D_length);
          buffer[end+D_length] = '\0';
          end = end + D_length; }
      while (i < end )
      {
          c = buffer[i++];
          CMask = Mask[c];
                r1 = B[0] & r_Init1;
                A[0] = (((B[0] >> 1)) & CMask | r1 ) ;
                for(k=1; k<=D; k++) {
                       r1 = r_Init1 & B[k];
                       r2 = B[k-1] | (((A[k-1]|B[k-1])>>1) & r_NO_ERR);
                       A[k] = ((B[k] >> 1) & CMask) | r2 | r1;
                }
          if(A[0] & endpos) {
             j++;  
             r1 = A[D];
             if(((AND == 1) && ((r1 & endposition) == endposition)) ||                           ((AND == 0) && (r1 & endposition)) ^ INVERSE )
                   {    
                        if(FILENAMEONLY) {
                           num_of_matched++;
                           printf("%s\n", CurrentFileName);
                           return;  }
                        printout_end = i - D_length - 1;           
                        if(!(lasti >= Max_record + l - 1))
                           output(buffer, lasti, printout_end, j);
                   }
             lasti = i - D_length; /* point to starting position of D_pat */
             for(k=0; k<= D; k++) {
                B[k] = Init[0];
             }
             r1 = B[0] & r_Init1;
             A[0] = (((B[0]>>1) & CMask) | r1) & D_Mask;
             for(k=1; k<= D; k++) {
                r1 = Init1 & B[k];
                r2 = B[k-1] | (((A[k-1] | B[k-1])>>1)&r_NO_ERR);
                A[k] = (((B[k]>>1)&CMask) | r1 | r2) ;
             }
          }
          c = buffer[i++];
          CMask = Mask[c];
                r1   = r_Init1 & A[0];
                B[0] = ((A[0] >> 1 ) & CMask) | r1;
                for(k=1; k<=D; k++) {
                       r1 = r_Init1 & A[k];
                       r2 = A[k-1] | (((A[k-1]|B[k-1])>>1) & r_NO_ERR);
                       B[k] = ((A[k] >> 1) & CMask) | r2 | r1;
                }
          if(B[0] & endpos) {
             j++;  
             r1 = B[D];
             if(((AND == 1) && ((r1 & endposition) == endposition)) ||                           ((AND == 0) && (r1 & endposition)) ^ INVERSE )
                   { 
                      if(FILENAMEONLY) {
                         num_of_matched++;
                         printf("%s\n", CurrentFileName);
                         return; }
                      printout_end = i - D_length -1 ; 
                      if(!(lasti >= Max_record + l - 1))
                         output(buffer, lasti, printout_end, j);
                   }
             lasti = i - D_length ;
             for(k=0; k<= D; k++) {
                A[k] = Init[0];
             }
             r1 = A[0] & r_Init1; 
             B[0] = (((A[0]>>1)&CMask) | r1) & D_Mask;
             for(k=1; k<= D; k++) {
                r1 = r_Init1 & A[k];
                r2 = A[k-1] | (((A[k-1] | B[k-1])>>1)&r_NO_ERR);
                B[k] = (((A[k]>>1)&CMask) | r1 | r2) ;
             }
          }
      }
      if(l < BlockSize) {
             lasti = Max_record;
      }
      else {
         ResidueSize = Max_record + l - lasti;
         if(ResidueSize > Max_record) {
            ResidueSize = Max_record;
            TRUNCATE = ON;         }
         strncpy(buffer+Max_record-ResidueSize, buffer+lasti, ResidueSize);
         lasti = Max_record - ResidueSize;
         if(lasti == 0)     lasti = 1; 
      }
    }
    return;
  }
  
  void asearch(CHAR old_D_pat[], int text, register unsigned D)
  {
    register unsigned i, c, r1, r2, CMask, r_NO_ERR, r_Init1; 
    register unsigned A0, B0, A1, B1, endpos;
    unsigned A2, B2, A3, B3, A4, B4;
    unsigned A[MaxError+1], B[MaxError+1];
    unsigned D_Mask;
    unsigned end;
    int D_length, FIRSTROUND, ResidueSize, lasti, l, k, j=0;
    int printout_end;
    CHAR buffer[2*Max_record+1];
       
    if (I == 0) Init1 = 037777777777;
    if(D > 4) {
           asearch0(old_D_pat, text, D); 
           return;  }
    D_length = strlen(old_D_pat);
    buffer[Max_record-1] = '\n';
    D_Mask = D_endpos;
    for ( i=1; i<D_length; i++) D_Mask = (D_Mask<<1) | D_Mask;
    D_Mask = ~D_Mask;
  
    r_Init1 = Init1; /* put Init1 in register */
    r_NO_ERR = NO_ERR_MASK; /* put NO_ERR_MASK in register */
    endpos = D_endpos;    
    FIRSTROUND = ON;
    A0 = B0 = A1 = B1 = A2 = B2 = A3 = B3 = A4 = B4 = Init[0];
    for(k=0; k<=D; k++) A[k] = B[k] = Init[0];
    lasti = Max_record;
  
    while ((l = fill_buf(text, buffer + Max_record, Max_record)) > 0)
    { i = Max_record; end = Max_record + l ;
      if (FIRSTROUND) { 
          i = Max_record - 1;
  	if(DELIMITER) {
  		for(k=0; k<D_length; k++) {
  					if(old_D_pat[k] != buffer[Max_record+k]) 						break;
  		}
  		if(k>=D_length) j--;
  	}
          FIRSTROUND = OFF; }
      if (l < BlockSize) {
          strncpy(buffer+end, old_D_pat, D_length);
          buffer[end+D_length] = '\0';
          end = end + D_length; }
      while (i < end )
      {
          c = buffer[i];
          CMask = Mask[c];
                r1 = r_Init1 & B0;
                A0 = ((B0 >>1 ) & CMask) | r1;
                r1 = r_Init1 & B1;
                r2 =  B0 | (((A0 | B0) >> 1) & r_NO_ERR); 
                A1 = ((B1 >>1 ) & CMask) | r2 | r1 ;  
                       if(D == 1) goto Nextchar;
                r1 = r_Init1 & B2;
                r2 =  B1 | (((A1 | B1) >> 1) & r_NO_ERR); 
                A2 = ((B2 >>1 ) & CMask) | r2 | r1 ;  
                       if(D == 2) goto Nextchar;
                r1 = r_Init1 & B3;
                r2 =  B2 | (((A2 | B2) >> 1) & r_NO_ERR); 
                A3 = ((B3 >>1 ) & CMask) | r2 | r1 ;  
                       if(D == 3) goto Nextchar;
                r1 = r_Init1 & B4;
                r2 =  B3 | (((A3 | B3) >> 1) & r_NO_ERR); 
                A4 = ((B4 >>1 ) & CMask) | r2 | r1 ;  
                       if(D == 4) goto Nextchar;
  Nextchar: i=i+1;
          if(A0 & endpos) {
             j++;  r1 = A0;
             if ( D == 1) r1 = A1;
             if ( D == 2) r1 = A2;
             if ( D == 3) r1 = A3;
             if ( D == 4) r1 = A4;
             if(((AND == 1) && ((r1 & endposition) == endposition)) ||                           ((AND == 0) && (r1 & endposition)) ^ INVERSE )
                   {    
                        if(FILENAMEONLY) {
                           num_of_matched++;
                           printf("%s\n", CurrentFileName);
                           return;  }
                        printout_end = i - D_length - 1;           
                        if(!(lasti >= Max_record + l - 1))
                           output(buffer, lasti, printout_end, j);
                   }
             lasti = i - D_length; /* point to starting position of D_pat */
             TRUNCATE = OFF;
             for(k=0; k<= D; k++) {
                B[k] = Init[0];
             }
             r1 = B[0] & Init1;
             A[0] = (((B[0]>>1) & CMask) | r1) & D_Mask;
             for(k=1; k<= D; k++) {
                r1 = Init1 & B[k];
                r2 = B[k-1] | (((A[k-1] | B[k-1])>>1)&r_NO_ERR);
                A[k] = (((B[k]>>1)&CMask) | r1 | r2) ;
             }
             A0 = A[0]; B0 = B[0]; A1 = A[1]; B1 = B[1]; A2 = A[2]; B2 = B[2];
             A3 = A[3]; B3 = B[3]; A4 = A[4]; B4 = B[4];
          }
          c = buffer[i];
          CMask = Mask[c];
                r1 = r_Init1 & A0;
                B0 = ((A0 >> 1 ) & CMask) | r1;
  #ifdef DEBUG
  	printf("Mask = %o, B0 = %o\n", CMask, B0);
  #endif
                r1 = r_Init1 & A1;
                r2 =  A0 | (((A0 | B0) >> 1) & r_NO_ERR); 
                B1 = ((A1 >>1 ) & CMask) | r2 | r1 ;  
                       if(D == 1) goto Nextchar1;
                r1 = r_Init1 & A2;
                r2 =  A1 | (((A1 | B1) >> 1) & r_NO_ERR); 
                B2 = ((A2 >>1 ) & CMask) | r2 | r1 ;  
                       if(D == 2) goto Nextchar1;
                r1 = r_Init1 & A3;
                r2 =  A2 | (((A2 | B2) >> 1) & r_NO_ERR); 
                B3 = ((A3 >>1 ) & CMask) | r2 | r1 ;  
                       if(D == 3) goto Nextchar1;
                r1 = r_Init1 & A4;
                r2 =  A3 | (((A3 | B3) >> 1) & r_NO_ERR); 
                B4 = ((A4 >>1 ) & CMask) | r2 | r1 ;  
                       if(D == 4) goto Nextchar1;
  Nextchar1: i=i+1;
          if(B0 & endpos) {
             j++;  r1 = B0;
             if ( D == 1) r1 = B1;
             if ( D == 2) r1 = B2;
             if ( D == 3) r1 = B3;
             if ( D == 4) r1 = B4;
             if(((AND == 1) && ((r1 & endposition) == endposition)) ||                           ((AND == 0) && (r1 & endposition)) ^ INVERSE )
                   { 
                      if(FILENAMEONLY) {
                         num_of_matched++;
                         printf("%s\n", CurrentFileName);
                         return; }
                      printout_end = i - D_length -1 ; 
                      if(!(lasti >= Max_record + l - 1))
                         output(buffer, lasti, printout_end, j);
                   }
             lasti = i - D_length ;
             TRUNCATE = OFF;
             for(k=0; k<= D; k++) {
                A[k] = Init[0];
             }
             r1 = A[0] & Init1; 
             B[0] = (((A[0]>>1)&CMask) | r1) & D_Mask;
             for(k=1; k<= D; k++) {
                r1 = Init1 & A[k];
                r2 = A[k-1] | (((A[k-1] | B[k-1])>>1)&r_NO_ERR);
                B[k] = (((A[k]>>1)&CMask) | r1 | r2) ;
             }
             A0 = A[0]; B0 = B[0]; A1 = A[1]; B1 = B[1]; A2 = A[2]; B2 = B[2];
             A3 = A[3]; B3 = B[3]; A4 = A[4]; B4 = B[4];
          }
      }
      if(l < BlockSize) {
             lasti = Max_record ;
      }
      else {
         ResidueSize = Max_record + l - lasti;
         if(ResidueSize > Max_record) {
            ResidueSize = Max_record;
            TRUNCATE = ON;         }
         strncpy(buffer+Max_record-ResidueSize, buffer+lasti, ResidueSize);
         lasti = Max_record - ResidueSize;
         if(lasti == 0)     lasti = 1; 
      }
    }
    return;
  }
  
  
  
  
  /*
  int fill_buf(int fd, unsigned char *buf, int record_size)
  {
  int num_read=1;
  int total_read=0;
  	while(total_read < record_size && num_read > 0) {
  		num_read = read(fd, buf+total_read, 4096);
  		total_read = total_read + num_read;
  	}
  	return(total_read);
  }
  */
  