home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / glimpse-2.1 / agrep / agrep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-16  |  95.5 KB  |  3,282 lines

  1.  
  2. /*
  3.  * bgopal: (1993-4) added a library interface and removed some bugs: also
  4.  * selectively modified many routines to work with our text-compression algo.
  5.  */
  6. #include "agrep.h"
  7. #include "checkfile.h"
  8.  
  9. #define PRINT(s)
  10.  
  11. extern char **environ;
  12. extern int errno;
  13. int pattern_index;    /* index in argv where the pattern is */
  14.  
  15. int glimpse_isserver=0;    /* so that there is no user interaction */
  16. int glimpse_call = 0;    /* So that usage message is not printed twice */
  17. int glimpse_clientdied=0;/* to quit search if glimpseserver's client dies */
  18. int use_previous_state;    /* VERY DIRTY SOLUTION TO OPTIMIZE GLIMPSE */
  19. int  agrep_initialfd;    /* Where does input come from? File/Memory? */
  20. CHAR *agrep_inbuffer;
  21. int  agrep_inlen;
  22. int  agrep_inpointer;
  23.  
  24. FILE *agrep_finalfp;    /* Where does output go to? File/Memory? */
  25. CHAR *agrep_outbuffer;
  26. int  agrep_outlen;
  27. int  agrep_outpointer;
  28.  
  29. int  execfd;    /* used by exec called within agrep_search, set in agrep_init */
  30. int  multifd = -1; /* fd for multipattern search used in ^^ , set in   ^^^^^^^^ */
  31. extern char *pat_spool, *tc_pat_spool;
  32. char *multibuf=NULL; /* buffer to put the multiple patterns in */
  33. int  multilen = 0; /* length of the multibuf: not the #of multi-patterns! */
  34.  
  35. extern int pos_cnt;    /* to re-initialize it to 0 for reg-exp search */
  36. unsigned Mask[MAXSYM];
  37. unsigned Init1, NO_ERR_MASK, Init[MaxError];
  38. unsigned Bit[WORD+1];
  39. CHAR buffer[BlockSize+Maxline+1];    /* should not be used anywhere: 10/18/93 */
  40. unsigned Next[MaxNext], Next1[MaxNext];
  41. unsigned wildmask, endposition, D_endpos; 
  42. int  LIMITOUTPUT;    /* maximum number of matches we are going to allow */
  43. int  EXITONERROR;    /* return -1 or exit on error? */
  44. int  REGEX, RE_ERR, FNAME, WHOLELINE, SIMPLEPATTERN;
  45. int  COUNT, HEAD, TAIL, LINENUM, INVERSE, I, S, DD, AND, SGREP, JUMP; 
  46. int  NOOUTPUTZERO;
  47. int  Num_Pat, PSIZE, prev_num_of_matched, num_of_matched, SILENT, NOPROMPT, BESTMATCH, NOUPPER;
  48. int  NOMATCH, TRUNCATE, FIRST_IN_RE, FIRSTOUTPUT;
  49. int  WORDBOUND, DELIMITER, D_length, tc_D_length, original_D_length;
  50. int  EATFIRST, OUTTAIL;
  51. int  BYTECOUNT;
  52. int  FILEOUT;
  53. int  DNA;
  54. int  APPROX;
  55. int  PAT_FILE;    /* multiple patterns from a given file */
  56. char PAT_FILE_NAME[MAX_LINE_LEN];
  57. int  PAT_BUFFER; /* multiple patterns from a given buffer */
  58. int  CONSTANT;
  59. int  RECURSIVE;
  60. int  total_line; /* used in mgrep */
  61. int  D;
  62. int  M;
  63. int  TCOMPRESSED;
  64. int  EASYSEARCH;    /* 1 used only for compressed files: LITTLE/BIG */
  65. int  ALWAYSFILENAME = OFF;
  66. int  POST_FILTER = OFF;
  67. int  NEW_FILE = OFF;    /* only when post-filter is used */
  68. int  PRINTPATTERN = OFF;
  69. int  MULTI_OUTPUT = OFF; /* should mgrep print the matched line multiple times for each matched pattern or just once? */
  70. /* invisible to the user, used only by glimpse: cannot use -l since it is incompatible with stdin and -A is used for the index search (done next) */
  71.  
  72. /* Stuff to handle complicated boolean patterns */
  73. int  AComplexBoolean = 0;
  74. ParseTree *AParse = NULL;
  75. int anum_terminals = 0;
  76. ParseTree aterminals[MAXNUM_PAT];
  77. char amatched_terminals[MAXNUM_PAT];
  78.  
  79. #if    MEASURE_TIMES
  80. /* timing variables */
  81. int OUTFILTER_ms;
  82. int FILTERALGO_ms;
  83. int INFILTER_ms;
  84. #endif    /*MEASURE_TIMES*/
  85.  
  86. CHAR **Textfiles = NULL;     /* array of filenames to be searched */
  87. int Numfiles = 0;    /* indicates how many files in Textfiles */
  88. int copied_from_argv = 0; /* were filenames copied from argv (should I free 'em)? */
  89. CHAR old_D_pat[MaxDelimit] = "\n";  /* to hold original D_pattern */
  90. CHAR original_old_D_pat[MaxDelimit] = "\n";
  91. CHAR Pattern[MAXPAT], OldPattern[MAXPAT];
  92. CHAR CurrentFileName[MAX_LINE_LEN]; 
  93. int SetCurrentFileName = 0;    /* dirty glimpse trick to make filters work: output seems to come from another file */
  94. int CurrentByteOffset;
  95. int SetCurrentByteOffset = 0;
  96. CHAR Progname[MAXNAME]; 
  97. CHAR D_pattern[MaxDelimit] = "\n; "; /* string which delimits records -- defaults to newline */
  98. CHAR tc_D_pattern[MaxDelimit * 2] = "\n";
  99. CHAR original_D_pattern[MaxDelimit] = "\n; ";
  100. char COMP_DIR[MAX_LINE_LEN];
  101. char FREQ_FILE[MAX_LINE_LEN], HASH_FILE[MAX_LINE_LEN], STRING_FILE[MAX_LINE_LEN];    /* interfacing with tcompress */
  102.  
  103. int  NOFILENAME,  /* Boolean flag, set for -h option */
  104.      FILENAMEONLY;/* Boolean flag, set for -l option */
  105. extern int init();
  106. int table[WORD][WORD];
  107.  
  108. /* This must be called before every agrep_search to reset agrep globals */
  109. reinit_value()
  110. {
  111.         int i, j;
  112.  
  113.     /* Added on 7th Oct 194 */
  114.     if (AParse) {
  115.         if (AComplexBoolean) destroy_tree(AParse);
  116.         AComplexBoolean = 0;
  117.         AParse = 0;
  118.         PAT_BUFFER = 0;
  119.         if (multibuf != NULL) free(multibuf);    /* this was allocated for arbit booleans, not multipattern search */
  120.         multibuf = NULL;
  121.         multilen = 0;
  122.         /* Cannot free multifd here since that is always allocated for multipattern search */
  123.     }
  124.     for (i=0; i<anum_terminals; i++) {
  125.         free(aterminals[i].data.leaf.value);
  126.         memset(&aterminals[i], '\0', sizeof(ParseTree));
  127.     }
  128.     anum_terminals = 0;
  129.  
  130.     num_of_matched = prev_num_of_matched = 0;
  131.         Bit[WORD] = 1;
  132.         for (i = WORD - 1; i > 0  ; i--)  Bit[i] = Bit[i+1] << 1;
  133.         for (i=0; i< MAXSYM; i++) Mask[i] = 0;
  134.  
  135.         /* bg: new things added on Mar 13 94 */
  136.         Init1 = 0;
  137.         NO_ERR_MASK = 0;
  138.         memset(Init, '\0', MaxError * sizeof(unsigned));
  139.         memset(Next, '\0', MaxNext * sizeof(unsigned));
  140.         memset(Next1, '\0', MaxNext * sizeof(unsigned));
  141.         wildmask = endposition = D_endpos = 0;
  142.         for (i=0; i<WORD; i++)
  143.                 for (j=0; j<WORD; j++)
  144.                         table[i][j] = 0;
  145.  
  146.         errno = 0;
  147.         strcpy(D_pattern, original_D_pattern);
  148.         D_length = original_D_length;
  149.         strcpy(old_D_pat, original_old_D_pat);
  150.  
  151.     /* Changed on Dec 26th: bg */
  152.     REGEX = 0;
  153.     HEAD = TAIL = ON;    /* were off initially */
  154.     RE_ERR = 0;
  155.     AND = 0;
  156.     FIRST_IN_RE = ON;
  157.     M = 0;
  158.     pos_cnt = 0;    /* added 31 Jan 95 */
  159. }
  160.  
  161. /* This must be called before every agrep_init to reset agrep options */
  162. initial_value()
  163. {
  164.     use_previous_state = 0;
  165.     SetCurrentFileName = 0;    /* 16/9/94 */
  166.     SetCurrentByteOffset = 0;    /* 23/9/94 */
  167.  
  168.     /* bg: new stuff on 17/Feb/94 */
  169.     if (multifd != -1) close(multifd);
  170.     multifd = -1;
  171.     if (multibuf != NULL) free(multibuf);
  172.     multibuf = NULL;
  173.     multilen = 0;
  174.     if (pat_spool != NULL) free(pat_spool);
  175.     pat_spool = NULL;
  176.     if (tc_pat_spool != NULL) free(tc_pat_spool);
  177.     tc_pat_spool = NULL;
  178.     LIMITOUTPUT = 0;    /* means infinity = current semantics */
  179.     EASYSEARCH = 1;
  180.     DNA = APPROX = PAT_FILE = PAT_BUFFER = CONSTANT = total_line = D = TCOMPRESSED = 0;
  181.     PAT_FILE_NAME[0] = '\0';
  182.     EXITONERROR = NOFILENAME = FILENAMEONLY = FILEOUT = ALWAYSFILENAME = NEW_FILE = POST_FILTER = 0;
  183.  
  184.         original_old_D_pat[0] = old_D_pat[0] = '\n';
  185.         original_old_D_pat[1] = old_D_pat[1] = '\0';
  186.         original_D_pattern[0] = D_pattern[0] = '\n';
  187.         original_D_pattern[1] = D_pattern[1] = ';';
  188.         original_D_pattern[2] = D_pattern[2] = ' ';
  189.         original_D_pattern[3] = D_pattern[3] = '\0';
  190.  
  191.     strcpy(tc_D_pattern, "\n");
  192.     tc_D_length = 1;
  193.  
  194.     /* the functions agrep_init and agrep_search take care of Textfiles and Numfiles */
  195.     agrep_inpointer = 0;
  196.     agrep_outpointer = 0;
  197.     agrep_outlen = 0;
  198. #if    MEASURE_TIMES
  199.     OUTFILTER_ms = FILTERALGO_ms = INFILTER_ms = 0;
  200. #endif    /*MEASURE_TIMES*/
  201.  
  202.     MULTI_OUTPUT = 0;
  203.     PRINTPATTERN = 0;
  204.     JUMP = FNAME = BESTMATCH = NOPROMPT = NOUPPER = 0;
  205.     RECURSIVE = 0;
  206.     COUNT = LINENUM = WHOLELINE = SGREP = 0;
  207.     NOOUTPUTZERO = 0;
  208.     EATFIRST = INVERSE = TRUNCATE = OUTTAIL = 0; 
  209.     NOMATCH = FIRSTOUTPUT = ON;    /* were off initally */
  210.     I = DD = S = 1;    /* were off initially */
  211.     original_D_length = D_length = 2;    /* was 0 initially */
  212.     SILENT = Num_Pat = PSIZE = SIMPLEPATTERN = prev_num_of_matched = num_of_matched = 0 ;
  213.     WORDBOUND = DELIMITER = 0;
  214.  
  215.     COMP_DIR[0] = '\0';
  216.     FREQ_FILE[0] = '\0';
  217.     HASH_FILE[0] = '\0';
  218.     STRING_FILE[0] = '\0';
  219.     BYTECOUNT = OFF;
  220.  
  221.     /* Pattern, OldPattern, execfd, Numfiles are set in agrep_init: so no need to initialize */
  222.     reinit_value();
  223.  
  224.     glimpse_clientdied = 0;    /* added 15th Feb 95 */
  225. }
  226.  
  227. compute_next(M, Next, Next1)
  228. int M; 
  229. unsigned *Next, *Next1;
  230. {
  231.     int i, j=0, n,  k, temp;
  232.     int mid, pp;
  233.     int MM, base;
  234.     unsigned V[WORD];
  235.  
  236.     base = WORD - M;
  237.     temp = Bit[base]; 
  238.     Bit[base] = 0;
  239.     for (i=0; i<WORD; i++) V[i] = 0;
  240.     for (i=1; i<M; i++)
  241.     {  
  242.         j=0;
  243.         while (table[i][j] > 0 && j < 10) {
  244.             V[i] = V[i] | Bit[base + table[i][j++]];
  245.         }
  246.     }
  247.     Bit[base]=temp;
  248.     if(M <= SHORTREG)
  249.     {
  250.         k = exponen(M);
  251.         pp = 2*k;
  252.         for(i=k; i<pp ; i++)
  253.         {   
  254.             n = i;
  255.             Next[i]= (k>>1);
  256.             for(j=M; j>=1; j--)
  257.             {
  258.                 if(n & Bit[WORD]) Next[i] = Next[i] | V[j];
  259.                 n = (n>>1);
  260.             }
  261.         }      
  262.         return;
  263.     }
  264.     if(M > MAXREG) fprintf(stderr, "%s: regular expression too long\n", Progname);
  265.     MM = M;
  266.     if(M & 1) M=M+1;
  267.     k = exponen(M/2);
  268.     pp = 2*k;
  269.     mid = MM/2;
  270.     for(i=k; i<pp ; i++)
  271.     {     
  272.         n = i;
  273.         Next[i]= (Bit[base]>>1);
  274.         for(j=MM; j>mid ; j--)
  275.         {
  276.             if(n & Bit[WORD]) Next[i] = Next[i] | V[j-mid];
  277.             n = (n>>1);
  278.         }
  279.         n=i-k;
  280.         Next1[i-k] = 0;
  281.         for(j = 0; j<mid; j++)
  282.         {
  283.             if(n & Bit[WORD]) Next1[i-k] = Next1[i-k] | V[MM-j];
  284.             n = (n>>1);
  285.         }
  286.     }      
  287.     return;
  288. }
  289.  
  290. exponen(m)
  291. int m;
  292.     int i, ex;
  293.     ex= 1;
  294.     for (i=0; i<m; i++) ex <<= 1;    /* was ex *= 2 */
  295.     return(ex);
  296. }
  297.  
  298. re1(Text, M, D)
  299. int Text, M, D;
  300. {
  301.     register unsigned i, c, r0, r1, r2, r3, CMask, Newline, Init0, r_NO_ERR; 
  302.     register unsigned end;
  303.     register unsigned hh, LL=0, k;  /* Lower part */
  304.     int  FIRST_TIME=ON, num_read , j=0, base;
  305.     unsigned A[MaxRerror+1], B[MaxRerror+1];
  306.     unsigned Next[MaxNext], Next1[MaxNext];
  307.     CHAR *buffer;
  308.     int FIRST_LOOP = 1;
  309.  
  310.     r_NO_ERR = NO_ERR_MASK;
  311.     if(M > 30) {
  312.         fprintf(stderr, "%s: regular expression too long\n", Progname);
  313.         if (!EXITONERROR){
  314.             errno = 2;
  315.             return -1;
  316.         }
  317.         else exit(2);
  318.     }
  319.     base = WORD - M;
  320.     hh = M/2;
  321.     for(i=WORD, j=0; j < hh ; i--, j++) LL = LL | Bit[i];
  322.     if(FIRST_IN_RE) compute_next(M, Next, Next1); 
  323.     /*SUN: try: change to memory allocation */
  324.     FIRST_IN_RE = 0;
  325.     Newline = '\n';
  326.     Init[0] = Bit[base];
  327.     if(HEAD) Init[0] = Init[0] | Bit[base+1];
  328.     for(i=1; i<= D; i++) Init[i] = Init[i-1] | Next[Init[i-1]>>hh] | Next1[Init[i-1]&LL];
  329.     Init1 = Init[0] | 1; 
  330.     Init0 = Init[0];
  331.     r2 = r3 = Init[0];
  332.     for(k=0; k<= D; k++) { 
  333.         A[k] = B[k] = Init[k]; 
  334.     }
  335.  
  336.     if ( D == 0 )
  337.     {
  338. #if    AGREP_POINTER
  339.         if (Text != -1)
  340.         {
  341. #endif    /*AGREP_POINTER*/
  342.         alloc_buf(Text, &buffer, BlockSize+Maxline+1);
  343.         while ((num_read = fill_buf(Text, buffer + Maxline, BlockSize)) > 0)
  344.         {
  345.             i=Maxline; 
  346.             end = num_read + Maxline;
  347.             if((num_read < BlockSize) && buffer[end-1] != '\n') buffer[end] = '\n';
  348.             if(FIRST_LOOP) {         /* if first time in the loop add a newline */
  349.                 buffer[i-1] = '\n';  /* in front the  text.  */
  350.                 i--;
  351.                 CurrentByteOffset --;
  352.                 FIRST_LOOP = 0;
  353.             }
  354.  
  355.             /* RE1_PROCESS_WHEN_DZERO: the while-loop below */
  356.             while ( i < end )
  357.             {
  358.                 c = buffer[i++];
  359.                 CurrentByteOffset ++;
  360.                 CMask = Mask[c];
  361.                 if(c != Newline)
  362.                 {
  363.                     if(CMask != 0) {
  364.                         r1 = Init1 & r3;
  365.                         r2 = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | r1;
  366.                     }
  367.                     else  {
  368.                         r2 = r3 & Init1;
  369.                     }
  370.                 }
  371.                 else {
  372.                     j++;
  373.                     if (DELIMITER) CurrentByteOffset -= D_length;
  374.                     else CurrentByteOffset -= 1;
  375.                     r1 = Init1 & r3;            /* match against endofline */
  376.                     r2 = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | r1;
  377.                     if(TAIL) r2 = (Next[r2>>hh] | Next1[r2&LL]) | r2;                                        /* epsilon move */
  378.                     if(( r2 & 1 ) ^ INVERSE) {
  379.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  380.                             num_of_matched++;
  381.  
  382.                             if (agrep_finalfp != NULL) 
  383.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  384.                             else {
  385.                                 int outindex;
  386.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  387.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  388.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  389.                                 }
  390.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  391.                                     OUTPUT_OVERFLOW;
  392.                                     free_buf(Text, buffer);
  393.                                     return -1;
  394.                                 }
  395.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  396.                                 agrep_outpointer += outindex;
  397.                             }
  398.  
  399.                             free_buf(Text, buffer);
  400.                             NEW_FILE = OFF;
  401.                             return 0;
  402.                         }
  403.                         if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
  404.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  405.                             free_buf(Text, buffer);
  406.                             return 0;    /* done */
  407.                         }
  408.                     }
  409.                     r3 = Init0;
  410.                     r2 = (Next[r3>>hh] | Next1[r3&LL]) & CMask | Init0;
  411.                     /* match begin of line */
  412.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  413.                     else CurrentByteOffset += 1*1;
  414.                 }
  415.                 c = buffer[i++];
  416.                 CurrentByteOffset ++;
  417.                 CMask = Mask[c];
  418.                 if(c != Newline)
  419.                 {
  420.                     if(CMask != 0) {
  421.                         r1 = Init1 & r2;
  422.                         r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
  423.                     }
  424.                     else   r3 = r2 & Init1;
  425.                 } /* if(NOT Newline) */
  426.                 else {
  427.                     j++;
  428.                     if (DELIMITER) CurrentByteOffset -= D_length;
  429.                     else CurrentByteOffset -= 1;
  430.                     r1 = Init1 & r2;            /* match against endofline */
  431.                     r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
  432.                     if(TAIL) r3 = ( Next[r3>>hh] | Next1[r3&LL] ) | r3;
  433.                     /* epsilon move */
  434.                     if(( r3 & 1 ) ^ INVERSE) {
  435.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  436.                             num_of_matched++;
  437.  
  438.                             if (agrep_finalfp != NULL)
  439.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  440.                             else {
  441.                                 int outindex;
  442.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  443.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  444.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  445.                                 }
  446.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  447.                                     OUTPUT_OVERFLOW;
  448.                                     free_buf(Text, buffer);
  449.                                     return -1;
  450.                                 }
  451.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  452.                                 agrep_outpointer += outindex;
  453.                             }
  454.  
  455.                             free_buf(Text, buffer);
  456.                             NEW_FILE = OFF;
  457.                             return 0;
  458.                         }
  459.                         if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
  460.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  461.                             free_buf(Text, buffer);
  462.                             return 0;    /* done */
  463.                         }
  464.                     }
  465.                     r2 = Init0;
  466.                     r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | Init0;
  467.                     /* match begin of line */
  468.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  469.                     else CurrentByteOffset += 1*1;
  470.                 }
  471.             } /* while i < end ... */
  472.  
  473.             strncpy(buffer, buffer+num_read, Maxline);
  474.         } /* end while fill_buf()... */
  475.  
  476.         free_buf(Text, buffer);
  477.         return 0;
  478. #if    AGREP_POINTER
  479.         }
  480.         else {    /* within the memory buffer: assume it starts with a newline at position 0, the actual pattern follows that, and it ends with a '\n' */
  481.         num_read = agrep_inlen;
  482.         buffer = (CHAR *)agrep_inbuffer;
  483.         end = num_read;
  484.         /* buffer[end-1] = '\n';*/ /* at end of the text. */
  485.         /* buffer[0] = '\n';*/  /* in front of the  text. */
  486.         i = 0;
  487.  
  488.             /* An exact copy of the above RE1_PROCESS_WHEN_DZERO: the while-loop below */
  489.             while ( i < end )
  490.             {
  491.                 c = buffer[i++];
  492.                 CurrentByteOffset ++;
  493.                 CMask = Mask[c];
  494.                 if(c != Newline)
  495.                 {
  496.                     if(CMask != 0) {
  497.                         r1 = Init1 & r3;
  498.                         r2 = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | r1;
  499.                     }
  500.                     else  {
  501.                         r2 = r3 & Init1;
  502.                     }
  503.                 }
  504.                 else {
  505.                     j++;
  506.                     if (DELIMITER) CurrentByteOffset -= D_length;
  507.                     else CurrentByteOffset -= 1;
  508.                     r1 = Init1 & r3;            /* match against endofline */
  509.                     r2 = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | r1;
  510.                     if(TAIL) r2 = (Next[r2>>hh] | Next1[r2&LL]) | r2;                                        /* epsilon move */
  511.                     if(( r2 & 1 ) ^ INVERSE) {
  512.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  513.                             num_of_matched++;
  514.  
  515.                             if (agrep_finalfp != NULL) 
  516.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  517.                             else {
  518.                                 int outindex;
  519.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  520.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  521.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  522.                                 }
  523.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  524.                                     OUTPUT_OVERFLOW;
  525.                                     free_buf(Text, buffer);
  526.                                     return -1;
  527.                                 }
  528.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  529.                                 agrep_outpointer += outindex;
  530.                             }
  531.  
  532.                             free_buf(Text, buffer);
  533.                             NEW_FILE = OFF;
  534.                             return 0;
  535.                         }
  536.                         if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
  537.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  538.                             free_buf(Text, buffer);
  539.                             return 0;    /* done */
  540.                         }
  541.                     }
  542.                     r3 = Init0;
  543.                     r2 = (Next[r3>>hh] | Next1[r3&LL]) & CMask | Init0;
  544.                     /* match begin of line */
  545.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  546.                     else CurrentByteOffset += 1*1;
  547.                 }
  548.                 c = buffer[i++];
  549.                 CurrentByteOffset ++;
  550.                 CMask = Mask[c];
  551.                 if(c != Newline)
  552.                 {
  553.                     if(CMask != 0) {
  554.                         r1 = Init1 & r2;
  555.                         r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
  556.                     }
  557.                     else   r3 = r2 & Init1;
  558.                 } /* if(NOT Newline) */
  559.                 else {
  560.                     j++;
  561.                     if (DELIMITER) CurrentByteOffset -= D_length;
  562.                     else CurrentByteOffset -= 1;
  563.                     r1 = Init1 & r2;            /* match against endofline */
  564.                     r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
  565.                     if(TAIL) r3 = ( Next[r3>>hh] | Next1[r3&LL] ) | r3;
  566.                     /* epsilon move */
  567.                     if(( r3 & 1 ) ^ INVERSE) {
  568.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  569.                             num_of_matched++;
  570.  
  571.                             if (agrep_finalfp != NULL)
  572.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  573.                             else {
  574.                                 int outindex;
  575.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  576.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  577.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  578.                                 }
  579.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  580.                                     OUTPUT_OVERFLOW;
  581.                                     free_buf(Text, buffer);
  582.                                     return -1;
  583.                                 }
  584.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  585.                                 agrep_outpointer += outindex;
  586.                             }
  587.  
  588.                             free_buf(Text, buffer);
  589.                             NEW_FILE = OFF;
  590.                             return 0;
  591.                         }
  592.                         if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
  593.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  594.                             free_buf(Text, buffer);
  595.                             return 0;    /* done */
  596.                         }
  597.                     }
  598.                     r2 = Init0;
  599.                     r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | Init0;
  600.                     /* match begin of line */
  601.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  602.                     else CurrentByteOffset += 1*1;
  603.                 }
  604.             } /* while i < end ... */
  605.  
  606.         return 0;
  607.         }
  608. #endif    /*AGREP_POINTER*/
  609.     } /*  end if (D == 0) */
  610.  
  611. #if    AGREP_POINTER
  612.     if (Text != -1)
  613.     {
  614. #endif    /*AGREP_POINTER*/
  615.         while ((num_read = fill_buf(Text, buffer + Maxline, BlockSize)) > 0)
  616.         {
  617.             i=Maxline; 
  618.             end = Maxline + num_read;
  619.             if((num_read < BlockSize) && buffer[end-1] != '\n') buffer[end] = '\n';
  620.             if(FIRST_TIME) {         /* if first time in the loop add a newline */
  621.                 buffer[i-1] = '\n';  /* in front the  text.  */
  622.                 i--;
  623.                 CurrentByteOffset --;
  624.                 FIRST_TIME = 0;
  625.             }
  626.  
  627.             /* RE1_PROCESS_WHEN_DNOTZERO: the while loop below */
  628.             while (i < end )
  629.             {
  630.                 c = buffer[i];
  631.                 CMask = Mask[c];
  632.                 if(c !=  Newline)
  633.                 {
  634.                     if(CMask != 0) {  
  635.                         r2 = B[0];
  636.                         r1 = Init1 & r2;
  637.                         A[0] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
  638.                         r3 = B[1];
  639.                         r1 = Init1 & r3;
  640.                         r0 = r2 | A[0];     /* A[0] | B[0] */
  641.                         A[1] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | (( r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  642.                         if(D == 1) goto Nextcharfile;
  643.                         r2 = B[2];
  644.                         r1 = Init1 & r2;
  645.                         r0 = r3 | A[1];
  646.                         A[2] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  647.                         if(D == 2) goto Nextcharfile;
  648.                         r3 = B[3];
  649.                         r1 = Init1 & r3;
  650.                         r0 = r2 | A[2];
  651.                         A[3] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  652.                         if(D == 3) goto Nextcharfile;
  653.                         r2 = B[4];
  654.                         r1 = Init1 & r2;
  655.                         r0 = r3 | A[3];
  656.                         A[4] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  657.                         if(D == 4)  goto Nextcharfile;
  658.                     }  /* if(CMask) */
  659.                     else  {
  660.                         r2 = B[0];
  661.                         A[0] = r2 & Init1; 
  662.                         r3 = B[1];
  663.                         r1 = Init1 & r3;
  664.                         r0 = r2 | A[0];
  665.                         A[1] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  666.                         if(D == 1) goto Nextcharfile;
  667.                         r2 = B[2];
  668.                         r1 = Init1 & r2;
  669.                         r0 = r3 | A[1];
  670.                         A[2] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  671.                         if(D == 2) goto Nextcharfile;
  672.                         r3 = B[3];
  673.                         r1 = Init1 & r3;
  674.                         r0 = r2 | A[2];
  675.                         A[3] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  676.                         if(D == 3) goto Nextcharfile;
  677.                         r2 = B[4];
  678.                         r1 = Init1 & r2;
  679.                         r0 = r3 | A[3];
  680.                         A[4] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  681.                         if(D == 4) goto Nextcharfile;
  682.                     }
  683.                 }
  684.                 else {  
  685.                     j++;
  686.                     if (DELIMITER) CurrentByteOffset -= D_length;
  687.                     else CurrentByteOffset -= 1;
  688.                     r1 = Init1 & B[D];            /* match against endofline */
  689.                     A[D] = ((Next[B[D]>>hh] | Next1[B[D]&LL]) & CMask) | r1;
  690.                     if(TAIL) A[D] = ( Next[A[D]>>hh] | Next1[A[D]&LL] ) | A[D]; 
  691.                     /* epsilon move */
  692.                     if(( A[D] & 1 ) ^ INVERSE) {
  693.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  694.                             num_of_matched++;
  695.  
  696.                             if (agrep_finalfp != NULL) 
  697.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  698.                             else {
  699.                                 int outindex;
  700.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  701.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  702.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  703.                                 }
  704.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  705.                                     OUTPUT_OVERFLOW;
  706.                                     free_buf(Text, buffer);
  707.                                     return -1;
  708.                                 }
  709.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  710.                                 agrep_outpointer += outindex;
  711.                             }
  712.  
  713.                             free_buf(Text, buffer);
  714.                             NEW_FILE = OFF;
  715.                             return 0;
  716.                         } 
  717.                         if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
  718.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  719.                             free_buf(Text, buffer);
  720.                             return 0;    /* done */
  721.                         }
  722.                     }
  723.                     for(k=0; k<=D; k++)  B[k] = Init[0];
  724.                     r1 = Init1 & B[0];
  725.                     A[0] = (( Next[B[0]>>hh] | Next1[B[0]&LL]) & CMask) | r1;
  726.                     for(k=1; k<=D; k++) {
  727.                         r3 = B[k];
  728.                         r1 = Init1 & r3;
  729.                         r2 = A[k-1] | B[k-1];
  730.                         A[k] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((B[k-1] | Next[r2>>hh] | Next1[r2&LL]) & r_NO_ERR) | r1;
  731.                     }
  732.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  733.                     else CurrentByteOffset += 1*1;
  734.                 }
  735.     Nextcharfile: 
  736.                 i=i+1;
  737.                 CurrentByteOffset ++;
  738.                 c = buffer[i];
  739.                 CMask = Mask[c];
  740.                 if(c != Newline)
  741.                 {
  742.                     if(CMask != 0) {  
  743.                         r2 = A[0];
  744.                         r1 = Init1 & r2;
  745.                         B[0] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
  746.                         r3 = A[1];
  747.                         r1 = Init1 & r3;
  748.                         r0 = B[0] | r2;
  749.                         B[1] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL]) & r_NO_ERR) | r1 ;  
  750.                         if(D == 1) goto Nextchar1file;
  751.                         r2 = A[2];
  752.                         r1 = Init1 & r2;
  753.                         r0 = B[1] | r3;
  754.                         B[2] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  755.                         if(D == 2) goto Nextchar1file;
  756.                         r3 = A[3];
  757.                         r1 = Init1 & r3;
  758.                         r0 = B[2] | r2;
  759.                         B[3] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  760.                         if(D == 3) goto Nextchar1file;
  761.                         r2 = A[4];
  762.                         r1 = Init1 & r2;
  763.                         r0 = B[3] | r3;
  764.                         B[4] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  765.                         if(D == 4)   goto Nextchar1file;
  766.                     }  /* if(CMask) */
  767.                     else  {
  768.                         r2 = A[0];
  769.                         B[0] = r2 & Init1; 
  770.                         r3 = A[1];
  771.                         r1 = Init1 & r3;
  772.                         r0 = B[0] | r2;
  773.                         B[1] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  774.                         if(D == 1) goto Nextchar1file;
  775.                         r2 = A[2];
  776.                         r1 = Init1 & r2;
  777.                         r0 = B[1] | r3;
  778.                         B[2] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  779.                         if(D == 2) goto Nextchar1file;
  780.                         r3 = A[3];
  781.                         r1 = Init1 & r3;
  782.                         r0 = B[2] | r2;
  783.                         B[3] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  784.                         if(D == 3) goto Nextchar1file;
  785.                         r2 = A[4];
  786.                         r1 = Init1 & r2;
  787.                         r0 = B[3] | r3;
  788.                         B[4] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  789.                         if(D == 4) goto Nextchar1file;
  790.                     }
  791.                 } /* if(NOT Newline) */
  792.                 else {  
  793.                     j++;
  794.                     if (DELIMITER) CurrentByteOffset -= D_length;
  795.                     else CurrentByteOffset -= 1;
  796.                     r1 = Init1 & A[D];            /* match against endofline */
  797.                     B[D] = ((Next[A[D]>>hh] | Next1[A[D]&LL]) & CMask) | r1;
  798.                     if(TAIL) B[D] = ( Next[B[D]>>hh] | Next1[B[D]&LL] ) | B[D]; 
  799.                     /* epsilon move */
  800.                     if(( B[D] & 1 ) ^ INVERSE) {
  801.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  802.                             num_of_matched++;
  803.  
  804.                             if (agrep_finalfp != NULL) 
  805.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  806.                             else {
  807.                                 int outindex;
  808.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  809.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  810.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  811.                                 }
  812.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  813.                                     OUTPUT_OVERFLOW;
  814.                                     free_buf(Text, buffer);
  815.                                     return -1;
  816.                                 }
  817.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  818.                                 agrep_outpointer += outindex;
  819.                             }
  820.  
  821.                             free_buf(Text, buffer);
  822.                             NEW_FILE = OFF;
  823.                             return 0;
  824.                         } 
  825.                         if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
  826.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  827.                             free_buf(Text, buffer);
  828.                             return 0;    /* done */
  829.                         }
  830.                     }
  831.                     for(k=0; k<=D; k++) A[k] = Init0; 
  832.                     r1 = Init1 & A[0];
  833.                     B[0] = ((Next[A[0]>>hh] | Next1[A[0]&LL]) & CMask) | r1;
  834.                     for(k=1; k<=D; k++) {
  835.                         r3 = A[k];
  836.                         r1 = Init1 & r3;
  837.                         r2 = A[k-1] | B[k-1];
  838.                         B[k] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((A[k-1] | Next[r2>>hh] | Next1[r2&LL]) & r_NO_ERR) | r1;
  839.                     }
  840.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  841.                     else CurrentByteOffset += 1*1;
  842.                 }
  843.     Nextchar1file: 
  844.                 i=i+1;
  845.                 CurrentByteOffset ++;
  846.             } /* while i < end */
  847.  
  848.             strncpy(buffer, buffer+num_read, Maxline);
  849.         } /* while fill_buf... */
  850.         free_buf(Text, buffer);
  851.         return 0;
  852. #if    AGREP_POINTER
  853.     }
  854.     else {    /* within the memory buffer: assume it starts with a newline at position 0, the actual pattern follows that, and it ends with a '\n' */
  855.         num_read = agrep_inlen;
  856.         buffer = (CHAR *)agrep_inbuffer;
  857.         end = num_read;
  858.         /* buffer[end-1] = '\n';*/ /* at end of the text. */
  859.         /* buffer[0] = '\n';*/  /* in front of the  text. */
  860.         i = 0;
  861.  
  862.             /* An exact copy of the above RE1_PROCESS_WHEN_DNOTZERO: the while loop below */
  863.             while (i < end )
  864.             {
  865.                 c = buffer[i];
  866.                 CMask = Mask[c];
  867.                 if(c !=  Newline)
  868.                 {
  869.                     if(CMask != 0) {  
  870.                         r2 = B[0];
  871.                         r1 = Init1 & r2;
  872.                         A[0] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
  873.                         r3 = B[1];
  874.                         r1 = Init1 & r3;
  875.                         r0 = r2 | A[0];     /* A[0] | B[0] */
  876.                         A[1] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | (( r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  877.                         if(D == 1) goto Nextcharmem;
  878.                         r2 = B[2];
  879.                         r1 = Init1 & r2;
  880.                         r0 = r3 | A[1];
  881.                         A[2] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  882.                         if(D == 2) goto Nextcharmem;
  883.                         r3 = B[3];
  884.                         r1 = Init1 & r3;
  885.                         r0 = r2 | A[2];
  886.                         A[3] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  887.                         if(D == 3) goto Nextcharmem;
  888.                         r2 = B[4];
  889.                         r1 = Init1 & r2;
  890.                         r0 = r3 | A[3];
  891.                         A[4] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  892.                         if(D == 4)  goto Nextcharmem;
  893.                     }  /* if(CMask) */
  894.                     else  {
  895.                         r2 = B[0];
  896.                         A[0] = r2 & Init1; 
  897.                         r3 = B[1];
  898.                         r1 = Init1 & r3;
  899.                         r0 = r2 | A[0];
  900.                         A[1] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  901.                         if(D == 1) goto Nextcharmem;
  902.                         r2 = B[2];
  903.                         r1 = Init1 & r2;
  904.                         r0 = r3 | A[1];
  905.                         A[2] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  906.                         if(D == 2) goto Nextcharmem;
  907.                         r3 = B[3];
  908.                         r1 = Init1 & r3;
  909.                         r0 = r2 | A[2];
  910.                         A[3] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  911.                         if(D == 3) goto Nextcharmem;
  912.                         r2 = B[4];
  913.                         r1 = Init1 & r2;
  914.                         r0 = r3 | A[3];
  915.                         A[4] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  916.                         if(D == 4) goto Nextcharmem;
  917.                     }
  918.                 }
  919.                 else {  
  920.                     j++;
  921.                     if (DELIMITER) CurrentByteOffset -= D_length;
  922.                     else CurrentByteOffset -= 1;
  923.                     r1 = Init1 & B[D];            /* match against endofline */
  924.                     A[D] = ((Next[B[D]>>hh] | Next1[B[D]&LL]) & CMask) | r1;
  925.                     if(TAIL) A[D] = ( Next[A[D]>>hh] | Next1[A[D]&LL] ) | A[D]; 
  926.                     /* epsilon move */
  927.                     if(( A[D] & 1 ) ^ INVERSE) {
  928.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  929.                             num_of_matched++;
  930.  
  931.                             if (agrep_finalfp != NULL) 
  932.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  933.                             else {
  934.                                 int outindex;
  935.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  936.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  937.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  938.                                 }
  939.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  940.                                     OUTPUT_OVERFLOW;
  941.                                     free_buf(Text, buffer);
  942.                                     return -1;
  943.                                 }
  944.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  945.                                 agrep_outpointer += outindex;
  946.                             }
  947.  
  948.                             free_buf(Text, buffer);
  949.                             NEW_FILE = OFF;
  950.                             return 0;
  951.                         } 
  952.                         if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
  953.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  954.                             free_buf(Text, buffer);
  955.                             return 0;    /* done */
  956.                         }
  957.                     }
  958.                     for(k=0; k<=D; k++)  B[k] = Init[0];
  959.                     r1 = Init1 & B[0];
  960.                     A[0] = (( Next[B[0]>>hh] | Next1[B[0]&LL]) & CMask) | r1;
  961.                     for(k=1; k<=D; k++) {
  962.                         r3 = B[k];
  963.                         r1 = Init1 & r3;
  964.                         r2 = A[k-1] | B[k-1];
  965.                         A[k] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((B[k-1] | Next[r2>>hh] | Next1[r2&LL]) & r_NO_ERR) | r1;
  966.                     }
  967.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  968.                     else CurrentByteOffset += 1*1;
  969.                 }
  970.     Nextcharmem: 
  971.                 i=i+1;
  972.                 CurrentByteOffset ++;
  973.                 c = buffer[i];
  974.                 CMask = Mask[c];
  975.                 if(c != Newline)
  976.                 {
  977.                     if(CMask != 0) {  
  978.                         r2 = A[0];
  979.                         r1 = Init1 & r2;
  980.                         B[0] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
  981.                         r3 = A[1];
  982.                         r1 = Init1 & r3;
  983.                         r0 = B[0] | r2;
  984.                         B[1] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL]) & r_NO_ERR) | r1 ;  
  985.                         if(D == 1) goto Nextchar1mem;
  986.                         r2 = A[2];
  987.                         r1 = Init1 & r2;
  988.                         r0 = B[1] | r3;
  989.                         B[2] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  990.                         if(D == 2) goto Nextchar1mem;
  991.                         r3 = A[3];
  992.                         r1 = Init1 & r3;
  993.                         r0 = B[2] | r2;
  994.                         B[3] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  995.                         if(D == 3) goto Nextchar1mem;
  996.                         r2 = A[4];
  997.                         r1 = Init1 & r2;
  998.                         r0 = B[3] | r3;
  999.                         B[4] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  1000.                         if(D == 4)   goto Nextchar1mem;
  1001.                     }  /* if(CMask) */
  1002.                     else  {
  1003.                         r2 = A[0];
  1004.                         B[0] = r2 & Init1; 
  1005.                         r3 = A[1];
  1006.                         r1 = Init1 & r3;
  1007.                         r0 = B[0] | r2;
  1008.                         B[1] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  1009.                         if(D == 1) goto Nextchar1mem;
  1010.                         r2 = A[2];
  1011.                         r1 = Init1 & r2;
  1012.                         r0 = B[1] | r3;
  1013.                         B[2] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  1014.                         if(D == 2) goto Nextchar1mem;
  1015.                         r3 = A[3];
  1016.                         r1 = Init1 & r3;
  1017.                         r0 = B[2] | r2;
  1018.                         B[3] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  1019.                         if(D == 3) goto Nextchar1mem;
  1020.                         r2 = A[4];
  1021.                         r1 = Init1 & r2;
  1022.                         r0 = B[3] | r3;
  1023.                         B[4] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
  1024.                         if(D == 4) goto Nextchar1mem;
  1025.                     }
  1026.                 } /* if(NOT Newline) */
  1027.                 else {  
  1028.                     j++;
  1029.                     if (DELIMITER) CurrentByteOffset -= D_length;
  1030.                     else CurrentByteOffset -= 1;
  1031.                     r1 = Init1 & A[D];            /* match against endofline */
  1032.                     B[D] = ((Next[A[D]>>hh] | Next1[A[D]&LL]) & CMask) | r1;
  1033.                     if(TAIL) B[D] = ( Next[B[D]>>hh] | Next1[B[D]&LL] ) | B[D]; 
  1034.                     /* epsilon move */
  1035.                     if(( B[D] & 1 ) ^ INVERSE) {
  1036.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  1037.                             num_of_matched++;
  1038.  
  1039.                             if (agrep_finalfp != NULL) 
  1040.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  1041.                             else {
  1042.                                 int outindex;
  1043.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  1044.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  1045.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  1046.                                 }
  1047.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  1048.                                     OUTPUT_OVERFLOW;
  1049.                                     free_buf(Text, buffer);
  1050.                                     return -1;
  1051.                                 }
  1052.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  1053.                                 agrep_outpointer += outindex;
  1054.                             }
  1055.  
  1056.                             free_buf(Text, buffer);
  1057.                             NEW_FILE = OFF;
  1058.                             return 0;
  1059.                         } 
  1060.                         if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
  1061.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  1062.                             free_buf(Text, buffer);
  1063.                             return 0;    /* done */
  1064.                         }
  1065.                     }
  1066.                     for(k=0; k<=D; k++) A[k] = Init0; 
  1067.                     r1 = Init1 & A[0];
  1068.                     B[0] = ((Next[A[0]>>hh] | Next1[A[0]&LL]) & CMask) | r1;
  1069.                     for(k=1; k<=D; k++) {
  1070.                         r3 = A[k];
  1071.                         r1 = Init1 & r3;
  1072.                         r2 = A[k-1] | B[k-1];
  1073.                         B[k] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | ((A[k-1] | Next[r2>>hh] | Next1[r2&LL]) & r_NO_ERR) | r1;
  1074.                     }
  1075.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  1076.                     else CurrentByteOffset += 1*1;
  1077.                 }
  1078.     Nextchar1mem: 
  1079.                 i=i+1;
  1080.                 CurrentByteOffset ++;
  1081.             } /* while i < end */
  1082.  
  1083.         return 0;
  1084.     }
  1085. #endif    /*AGREP_POINTER*/
  1086. } /* re1 */
  1087.  
  1088. re(Text, M, D)
  1089. int Text, M, D;
  1090. {
  1091.     register unsigned i, c, r1, r2, r3, CMask, k, Newline, Init0, Init1, end; 
  1092.     register unsigned r_even, r_odd, r_NO_ERR ;
  1093.     unsigned RMask[MAXSYM];
  1094.     unsigned A[MaxRerror+1], B[MaxRerror+1];
  1095.     int num_read, j=0, lasti, base, ResidueSize; 
  1096.     int FIRST_TIME; /* Flag */
  1097.     CHAR *buffer;
  1098.  
  1099.     base = WORD - M;
  1100.     k = 2*exponen(M);
  1101.     if(FIRST_IN_RE) {
  1102.         compute_next(M, Next, Next1); 
  1103.         FIRST_IN_RE = 0;    
  1104.     }
  1105.     for(i=0; i< MAXSYM; i++) RMask[i] = Mask[i];
  1106.     r_NO_ERR = NO_ERR_MASK;
  1107.     Newline = '\n';
  1108.     Init0 = Init[0] = Bit[base];
  1109.     if(HEAD) Init0  = Init[0] = Init0 | Bit[base+1] ;
  1110.     for(i=1; i<= D; i++) Init[i] = Init[i-1] | Next[Init[i-1]]; /* can be out? */
  1111.     Init1 = Init0 | 1; 
  1112.     r2 = r3 = Init0;
  1113.     for(k=0; k<= D; k++) { 
  1114.         A[k] = B[k] = Init[0]; 
  1115.     }  /* can be out? */
  1116.     FIRST_TIME = ON;
  1117.     alloc_buf(Text, &buffer, BlockSize+Maxline+1);
  1118.     if ( D == 0 )
  1119.     {
  1120. #if    AGREP_POINTER
  1121.         if(Text != -1) {
  1122. #endif    /*AGREP_POINTER*/
  1123.         lasti = Maxline;
  1124.         while ((num_read = fill_buf(Text, buffer + Maxline, BlockSize)) > 0)
  1125.         {
  1126.             i=Maxline; 
  1127.             end = Maxline + num_read ;
  1128.             if((num_read < BlockSize)&&buffer[end-1] != '\n') buffer[end] = '\n';
  1129.             if(FIRST_TIME) {
  1130.                 buffer[i-1] = '\n';
  1131.                 i--;
  1132.                 CurrentByteOffset --;
  1133.                 FIRST_TIME = 0;
  1134.             }
  1135.  
  1136.             /* RE_PROCESS_WHEN_DZERO: the while-loop below */
  1137.             while (i < end) 
  1138.             {
  1139.                 c = buffer[i++];
  1140.                 CurrentByteOffset ++;
  1141.                 CMask = RMask[c];
  1142.                 if(c != Newline)
  1143.                 {  
  1144.                     r1 = Init1 & r3;
  1145.                     r2 = (Next[r3] & CMask) | r1;
  1146.                 }
  1147.                 else {  
  1148.                     r1 = Init1 & r3;            /* match against '\n' */
  1149.                     r2 = Next[r3] & CMask | r1;
  1150.                     j++;
  1151.                     if (DELIMITER) CurrentByteOffset -= D_length;
  1152.                     else CurrentByteOffset -= 1;
  1153.                     if(TAIL) r2 = Next[r2] | r2 ;   /* epsilon move */
  1154.                     if(( r2 & 1) ^ INVERSE) {
  1155.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  1156.                             num_of_matched++;
  1157.  
  1158.                             if (agrep_finalfp != NULL) 
  1159.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  1160.                             else {
  1161.                                 int outindex;
  1162.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  1163.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  1164.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  1165.                                 }
  1166.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  1167.                                     OUTPUT_OVERFLOW;
  1168.                                     free_buf(Text, buffer);
  1169.                                     return -1;
  1170.                                 }
  1171.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  1172.                                 agrep_outpointer += outindex;
  1173.                             }
  1174.  
  1175.                             free_buf(Text, buffer);
  1176.                             NEW_FILE = OFF;
  1177.                             return 0;
  1178.                         } 
  1179.                         if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
  1180.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  1181.                             free_buf(Text, buffer);
  1182.                             return 0;    /* done */
  1183.                         }
  1184.                     }
  1185.                     lasti = i - 1;
  1186.                     r3 = Init0;
  1187.                     r2 = (Next[r3] & CMask) | Init0;
  1188.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  1189.                     else CurrentByteOffset += 1*1;
  1190.                 }
  1191.                 c = buffer[i++];   
  1192.                 CurrentByteOffset ++;
  1193.                 CMask = RMask[c];
  1194.                 if(c != Newline)
  1195.                 {
  1196.                     r1 = Init1 & r2;
  1197.                     r3 = (Next[r2] & CMask) | r1;
  1198.                 }
  1199.                 else {  
  1200.                     j++;
  1201.                     if (DELIMITER) CurrentByteOffset -= D_length;
  1202.                     else CurrentByteOffset -= 1;
  1203.                     r1 = Init1 & r2;            /* match against endofline */
  1204.                     r3 = Next[r2] & CMask | r1;
  1205.                     if(TAIL) r3 = Next[r3] | r3;
  1206.                     if(( r3 & 1) ^ INVERSE) {
  1207.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  1208.                             num_of_matched++;
  1209.  
  1210.                             if (agrep_finalfp != NULL) 
  1211.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  1212.                             else {
  1213.                                 int outindex;
  1214.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  1215.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  1216.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  1217.                                 }
  1218.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  1219.                                     OUTPUT_OVERFLOW;
  1220.                                     free_buf(Text, buffer);
  1221.                                     return -1;
  1222.                                 }
  1223.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  1224.                                 agrep_outpointer += outindex;
  1225.                             }
  1226.  
  1227.                             free_buf(Text, buffer);
  1228.                             NEW_FILE = OFF;
  1229.                             return 0;
  1230.                         } 
  1231.                         if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
  1232.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  1233.                             free_buf(Text, buffer);
  1234.                             return 0;    /* done */
  1235.                         }
  1236.                     }
  1237.                     lasti = i - 1;
  1238.                     r2 = Init0; 
  1239.                     r3 = (Next[r2] & CMask) | Init0;  /* match the newline */
  1240.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  1241.                     else CurrentByteOffset += 1*1;
  1242.                 }
  1243.             } /* while */
  1244.  
  1245.             ResidueSize = Maxline + num_read - lasti;
  1246.             if(ResidueSize > Maxline) {
  1247.                 ResidueSize = Maxline;  
  1248.             }
  1249.             strncpy(buffer+Maxline-ResidueSize, buffer+lasti, ResidueSize);
  1250.             lasti = Maxline - ResidueSize;
  1251.         } /* while fill_buf() */
  1252.         free_buf(Text, buffer);
  1253.         return 0;
  1254. #if    AGREP_POINTER
  1255.         }
  1256.         else {
  1257.         num_read = agrep_inlen;
  1258.         buffer = (CHAR *)agrep_inbuffer;
  1259.         end = num_read;
  1260.         /* buffer[end-1] = '\n';*/ /* at end of the text. */
  1261.         /* buffer[0] = '\n';*/  /* in front of the  text. */
  1262.         i = 0;
  1263.         lasti = 1;
  1264.  
  1265.             /* An exact copy of the above RE_PROCESS_WHEN_DZERO: the while-loop below */
  1266.             while (i < end) 
  1267.             {
  1268.                 c = buffer[i++];
  1269.                 CurrentByteOffset ++;
  1270.                 CMask = RMask[c];
  1271.                 if(c != Newline)
  1272.                 {  
  1273.                     r1 = Init1 & r3;
  1274.                     r2 = (Next[r3] & CMask) | r1;
  1275.                 }
  1276.                 else {  
  1277.                     r1 = Init1 & r3;            /* match against '\n' */
  1278.                     r2 = Next[r3] & CMask | r1;
  1279.                     j++;
  1280.                     if (DELIMITER) CurrentByteOffset -= D_length;
  1281.                     else CurrentByteOffset -= 1;
  1282.                     if(TAIL) r2 = Next[r2] | r2 ;   /* epsilon move */
  1283.                     if(( r2 & 1) ^ INVERSE) {
  1284.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  1285.                             num_of_matched++;
  1286.  
  1287.                             if (agrep_finalfp != NULL) 
  1288.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  1289.                             else {
  1290.                                 int outindex;
  1291.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  1292.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  1293.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  1294.                                 }
  1295.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  1296.                                     OUTPUT_OVERFLOW;
  1297.                                     free_buf(Text, buffer);
  1298.                                     return -1;
  1299.                                 }
  1300.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  1301.                                 agrep_outpointer += outindex;
  1302.                             }
  1303.  
  1304.                             free_buf(Text, buffer);
  1305.                             NEW_FILE = OFF;
  1306.                             return 0;
  1307.                         } 
  1308.                         if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
  1309.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  1310.                             free_buf(Text, buffer);
  1311.                             return 0;    /* done */
  1312.                         }
  1313.                     }
  1314.                     lasti = i - 1;
  1315.                     r3 = Init0;
  1316.                     r2 = (Next[r3] & CMask) | Init0;
  1317.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  1318.                     else CurrentByteOffset += 1*1;
  1319.                 }
  1320.                 c = buffer[i++];   
  1321.                 CurrentByteOffset ++;
  1322.                 CMask = RMask[c];
  1323.                 if(c != Newline)
  1324.                 {
  1325.                     r1 = Init1 & r2;
  1326.                     r3 = (Next[r2] & CMask) | r1;
  1327.                 }
  1328.                 else {  
  1329.                     j++;
  1330.                     if (DELIMITER) CurrentByteOffset -= D_length;
  1331.                     else CurrentByteOffset -= 1;
  1332.                     r1 = Init1 & r2;            /* match against endofline */
  1333.                     r3 = Next[r2] & CMask | r1;
  1334.                     if(TAIL) r3 = Next[r3] | r3;
  1335.                     if(( r3 & 1) ^ INVERSE) {
  1336.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  1337.                             num_of_matched++;
  1338.  
  1339.                             if (agrep_finalfp != NULL) 
  1340.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  1341.                             else {
  1342.                                 int outindex;
  1343.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  1344.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  1345.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  1346.                                 }
  1347.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  1348.                                     OUTPUT_OVERFLOW;
  1349.                                     free_buf(Text, buffer);
  1350.                                     return -1;
  1351.                                 }
  1352.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  1353.                                 agrep_outpointer += outindex;
  1354.                             }
  1355.  
  1356.                             free_buf(Text, buffer);
  1357.                             NEW_FILE = OFF;
  1358.                             return 0;
  1359.                         } 
  1360.                         if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
  1361.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  1362.                             free_buf(Text, buffer);
  1363.                             return 0;    /* done */
  1364.                         }
  1365.                     }
  1366.                     lasti = i - 1;
  1367.                     r2 = Init0; 
  1368.                     r3 = (Next[r2] & CMask) | Init0;  /* match the newline */
  1369.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  1370.                     else CurrentByteOffset += 1*1;
  1371.                 }
  1372.             } /* while */
  1373.  
  1374.         /* If a residue is left for within-memory-buffer, since nothing can be "read" after that, we can ignore it: as if only 1 iteration of while */
  1375.         return 0;
  1376.         }
  1377. #endif    /*AGREP_POINTER*/
  1378.     } /* end if(D==0) */
  1379.  
  1380. #if    AGREP_POINTER
  1381.     if (Text != -1) {
  1382. #endif    /*AGREP_POINTER*/
  1383.         while ((num_read = fill_buf(Text, buffer + Maxline, BlockSize)) > 0)
  1384.         {
  1385.             i=Maxline; 
  1386.             end = Maxline+num_read;
  1387.             if((num_read < BlockSize) && buffer[end-1] != '\n') buffer[end] = '\n';
  1388.             if(FIRST_TIME) {
  1389.                 buffer[i-1] = '\n';
  1390.                 i--;
  1391.                 CurrentByteOffset --;
  1392.                 FIRST_TIME = 0;
  1393.             }
  1394.  
  1395.             /* RE_PROCESS_WHEN_DNOTZERO: the while-loop below */
  1396.             while (i < end)
  1397.             {   
  1398.                 c = buffer[i++];
  1399.                 CurrentByteOffset ++;
  1400.                 CMask = RMask[c];
  1401.                 if (c != Newline)
  1402.                 {  
  1403.                     r_even = B[0];
  1404.                     r1 = Init1 & r_even;
  1405.                     A[0] = (Next[r_even] & CMask) | r1;
  1406.                     r_odd = B[1];
  1407.                     r1 = Init1 & r_odd;
  1408.                     r2 = (r_even | Next[r_even|A[0]]) &r_NO_ERR;
  1409.                     A[1] = (Next[r_odd] & CMask) | r2 | r1 ;  
  1410.                     if(D == 1) goto Nextcharfile;
  1411.                     r_even = B[2];
  1412.                     r1 = Init1 & r_even;
  1413.                     r2 = (r_odd | Next[r_odd|A[1]]) &r_NO_ERR;
  1414.                     A[2] = (Next[r_even] & CMask) | r2 | r1 ;  
  1415.                     if(D == 2) goto Nextcharfile;
  1416.                     r_odd = B[3];
  1417.                     r1 = Init1 & r_odd;
  1418.                     r2 = (r_even | Next[r_even|A[2]]) &r_NO_ERR;
  1419.                     A[3] = (Next[r_odd] & CMask) | r2 | r1 ;  
  1420.                     if(D == 3) goto Nextcharfile;
  1421.                     r_even = B[4];
  1422.                     r1 = Init1 & r_even;
  1423.                     r2 = (r_odd | Next[r_odd|A[3]]) &r_NO_ERR;
  1424.                     A[4] = (Next[r_even] & CMask) | r2 | r1 ;  
  1425.                     goto Nextcharfile;
  1426.                 } /* if NOT Newline */
  1427.                 else {  
  1428.                     j++;
  1429.                     if (DELIMITER) CurrentByteOffset -= D_length;
  1430.                     else CurrentByteOffset -= 1;
  1431.                     r1 = Init1 & B[D];               /* match endofline */
  1432.                     A[D] = (Next[B[D]] & CMask) | r1;
  1433.                     if(TAIL) A[D] = Next[A[D]] | A[D];
  1434.                     if((A[D] & 1) ^ INVERSE )  {
  1435.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  1436.                             num_of_matched++;    
  1437.  
  1438.                             if (agrep_finalfp != NULL) 
  1439.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  1440.                             else {
  1441.                                 int outindex;
  1442.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  1443.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  1444.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  1445.                                 }
  1446.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  1447.                                     OUTPUT_OVERFLOW;
  1448.                                     free_buf(Text, buffer);
  1449.                                     return -1;
  1450.                                 }
  1451.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  1452.                                 agrep_outpointer += outindex;
  1453.                             }
  1454.  
  1455.                             free_buf(Text, buffer);
  1456.                             NEW_FILE = OFF;
  1457.                             return 0;
  1458.                         }  
  1459.                         if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
  1460.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  1461.                             free_buf(Text, buffer);
  1462.                             return 0;    /* done */
  1463.                         }
  1464.                     }
  1465.                     for(k=0; k<= D; k++) { 
  1466.                         A[k] = B[k] = Init[k]; 
  1467.                     }
  1468.                     r1 = Init1 & B[0]; 
  1469.                     A[0] = (Next[B[0]] & CMask) | r1;
  1470.                     for(k=1; k<= D; k++) {
  1471.                         r1 = Init1 & B[k];
  1472.                         r2 = (B[k-1] | Next[A[k-1]|B[k-1]]) &r_NO_ERR;
  1473.                         A[k] = (Next[B[k]] & CMask) | r1 | r2;
  1474.                     }
  1475.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  1476.                     else CurrentByteOffset += 1*1;
  1477.                 }
  1478.     Nextcharfile: 
  1479.                 c = buffer[i];
  1480.                 CMask = RMask[c];
  1481.                 if(c != Newline)
  1482.                 { 
  1483.                     r1 = Init1 & A[0];
  1484.                     B[0] = (Next[A[0]] & CMask) | r1;
  1485.                     r1 = Init1 & A[1];
  1486.                     B[1] = (Next[A[1]] & CMask) | ((A[0] | Next[A[0] | B[0]]) & r_NO_ERR) | r1 ;  
  1487.                     if(D == 1) goto Nextchar1file;
  1488.                     r1 = Init1 & A[2];
  1489.                     B[2] = (Next[A[2]] & CMask) | ((A[1] | Next[A[1] | B[1]]) &r_NO_ERR) | r1 ;  
  1490.                     if(D == 2) goto Nextchar1file;
  1491.                     r1 = Init1 & A[3];
  1492.                     B[3] = (Next[A[3]] & CMask) | ((A[2] | Next[A[2] | B[2]])&r_NO_ERR) | r1 ;  
  1493.                     if(D == 3) goto Nextchar1file;
  1494.                     r1 = Init1 & A[4];
  1495.                     B[4] = (Next[A[4]] & CMask) | ((A[3] | Next[A[3] | B[3]])&r_NO_ERR) | r1 ;  
  1496.                     goto Nextchar1file;
  1497.                 } /* if(NOT Newline) */
  1498.                 else {  
  1499.                     j++;
  1500.                     if (DELIMITER) CurrentByteOffset -= D_length;
  1501.                     else CurrentByteOffset -= 1;
  1502.                     r1 = Init1 & A[D];               /* match endofline */
  1503.                     B[D] = (Next[A[D]] & CMask) | r1;
  1504.                     if(TAIL) B[D] = Next[B[D]] | B[D];
  1505.                     if((B[D] & 1) ^ INVERSE )  {
  1506.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  1507.                             num_of_matched++;
  1508.  
  1509.                             if (agrep_finalfp != NULL) 
  1510.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  1511.                             else {
  1512.                                 int outindex;
  1513.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  1514.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  1515.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  1516.                                 }
  1517.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  1518.                                     OUTPUT_OVERFLOW;
  1519.                                     free_buf(Text, buffer);
  1520.                                     return -1;
  1521.                                 }
  1522.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  1523.                                 agrep_outpointer += outindex;
  1524.                             }
  1525.  
  1526.                             free_buf(Text, buffer);
  1527.                             NEW_FILE = OFF;
  1528.                             return 0;
  1529.                         } 
  1530.                         if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
  1531.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  1532.                             free_buf(Text, buffer);
  1533.                             return 0;    /* done */
  1534.                         }
  1535.                     }
  1536.                     for(k=0; k<= D; k++) { 
  1537.                         A[k] = B[k] = Init[k]; 
  1538.                     }
  1539.                     r1 = Init1 & A[0]; 
  1540.                     B[0] = (Next[A[0]] & CMask) | r1;
  1541.                     for(k=1; k<= D; k++) {
  1542.                         r1 = Init1 & A[k];
  1543.                         r2 = (A[k-1] | Next[A[k-1]|B[k-1]])&r_NO_ERR;
  1544.                         B[k] = (Next[A[k]] & CMask) | r1 | r2;
  1545.                     }
  1546.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  1547.                     else CurrentByteOffset += 1*1;
  1548.                 }
  1549.     Nextchar1file: 
  1550.                 i++;
  1551.                 CurrentByteOffset ++;
  1552.             } /* while i < end */
  1553.  
  1554.             strncpy(buffer, buffer+num_read, Maxline);
  1555.         } /* while  fill_buf() */
  1556.         free_buf(Text, buffer);
  1557.         return 0;
  1558. #if    AGREP_POINTER
  1559.     }
  1560.     else {
  1561.         num_read = agrep_inlen;
  1562.         buffer = (CHAR *)agrep_inbuffer;
  1563.         end = num_read;
  1564.         /* buffer[end-1] = '\n';*/ /* at end of the text. */
  1565.         /* buffer[0] = '\n';*/  /* in front of the  text. */
  1566.         i = 0;
  1567.  
  1568.             /* An exact copy of the above RE_PROCESS_WHEN_DNOTZERO: the while-loop below */
  1569.             while (i < end)
  1570.             {   
  1571.                 c = buffer[i++];
  1572.                 CurrentByteOffset ++;
  1573.                 CMask = RMask[c];
  1574.                 if (c != Newline)
  1575.                 {  
  1576.                     r_even = B[0];
  1577.                     r1 = Init1 & r_even;
  1578.                     A[0] = (Next[r_even] & CMask) | r1;
  1579.                     r_odd = B[1];
  1580.                     r1 = Init1 & r_odd;
  1581.                     r2 = (r_even | Next[r_even|A[0]]) &r_NO_ERR;
  1582.                     A[1] = (Next[r_odd] & CMask) | r2 | r1 ;  
  1583.                     if(D == 1) goto Nextcharmem;
  1584.                     r_even = B[2];
  1585.                     r1 = Init1 & r_even;
  1586.                     r2 = (r_odd | Next[r_odd|A[1]]) &r_NO_ERR;
  1587.                     A[2] = (Next[r_even] & CMask) | r2 | r1 ;  
  1588.                     if(D == 2) goto Nextcharmem;
  1589.                     r_odd = B[3];
  1590.                     r1 = Init1 & r_odd;
  1591.                     r2 = (r_even | Next[r_even|A[2]]) &r_NO_ERR;
  1592.                     A[3] = (Next[r_odd] & CMask) | r2 | r1 ;  
  1593.                     if(D == 3) goto Nextcharmem;
  1594.                     r_even = B[4];
  1595.                     r1 = Init1 & r_even;
  1596.                     r2 = (r_odd | Next[r_odd|A[3]]) &r_NO_ERR;
  1597.                     A[4] = (Next[r_even] & CMask) | r2 | r1 ;  
  1598.                     goto Nextcharmem;
  1599.                 } /* if NOT Newline */
  1600.                 else {  
  1601.                     j++;
  1602.                     if (DELIMITER) CurrentByteOffset -= D_length;
  1603.                     else CurrentByteOffset -= 1;
  1604.                     r1 = Init1 & B[D];               /* match endofline */
  1605.                     A[D] = (Next[B[D]] & CMask) | r1;
  1606.                     if(TAIL) A[D] = Next[A[D]] | A[D];
  1607.                     if((A[D] & 1) ^ INVERSE )  {
  1608.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  1609.                             num_of_matched++;    
  1610.  
  1611.                             if (agrep_finalfp != NULL) 
  1612.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  1613.                             else {
  1614.                                 int outindex;
  1615.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  1616.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  1617.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  1618.                                 }
  1619.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  1620.                                     OUTPUT_OVERFLOW;
  1621.                                     free_buf(Text, buffer);
  1622.                                     return -1;
  1623.                                 }
  1624.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  1625.                                 agrep_outpointer += outindex;
  1626.                             }
  1627.  
  1628.                             free_buf(Text, buffer);
  1629.                             NEW_FILE = OFF;
  1630.                             return 0;
  1631.                         }  
  1632.                         if (-1 == r_output(buffer, i-1, end, j)) {free_buf(Text, buffer); return -1;}
  1633.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  1634.                             free_buf(Text, buffer);
  1635.                             return 0;    /* done */
  1636.                         }
  1637.                     }
  1638.                     for(k=0; k<= D; k++) { 
  1639.                         A[k] = B[k] = Init[k]; 
  1640.                     }
  1641.                     r1 = Init1 & B[0]; 
  1642.                     A[0] = (Next[B[0]] & CMask) | r1;
  1643.                     for(k=1; k<= D; k++) {
  1644.                         r1 = Init1 & B[k];
  1645.                         r2 = (B[k-1] | Next[A[k-1]|B[k-1]]) &r_NO_ERR;
  1646.                         A[k] = (Next[B[k]] & CMask) | r1 | r2;
  1647.                     }
  1648.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  1649.                     else CurrentByteOffset += 1*1;
  1650.                 }
  1651.     Nextcharmem: 
  1652.                 c = buffer[i];
  1653.                 CMask = RMask[c];
  1654.                 if(c != Newline)
  1655.                 { 
  1656.                     r1 = Init1 & A[0];
  1657.                     B[0] = (Next[A[0]] & CMask) | r1;
  1658.                     r1 = Init1 & A[1];
  1659.                     B[1] = (Next[A[1]] & CMask) | ((A[0] | Next[A[0] | B[0]]) & r_NO_ERR) | r1 ;  
  1660.                     if(D == 1) goto Nextchar1mem;
  1661.                     r1 = Init1 & A[2];
  1662.                     B[2] = (Next[A[2]] & CMask) | ((A[1] | Next[A[1] | B[1]]) &r_NO_ERR) | r1 ;  
  1663.                     if(D == 2) goto Nextchar1mem;
  1664.                     r1 = Init1 & A[3];
  1665.                     B[3] = (Next[A[3]] & CMask) | ((A[2] | Next[A[2] | B[2]])&r_NO_ERR) | r1 ;  
  1666.                     if(D == 3) goto Nextchar1mem;
  1667.                     r1 = Init1 & A[4];
  1668.                     B[4] = (Next[A[4]] & CMask) | ((A[3] | Next[A[3] | B[3]])&r_NO_ERR) | r1 ;  
  1669.                     goto Nextchar1mem;
  1670.                 } /* if(NOT Newline) */
  1671.                 else {  
  1672.                     j++;
  1673.                     if (DELIMITER) CurrentByteOffset -= D_length;
  1674.                     else CurrentByteOffset -= 1;
  1675.                     r1 = Init1 & A[D];               /* match endofline */
  1676.                     B[D] = (Next[A[D]] & CMask) | r1;
  1677.                     if(TAIL) B[D] = Next[B[D]] | B[D];
  1678.                     if((B[D] & 1) ^ INVERSE )  {
  1679.                         if(FILENAMEONLY && (NEW_FILE || !POST_FILTER)) {
  1680.                             num_of_matched++;
  1681.  
  1682.                             if (agrep_finalfp != NULL) 
  1683.                                 fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  1684.                             else {
  1685.                                 int outindex;
  1686.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) && 
  1687.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  1688.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  1689.                                 }
  1690.                                 if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+1>=agrep_outlen)) {
  1691.                                     OUTPUT_OVERFLOW;
  1692.                                     free_buf(Text, buffer);
  1693.                                     return -1;
  1694.                                 }
  1695.                                 else agrep_outbuffer[agrep_outpointer+outindex++] = '\n';
  1696.                                 agrep_outpointer += outindex;
  1697.                             }
  1698.  
  1699.                             free_buf(Text, buffer);
  1700.                             NEW_FILE = OFF;
  1701.                             return 0;
  1702.                         } 
  1703.                         if (-1 == r_output(buffer, i, end, j)) {free_buf(Text, buffer); return -1;}
  1704.                         if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  1705.                             free_buf(Text, buffer);
  1706.                             return 0;    /* done */
  1707.                         }
  1708.                     }
  1709.                     for(k=0; k<= D; k++) { 
  1710.                         A[k] = B[k] = Init[k]; 
  1711.                     }
  1712.                     r1 = Init1 & A[0]; 
  1713.                     B[0] = (Next[A[0]] & CMask) | r1;
  1714.                     for(k=1; k<= D; k++) {
  1715.                         r1 = Init1 & A[k];
  1716.                         r2 = (A[k-1] | Next[A[k-1]|B[k-1]])&r_NO_ERR;
  1717.                         B[k] = (Next[A[k]] & CMask) | r1 | r2;
  1718.                     }
  1719.                     if (DELIMITER) CurrentByteOffset += 1*D_length;
  1720.                     else CurrentByteOffset += 1*1;
  1721.                 }
  1722.     Nextchar1mem: 
  1723.                 i++;
  1724.                 CurrentByteOffset ++;
  1725.             } /* while i < end */
  1726.  
  1727.         return 0;
  1728.     }
  1729. #endif    /*AGREP_POINTER*/
  1730. } /* re */
  1731.  
  1732.  
  1733. r_output (buffer, i, end, j) 
  1734. int i, end, j; 
  1735. CHAR *buffer;
  1736. {
  1737.     int bp;
  1738.     if(i >= end) return 0;
  1739.     num_of_matched++;
  1740.     if(COUNT)  return; 
  1741.     if(FNAME && (NEW_FILE || !POST_FILTER)) {
  1742.         char    nextchar = (POST_FILTER == ON)?'\n':' ';
  1743.         char    *prevstring = (POST_FILTER == ON)?"\n":"";
  1744.         if (agrep_finalfp != NULL)
  1745.             fprintf(agrep_finalfp, "%s%s:%c", prevstring, CurrentFileName, nextchar);
  1746.         else {
  1747.             int outindex;
  1748.             if (prevstring[0] != '\0') {
  1749.                 if(agrep_outpointer + 1 >= agrep_outlen) {
  1750.                     OUTPUT_OVERFLOW;
  1751.                     return -1;
  1752.                 }
  1753.                 else agrep_outbuffer[agrep_outpointer ++] = prevstring[0];
  1754.             }
  1755.             for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  1756.                     (CurrentFileName[outindex] != '\0'); outindex++) {
  1757.                 agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  1758.             }
  1759.             if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+2>=agrep_outlen)) {
  1760.                 OUTPUT_OVERFLOW;
  1761.                 return -1;
  1762.             }
  1763.             else {
  1764.                 agrep_outbuffer[agrep_outpointer+outindex++] = ':';
  1765.                 agrep_outbuffer[agrep_outpointer+outindex++] = nextchar;
  1766.             }
  1767.             agrep_outpointer += outindex;
  1768.         }
  1769.         NEW_FILE = OFF;
  1770.     }
  1771.     bp = i-1;
  1772.     while ((buffer[bp] != '\n') && (bp > 0)) bp--;
  1773.     if(LINENUM) {
  1774.         if (agrep_finalfp != NULL)
  1775.             fprintf(agrep_finalfp, "%d: ", j); 
  1776.         else {
  1777.             char s[32];
  1778.             int  outindex;
  1779.  
  1780.             sprintf(s, "%d: ", j);
  1781.             for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  1782.                     (s[outindex] != '\0'); outindex++) {
  1783.                 agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
  1784.             }
  1785.             if (s[outindex] != '\0') {
  1786.                 OUTPUT_OVERFLOW;
  1787.                 return -1;
  1788.             }
  1789.             agrep_outpointer += outindex;
  1790.         }
  1791.     }
  1792.  
  1793.     if(BYTECOUNT) {
  1794.         if (agrep_finalfp != NULL)
  1795.             fprintf(agrep_finalfp, "%d= ", CurrentByteOffset);
  1796.         else {
  1797.             char s[32];
  1798.             int  outindex;
  1799.             sprintf(s, "%d= ", CurrentByteOffset);
  1800.             for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  1801.                     (s[outindex] != '\0'); outindex++) {
  1802.                 agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
  1803.             }
  1804.             if (s[outindex] != '\0') {
  1805.                 OUTPUT_OVERFLOW;
  1806.                 return -1;
  1807.             }
  1808.             agrep_outpointer += outindex;
  1809.         }
  1810.     }
  1811.  
  1812.     if(buffer[bp] != '\n') bp = Maxline-1;
  1813.     bp++;
  1814.  
  1815.     if (agrep_finalfp != NULL)
  1816.         while(bp <= i) fputc(buffer[bp++], agrep_finalfp);
  1817.     else {
  1818.         if (i - bp + 1 + agrep_outpointer >= agrep_outlen) {
  1819.             OUTPUT_OVERFLOW;
  1820.             return -1;
  1821.         }
  1822.         while(bp <= i) agrep_outbuffer[agrep_outpointer ++] = buffer[bp++];
  1823.     }
  1824.  
  1825.     return 0;
  1826. }
  1827.  
  1828. /*
  1829.  * Processes the options specified in argc and argv, and fetches the pattern.
  1830.  * Also sets the set of filenames to be searched for internally. Returns: -1
  1831.  * if there is a serious error, 0 if there is no pattern or an error in getting
  1832.  * the file names, the length (> 0) of the pattern if there is no error. When a
  1833.  * 0 is returned, it means that at least the options were processed correctly.
  1834.  */
  1835. int
  1836. agrep_init(argc, argv, initialfd, pattern_len, pattern_buffer)
  1837.     int    argc;
  1838.     char    *argv[];
  1839.     int    initialfd;
  1840.     int    pattern_len;
  1841.     CHAR    *pattern_buffer;
  1842. {
  1843.     int i, j, seenlsq = 0;
  1844.     char c, *p;
  1845.     int filetype;
  1846.     char **original_argv = argv;
  1847.     char *home;
  1848.     int quitwhile;
  1849.     int NOOUTTAIL=OFF;
  1850.  
  1851.     initial_value();
  1852.  
  1853.     if (pattern_len < 1) {
  1854.         fprintf(stderr, "agrep_init: pattern length %d too small\n", pattern_len);
  1855.         errno = 3;
  1856.         return -1;
  1857.     }
  1858.     agrep_initialfd = initialfd;
  1859.     strncpy(Progname, argv[0], MAXNAME);
  1860.     if (argc < 2) return agrep_usage();
  1861.  
  1862.     Pattern[0] = '\0';
  1863.  
  1864.     while(--argc > 0 && (*++argv)[0] == '-') { /* argv is incremented automatically here */
  1865.         p = argv[0]+1;                 /* ptr to first character after '-' */
  1866.         c = *(argv[0]+1); 
  1867.         quitwhile = OFF;
  1868.         while(!quitwhile && (*p != '\0')) {
  1869.             c = *p;
  1870.             switch(c) {
  1871.             case 'z' :
  1872.                 NOOUTPUTZERO = ON;    /* don't output files with 0 matches */
  1873.                 PRINT(printf("z\n");
  1874.                 )
  1875.                     break;
  1876.  
  1877.             case 'c' : 
  1878.                 COUNT = ON;    /* output the # of matches */
  1879.                 PRINT(printf("c\n");
  1880.                 )
  1881.                     break;
  1882.  
  1883.             case 's' : 
  1884.                 SILENT = ON;   /* silent mode  */
  1885.                 PRINT(printf("s\n");
  1886.                 )
  1887.                     break;
  1888.  
  1889.             case 'p' : 
  1890.                 I = 0;         /* insertion cost is 0 */
  1891.                 PRINT(printf("p\n");
  1892.                 )
  1893.                     break; 
  1894.             case 'P' :
  1895.                 PRINTPATTERN = 1;    /* print pattern before every matched line */
  1896.                 PRINT(printf("p\n");
  1897.                 )
  1898.                     break;
  1899.  
  1900.             case 'x' : 
  1901.                 WHOLELINE = ON;  /* match the whole line */
  1902.                 PRINT(printf("x\n");
  1903.                 )
  1904.                     if(WORDBOUND) {
  1905.                         fprintf(stderr, "%s: illegal option combination (-x and -w)\n", Progname);
  1906.                         if (!EXITONERROR) {
  1907.                             errno = 2;
  1908.                             return -1;
  1909.                         }
  1910.                         else exit(2);
  1911.                     }
  1912.                 break;
  1913.  
  1914.             case 'b' : 
  1915.                 BYTECOUNT = ON;
  1916.                 PRINT(printf("b\n");
  1917.                 )
  1918.                 break;
  1919.  
  1920.             case 'L' :
  1921.                 if ( *(p + 1) == '\0') {/* space after -L option */
  1922.                     if(argc <= 1) {
  1923.                         fprintf(stderr, "%s: the -L option must have an output-limit argument\n", Progname);
  1924.                         if (!EXITONERROR) {
  1925.                             errno = 2;
  1926.                             return -1;
  1927.                         }
  1928.                         else exit(2);
  1929.                     }
  1930.                     argv++;
  1931.                     if ((LIMITOUTPUT = atoi(argv[0])) < 0) {
  1932.                         fprintf(stderr, "%s: invalid output limit %s\n", Progname, argv[0]);
  1933.                         if (!EXITONERROR) {
  1934.                             errno = 2;
  1935.                             return -1;
  1936.                         }
  1937.                         else exit(2);
  1938.                     }
  1939.                     argc--;
  1940.                 } 
  1941.                 else {
  1942.                     if ((LIMITOUTPUT = atoi(p + 1)) < 0) {
  1943.                         fprintf(stderr, "%s: invalid output limit %s\n", Progname, p+1);
  1944.                         if (!EXITONERROR) {
  1945.                             errno = 2;
  1946.                             return -1;
  1947.                         }
  1948.                         else exit(2);
  1949.                     }
  1950.                 } /* else */
  1951.                 PRINT(printf("L\n");
  1952.                 )
  1953.                 quitwhile = ON;
  1954.                 break;
  1955.  
  1956.             case 'd' : 
  1957.                 DELIMITER = ON;  /* user defines delimiter */
  1958.                 PRINT(printf("d\n");
  1959.                 )
  1960.                 if ( *(p + 1) == '\0') {/* space after -d option */
  1961.                     if(argc <= 1) {
  1962.                         fprintf(stderr, "%s: the -d option must have a delimiter argument\n", Progname);
  1963.                         if (!EXITONERROR) {
  1964.                             errno = 2;
  1965.                             return -1;
  1966.                         }
  1967.                         else exit(2);
  1968.                     }
  1969.                     argv++;
  1970.                     if ((D_length = strlen(argv[0])) > MaxDelimit) {
  1971.                         fprintf(stderr, "%s: delimiter pattern too long (has > %d chars)\n", Progname, MaxDelimit);
  1972.                         if (!EXITONERROR) {
  1973.                             errno = 2;
  1974.                             return -1;
  1975.                         }
  1976.                         else exit(2);
  1977.                     }
  1978.                     D_pattern[0] = '<';
  1979.                     strcpy(D_pattern+1, argv[0]);
  1980.                     if ((argv[0][D_length-1] == '\n') || (argv[0][D_length-1] == '$') || (argv[0][D_length-1] == '^'))
  1981.                         OUTTAIL = ON;
  1982.                     argc--;
  1983.                     PRINT(printf("space\n");
  1984.                     )
  1985.                 } 
  1986.                 else {
  1987.                     if ((D_length = strlen(p + 1)) > MaxDelimit) {
  1988.                         fprintf(stderr, "%s: delimiter pattern too long (has > %d chars)\n", Progname, MaxDelimit);
  1989.                         if (!EXITONERROR) {
  1990.                             errno = 2;
  1991.                             return -1;
  1992.                         }
  1993.                         else exit(2);
  1994.                     }
  1995.                     D_pattern[0] = '<';
  1996.                     strcpy(D_pattern+1, p + 1);
  1997.                     if (((p+1)[D_length-1] == '\n') || ((p+1)[D_length-1] == '$') || ((p+1)[D_length-1] == '^'))
  1998.                         OUTTAIL = ON;
  1999.                 } /* else */
  2000.                 strcat(D_pattern, ">; ");
  2001.                 D_length++;   /* to count '<' as one */
  2002.                 PRINT(printf("D_pattern=%s\n", D_pattern);
  2003.                 )
  2004.                 strcpy(original_D_pattern, D_pattern);
  2005.                 original_D_length = D_length;
  2006.                 quitwhile = ON;
  2007.                 break;
  2008.  
  2009.             case 'H':
  2010.                 if (*(p + 1) == '\0') {/* space after - option */
  2011.                     if (argc <= 1) {
  2012.                         fprintf(stderr, "%s: a directory name must follow the -H option\n", Progname);
  2013.                         if (!EXITONERROR) {
  2014.                             errno = 2;
  2015.                             return agrep_usage();
  2016.                         }
  2017.                         else exit(2);
  2018.                     }
  2019.                     argv ++;
  2020.                     strcpy(COMP_DIR, argv[0]);
  2021.                     argc --;
  2022.                 }
  2023.                 else {
  2024.                     strcpy(COMP_DIR, p+1);
  2025.                 }
  2026.                 quitwhile = ON;
  2027.                 break;
  2028.  
  2029.             case 'e' : 
  2030.                 if ( *(p + 1) == '\0') {/* space after -e option */
  2031.                     if(argc <= 1) {
  2032.                         fprintf(stderr, "%s: the -e option must have a pattern argument\n", Progname);
  2033.                         if (!EXITONERROR) {
  2034.                             errno = 2;
  2035.                             return -1;
  2036.                         }
  2037.                         else exit(2);
  2038.                     }
  2039.                     argv++;
  2040.                     if(argv[0][0] == '-') {    /* not strictly necessary but no harm done */
  2041.                         Pattern[0] = '\\';
  2042.                         strcat(Pattern, (argv)[0]);
  2043.                     }
  2044.                     else strcat(Pattern, argv[0]);
  2045.                     argc--;
  2046.                 }
  2047.                 else {
  2048.                     if (*(p+1) == '-') {    /* not strictly necessary but no harm done */
  2049.                         Pattern[0] = '\\';
  2050.                         strcat(Pattern, p+1);
  2051.                     }
  2052.                     else strcat (Pattern, p+1);
  2053.                 } /* else */
  2054.  
  2055.                 PRINT(printf("Pattern=%s\n", Pattern);
  2056.                 )
  2057.                 pattern_index = abs(argv - original_argv);
  2058.                 quitwhile = ON;
  2059.                 break;
  2060.  
  2061.             case 'k' : 
  2062.                 CONSTANT = ON;
  2063.                 if ( *(p + 1) == '\0') {/* space after -e option */
  2064.                     if(argc <= 1) {
  2065.                         fprintf(stderr, "%s: the -k option must have a pattern argument\n", Progname);
  2066.                         if (!EXITONERROR) {
  2067.                             errno = 2;
  2068.                             return -1;
  2069.                         }
  2070.                         else exit(2);
  2071.                     }
  2072.                     argv++;
  2073.                     strcat(Pattern, argv[0]);
  2074.                     if((argc > 2) && (argv[1][0] == '-')) {
  2075.                         fprintf(stderr, "%s: -k should be the last option in the command\n", Progname);
  2076.                         if (!EXITONERROR) {
  2077.                             errno = 2;
  2078.                             return -1;
  2079.                         }
  2080.                         else exit(2);
  2081.                     }
  2082.                     argc--;
  2083.                 }
  2084.                 else {
  2085.                     if((argc > 1) && (argv[1][0] == '-')) {
  2086.                         fprintf(stderr, "%s: -k should be the last option in the command\n", Progname);
  2087.                         if (!EXITONERROR) {
  2088.                             errno = 2;
  2089.                             return -1;
  2090.                         }
  2091.                         else exit(2);
  2092.                     }
  2093.                     strcat (Pattern, p+1);
  2094.                 } /* else */
  2095.  
  2096.                 pattern_index = abs(argv - original_argv);
  2097.                 quitwhile = ON;
  2098.                 break;
  2099.  
  2100.             case 'f' : 
  2101.                 if (PAT_FILE == ON) {
  2102.                     fprintf(stderr, "%s: multiple -f options\n", Progname);
  2103.                     if (multifd >= 0) close(multifd);
  2104.                     if (!EXITONERROR) {
  2105.                         errno = 2;
  2106.                         return -1;
  2107.                     }
  2108.                     else exit(2);
  2109.                 }
  2110.                 if (PAT_BUFFER == ON) {
  2111.                     fprintf(stderr, "%s: -f and -m are incompatible\n", Progname);
  2112.                     if (multibuf != NULL) free(multibuf);
  2113.                     multibuf = NULL;
  2114.                     multilen = 0;
  2115.                     if (!EXITONERROR) {
  2116.                         errno = 2;
  2117.                         return -1;
  2118.                     }
  2119.                     else exit(2);
  2120.                 }
  2121.                 PAT_FILE = ON;
  2122.                 PRINT(printf("f\n");
  2123.                 )
  2124.                 argv++;
  2125.                 argc--;
  2126.  
  2127.                 if (argv[0] == NULL) {
  2128.                     /* A -f option with a NULL file name is a NO-OP: stupid, but simplifies glimpse :-) */
  2129.                     PAT_FILE = OFF;
  2130.                     quitwhile = ON;
  2131.                     break;
  2132.                 }
  2133.  
  2134.                 if((multifd = open(argv[0], O_RDONLY)) < 0) {
  2135.                     PAT_FILE = OFF;
  2136.                     fprintf(stderr, "%s: can't open pattern file for reading: %s\n", Progname, argv[0]);
  2137.                     if (!EXITONERROR) {
  2138.                         errno = 2;
  2139.                         return -1;
  2140.                     }
  2141.                     else exit(2);
  2142.                 }
  2143.                 PRINT(printf("file=%s\n", argv[0]);
  2144.                 )
  2145.                 strcpy(PAT_FILE_NAME, argv[0]);
  2146.                 if (prepf(multifd, NULL, 0) <= -1) {
  2147.                     close(multifd);
  2148.                     PAT_FILE = OFF;
  2149.                     fprintf(stderr, "%s: error in processing pattern file: %s\n", Progname, argv[0]);
  2150.                     if (!EXITONERROR) {
  2151.                         errno = 2;
  2152.                         return -1;
  2153.                     }
  2154.                     else exit(2);
  2155.                 }
  2156.                 quitwhile = ON;
  2157.                 break;
  2158.  
  2159.             case 'm' :
  2160.                 if (PAT_BUFFER == ON) {
  2161.                     fprintf(stderr, "%s: multiple -m options\n", Progname);
  2162.                     if (multibuf != NULL) free(multibuf);
  2163.                     multilen = 0;
  2164.                     if (!EXITONERROR) {
  2165.                         errno = 2;
  2166.                         return -1;
  2167.                     }
  2168.                     else exit(2);
  2169.                 }
  2170.                 if (PAT_FILE == ON) {
  2171.                     fprintf(stderr, "%s: -f and -m are incompatible\n", Progname);
  2172.                     if (multifd >= 0) close(multifd);
  2173.                     if (!EXITONERROR) {
  2174.                         errno = 2;
  2175.                         return -1;
  2176.                     }
  2177.                     else exit(2);
  2178.                 }
  2179.                 PAT_BUFFER = ON;
  2180.                 PRINT(printf("m\n");
  2181.                 )
  2182.                 argv ++;
  2183.                 argc --;
  2184.  
  2185.  
  2186.                 if ((argv[0] == NULL) || ((multilen = strlen(argv[0])) <= 0)) {
  2187.                     /* A -m option with a NULL or empty pattern buffer is a NO-OP: stupid, but simplifies glimpse :-) */
  2188.                     PAT_BUFFER = OFF;
  2189.                     multilen = 0;
  2190.                     multibuf = NULL;
  2191.                 }
  2192.                 else {
  2193.                     multibuf = (char *)malloc(multilen + 2);
  2194.                     strcpy(multibuf, argv[0]);
  2195.                     PRINT(printf("patterns=%s\n", multibuf);
  2196.                     )
  2197.                     if (prepf(-1, multibuf, multilen) <= -1) {
  2198.                         free(multibuf);
  2199.                         multilen = 0;
  2200.                         PAT_BUFFER = OFF;
  2201.                         fprintf(stderr, "%s: error in processing pattern buffer\n", Progname);
  2202.                         if (!EXITONERROR) {
  2203.                             errno = 2;
  2204.                             return -1;
  2205.                         }
  2206.                         else exit(2);
  2207.                     }
  2208.                 }
  2209.                 quitwhile = ON;
  2210.                 break;
  2211.  
  2212.             case 'h' : 
  2213.                 NOFILENAME = ON;
  2214.                 PRINT(printf("h\n");
  2215.                 )
  2216.                     break;
  2217.  
  2218.             case 'i' : 
  2219.                 NOUPPER = ON;
  2220.                 PRINT(printf("i\n");
  2221.                 )
  2222.                     break;
  2223.  
  2224.             case 'l' : 
  2225.                 FILENAMEONLY = ON;
  2226.                 PRINT(printf("l\n");
  2227.                 )
  2228.                     break;
  2229.  
  2230.             case 'n' : 
  2231.                 LINENUM = ON;  /* output prefixed by line no*/
  2232.                 PRINT(printf("n\n");
  2233.                 )
  2234.                     break;
  2235.  
  2236.             case 'r' : 
  2237.                 RECURSIVE = ON;
  2238.                 PRINT(printf("r\n");
  2239.                 )
  2240.                     break;
  2241.             
  2242.             case 'V' :
  2243.                 printf("\nThis is agrep version %s, %s.\n\n", AGREP_VERSION, AGREP_DATE);
  2244.                 return 0;
  2245.  
  2246.             case 'v' : 
  2247.                 INVERSE = ON;  /* output no-matched lines */
  2248.                 PRINT(printf("v\n");
  2249.                 )
  2250.                     break;
  2251.  
  2252.             case 't' : 
  2253.                 OUTTAIL = ON;  /* output from tail of delimiter */
  2254.                 PRINT(printf("t\n");
  2255.                 )
  2256.                     break;
  2257.  
  2258.             case 'o' : 
  2259.                 NOOUTTAIL = ON;  /* output from front of delimiter */
  2260.                 PRINT(printf("t\n");
  2261.                 )
  2262.                     break;
  2263.  
  2264.             case 'B' : 
  2265.                 BESTMATCH = ON;
  2266.                 PRINT(printf("B\n");
  2267.                 )
  2268.                     break;
  2269.  
  2270.             case 'w' : 
  2271.                 WORDBOUND = ON;/* match to words */
  2272.                 PRINT(printf("w\n");
  2273.                 )
  2274.                     if(WHOLELINE) {
  2275.                         fprintf(stderr, "%s: illegal option combination (-w and -x)\n", Progname);
  2276.                         if (!EXITONERROR) {
  2277.                             errno = 2;
  2278.                             return -1;
  2279.                         }
  2280.                         else exit(2);
  2281.                     }
  2282.                 break;
  2283.  
  2284.             case 'y' : 
  2285.                 NOPROMPT = ON;
  2286.                 PRINT(printf("y\n");
  2287.                 )
  2288.                     break;
  2289.  
  2290.             case 'I' : 
  2291.                 I = atoi(p + 1);  /* Insertion Cost */
  2292.                 JUMP = ON;
  2293.                 quitwhile = ON;
  2294.                 break;
  2295.  
  2296.             case 'S' : 
  2297.                 S = atoi(p + 1);  /* Substitution Cost */
  2298.                 JUMP = ON;
  2299.                 quitwhile = ON;
  2300.                 break;
  2301.  
  2302.             case 'D' : 
  2303.                 DD = atoi(p + 1); /* Deletion Cost */
  2304.                 JUMP = ON;
  2305.                 quitwhile = ON;
  2306.                 break;
  2307.  
  2308.             case 'G' : 
  2309.                 FILEOUT = ON; 
  2310.                 COUNT = ON;
  2311.                 break;
  2312.  
  2313.             case 'A':
  2314.                 ALWAYSFILENAME = ON;
  2315.                 break;
  2316.  
  2317.             case 'O':
  2318.                 POST_FILTER = ON;
  2319.  
  2320.             case 'M':
  2321.                 MULTI_OUTPUT = ON;
  2322.  
  2323.             case 'Z': break;    /* no-op: used by glimpse */
  2324.             
  2325.             default  : 
  2326.                 if (isdigit(c)) {
  2327.                     APPROX = ON;
  2328.                     D = atoi(p);
  2329.                     if (D > MaxError) {
  2330.                         fprintf(stderr,"%s: the maximum number of errors is %d\n", Progname, MaxError);
  2331.                         if (!EXITONERROR) {
  2332.                             errno = 2;
  2333.                             return -1;
  2334.                         }
  2335.                         else exit(2);
  2336.                     }
  2337.                     quitwhile = ON;    /* note that even a number should occur at the end of a group of options, as f & e */
  2338.                 }
  2339.                 else {
  2340.                     fprintf(stderr, "%s: illegal option  -%c\n",Progname, c);
  2341.                     return agrep_usage();
  2342.                 }
  2343.  
  2344.             } /* switch(c) */
  2345.             p ++;
  2346.         }
  2347.     } /* while (--argc > 0 && (*++argv)[0] == '-') */
  2348.  
  2349.     if (NOOUTTAIL == ON) OUTTAIL = OFF;
  2350.  
  2351.     if (COMP_DIR[0] == '\0') {
  2352.         if ((home = (char *)getenv("HOME")) == NULL) {
  2353.             getcwd(COMP_DIR, MAX_LINE_LEN-1);
  2354.             fprintf(stderr, "using working-directory '%s' to locate dictionaries\n", COMP_DIR);
  2355.         }
  2356.         else strncpy(COMP_DIR, home, MAX_LINE_LEN);
  2357.     }
  2358.  
  2359.     strcpy(FREQ_FILE, COMP_DIR);
  2360.     strcat(FREQ_FILE, "/");
  2361.     strcat(FREQ_FILE, DEF_FREQ_FILE);
  2362.     strcpy(HASH_FILE, COMP_DIR);
  2363.     strcat(HASH_FILE, "/");
  2364.     strcat(HASH_FILE, DEF_HASH_FILE);
  2365.     strcpy(STRING_FILE, COMP_DIR);
  2366.     strcat(STRING_FILE, "/");
  2367.     strcat(STRING_FILE, DEF_STRING_FILE);
  2368.     initialize_common(FREQ_FILE, 0);    /* no error msgs */
  2369.  
  2370.     if (FILENAMEONLY && NOFILENAME) {
  2371.         fprintf(stderr, "%s: -h and -l options are mutually exclusive\n",Progname);
  2372.     }
  2373.     if (COUNT && (FILENAMEONLY || NOFILENAME)) {
  2374.         FILENAMEONLY = OFF; 
  2375.         if(!FILEOUT) NOFILENAME = OFF;
  2376.     }
  2377.  
  2378.     if (!(PAT_FILE || PAT_BUFFER) && Pattern[0] == '\0') { /* Pattern not set with -e option */
  2379.         if (argc <= 0) {
  2380.             agrep_usage();
  2381.             return 0;
  2382.         }
  2383.         strcpy(Pattern, *argv); 
  2384.         pattern_index = abs(argv - original_argv);
  2385.         argc--;
  2386.         argv++;
  2387.     }
  2388.     /* if multi-pattern search, just ignore any specified pattern altogether: treat it as a filename */
  2389.  
  2390.     if (copied_from_argv) {
  2391.         for (i=0; i<Numfiles; i++) free(Textfiles[i]);
  2392.         if (Textfiles != NULL) free(Textfiles);
  2393.     }
  2394.     copied_from_argv = 0;
  2395.     Numfiles = 0; Textfiles = NULL;
  2396.     execfd = agrep_initialfd;
  2397.     if (argc <= 0)  /* check Pattern against stdin */
  2398.         execfd = 0;
  2399.     else {    /* filenames were specified as a part of the command line */
  2400.         if (!(Textfiles = (CHAR **)malloc(argc * sizeof(CHAR *) ))) {
  2401.             fprintf(stderr, "%s: malloc failure in %s:%d\n", Progname, __FILE__, __LINE__);
  2402.             if (!EXITONERROR) {
  2403.                 errno = 2;
  2404.                 return 0;
  2405.             }
  2406.             else exit(2);
  2407.         }
  2408.         copied_from_argv = 1;    /* should I free Textfiles next time? */
  2409.         while (argc--)
  2410.         {    /* one or more filenames on command line -- put the valid filenames in a array of strings */
  2411.  
  2412.             if ((filetype = check_file(*argv)) == NOSUCHFILE) {
  2413.                 if (!glimpse_call) if (!glimpse_call) fprintf(stderr,"%s: '%s' no such file or directory\n",Progname,*argv);
  2414.                 argv++;
  2415.             }
  2416.             else { /* file is ascii*/
  2417.                 if (!(Textfiles[Numfiles] = (CHAR *)malloc((strlen(*argv)+2)))) {
  2418.                     fprintf(stderr, "%s: malloc failure in %s:%d\n", Progname, __FILE__, __LINE__);
  2419.                     if (!EXITONERROR) {
  2420.                         errno = 2;
  2421.                         return 0;
  2422.                     }
  2423.                     else exit(2);
  2424.                 }
  2425.                 strcpy(Textfiles[Numfiles++], *argv++);
  2426.             } /* else */
  2427.         } /* while (argc--) */
  2428.         if (Numfiles <= 0) return 0;
  2429.         /* If user specified wrong filenames, then we quit rather than taking input from stdin! */
  2430.     } /* else */
  2431.  
  2432.     M = strlen(Pattern);
  2433.     if (M<=0) return 0;
  2434.     for (i=0; i<M; i++) {
  2435.         if ( ((unsigned char *)Pattern)[i] > USERRANGE) {
  2436.             fprintf(stderr, "Warning: pattern has non-ascii meta-characters interepreted by agrep!\n");
  2437.             break;
  2438.         }
  2439.         else if (Pattern[i] == '\\') i++;    /* extra */
  2440.         else if (Pattern[i] == '[') seenlsq = 1;
  2441.         else if ((Pattern[i] == '-') && !seenlsq) {
  2442.             for (j=M; j>=i; j--)
  2443.                 Pattern[j+1] = Pattern[j];    /* right shift including '\0' */
  2444.             Pattern[i] = '\\';    /* escape the - */
  2445.             M ++;
  2446.             i++;
  2447.         }
  2448.         else if (Pattern[i] == ']') seenlsq = 0;
  2449.     }
  2450.  
  2451.     if (M > pattern_len - 1) {
  2452.         fprintf(stderr, "%s: pattern '%s' does not fit in specified buffer\n", Progname, Pattern);
  2453.         errno = 3;
  2454.         return 0;
  2455.     }
  2456.     if (pattern_buffer != Pattern)    /* not from mem/file-agrep() */
  2457.         strncpy(pattern_buffer, Pattern, M+1); /* copy \0 */
  2458.     return M;
  2459. }
  2460.  
  2461. /*
  2462.  * User need not bother about initialfd.
  2463.  * Both functions return -1 on error, 0 if there was no pattern,
  2464.  * length (>=1) of pattern otherwise.
  2465.  */
  2466.  
  2467. int
  2468. memagrep_init(argc, argv, pattern_len, pattern_buffer)
  2469.     int    argc;
  2470.     char    *argv[];
  2471.     int    pattern_len;
  2472.     char    *pattern_buffer;
  2473. {
  2474.     return (agrep_init(argc, argv, -1, pattern_len, pattern_buffer));
  2475. }
  2476.  
  2477. int
  2478. fileagrep_init(argc, argv, pattern_len, pattern_buffer)
  2479.     int    argc;
  2480.     char    *argv[];
  2481.     int    pattern_len;
  2482.     char    *pattern_buffer;
  2483. {
  2484.     return (agrep_init(argc, argv, 3, pattern_len, pattern_buffer));
  2485. }
  2486.  
  2487. /* returns -1 on error, num of matches (>=0) otherwise */
  2488. int
  2489. agrep_search(pattern_len, pattern_buffer, initialfd, input_len, input, output_len, output)
  2490. int pattern_len; 
  2491. CHAR *pattern_buffer;
  2492. int initialfd;
  2493. int input_len;
  2494. void *input;
  2495. int output_len;
  2496. void *output;
  2497. {
  2498.     int    i;
  2499.     int    filetype;
  2500.     int    ret;
  2501.  
  2502.     reinit_value();
  2503.  
  2504.     if ((multifd == -1) && (multibuf == NULL) && (pattern_len < 1)) {
  2505.         fprintf(stderr, "%s: pattern length %d too small\n", Progname, pattern_len);
  2506.         errno = 3;
  2507.         return -1;
  2508.     }
  2509.     if (pattern_len >= MAXPAT) {
  2510.         fprintf(stderr, "%s: pattern '%s' too long\n", Progname, pattern_buffer);
  2511.         errno = 3;
  2512.         return -1;
  2513.     }
  2514.     if (pattern_buffer != Pattern)    /* not from mem/file-agrep() */
  2515.         strncpy(Pattern, pattern_buffer, pattern_len+1); /* copy \0 */
  2516.     M = strlen(Pattern);
  2517.  
  2518.     if (output == NULL) {
  2519.         fprintf(stderr, "%s: invalid output descriptor\n", Progname);
  2520.         return -1;
  2521.     }
  2522.     if (output_len <= 0) {
  2523.         agrep_finalfp = (FILE *)output;
  2524.         agrep_outlen = 0;
  2525.         agrep_outbuffer = NULL;
  2526.         agrep_outpointer = 0;
  2527.     }
  2528.     else {
  2529.         agrep_finalfp = NULL;
  2530.         agrep_outlen = output_len;
  2531.         agrep_outbuffer = (CHAR *)output;
  2532.         agrep_outpointer = 0;
  2533.     }
  2534.  
  2535.     agrep_initialfd = initialfd;
  2536.     execfd = initialfd;
  2537.     if (initialfd == -1) {
  2538.         agrep_inbuffer = (CHAR *)input;
  2539.         agrep_inlen = input_len;
  2540.         agrep_inpointer = 0;
  2541.     }
  2542.     else if ((input_len > 0) && (input != NULL)) {
  2543.         /* Copy the set of filenames into Textfiles */
  2544.         if (copied_from_argv) {
  2545.             for (i=0; i<Numfiles; i++) free(Textfiles[i]);
  2546.             if (Textfiles != NULL) free(Textfiles);
  2547.         }
  2548.         copied_from_argv = 0;
  2549.         Numfiles = 0; Textfiles = NULL;
  2550. #if    0
  2551.         if (!(Textfiles = (CHAR **)malloc(input_len * sizeof(CHAR *) ))) {
  2552.             fprintf(stderr, "%s: malloc failure in %s:%d\n", Progname, __FILE__, __LINE__);
  2553.             if (!EXITONERROR) {
  2554.                 errno = 2;
  2555.                 return 0;
  2556.             }
  2557.             else exit(2);
  2558.         }
  2559. #else    /*0*/
  2560.         Textfiles = (CHAR **)input;
  2561. #endif    /*0*/
  2562.  
  2563.         while (input_len --)
  2564.         {    /* one or more filenames on command line -- put the valid filenames in a array of strings */
  2565.  
  2566.             if ((filetype = check_file(*(char **)input)) == NOSUCHFILE) {
  2567.                 if(filetype == NOSUCHFILE) if (!glimpse_call) fprintf(stderr,"%s: '%s' no such file or directory\n",Progname,*(char **)input);
  2568.                 input = (void *)(((long)input) + sizeof(char *));
  2569.             } 
  2570.             else { /* file is ascii*/
  2571. #if    0
  2572.                 if (!(Textfiles[Numfiles] = (CHAR *)malloc((strlen(*(char **)input)+2)))) {
  2573.                     fprintf(stderr, "%s: malloc failure in %s:%d\n", Progname, __FILE__, __LINE__);
  2574.                     if (!EXITONERROR) {
  2575.                         errno = 2;
  2576.                         return 0;
  2577.                     }
  2578.                     else exit(2);
  2579.                 }
  2580.                 strcpy(Textfiles[Numfiles++], *((char **)input));
  2581. #else    /*0*/
  2582.                 Textfiles[Numfiles++] = *((CHAR **)input);
  2583. #endif    /*0*/
  2584.                 input = (void *)(((long)input) + sizeof(char *));
  2585.             } /* else */
  2586.         } /* while (argc--) */
  2587.         if (Numfiles <= 0) return 0;
  2588.         /* If user specified wrong filenames, then we quit rather than taking input from stdin! */
  2589.     }
  2590.     else if (Numfiles <= 0) execfd = 0;
  2591.     /* the old set of files (agrep_init) are used */
  2592.  
  2593. #if    0
  2594.     printf("agrep_search: pat=%s buf=%s\n", Pattern, ((agrep_initialfd == -1) && (agrep_inlen < 20)) ? agrep_inbuffer : NULL);
  2595. #endif    /*0*/
  2596.  
  2597.     if (-1 == checksg(Pattern, D, 1)) return -1;       /* check if the pattern is simple */
  2598.     strcpy(OldPattern, Pattern);
  2599.  
  2600.     /* Must do this everytime since processing depends on the pattern being searched */
  2601.     if (SGREP == 0) {
  2602.         if (-1 == preprocess(D_pattern, Pattern)) return -1;
  2603.         strcpy(old_D_pat, D_pattern);
  2604.         /* fprintf(stderr, "agrep_search: len=%d pat=%s\n", strlen(Pattern), Pattern); */
  2605.         if(!AParse &&  ((M = maskgen(Pattern, D)) == -1)) return -1;
  2606.     }
  2607.     else {    /* sgrep too can handle delimiters */
  2608.         if (DELIMITER) {
  2609.             /* D_pattern is "<PAT>; ", D_length is 1 + length of string PAT: see agrep.c/'d' */
  2610.             preprocess_delimiter(D_pattern+1, D_length - 1, D_pattern, &D_length);
  2611.             /* D_pattern is the exact stuff we want to match, D_length is its strlen */
  2612.             if ((tc_D_length = quick_tcompress(FREQ_FILE, HASH_FILE, D_pattern, D_length, tc_D_pattern, MaxDelimit*2, TC_EASYSEARCH)) <= 0) {
  2613.                 strcpy(tc_D_pattern, D_pattern);
  2614.                 tc_D_length = D_length;
  2615.             }
  2616.             /* printf("sgrep's delim=%s,%d tc_delim=%s,%d\n", D_pattern, D_length, tc_D_pattern, tc_D_length); */
  2617.         }
  2618.         M = strlen(OldPattern);
  2619.     }
  2620.     if (AParse)  {    /* boolean converted to multi-pattern search */
  2621.         if (prepf(-1, multibuf, multilen) <= -1) {
  2622.             if (AComplexBoolean) destroy_tree(AParse);
  2623.             AParse = 0;
  2624.             PAT_BUFFER = 0;
  2625.             if (multibuf != NULL) free(multibuf);    /* this was allocated for arbit booleans, not multipattern search */
  2626.             multilen = 0;
  2627.             /* Cannot free multifd here since that is always allocated for multipattern search */
  2628.             return -1;
  2629.         }
  2630.     }
  2631.     if (Numfiles > 1) FNAME = ON;
  2632.     if (NOFILENAME) FNAME = 0;
  2633.     if (ALWAYSFILENAME) FNAME = ON;    /* used by glimpse ONLY: 15/dec/93 */
  2634.  
  2635.     if (agrep_initialfd == -1) ret = exec(execfd, NULL);
  2636.     else if(RECURSIVE) ret = (recursive(Numfiles, Textfiles));
  2637.     else  ret = (exec(execfd, Textfiles));
  2638.  
  2639.     if (AParse && !use_previous_state) {    /* DIRTY TRICK: glimpse can call exec directly and save lot of time */
  2640.         if (AComplexBoolean) destroy_tree(AParse);
  2641.         AComplexBoolean = 0;
  2642.         AParse = 0;
  2643.         PAT_BUFFER = 0;
  2644.         if (multibuf != NULL) free(multibuf);    /* this was allocated for arbit booleans, not multipattern search */
  2645.         multibuf = NULL;
  2646.         multilen = 0;
  2647.         /* Cannot free multifd here since that is always allocated for multipattern search */
  2648.     }
  2649.     return ret;
  2650. }
  2651.  
  2652. /*
  2653.  * User need not bother about initialfd.
  2654.  * Both functions return -1 on error, 0 otherwise.
  2655.  */
  2656.  
  2657. int
  2658. memagrep_search(pattern_len, pattern_buffer, input_len, input_buffer, output_len, output)
  2659. int pattern_len;
  2660. char *pattern_buffer;
  2661. int input_len;
  2662. char *input_buffer;
  2663. int output_len;
  2664. void *output;
  2665. {
  2666.     return(agrep_search(pattern_len, pattern_buffer, -1, input_len, input_buffer, output_len, output));
  2667. }
  2668.  
  2669. int
  2670. fileagrep_search(pattern_len, pattern_buffer, file_num, file_buffer, output_len, output)
  2671. int pattern_len;
  2672. char *pattern_buffer;
  2673. int file_num;
  2674. char **file_buffer;
  2675. int output_len;
  2676. void *output;
  2677. {
  2678.     return(agrep_search(pattern_len, pattern_buffer, 3, file_num, file_buffer, output_len, output));
  2679. }
  2680.  
  2681. /*
  2682.  * The original agrep_run() routine was split into agrep_search and agrep_init
  2683.  * so that the interface with glimpse could be made cleaner: see glimpse.
  2684.  * Now, the user can specify an initial set of options, and use them in future
  2685.  * searches. If agrep_init does not find the pattern, options are still SET.
  2686.  * In fileagrep_search, the user can specify a NEW set of files to be searched
  2687.  * after the options are processed (this is used in glimpse).
  2688.  *
  2689.  * Both functions return -1 on error, 0 otherwise.
  2690.  *
  2691.  * The arguments are self explanatory. The pattern should be specified in
  2692.  * one of the argvs. Options too can be specified in one of the argvs -- it
  2693.  * is exactly as if the options are being given to agrep at run time.
  2694.  * The only restrictions are that the input_buffer should begin with a '\n'
  2695.  * and after its end, there must be valid memory to store a copy of the pattern.
  2696.  */
  2697.  
  2698. int
  2699. memagrep(argc, argv, input_len, input_buffer, output_len, output)
  2700. int argc; 
  2701. char *argv[];
  2702. int input_len;
  2703. char *input_buffer;
  2704. int output_len;
  2705. void *output;
  2706. {
  2707.     int    ret;
  2708.  
  2709.     if ((ret = memagrep_init(argc, argv, MAXPAT, Pattern)) < 0) return -1;
  2710.     else if ((ret == 0) && (multifd == -1) && (multibuf == NULL)) return -1;
  2711.     /* ^^^ because one need not specify the pattern on the cmd line if -f OR -m */
  2712.     return memagrep_search(ret, Pattern, input_len, input_buffer, output_len, output);
  2713. }
  2714.  
  2715. int
  2716. fileagrep(argc, argv, output_len, output)
  2717. int argc; 
  2718. char *argv[];
  2719. int output_len;
  2720. void *output;
  2721. {
  2722.     int    ret;
  2723.  
  2724.     if ((ret = fileagrep_init(argc, argv, MAXPAT, Pattern)) < 0) return -1;
  2725.     else if ((ret == 0) && (multifd == -1) && (multibuf == NULL)) return -1;
  2726.     /* ^^^ because one need not specify the pattern on the cmd line if -f OR -m */
  2727.     return fileagrep_search(ret, Pattern, 0, NULL, output_len, output);
  2728. }
  2729.  
  2730. /*
  2731.  * RETURNS: total number of matched lines in all files that were searched.
  2732.  *
  2733.  * The pattern(s) remain(s) constant irrespective of the number of files.
  2734.  * Hence, essentially, all the interface routines below have to be changed
  2735.  * so that they DONT do that preprocessing again and again for multiple
  2736.  * files. This bug was found while interfacing agrep with cast.
  2737.  *
  2738.  * At present, sgrep() has been modified to have another parameter,
  2739.  * "samepattern" that tells it whether the pattern is the same as before.
  2740.  * Other funtions too should have such a parameter and should not repeat
  2741.  * preprocessing for all patterns. Since preprocessing for a pattern to
  2742.  * be searched in compressed files is siginificant, this bug was found.
  2743.  *
  2744.  * - bgopal on 15/Nov/93.
  2745.  */
  2746. int
  2747. exec(fd, file_list)
  2748. int fd;
  2749. char **file_list;
  2750. {
  2751.     int i;
  2752.     char c[8];
  2753.     int ret = 0;    /* no error */
  2754.  
  2755.     if ((Numfiles > 1) && (NOFILENAME == OFF)) FNAME = ON;
  2756.     if (!use_previous_state && (-1 == compat())) return -1; /* check compatibility between options */
  2757.  
  2758.     if (fd <= 0) {
  2759.         TCOMPRESSED = ON;    /* there is a possibility that the data might be tuncompressible */
  2760.         if (!SetCurrentByteOffset) CurrentByteOffset = 0;
  2761.         if((fd == 0) && FILENAMEONLY && !use_previous_state) {
  2762.             fprintf(stderr, "%s: -l option is not compatible with standard input\n", Progname);
  2763.             if (!EXITONERROR) {
  2764.                 errno = 2;
  2765.                 return -1;
  2766.             }
  2767.             else exit(2);  
  2768.         }
  2769.         if(PAT_FILE || PAT_BUFFER) mgrep(fd, AParse);
  2770.         else {
  2771.             if(SGREP) ret = sgrep(OldPattern, strlen(OldPattern), fd, D, 0);
  2772.             else      ret = bitap(old_D_pat, Pattern, fd, M, D);
  2773.         }
  2774.         if (ret <= -1) return -1;
  2775.         if (COUNT && !use_previous_state && ret) {    /* dirty solution for glimpse's -b! */
  2776.             if(INVERSE && (PAT_FILE || PAT_BUFFER)) {    /* inverse will never be set in glimpse */
  2777.                 if (agrep_finalfp != NULL)
  2778.                     fprintf(agrep_finalfp, "%d\n", total_line-(num_of_matched - prev_num_of_matched));
  2779.                 else {
  2780.                     char s[32];
  2781.                     int  outindex;
  2782.  
  2783.                     sprintf(s, "%d\n", total_line-(num_of_matched - prev_num_of_matched));
  2784.  
  2785.                     for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  2786.                             (s[outindex] != '\0'); outindex++) {
  2787.                         agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
  2788.                     }
  2789.                     if (s[outindex] != '\0') {
  2790.                         OUTPUT_OVERFLOW;
  2791.                         return -1;
  2792.                     }
  2793.                     agrep_outpointer += outindex;
  2794.                 }
  2795.             }
  2796.             else {
  2797.                 if (agrep_finalfp != NULL)
  2798.                     fprintf(agrep_finalfp, "%d\n", (num_of_matched - prev_num_of_matched));
  2799.                 else {
  2800.                     char s[32];
  2801.                     int  outindex;
  2802.  
  2803.                     sprintf(s, "%d\n", (num_of_matched - prev_num_of_matched));
  2804.  
  2805.                     for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  2806.                             (s[outindex] != '\0'); outindex++) {
  2807.                         agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
  2808.                     }
  2809.                     if (s[outindex] != '\0') {
  2810.                         OUTPUT_OVERFLOW;
  2811.                         return -1;
  2812.                     }
  2813.                     agrep_outpointer += outindex;
  2814.                 }
  2815.             }
  2816.         }
  2817.     }
  2818.     else {
  2819.         /* fd > 0 => Numfiles > 0 */
  2820.  
  2821.         for (i = 0; i < Numfiles; i++, close(fd)) {
  2822.             prev_num_of_matched = num_of_matched;
  2823.             if (!SetCurrentByteOffset) CurrentByteOffset = 0;
  2824.             if (!SetCurrentFileName) strcpy(CurrentFileName, file_list[i]);
  2825.             TCOMPRESSED = ON;
  2826.             if (!tuncompressible_filename(file_list[i], strlen(file_list[i]))) TCOMPRESSED = OFF;
  2827.             NEW_FILE = ON;
  2828.             if ((fd = open(file_list[i], O_RDONLY)) < /*=*/ 0) {
  2829.                 fprintf(stderr, "%s: can't open file for reading: %s\n",Progname, file_list[i]);
  2830.             } 
  2831.             else { 
  2832.                 if(PAT_FILE || PAT_BUFFER) mgrep(fd, AParse);
  2833.                 else {
  2834.                     if(SGREP) ret = sgrep(OldPattern, strlen(OldPattern), fd, D, i);
  2835.                     else      ret = bitap(old_D_pat, Pattern, fd, M, D);
  2836.                 }
  2837.                 if (ret <= -1) {
  2838.                     close(fd);
  2839.                     return -1;
  2840.                 }
  2841.                 if (num_of_matched - prev_num_of_matched > 0) NOMATCH = OFF;
  2842.  
  2843.                 if (COUNT && !FILEOUT) {
  2844.                     if( (INVERSE && (PAT_FILE || PAT_BUFFER)) && ((total_line - (num_of_matched - prev_num_of_matched)> 0) || !NOOUTPUTZERO) ) {
  2845.                         if(FNAME && (NEW_FILE || !POST_FILTER)) {
  2846.                             if (agrep_finalfp != NULL)
  2847.                                 fprintf(agrep_finalfp, "%s: %d\n", CurrentFileName, total_line - (num_of_matched - prev_num_of_matched));
  2848.                             else {
  2849.                                 char s[32];
  2850.                                 int  outindex;
  2851.  
  2852.                                 sprintf(s, ": %d\n", total_line - (num_of_matched - prev_num_of_matched));
  2853.  
  2854.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  2855.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  2856.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  2857.                                 }
  2858.                                 if (CurrentFileName[outindex] != '\0') {
  2859.                                     OUTPUT_OVERFLOW;
  2860.                                     close(fd);
  2861.                                     return -1;
  2862.                                 }
  2863.                                 agrep_outpointer += outindex;
  2864.  
  2865.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  2866.                                         (s[outindex] != '\0'); outindex++) {
  2867.                                     agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
  2868.                                 }
  2869.                                 if (s[outindex] != '\0') {
  2870.                                     OUTPUT_OVERFLOW;
  2871.                                     close(fd);
  2872.                                     return -1;
  2873.                                 }
  2874.                                 agrep_outpointer += outindex;
  2875.                             }
  2876.                             NEW_FILE = OFF;
  2877.                         }
  2878.                         else if (!FNAME) {
  2879.                             if (agrep_finalfp != NULL)
  2880.                                 fprintf(agrep_finalfp, "%d\n", total_line - (num_of_matched - prev_num_of_matched));
  2881.                             else {
  2882.                                 char s[32];
  2883.                                 int  outindex;
  2884.  
  2885.                                 sprintf(s, "%d\n", total_line - (num_of_matched - prev_num_of_matched));
  2886.  
  2887.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  2888.                                         (s[outindex] != '\0'); outindex++) {
  2889.                                     agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
  2890.                                 }
  2891.                                 if (s[outindex] != '\0') {
  2892.                                     OUTPUT_OVERFLOW;
  2893.                                     close(fd);
  2894.                                     return -1;
  2895.                                 }
  2896.                                 agrep_outpointer += outindex;
  2897.                             }
  2898.                         }
  2899.                     }
  2900.                     else if ( !(INVERSE && (PAT_FILE || PAT_BUFFER)) && (((num_of_matched - prev_num_of_matched) > 0) || !NOOUTPUTZERO) ) {
  2901.                         /* inverse is always 0 in glimpse, so we always come here */
  2902.                         if(FNAME && (NEW_FILE || !POST_FILTER)) {
  2903.                             if (agrep_finalfp != NULL)
  2904.                                 fprintf(agrep_finalfp, "%s: %d\n", CurrentFileName, (num_of_matched - prev_num_of_matched)); 
  2905.                             else {
  2906.                                 char s[32];
  2907.                                 int  outindex;
  2908.  
  2909.                                 sprintf(s, ": %d\n", (num_of_matched - prev_num_of_matched));
  2910.  
  2911.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  2912.                                         (CurrentFileName[outindex] != '\0'); outindex++) {
  2913.                                     agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  2914.                                 }
  2915.                                 if (CurrentFileName[outindex] != '\0') {
  2916.                                     OUTPUT_OVERFLOW;
  2917.                                     close(fd);
  2918.                                     return -1;
  2919.                                 }
  2920.                                 agrep_outpointer += outindex;
  2921.  
  2922.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  2923.                                         (s[outindex] != '\0'); outindex++) {
  2924.                                     agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
  2925.                                 }
  2926.                                 if (s[outindex] != '\0') {
  2927.                                     OUTPUT_OVERFLOW;
  2928.                                     close(fd);
  2929.                                     return -1;
  2930.                                 }
  2931.                                 agrep_outpointer += outindex;
  2932.                             }
  2933.                             NEW_FILE = OFF;
  2934.                         }
  2935.                         else if (!FNAME) {
  2936.                             if (agrep_finalfp != NULL)
  2937.                                 fprintf(agrep_finalfp, "%d\n", (num_of_matched - prev_num_of_matched));
  2938.                             else {
  2939.                                 char s[32];
  2940.                                 int  outindex;
  2941.  
  2942.                                 sprintf(s, "%d\n", (num_of_matched - prev_num_of_matched));
  2943.  
  2944.                                 for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  2945.                                         (s[outindex] != '\0'); outindex++) {
  2946.                                     agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
  2947.                                 }
  2948.                                 if (s[outindex] != '\0') {
  2949.                                     OUTPUT_OVERFLOW;
  2950.                                     close(fd);
  2951.                                     return -1;
  2952.                                 }
  2953.                                 agrep_outpointer += outindex;
  2954.                             }
  2955.                         }
  2956.                     }
  2957.                 }  /* if COUNT */
  2958.                 if(FILEOUT && (num_of_matched - prev_num_of_matched)) {
  2959.                     if (-1 == file_out(CurrentFileName)) {
  2960.                         close(fd);
  2961.                         return -1;
  2962.                     }
  2963.                 }
  2964.             } /* else */
  2965.             if (glimpse_clientdied) {
  2966.                 close(fd);
  2967.                 return -1;
  2968.             }
  2969.             if (agrep_finalfp != NULL) fflush(agrep_finalfp);
  2970.             if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  2971.                 close(fd);
  2972.                 break;    /* done */
  2973.             }
  2974.         }  /* for i < Numfiles */
  2975.  
  2976.         if(NOMATCH && BESTMATCH) {
  2977.             if(WORDBOUND || WHOLELINE || LINENUM || INVERSE) { 
  2978.                 SGREP = 0;    
  2979.                 if(-1 == preprocess(D_pattern, Pattern)) return -1;
  2980.                 strcpy(old_D_pat, D_pattern);
  2981.                 if((M = maskgen(Pattern, D)) == -1) return -1;
  2982.             }
  2983.             COUNT=ON; 
  2984.             D=1;
  2985.             while(D<M && D<=MaxError && (num_of_matched - prev_num_of_matched == 0)) {
  2986.                 for (i = 0; i < Numfiles; i++, close(fd)) {
  2987.                     prev_num_of_matched = num_of_matched;
  2988.                     CurrentByteOffset = 0;
  2989.                     strcpy(CurrentFileName, Textfiles[i]);
  2990.                     NEW_FILE = ON;
  2991.                     if ((fd = open(Textfiles[i], O_RDONLY)) > 0) {
  2992.                         if(PAT_FILE || PAT_BUFFER) mgrep(fd, AParse);
  2993.                         else {
  2994.                             if(SGREP) ret = sgrep(OldPattern,strlen(OldPattern),fd,D, i);
  2995.                             else ret = bitap(old_D_pat,Pattern,fd,M,D);
  2996.                         }
  2997.                         if (ret <= -1) return -1;
  2998.                     }
  2999.                     if (glimpse_clientdied) {
  3000.                         close(fd);
  3001.                         return -1;
  3002.                     }
  3003.                     if (agrep_finalfp != NULL) fflush(agrep_finalfp);
  3004.                     if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched) && (num_of_matched > prev_num_of_matched)) {
  3005.                         close(fd);
  3006.                         break;
  3007.                     }
  3008.                 }  /* for i < Numfiles */
  3009.                 D++;
  3010.             } /* while */
  3011.  
  3012.             if(num_of_matched - prev_num_of_matched > 0) {
  3013.                 D--; 
  3014.                 errno = D;    /* #of errors if proper return */
  3015.                 COUNT = 0;
  3016.  
  3017.                 if(num_of_matched - prev_num_of_matched == 1) fprintf(stderr,"%s: 1 word matches ", Progname);
  3018.                 else fprintf(stderr,"%s: %d words match ", Progname, num_of_matched - prev_num_of_matched);
  3019.                 if(D==1) fprintf(stderr, "within 1 error");
  3020.                 else fprintf(stderr, "within %d errors", D);
  3021.  
  3022.                 fflush(stderr);
  3023.  
  3024.                 if(NOPROMPT) fprintf(stderr, "\n");
  3025.                 else {
  3026.                     if(num_of_matched - prev_num_of_matched == 1) fprintf(stderr,"; search for it? (y/n)");
  3027.                     else fprintf(stderr,"; search for them? (y/n)");
  3028.                     c[0] = 'y';
  3029.                     if (!glimpse_isserver && (fgets(c, 4, stdin) == NULL)) goto CONT;
  3030.                     if(c[0] != 'y') goto CONT;
  3031.                 }
  3032.  
  3033.                 for (i = 0; i < Numfiles; i++, close(fd)) {
  3034.                     prev_num_of_matched = num_of_matched;
  3035.                     CurrentByteOffset = 0;
  3036.                     strcpy(CurrentFileName, Textfiles[i]);
  3037.                     NEW_FILE = ON;
  3038.                     if ((fd = open(Textfiles[i], O_RDONLY)) > 0) {
  3039.                         if(PAT_FILE || PAT_BUFFER) mgrep(fd, AParse);
  3040.                         else {
  3041.                             if(SGREP) ret = sgrep(OldPattern,strlen(OldPattern),fd,D, i);
  3042.                             else ret = bitap(old_D_pat,Pattern,fd,M,D);
  3043.                         }
  3044.                         if (ret <= -1) {
  3045.                             close(fd);
  3046.                             return -1;
  3047.                         }
  3048.                     }
  3049.                     if (glimpse_clientdied) {
  3050.                         close(fd);
  3051.                         return -1;
  3052.                     }
  3053.                     if (agrep_finalfp != NULL) fflush(agrep_finalfp);
  3054.                     if ((LIMITOUTPUT > 0) && (LIMITOUTPUT <= num_of_matched)) {
  3055.                         close(fd);
  3056.                         break;    /* done */
  3057.                     }
  3058.                 }  /* for i < Numfiles */
  3059.                 NOMATCH = 0;
  3060.             }
  3061.         }
  3062.     }
  3063. CONT:
  3064.     if(EATFIRST) {
  3065.         if (agrep_finalfp != NULL) fprintf(agrep_finalfp, "\n");
  3066.         else if (agrep_outpointer >= agrep_outlen) {
  3067.             OUTPUT_OVERFLOW;
  3068.             return -1;
  3069.         }
  3070.         else agrep_outbuffer[agrep_outpointer++] = '\n';
  3071.         EATFIRST = OFF;
  3072.     }
  3073.     if(num_of_matched - prev_num_of_matched > 0) NOMATCH = OFF;
  3074.     /* if(NOMATCH) return(0); */
  3075.     /*printf("exec=%d\n", num_of_matched);*/
  3076.     return(num_of_matched);
  3077.  
  3078. } /* end of exec() */
  3079.  
  3080.  
  3081. /* Just output the contents of the file fname onto the std output */
  3082. file_out(fname)
  3083. char *fname;
  3084. {
  3085.     int num_read;
  3086.     int fd;
  3087.     int i, len;
  3088.     CHAR buf[SIZE+2];
  3089.     if(FNAME) {
  3090.         len = strlen(fname);
  3091.         if (agrep_finalfp != NULL) {
  3092.             fputc('\n', agrep_finalfp);
  3093.             for(i=0; i< len; i++) fputc(':', agrep_finalfp);
  3094.             fputc('\n', agrep_finalfp);
  3095.             fprintf(agrep_finalfp, "%s\n", CurrentFileName);
  3096.             for(i=0; i< len; i++) fputc(':', agrep_finalfp);
  3097.             fputc('\n', agrep_finalfp);
  3098.             fflush(agrep_finalfp);
  3099.         }
  3100.         else {
  3101.             if (1+len+1+len+1+len+1+agrep_outpointer >= agrep_outlen) {
  3102.                 OUTPUT_OVERFLOW;
  3103.                 return -1;
  3104.             }
  3105.             agrep_outbuffer[agrep_outpointer++] = '\n';
  3106.             for (i=0; i<len; i++) agrep_outbuffer[agrep_outpointer++] = ':';
  3107.             agrep_outbuffer[agrep_outpointer++] = '\n';
  3108.             for (i=0; i<len; i++) agrep_outbuffer[agrep_outpointer++] = CurrentFileName[i];
  3109.             agrep_outbuffer[agrep_outpointer++] = '\n';
  3110.             for (i=0; i<len; i++) agrep_outbuffer[agrep_outpointer++] = ':';
  3111.             agrep_outbuffer[agrep_outpointer++] = '\n';
  3112.         }
  3113.     }
  3114.     fd = open(fname, O_RDONLY);
  3115.     if (agrep_finalfp != NULL) {
  3116.         while((num_read = fill_buf(fd, buf, SIZE)) > 0) 
  3117.             write(1, buf, num_read);
  3118.         if (glimpse_clientdied) {
  3119.             close(fd);
  3120.             return -1;
  3121.         }
  3122.     }
  3123.     else {
  3124.         if ((num_read = fill_buf(fd, agrep_outbuffer + agrep_outpointer, agrep_outlen - agrep_outpointer)) > 0)
  3125.             agrep_outpointer += num_read;
  3126.     }
  3127.     close(fd);
  3128.     return 0;
  3129. }
  3130.  
  3131. output(buffer, i1, i2, j)  
  3132. register CHAR *buffer; 
  3133. int i1, i2, j;
  3134. {
  3135.     register CHAR *bp, *outend;
  3136.     if(i1 > i2) return 0;
  3137.     num_of_matched++;
  3138.     if(COUNT)  return 0;
  3139.     if(SILENT) return 0;
  3140.     if(OUTTAIL || (!DELIMITER && (D_length == 1) && (D_pattern[0] == '\n')) ) {
  3141.         i1 = i1 + D_length;
  3142.         i2 = i2 + D_length;
  3143.     }
  3144.     if(DELIMITER) j = j+1;
  3145.     if(FIRSTOUTPUT) {
  3146.         if (buffer[i1] == '\n')  {
  3147.             i1++;
  3148.             EATFIRST = ON;
  3149.         }
  3150.         FIRSTOUTPUT = 0;
  3151.     }
  3152.     if(TRUNCATE) {
  3153.         fprintf(stderr, "WARNING!  some lines have been truncated in output record #%d\n", num_of_matched-1);
  3154.     }
  3155.  
  3156.     /* Why do we have to do this? */
  3157.     while ((buffer[i1] == '\n') && (i1 <= i2)) {
  3158.         if (agrep_finalfp != NULL) fprintf(agrep_finalfp, "\n");
  3159.         else {
  3160.             if (agrep_outpointer < agrep_outlen)
  3161.                 agrep_outbuffer[agrep_outpointer ++] = '\n';
  3162.             else {
  3163.                 OUTPUT_OVERFLOW;
  3164.                 return -1;
  3165.             }
  3166.         }
  3167.         i1++;
  3168.     }
  3169.  
  3170.     if(FNAME && (NEW_FILE || !POST_FILTER)) {
  3171.         char    nextchar = (POST_FILTER == ON)?'\n':' ';
  3172.         char    *prevstring = (POST_FILTER == ON)?"\n":"";
  3173.         if (agrep_finalfp != NULL)
  3174.             fprintf(agrep_finalfp, "%s%s:%c", prevstring, CurrentFileName, nextchar);
  3175.         else {
  3176.             int outindex;
  3177.             if (prevstring[0] != '\0') {
  3178.                 if(agrep_outpointer + 1 >= agrep_outlen) {
  3179.                     OUTPUT_OVERFLOW;
  3180.                     return -1;
  3181.                 }
  3182.                 else agrep_outbuffer[agrep_outpointer ++] = prevstring[0];
  3183.             }
  3184.             for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  3185.                     (CurrentFileName[outindex] != '\0'); outindex++) {
  3186.                 agrep_outbuffer[agrep_outpointer+outindex] = CurrentFileName[outindex];
  3187.             }
  3188.             if ((CurrentFileName[outindex] != '\0') || (outindex+agrep_outpointer+2>=agrep_outlen)) {
  3189.                 OUTPUT_OVERFLOW;
  3190.                 return -1;
  3191.             }
  3192.             else {
  3193.                 agrep_outbuffer[agrep_outpointer+outindex++] = ':';
  3194.                 agrep_outbuffer[agrep_outpointer+outindex++] = nextchar;
  3195.             }
  3196.             agrep_outpointer += outindex;
  3197.         }
  3198.         NEW_FILE = OFF;
  3199.     }
  3200.     if(LINENUM) {
  3201.         if (agrep_finalfp != NULL)
  3202.             fprintf(agrep_finalfp, "%d: ", j-1); 
  3203.         else {
  3204.             char s[32];
  3205.             int  outindex;
  3206.  
  3207.             sprintf(s, "%d: ", j-1);
  3208.             for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  3209.                     (s[outindex] != '\0'); outindex++) {
  3210.                 agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
  3211.             }
  3212.             if (s[outindex] != '\0') {
  3213.                 OUTPUT_OVERFLOW;
  3214.                 return -1;
  3215.             }
  3216.             agrep_outpointer += outindex;
  3217.         }
  3218.     }
  3219.     if(BYTECOUNT) {
  3220.         if (agrep_finalfp != NULL)
  3221.             fprintf(agrep_finalfp, "%d= ", CurrentByteOffset-1);
  3222.         else {
  3223.             char s[32];
  3224.             int  outindex;
  3225.             sprintf(s, "%d= ", CurrentByteOffset-1);
  3226.             for(outindex=0; (outindex+agrep_outpointer<agrep_outlen) &&
  3227.                     (s[outindex] != '\0'); outindex++) {
  3228.                 agrep_outbuffer[agrep_outpointer+outindex] = s[outindex];
  3229.             }
  3230.             if (s[outindex] != '\0') {
  3231.                 OUTPUT_OVERFLOW;
  3232.                 return -1;
  3233.             }
  3234.             agrep_outpointer += outindex;
  3235.         }
  3236.     }
  3237.  
  3238.     bp = buffer + i1;
  3239.     outend = buffer + i2;
  3240.  
  3241.     if (agrep_finalfp != NULL)
  3242.         while(bp <= outend) fputc(*bp++, agrep_finalfp);
  3243.     else {
  3244.         if (outend - bp + 1 + agrep_outpointer >= agrep_outlen) {
  3245.             OUTPUT_OVERFLOW;
  3246.             return -1;
  3247.         }
  3248.         while(bp <= outend) agrep_outbuffer[agrep_outpointer ++] = *bp++;
  3249.     }
  3250.  
  3251.     return 0;
  3252. }
  3253.  
  3254. agrep_usage()
  3255. {
  3256.     if (glimpse_call) return -1;
  3257.     fprintf(stderr, "usage: %s [-#abcdehiklnoprstvwxyBDGIMSV] [-f patternfile] [-H dir] pattern [files]\n", Progname); 
  3258.     fprintf(stderr, "\n");    
  3259.     fprintf(stderr, "summary of frequently used options:\n");
  3260.     fprintf(stderr, "(For a more detailed listing see 'man agrep'.)\n");
  3261.     fprintf(stderr, "-#: find matches with at most # errors\n");
  3262.     fprintf(stderr, "-c: output the number of matched records\n");
  3263.     fprintf(stderr, "-d: define record delimiter\n");
  3264.     fprintf(stderr, "-h: do not output file names\n");
  3265.     fprintf(stderr, "-i: case-insensitive search, e.g., 'a' = 'A'\n");
  3266.     fprintf(stderr, "-l: output the names of files that contain a match\n");
  3267.     fprintf(stderr, "-n: output record prefixed by record number\n");
  3268.     fprintf(stderr, "-v: output those records that have no matches\n");
  3269.     fprintf(stderr, "-w: pattern has to match as a word, e.g., 'win' will not match 'wind'\n");
  3270.     fprintf(stderr, "-B: best match mode. find the closest matches to the pattern\n"); 
  3271.     fprintf(stderr, "-G: output the files that contain a match\n");
  3272.     fprintf(stderr, "-H 'dir': the cast-dictionary is located in directory 'dir'\n");
  3273.     fprintf(stderr, "\n");    
  3274.  
  3275.     if (!EXITONERROR) {
  3276.         errno = 2;
  3277.         return -1;
  3278.     }
  3279.     else exit(2);
  3280. }
  3281.