1 /* stringlib: fastsearch implementation */
3 #ifndef STRINGLIB_FASTSEARCH_H
4 #define STRINGLIB_FASTSEARCH_H
6 /* fast search/count implementation, based on a mix between boyer-
7 moore and horspool, with a few more bells and whistles on the top.
8 for some more background, see: http://effbot.org/stringlib */
10 /* note: fastsearch may access s[n], which isn't a problem when using
11 Python's ordinary string types, but may cause problems if you're
12 using this code in other contexts. also, the count mode returns -1
13 if there cannot possible be a match in the target string, and 0 if
14 it has actually checked for matches, but didn't find any. callers
20 Py_LOCAL_INLINE(Py_ssize_t
)
21 fastsearch(const STRINGLIB_CHAR
* s
, Py_ssize_t n
,
22 const STRINGLIB_CHAR
* p
, Py_ssize_t m
,
26 Py_ssize_t skip
, count
= 0;
27 Py_ssize_t i
, j
, mlast
, w
;
34 /* look for special cases */
38 /* use special case for 1-character strings */
39 if (mode
== FAST_COUNT
) {
40 for (i
= 0; i
< n
; i
++)
45 for (i
= 0; i
< n
; i
++)
54 /* create compressed boyer-moore delta 1 table */
56 /* process pattern[:-1] */
57 for (mask
= i
= 0; i
< mlast
; i
++) {
58 mask
|= (1 << (p
[i
] & 0x1F));
62 /* process pattern[-1] outside the loop */
63 mask
|= (1 << (p
[mlast
] & 0x1F));
65 for (i
= 0; i
<= w
; i
++) {
66 /* note: using mlast in the skip path slows things down on x86 */
67 if (s
[i
+m
-1] == p
[m
-1]) {
69 for (j
= 0; j
< mlast
; j
++)
74 if (mode
!= FAST_COUNT
)
80 /* miss: check if next character is part of pattern */
81 if (!(mask
& (1 << (s
[i
+m
] & 0x1F))))
86 /* skip: check if next character is part of pattern */
87 if (!(mask
& (1 << (s
[i
+m
] & 0x1F))))
92 if (mode
!= FAST_COUNT
)
102 indent-tabs-mode: nil