sdk-core
v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Toggle main menu visibility
Loading...
Searching...
No Matches
strstr.c
1
#define SYSCLIB_DISABLE_BUILTINS
2
#include <
sysclib.h
>
3
#include <stdint.h>
4
5
static
char
*twobyte_strstr(
const
unsigned
char
*h,
const
unsigned
char
*n)
6
{
7
uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
8
for
(h++; *h && hw != nw; hw = hw<<8 | *++h);
9
return
*h ? (
char
*)h-1 : 0;
10
}
11
12
static
char
*threebyte_strstr(
const
unsigned
char
*h,
const
unsigned
char
*n)
13
{
14
uint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8;
15
uint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8;
16
for
(h+=2; *h && hw != nw; hw = (hw|*++h)<<8);
17
return
*h ? (
char
*)h-2 : 0;
18
}
19
20
static
char
*fourbyte_strstr(
const
unsigned
char
*h,
const
unsigned
char
*n)
21
{
22
uint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
23
uint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
24
for
(h+=3; *h && hw != nw; hw = hw<<8 | *++h);
25
return
*h ? (
char
*)h-3 : 0;
26
}
27
28
#define MAX(a,b) ((a)>(b)?(a):(b))
29
#define MIN(a,b) ((a)<(b)?(a):(b))
30
31
#define BITOP(a,b,op) \
32
((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
33
34
static
char
*twoway_strstr(
const
unsigned
char
*h,
const
unsigned
char
*n)
35
{
36
const
unsigned
char
*z;
37
size_t
l, ip, jp, k, p, ms, p0,
mem
, mem0;
38
size_t
byteset[32 /
sizeof
(size_t)] = { 0 };
39
size_t
shift[256];
40
41
/* Computing length of needle and fill shift table */
42
for
(l=0; n[l] && h[l]; l++)
43
BITOP(byteset, n[l], |=), shift[n[l]] = l+1;
44
if
(n[l])
return
0;
/* hit the end of h */
45
46
/* Compute maximal suffix */
47
ip = -1; jp = 0; k = p = 1;
48
while
(jp+k<l) {
49
if
(n[ip+k] == n[jp+k]) {
50
if
(k == p) {
51
jp += p;
52
k = 1;
53
}
else
k++;
54
}
else
if
(n[ip+k] > n[jp+k]) {
55
jp += k;
56
k = 1;
57
p = jp - ip;
58
}
else
{
59
ip = jp++;
60
k = p = 1;
61
}
62
}
63
ms = ip;
64
p0 = p;
65
66
/* And with the opposite comparison */
67
ip = -1; jp = 0; k = p = 1;
68
while
(jp+k<l) {
69
if
(n[ip+k] == n[jp+k]) {
70
if
(k == p) {
71
jp += p;
72
k = 1;
73
}
else
k++;
74
}
else
if
(n[ip+k] < n[jp+k]) {
75
jp += k;
76
k = 1;
77
p = jp - ip;
78
}
else
{
79
ip = jp++;
80
k = p = 1;
81
}
82
}
83
if
(ip+1 > ms+1) ms = ip;
84
else
p = p0;
85
86
/* Periodic needle? */
87
if
(memcmp(n, n+p, ms+1)) {
88
mem0 = 0;
89
p = MAX(ms, l-ms-1) + 1;
90
}
else
mem0 = l-p;
91
mem
= 0;
92
93
/* Initialize incremental end-of-haystack pointer */
94
z = h;
95
96
/* Search loop */
97
for
(;;) {
98
/* Update incremental end-of-haystack pointer */
99
if
((
size_t
)(z-h) < l) {
100
/* Fast estimate for MAX(l,63) */
101
size_t
grow = l | 63;
102
const
unsigned
char
*z2 = memchr(z, 0, grow);
103
if
(z2) {
104
z = z2;
105
if
((
size_t
)(z-h) < l)
return
0;
106
}
else
z += grow;
107
}
108
109
/* Check last byte first; advance by shift on mismatch */
110
if
(BITOP(byteset, h[l-1], &)) {
111
k = l-shift[h[l-1]];
112
if
(k) {
113
if
(k <
mem
) k =
mem
;
114
h += k;
115
mem
= 0;
116
continue
;
117
}
118
}
else
{
119
h += l;
120
mem
= 0;
121
continue
;
122
}
123
124
/* Compare right half */
125
for
(k=MAX(ms+1,
mem
); n[k] && n[k] == h[k]; k++);
126
if
(n[k]) {
127
h += k-ms;
128
mem
= 0;
129
continue
;
130
}
131
/* Compare left half */
132
for
(k=ms+1; k>
mem
&& n[k-1] == h[k-1]; k--);
133
if
(k <=
mem
)
return
(
char
*)h;
134
h += p;
135
mem
= mem0;
136
}
137
}
138
139
char
*strstr(
const
char
*h,
const
char
*n)
140
{
141
/* Return immediately on empty needle */
142
if
(!n[0])
return
(
char
*)h;
143
144
/* Use faster algorithms for short needles */
145
h = strchr(h, *n);
146
if
(!h || !n[1])
return
(
char
*)h;
147
if
(!h[1])
return
0;
148
if
(!n[2])
return
twobyte_strstr((
void
*)h, (
void
*)n);
149
if
(!h[2])
return
0;
150
if
(!n[3])
return
threebyte_strstr((
void
*)h, (
void
*)n);
151
if
(!h[3])
return
0;
152
if
(!n[4])
return
fourbyte_strstr((
void
*)h, (
void
*)n);
153
154
return
twoway_strstr((
void
*)h, (
void
*)n);
155
}
mem
Definition
mem.c:336
sysclib.h
core
sysclib
src
musl
string
strstr.c
Generated by
1.18.0