* gdb.java/jprint.exp: XFAIL printing of static class members
[deliverable/binutils-gdb.git] / gdb / gnulib / str-two-way.h
1 /* Byte-wise substring search, using the Two-Way algorithm.
2 Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Written by Eric Blake <ebb9@byu.net>, 2008.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation,
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19
20 /* Before including this file, you need to include <config.h> and
21 <string.h>, and define:
22 RESULT_TYPE A macro that expands to the return type.
23 AVAILABLE(h, h_l, j, n_l)
24 A macro that returns nonzero if there are
25 at least N_L bytes left starting at H[J].
26 H is 'unsigned char *', H_L, J, and N_L
27 are 'size_t'; H_L is an lvalue. For
28 NUL-terminated searches, H_L can be
29 modified each iteration to avoid having
30 to compute the end of H up front.
31
32 For case-insensitivity, you may optionally define:
33 CMP_FUNC(p1, p2, l) A macro that returns 0 iff the first L
34 characters of P1 and P2 are equal.
35 CANON_ELEMENT(c) A macro that canonicalizes an element right after
36 it has been fetched from one of the two strings.
37 The argument is an 'unsigned char'; the result
38 must be an 'unsigned char' as well.
39
40 This file undefines the macros documented above, and defines
41 LONG_NEEDLE_THRESHOLD.
42 */
43
44 #include <limits.h>
45 #include <stdint.h>
46
47 /* We use the Two-Way string matching algorithm, which guarantees
48 linear complexity with constant space. Additionally, for long
49 needles, we also use a bad character shift table similar to the
50 Boyer-Moore algorithm to achieve improved (potentially sub-linear)
51 performance.
52
53 See http://www-igm.univ-mlv.fr/~lecroq/string/node26.html#SECTION00260
54 and http://en.wikipedia.org/wiki/Boyer-Moore_string_search_algorithm
55 */
56
57 /* Point at which computing a bad-byte shift table is likely to be
58 worthwhile. Small needles should not compute a table, since it
59 adds (1 << CHAR_BIT) + NEEDLE_LEN computations of preparation for a
60 speedup no greater than a factor of NEEDLE_LEN. The larger the
61 needle, the better the potential performance gain. On the other
62 hand, on non-POSIX systems with CHAR_BIT larger than eight, the
63 memory required for the table is prohibitive. */
64 #if CHAR_BIT < 10
65 # define LONG_NEEDLE_THRESHOLD 32U
66 #else
67 # define LONG_NEEDLE_THRESHOLD SIZE_MAX
68 #endif
69
70 #define MAX(a, b) ((a < b) ? (b) : (a))
71
72 #ifndef CANON_ELEMENT
73 # define CANON_ELEMENT(c) c
74 #endif
75 #ifndef CMP_FUNC
76 # define CMP_FUNC memcmp
77 #endif
78
79 /* Perform a critical factorization of NEEDLE, of length NEEDLE_LEN.
80 Return the index of the first byte in the right half, and set
81 *PERIOD to the global period of the right half.
82
83 The global period of a string is the smallest index (possibly its
84 length) at which all remaining bytes in the string are repetitions
85 of the prefix (the last repetition may be a subset of the prefix).
86
87 When NEEDLE is factored into two halves, a local period is the
88 length of the smallest word that shares a suffix with the left half
89 and shares a prefix with the right half. All factorizations of a
90 non-empty NEEDLE have a local period of at least 1 and no greater
91 than NEEDLE_LEN.
92
93 A critical factorization has the property that the local period
94 equals the global period. All strings have at least one critical
95 factorization with the left half smaller than the global period.
96
97 Given an ordered alphabet, a critical factorization can be computed
98 in linear time, with 2 * NEEDLE_LEN comparisons, by computing the
99 larger of two ordered maximal suffixes. The ordered maximal
100 suffixes are determined by lexicographic comparison of
101 periodicity. */
102 static size_t
103 critical_factorization (const unsigned char *needle, size_t needle_len,
104 size_t *period)
105 {
106 /* Index of last byte of left half, or SIZE_MAX. */
107 size_t max_suffix, max_suffix_rev;
108 size_t j; /* Index into NEEDLE for current candidate suffix. */
109 size_t k; /* Offset into current period. */
110 size_t p; /* Intermediate period. */
111 unsigned char a, b; /* Current comparison bytes. */
112
113 /* Invariants:
114 0 <= j < NEEDLE_LEN - 1
115 -1 <= max_suffix{,_rev} < j (treating SIZE_MAX as if it were signed)
116 min(max_suffix, max_suffix_rev) < global period of NEEDLE
117 1 <= p <= global period of NEEDLE
118 p == global period of the substring NEEDLE[max_suffix{,_rev}+1...j]
119 1 <= k <= p
120 */
121
122 /* Perform lexicographic search. */
123 max_suffix = SIZE_MAX;
124 j = 0;
125 k = p = 1;
126 while (j + k < needle_len)
127 {
128 a = CANON_ELEMENT (needle[j + k]);
129 b = CANON_ELEMENT (needle[max_suffix + k]);
130 if (a < b)
131 {
132 /* Suffix is smaller, period is entire prefix so far. */
133 j += k;
134 k = 1;
135 p = j - max_suffix;
136 }
137 else if (a == b)
138 {
139 /* Advance through repetition of the current period. */
140 if (k != p)
141 ++k;
142 else
143 {
144 j += p;
145 k = 1;
146 }
147 }
148 else /* b < a */
149 {
150 /* Suffix is larger, start over from current location. */
151 max_suffix = j++;
152 k = p = 1;
153 }
154 }
155 *period = p;
156
157 /* Perform reverse lexicographic search. */
158 max_suffix_rev = SIZE_MAX;
159 j = 0;
160 k = p = 1;
161 while (j + k < needle_len)
162 {
163 a = CANON_ELEMENT (needle[j + k]);
164 b = CANON_ELEMENT (needle[max_suffix_rev + k]);
165 if (b < a)
166 {
167 /* Suffix is smaller, period is entire prefix so far. */
168 j += k;
169 k = 1;
170 p = j - max_suffix_rev;
171 }
172 else if (a == b)
173 {
174 /* Advance through repetition of the current period. */
175 if (k != p)
176 ++k;
177 else
178 {
179 j += p;
180 k = 1;
181 }
182 }
183 else /* a < b */
184 {
185 /* Suffix is larger, start over from current location. */
186 max_suffix_rev = j++;
187 k = p = 1;
188 }
189 }
190
191 /* Choose the longer suffix. Return the first byte of the right
192 half, rather than the last byte of the left half. */
193 if (max_suffix_rev + 1 < max_suffix + 1)
194 return max_suffix + 1;
195 *period = p;
196 return max_suffix_rev + 1;
197 }
198
199 /* Return the first location of non-empty NEEDLE within HAYSTACK, or
200 NULL. HAYSTACK_LEN is the minimum known length of HAYSTACK. This
201 method is optimized for NEEDLE_LEN < LONG_NEEDLE_THRESHOLD.
202 Performance is guaranteed to be linear, with an initialization cost
203 of 2 * NEEDLE_LEN comparisons.
204
205 If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at
206 most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching.
207 If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 *
208 HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. */
209 static RETURN_TYPE
210 two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
211 const unsigned char *needle, size_t needle_len)
212 {
213 size_t i; /* Index into current byte of NEEDLE. */
214 size_t j; /* Index into current window of HAYSTACK. */
215 size_t period; /* The period of the right half of needle. */
216 size_t suffix; /* The index of the right half of needle. */
217
218 /* Factor the needle into two halves, such that the left half is
219 smaller than the global period, and the right half is
220 periodic (with a period as large as NEEDLE_LEN - suffix). */
221 suffix = critical_factorization (needle, needle_len, &period);
222
223 /* Perform the search. Each iteration compares the right half
224 first. */
225 if (CMP_FUNC (needle, needle + period, suffix) == 0)
226 {
227 /* Entire needle is periodic; a mismatch can only advance by the
228 period, so use memory to avoid rescanning known occurrences
229 of the period. */
230 size_t memory = 0;
231 j = 0;
232 while (AVAILABLE (haystack, haystack_len, j, needle_len))
233 {
234 /* Scan for matches in right half. */
235 i = MAX (suffix, memory);
236 while (i < needle_len && (CANON_ELEMENT (needle[i])
237 == CANON_ELEMENT (haystack[i + j])))
238 ++i;
239 if (needle_len <= i)
240 {
241 /* Scan for matches in left half. */
242 i = suffix - 1;
243 while (memory < i + 1 && (CANON_ELEMENT (needle[i])
244 == CANON_ELEMENT (haystack[i + j])))
245 --i;
246 if (i + 1 < memory + 1)
247 return (RETURN_TYPE) (haystack + j);
248 /* No match, so remember how many repetitions of period
249 on the right half were scanned. */
250 j += period;
251 memory = needle_len - period;
252 }
253 else
254 {
255 j += i - suffix + 1;
256 memory = 0;
257 }
258 }
259 }
260 else
261 {
262 /* The two halves of needle are distinct; no extra memory is
263 required, and any mismatch results in a maximal shift. */
264 period = MAX (suffix, needle_len - suffix) + 1;
265 j = 0;
266 while (AVAILABLE (haystack, haystack_len, j, needle_len))
267 {
268 /* Scan for matches in right half. */
269 i = suffix;
270 while (i < needle_len && (CANON_ELEMENT (needle[i])
271 == CANON_ELEMENT (haystack[i + j])))
272 ++i;
273 if (needle_len <= i)
274 {
275 /* Scan for matches in left half. */
276 i = suffix - 1;
277 while (i != SIZE_MAX && (CANON_ELEMENT (needle[i])
278 == CANON_ELEMENT (haystack[i + j])))
279 --i;
280 if (i == SIZE_MAX)
281 return (RETURN_TYPE) (haystack + j);
282 j += period;
283 }
284 else
285 j += i - suffix + 1;
286 }
287 }
288 return NULL;
289 }
290
291 /* Return the first location of non-empty NEEDLE within HAYSTACK, or
292 NULL. HAYSTACK_LEN is the minimum known length of HAYSTACK. This
293 method is optimized for LONG_NEEDLE_THRESHOLD <= NEEDLE_LEN.
294 Performance is guaranteed to be linear, with an initialization cost
295 of 3 * NEEDLE_LEN + (1 << CHAR_BIT) operations.
296
297 If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at
298 most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching,
299 and sublinear performance O(HAYSTACK_LEN / NEEDLE_LEN) is possible.
300 If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 *
301 HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, and
302 sublinear performance is not possible. */
303 static RETURN_TYPE
304 two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
305 const unsigned char *needle, size_t needle_len)
306 {
307 size_t i; /* Index into current byte of NEEDLE. */
308 size_t j; /* Index into current window of HAYSTACK. */
309 size_t period; /* The period of the right half of needle. */
310 size_t suffix; /* The index of the right half of needle. */
311 size_t shift_table[1U << CHAR_BIT]; /* See below. */
312
313 /* Factor the needle into two halves, such that the left half is
314 smaller than the global period, and the right half is
315 periodic (with a period as large as NEEDLE_LEN - suffix). */
316 suffix = critical_factorization (needle, needle_len, &period);
317
318 /* Populate shift_table. For each possible byte value c,
319 shift_table[c] is the distance from the last occurrence of c to
320 the end of NEEDLE, or NEEDLE_LEN if c is absent from the NEEDLE.
321 shift_table[NEEDLE[NEEDLE_LEN - 1]] contains the only 0. */
322 for (i = 0; i < 1U << CHAR_BIT; i++)
323 shift_table[i] = needle_len;
324 for (i = 0; i < needle_len; i++)
325 shift_table[CANON_ELEMENT (needle[i])] = needle_len - i - 1;
326
327 /* Perform the search. Each iteration compares the right half
328 first. */
329 if (CMP_FUNC (needle, needle + period, suffix) == 0)
330 {
331 /* Entire needle is periodic; a mismatch can only advance by the
332 period, so use memory to avoid rescanning known occurrences
333 of the period. */
334 size_t memory = 0;
335 size_t shift;
336 j = 0;
337 while (AVAILABLE (haystack, haystack_len, j, needle_len))
338 {
339 /* Check the last byte first; if it does not match, then
340 shift to the next possible match location. */
341 shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
342 if (0 < shift)
343 {
344 if (memory && shift < period)
345 {
346 /* Since needle is periodic, but the last period has
347 a byte out of place, there can be no match until
348 after the mismatch. */
349 shift = needle_len - period;
350 memory = 0;
351 }
352 j += shift;
353 continue;
354 }
355 /* Scan for matches in right half. The last byte has
356 already been matched, by virtue of the shift table. */
357 i = MAX (suffix, memory);
358 while (i < needle_len - 1 && (CANON_ELEMENT (needle[i])
359 == CANON_ELEMENT (haystack[i + j])))
360 ++i;
361 if (needle_len - 1 <= i)
362 {
363 /* Scan for matches in left half. */
364 i = suffix - 1;
365 while (memory < i + 1 && (CANON_ELEMENT (needle[i])
366 == CANON_ELEMENT (haystack[i + j])))
367 --i;
368 if (i + 1 < memory + 1)
369 return (RETURN_TYPE) (haystack + j);
370 /* No match, so remember how many repetitions of period
371 on the right half were scanned. */
372 j += period;
373 memory = needle_len - period;
374 }
375 else
376 {
377 j += i - suffix + 1;
378 memory = 0;
379 }
380 }
381 }
382 else
383 {
384 /* The two halves of needle are distinct; no extra memory is
385 required, and any mismatch results in a maximal shift. */
386 size_t shift;
387 period = MAX (suffix, needle_len - suffix) + 1;
388 j = 0;
389 while (AVAILABLE (haystack, haystack_len, j, needle_len))
390 {
391 /* Check the last byte first; if it does not match, then
392 shift to the next possible match location. */
393 shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
394 if (0 < shift)
395 {
396 j += shift;
397 continue;
398 }
399 /* Scan for matches in right half. The last byte has
400 already been matched, by virtue of the shift table. */
401 i = suffix;
402 while (i < needle_len - 1 && (CANON_ELEMENT (needle[i])
403 == CANON_ELEMENT (haystack[i + j])))
404 ++i;
405 if (needle_len - 1 <= i)
406 {
407 /* Scan for matches in left half. */
408 i = suffix - 1;
409 while (i != SIZE_MAX && (CANON_ELEMENT (needle[i])
410 == CANON_ELEMENT (haystack[i + j])))
411 --i;
412 if (i == SIZE_MAX)
413 return (RETURN_TYPE) (haystack + j);
414 j += period;
415 }
416 else
417 j += i - suffix + 1;
418 }
419 }
420 return NULL;
421 }
422
423 #undef AVAILABLE
424 #undef CANON_ELEMENT
425 #undef CMP_FUNC
426 #undef MAX
427 #undef RETURN_TYPE
This page took 0.041554 seconds and 4 git commands to generate.