|
|
|
|
|
|
|
|
|
|
|
static INLINE HCHAR *NameNH(MEMCHR)(HCHAR *p, NCHAR c, ptrdiff_t e) |
{ |
#if NSHIFT > HSHIFT |
if(c > (1<<(8*HSHIFT))) return 0; |
#endif |
return NameH(MEMCHR)(p,c,e); |
} |
|
|
static INLINE int NameNH(MEMCMP)(NCHAR *a, HCHAR *b, ptrdiff_t e) |
{ |
#if NSHIFT == HSHIFT |
return MEMCMP(a, b, sizeof(HCHAR)*e); |
#else |
for(;e;e--,b++,a++) |
{ |
if(*b!=*a) |
{ |
if(*b<*a) return -1; |
if(*b>*a) return 1; |
} |
} |
return 0; |
|
#endif |
} |
|
HCHAR *NameNH(memchr_search)(void *data, |
HCHAR *haystack, |
ptrdiff_t haystacklen) |
{ |
return NameNH(MEMCHR)(haystack, |
DO_NOT_WARN((NCHAR)(ptrdiff_t) PTR_TO_INT(data)), |
haystacklen); |
} |
|
|
#ifndef DEBUG_CLANG |
static |
#endif |
INLINE HCHAR *NameNH(memchr_memcmp)(NCHAR *needle, |
ptrdiff_t needlelen, |
HCHAR *haystack, |
ptrdiff_t haystacklen) |
{ |
NCHAR c; |
HCHAR *end; |
|
if(needlelen > haystacklen) return 0; |
|
end=haystack + haystacklen - needlelen+1; |
c=needle[0]; |
needle++; |
needlelen--; |
while((haystack=NameNH(MEMCHR)(haystack,c,end-haystack))) |
if(!NameNH(MEMCMP)(needle,++haystack,needlelen)) |
return haystack-1; |
|
return 0; |
} |
|
|
#define make_memchr_memcmpX(X) \ |
HCHAR *PxC4(memchr_memcmp,X,NSHIFT,HSHIFT)(void *n, \ |
HCHAR *haystack, \ |
ptrdiff_t haystacklen) \ |
{ \ |
return NameNH(memchr_memcmp)((NCHAR *)n, \ |
X, \ |
haystack, \ |
haystacklen); \ |
} |
|
make_memchr_memcmpX(2) |
make_memchr_memcmpX(3) |
make_memchr_memcmpX(4) |
make_memchr_memcmpX(5) |
make_memchr_memcmpX(6) |
|
#undef make_memchr_memcmpX |
|
HCHAR *NameNH(boyer_moore_hubbe)(struct boyer_moore_hubbe_searcher *s, |
HCHAR *haystack, |
ptrdiff_t haystacklen) |
{ |
NCHAR *needle = NEEDLE; |
ptrdiff_t nlen = NEEDLELEN; |
ptrdiff_t plen = s->plen; |
|
ptrdiff_t i=plen-1; |
ptrdiff_t hlen=haystacklen; |
if(nlen > plen) |
hlen -= nlen-plen; |
|
restart: |
while(i<hlen) |
{ |
ptrdiff_t k,j; |
|
if((k=s->d1[ NameNH(BMHASH)( haystack[i] ) ])) |
i+=k; |
else |
{ |
#if NSHIFT == 0 |
j=plen-1; |
|
#ifdef PIKE_DEBUG |
if(needle[j] != haystack[i]) |
Pike_fatal("T2BM failed!\n"); |
#endif |
|
#else |
i++; |
j=plen; |
#endif |
|
while(needle[--j] == haystack[--i]) |
{ |
if(!j) |
{ |
if(nlen > plen) |
{ |
if(!NameNH(MEMCMP)(needle+plen, |
haystack+i+plen, nlen-plen)) |
{ |
return haystack+i; |
}else{ |
|
i+=plen; |
goto restart; |
} |
}else{ |
return haystack+i; |
} |
} |
} |
|
i+= |
(s->d1[ NameNH(BMHASH)(haystack[i]) ] >= s->d2[j]) ? |
(s->d1[ NameNH(BMHASH)(haystack[i]) ]): |
(s->d2[j]); |
} |
} |
return 0; |
} |
|
|
HCHAR *NameNH(hubbe_search)(struct hubbe_searcher *s, |
HCHAR *haystack, |
ptrdiff_t haystacklen) |
{ |
NCHAR *needle = NEEDLE; |
ptrdiff_t nlen = NEEDLELEN; |
size_t hsize = s->hsize; |
size_t max = s->max; |
|
INT32 tmp, h; |
HCHAR *q, *end; |
register struct hubbe_search_link *ptr; |
|
end=haystack+haystacklen; |
q=haystack + max - 4; |
|
NameH(HUBBE_ALIGN)(q); |
|
for(;q<=(HCHAR*)(((char *)end)-sizeof(INT32));q+=max) |
{ |
h=tmp=NameH(GET_4_ALIGNED_CHARS)(q); |
|
h+=h>>7; |
h+=h>>17; |
h&=hsize; |
|
for(ptr=s->set[h];ptr;ptr=ptr->next) |
{ |
HCHAR *where; |
|
if(ptr->key != tmp) continue; |
|
where=q-ptr->offset; |
|
|
|
|
if(where<haystack) continue; |
|
if(where+nlen>end) return 0; |
|
if(!NameNH(MEMCMP)(needle,where,nlen)) |
return where; |
} |
} |
return 0; |
} |
|
|