3 #define MAX(a,b) ((a)>(b)?(a):(b))
4 #define MIN(a,b) ((a)<(b)?(a):(b))
6 static wchar_t *twoway_wcsstr(const wchar_t *h
, const wchar_t *n
)
9 size_t l
, ip
, jp
, k
, p
, ms
, p0
, mem
, mem0
;
11 /* Computing length of needle */
12 for (l
=0; n
[l
] && h
[l
]; l
++);
13 if (n
[l
]) return 0; /* hit the end of h */
15 /* Compute maximal suffix */
16 ip
= -1; jp
= 0; k
= p
= 1;
18 if (n
[ip
+k
] == n
[jp
+k
]) {
23 } else if (n
[ip
+k
] > n
[jp
+k
]) {
35 /* And with the opposite comparison */
36 ip
= -1; jp
= 0; k
= p
= 1;
38 if (n
[ip
+k
] == n
[jp
+k
]) {
43 } else if (n
[ip
+k
] < n
[jp
+k
]) {
52 if (ip
+1 > ms
+1) ms
= ip
;
55 /* Periodic needle? */
56 if (wmemcmp(n
, n
+p
, ms
+1)) {
58 p
= MAX(ms
, l
-ms
-1) + 1;
62 /* Initialize incremental end-of-haystack pointer */
67 /* Update incremental end-of-haystack pointer */
69 /* Fast estimate for MIN(l,63) */
71 const wchar_t *z2
= wmemchr(z
, 0, grow
);
74 if (z
-h
< l
) return 0;
78 /* Compare right half */
79 for (k
=MAX(ms
+1,mem
); n
[k
] && n
[k
] == h
[k
]; k
++);
85 /* Compare left half */
86 for (k
=ms
+1; k
>mem
&& n
[k
-1] == h
[k
-1]; k
--);
87 if (k
<= mem
) return (wchar_t *)h
;
93 wchar_t *wcsstr(const wchar_t *restrict h
, const wchar_t *restrict n
)
95 /* Return immediately on empty needle or haystack */
96 if (!n
[0]) return (wchar_t *)h
;
99 /* Use faster algorithms for short needles */
101 if (!h
|| !n
[1]) return (wchar_t *)h
;
104 return twoway_wcsstr(h
, n
);