home *** CD-ROM | disk | FTP | other *** search
- /*
- search routine generated by gen.
- skip=uf, match=rev (using revr), shift=gd2
- */
- /*
- * The authors of this software are Andrew Hume and Daniel Sunday.
- *
- * Copyright (c) 1991 by AT&T and Daniel Sunday.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose without fee is hereby granted, provided that this entire notice
- * is included in all copies of any software which is or includes a copy
- * or modification of this software and in all copies of the supporting
- * documentation for such software.
- *
- * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
- * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
- * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
- */
-
- #ifndef CHARTYPE
- #define CHARTYPE unsigned char
- #endif
- #define MAXPAT 256
-
- #include "stats.h"
-
- #ifndef TABTYPE
- #define TABTYPE long
- #endif
- typedef TABTYPE Tab;
-
- static struct
- {
- int patlen;
- CHARTYPE pat[MAXPAT];
- Tab delta[256];
- Tab dg[MAXPAT][128]; /* bad size but the 386 is small (128 is charset) */
- } pat;
-
- prep(base, m)
- CHARTYPE *base;
- register m;
- {
- CHARTYPE *skipc;
- register CHARTYPE *pe, *p;
- register int j;
- register Tab *d;
- register j0, k, q, i, jj;
- int endof[MAXPAT], rmin[MAXPAT];
-
- pat.patlen = m;
- if(m > MAXPAT)
- abort();
- memcpy(pat.pat, base, m);
- skipc = 0;
- stats.len = m;
- d = pat.delta;
- for(j = 0; j < 256; j++)
- d[j] = pat.patlen;
- for(p = pat.pat, pe = p+m-1; p < pe; p++)
- d[*p] = pe-p;
- d[*p] = 0;
- skipc = (CHARTYPE *)p;
- /*
- endof[k] is the maximal integer such that k is not a period
- rmin[jj] is the minimal period of p[0,m-1] > jj
- rmin[0] is the period of pat
- */
-
- for(i=0; i<m; i++)
- rmin[i] = m;
- for(k = 1, i = k, jj = 0; k < m; ){
- while((pat.pat[i] == pat.pat[i-k]) && (i < m))
- i++;
- endof[k] = i;
- q = k+1;
- if(i == m){
- for(j0 = jj; j0 < k; j0++)
- rmin[j0] = k;
- jj = k;
- }
- while(endof[q-k]+k < i){
- endof[q] = endof[q-k]+k;
- q = q+1;
- }
- k = q;
- if(k == i+1)
- i = k;
- }
- /*for (i=0; i<m; i++) printf("%d\t%d\n",endof[i], rmin[i]);/**/
-
- /* compute pat.dg[jj,a] */
- for(jj = 0; jj < m; jj++){
- for(i = 0; i < 128; i++)
- pat.dg[jj][i] = m-1-jj+rmin[jj];
- }
- for(k = m-2; k >= 0; k--){
- for(i = k, jj = m-1; pat.pat[i] == pat.pat[jj]; i--, jj--)
- ;
- if((i >= 0) && (pat.dg[jj][pat.pat[i]]>=m))
- pat.dg[jj][pat.pat[i]] = m-1-i;
- }
- }
-
- exec(base, n)
- CHARTYPE *base;
- {
- int nmatch = 0;
- register CHARTYPE *e, *s;
- register Tab *d0 = pat.delta;
- register k;
- register CHARTYPE *p, *q;
- register CHARTYPE *prev = pat.pat+pat.patlen-1;
- register kg;
-
- s = base+pat.patlen-1;
- e = base+n;
- memset(e, pat.pat[pat.patlen-1], pat.patlen);
- while(s < e){
- #ifdef STATS
- k = d0[*s];
- stats.jump++;
- while(k){
- stats.jump++; stats.step[k]++;
- k = d0[*(s += k)];
- stats.jump++; stats.step[k]++;
- k = d0[*(s += k)];
- stats.jump++; stats.step[k]++;
- k = d0[*(s += k)];
- }
- #else
- k = d0[*s];
- while(k){
- k = d0[*(s += k)];
- k = d0[*(s += k)];
- k = d0[*(s += k)];
- }
- #endif
- if(s >= e)
- break;
- #ifdef STATS
- stats.slow++;
- #endif
- #define RH s
- for(p = prev, q = RH; p > pat.pat; ){
- #ifdef STATS
- stats.cmp++;
- #endif
- if(*--q != *--p)
- goto mismatch;
- }
- nmatch++;
- mismatch:
- if(p < pat.pat)
- kg = pat.patlen+1;
- else
- kg = pat.dg[p-pat.pat][*q];
- #ifdef STATS
- stats.step[q+kg-s]++; stats.extra++;
- #endif
- s = q+kg;
- }
- return(nmatch);
- }
-