Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | | - |
10 | | - |
11 | | - |
12 | | - |
13 | | - |
14 | | - |
15 | | - |
16 | | - |
17 | | - |
18 | #include <config.h> | - |
19 | | - |
20 | | - |
21 | #include <string.h> | - |
22 | | - |
23 | #include <stdbool.h> | - |
24 | #include <stddef.h> /* for NULL, in case a nonstandard string.h lacks it */ | - |
25 | | - |
26 | #include "malloca.h" | - |
27 | #include "mbuiter.h" | - |
28 | | - |
29 | | - |
30 | #define UNIT unsigned char | - |
31 | #define CANON_ELEMENT(c) c | - |
32 | #include "str-kmp.h" | - |
33 | | - |
34 | | - |
35 | | - |
36 | | - |
37 | | - |
38 | | - |
39 | static bool | - |
40 | knuth_morris_pratt_multibyte (const char *haystack, const char *needle, | - |
41 | const char **resultp) | - |
42 | { | - |
43 | size_t m = mbslen (needle); | - |
44 | mbchar_t *needle_mbchars; | - |
45 | size_t *table; | - |
46 | | - |
47 | | - |
48 | void *memory = nmalloca (m, sizeof (mbchar_t) + sizeof (size_t));TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
49 | void *table_memory; | - |
50 | if (memory == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
51 | return false; never executed: return 0 ; | 0 |
52 | needle_mbchars = memory; | - |
53 | table_memory = needle_mbchars + m; | - |
54 | table = table_memory; | - |
55 | | - |
56 | | - |
57 | { | - |
58 | mbui_iterator_t iter; | - |
59 | size_t j; | - |
60 | | - |
61 | j = 0; | - |
62 | for (mbui_init (iter, needle); mbui_avail (iter); mbui_advance (iter), j++)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
63 | mb_copy (&needle_mbchars[j], &mbui_cur (iter)); never executed: mb_copy (&needle_mbchars[j], &(iter).cur); | 0 |
64 | } | - |
65 | | - |
66 | | - |
67 | | - |
68 | | - |
69 | | - |
70 | | - |
71 | | - |
72 | | - |
73 | | - |
74 | | - |
75 | | - |
76 | | - |
77 | | - |
78 | | - |
79 | | - |
80 | | - |
81 | { | - |
82 | size_t i, j; | - |
83 | | - |
84 | | - |
85 | table[1] = 1; | - |
86 | j = 0; | - |
87 | | - |
88 | for (i = 2; i < m; i++)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
89 | { | - |
90 | | - |
91 | | - |
92 | | - |
93 | | - |
94 | mbchar_t *b = &needle_mbchars[i - 1]; | - |
95 | | - |
96 | for (;;) | - |
97 | { | - |
98 | | - |
99 | | - |
100 | | - |
101 | if (mb_equal (*b, needle_mbchars[j]))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
102 | { | - |
103 | | - |
104 | table[i] = i - ++j; | - |
105 | break; never executed: break; | 0 |
106 | } | - |
107 | | - |
108 | | - |
109 | | - |
110 | if (j == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
111 | { | - |
112 | | - |
113 | table[i] = i; | - |
114 | break; never executed: break; | 0 |
115 | } | - |
116 | | - |
117 | | - |
118 | | - |
119 | | - |
120 | | - |
121 | | - |
122 | | - |
123 | | - |
124 | | - |
125 | | - |
126 | | - |
127 | j = j - table[j]; | - |
128 | } never executed: end of block | 0 |
129 | | - |
130 | } never executed: end of block | 0 |
131 | } | - |
132 | | - |
133 | | - |
134 | { | - |
135 | size_t j; | - |
136 | mbui_iterator_t rhaystack; | - |
137 | mbui_iterator_t phaystack; | - |
138 | | - |
139 | *resultp = NULL; | - |
140 | j = 0; | - |
141 | mbui_init (rhaystack, haystack); | - |
142 | mbui_init (phaystack, haystack); | - |
143 | | - |
144 | while (mbui_avail (phaystack))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
145 | if (mb_equal (needle_mbchars[j], mbui_cur (phaystack)))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
146 | { | - |
147 | j++; | - |
148 | mbui_advance (phaystack); | - |
149 | if (j == m)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
150 | { | - |
151 | | - |
152 | *resultp = mbui_cur_ptr (rhaystack); | - |
153 | break; never executed: break; | 0 |
154 | } | - |
155 | } never executed: end of block | 0 |
156 | else if (j > 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
157 | { | - |
158 | | - |
159 | size_t count = table[j]; | - |
160 | j -= count; | - |
161 | for (; count > 0; count--)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
162 | { | - |
163 | if (!mbui_avail (rhaystack))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
164 | abort (); never executed: abort (); | 0 |
165 | mbui_advance (rhaystack); | - |
166 | } never executed: end of block | 0 |
167 | } never executed: end of block | 0 |
168 | else | - |
169 | { | - |
170 | | - |
171 | if (!mbui_avail (rhaystack))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
172 | abort (); never executed: abort (); | 0 |
173 | mbui_advance (rhaystack); | - |
174 | mbui_advance (phaystack); | - |
175 | } never executed: end of block | 0 |
176 | } | - |
177 | | - |
178 | freea (memory); | - |
179 | return true; never executed: return 1 ; | 0 |
180 | } | - |
181 | | - |
182 | | - |
183 | | - |
184 | char * | - |
185 | mbsstr (const char *haystack, const char *needle) | - |
186 | { | - |
187 | | - |
188 | | - |
189 | | - |
190 | | - |
191 | | - |
192 | if (MB_CUR_MAX > 1)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
193 | { | - |
194 | mbui_iterator_t iter_needle; | - |
195 | | - |
196 | mbui_init (iter_needle, needle); | - |
197 | if (mbui_avail (iter_needle))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
198 | { | - |
199 | | - |
200 | | - |
201 | | - |
202 | | - |
203 | | - |
204 | | - |
205 | | - |
206 | | - |
207 | | - |
208 | | - |
209 | | - |
210 | | - |
211 | | - |
212 | | - |
213 | bool try_kmp = true; | - |
214 | size_t outer_loop_count = 0; | - |
215 | size_t comparison_count = 0; | - |
216 | size_t last_ccount = 0; | - |
217 | mbui_iterator_t iter_needle_last_ccount; | - |
218 | | - |
219 | mbui_iterator_t iter_haystack; | - |
220 | | - |
221 | mbui_init (iter_needle_last_ccount, needle); | - |
222 | mbui_init (iter_haystack, haystack); | - |
223 | for (;; mbui_advance (iter_haystack)) | - |
224 | { | - |
225 | if (!mbui_avail (iter_haystack))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
226 | | - |
227 | return NULL; never executed: return ((void *)0) ; | 0 |
228 | | - |
229 | | - |
230 | | - |
231 | if (try_kmpTRUE | never evaluated | FALSE | never evaluated |
| 0 |
232 | && outer_loop_count >= 10TRUE | never evaluated | FALSE | never evaluated |
| 0 |
233 | && comparison_count >= 5 * outer_loop_count)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
234 | { | - |
235 | | - |
236 | | - |
237 | size_t count = comparison_count - last_ccount; | - |
238 | for (; | - |
239 | count > 0 && mbui_avail (iter_needle_last_ccount);TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
240 | count--) | - |
241 | mbui_advance (iter_needle_last_ccount); never executed: ((iter_needle_last_ccount).cur.ptr += (iter_needle_last_ccount).cur.bytes, (iter_needle_last_ccount).next_done = 0 ); | 0 |
242 | last_ccount = comparison_count; | - |
243 | if (!mbui_avail (iter_needle_last_ccount))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
244 | { | - |
245 | | - |
246 | const char *result; | - |
247 | bool success = | - |
248 | knuth_morris_pratt_multibyte (haystack, needle, | - |
249 | &result); | - |
250 | if (success)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
251 | return (char *) result; never executed: return (char *) result; | 0 |
252 | try_kmp = false; | - |
253 | } never executed: end of block | 0 |
254 | } never executed: end of block | 0 |
255 | | - |
256 | outer_loop_count++; | - |
257 | comparison_count++; | - |
258 | if (mb_equal (mbui_cur (iter_haystack), mbui_cur (iter_needle)))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
259 | | - |
260 | { | - |
261 | mbui_iterator_t rhaystack; | - |
262 | mbui_iterator_t rneedle; | - |
263 | | - |
264 | memcpy (&rhaystack, &iter_haystack, sizeof (mbui_iterator_t)); | - |
265 | mbui_advance (rhaystack); | - |
266 | | - |
267 | mbui_init (rneedle, needle); | - |
268 | if (!mbui_avail (rneedle))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
269 | abort (); never executed: abort (); | 0 |
270 | mbui_advance (rneedle); | - |
271 | | - |
272 | for (;; mbui_advance (rhaystack), mbui_advance (rneedle)) | - |
273 | { | - |
274 | if (!mbui_avail (rneedle))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
275 | | - |
276 | return (char *) mbui_cur_ptr (iter_haystack); never executed: return (char *) (iter_haystack).cur.ptr; | 0 |
277 | if (!mbui_avail (rhaystack))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
278 | | - |
279 | return NULL; never executed: return ((void *)0) ; | 0 |
280 | comparison_count++; | - |
281 | if (!mb_equal (mbui_cur (rhaystack), mbui_cur (rneedle)))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
282 | | - |
283 | break; never executed: break; | 0 |
284 | } never executed: end of block | 0 |
285 | } never executed: end of block | 0 |
286 | } never executed: end of block | 0 |
287 | } never executed: end of block | 0 |
288 | else | - |
289 | return (char *) haystack; never executed: return (char *) haystack; | 0 |
290 | } | - |
291 | else | - |
292 | { | - |
293 | if (*needle != '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
294 | { | - |
295 | | - |
296 | | - |
297 | | - |
298 | | - |
299 | | - |
300 | | - |
301 | | - |
302 | | - |
303 | | - |
304 | | - |
305 | | - |
306 | | - |
307 | | - |
308 | | - |
309 | bool try_kmp = true; | - |
310 | size_t outer_loop_count = 0; | - |
311 | size_t comparison_count = 0; | - |
312 | size_t last_ccount = 0; | - |
313 | const char *needle_last_ccount = needle; | - |
314 | | - |
315 | | - |
316 | | - |
317 | char b = *needle++; | - |
318 | | - |
319 | for (;; haystack++) | - |
320 | { | - |
321 | if (*haystack == '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
322 | | - |
323 | return NULL; never executed: return ((void *)0) ; | 0 |
324 | | - |
325 | | - |
326 | | - |
327 | if (try_kmpTRUE | never evaluated | FALSE | never evaluated |
| 0 |
328 | && outer_loop_count >= 10TRUE | never evaluated | FALSE | never evaluated |
| 0 |
329 | && comparison_count >= 5 * outer_loop_count)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
330 | { | - |
331 | | - |
332 | | - |
333 | if (needle_last_ccount != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
334 | { | - |
335 | needle_last_ccount += | - |
336 | strnlen (needle_last_ccount, | - |
337 | comparison_count - last_ccount); | - |
338 | if (*needle_last_ccount == '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
339 | needle_last_ccount = NULL; never executed: needle_last_ccount = ((void *)0) ; | 0 |
340 | last_ccount = comparison_count; | - |
341 | } never executed: end of block | 0 |
342 | if (needle_last_ccount == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
343 | { | - |
344 | | - |
345 | const unsigned char *result; | - |
346 | bool success = | - |
347 | knuth_morris_pratt ((const unsigned char *) haystack, | - |
348 | (const unsigned char *) (needle - 1), | - |
349 | strlen (needle - 1), | - |
350 | &result); | - |
351 | if (success)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
352 | return (char *) result; never executed: return (char *) result; | 0 |
353 | try_kmp = false; | - |
354 | } never executed: end of block | 0 |
355 | } never executed: end of block | 0 |
356 | | - |
357 | outer_loop_count++; | - |
358 | comparison_count++; | - |
359 | if (*haystack == b)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
360 | | - |
361 | { | - |
362 | const char *rhaystack = haystack + 1; | - |
363 | const char *rneedle = needle; | - |
364 | | - |
365 | for (;; rhaystack++, rneedle++) | - |
366 | { | - |
367 | if (*rneedle == '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
368 | | - |
369 | return (char *) haystack; never executed: return (char *) haystack; | 0 |
370 | if (*rhaystack == '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
371 | | - |
372 | return NULL; never executed: return ((void *)0) ; | 0 |
373 | comparison_count++; | - |
374 | if (*rhaystack != *rneedle)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
375 | | - |
376 | break; never executed: break; | 0 |
377 | } never executed: end of block | 0 |
378 | } never executed: end of block | 0 |
379 | } never executed: end of block | 0 |
380 | } never executed: end of block | 0 |
381 | else | - |
382 | return (char *) haystack; never executed: return (char *) haystack; | 0 |
383 | } | - |
384 | } | - |
| | |