1*09d4459fSDaniel Fojt /* Copyright (C) 1991-1994, 1996-1998, 2000, 2004, 2007-2020 Free Software
2dc7c36e4SJohn Marino Foundation, Inc.
3dc7c36e4SJohn Marino This file is part of the GNU C Library.
4dc7c36e4SJohn Marino
5dc7c36e4SJohn Marino This program is free software; you can redistribute it and/or modify
6dc7c36e4SJohn Marino it under the terms of the GNU General Public License as published by
7dc7c36e4SJohn Marino the Free Software Foundation; either version 3, or (at your option)
8dc7c36e4SJohn Marino any later version.
9dc7c36e4SJohn Marino
10dc7c36e4SJohn Marino This program is distributed in the hope that it will be useful,
11dc7c36e4SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
12dc7c36e4SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13dc7c36e4SJohn Marino GNU General Public License for more details.
14dc7c36e4SJohn Marino
15dc7c36e4SJohn Marino You should have received a copy of the GNU General Public License along
16*09d4459fSDaniel Fojt with this program; if not, see <https://www.gnu.org/licenses/>. */
17dc7c36e4SJohn Marino
18dc7c36e4SJohn Marino /* This particular implementation was written by Eric Blake, 2008. */
19dc7c36e4SJohn Marino
20dc7c36e4SJohn Marino #ifndef _LIBC
21dc7c36e4SJohn Marino # include <config.h>
22dc7c36e4SJohn Marino #endif
23dc7c36e4SJohn Marino
24dc7c36e4SJohn Marino /* Specification of strstr. */
25dc7c36e4SJohn Marino #include <string.h>
26dc7c36e4SJohn Marino
27dc7c36e4SJohn Marino #include <stdbool.h>
28dc7c36e4SJohn Marino
29dc7c36e4SJohn Marino #define RETURN_TYPE char *
30dc7c36e4SJohn Marino #define AVAILABLE(h, h_l, j, n_l) \
31dc7c36e4SJohn Marino (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \
32dc7c36e4SJohn Marino && ((h_l) = (j) + (n_l)))
33dc7c36e4SJohn Marino #include "str-two-way.h"
34dc7c36e4SJohn Marino
35dc7c36e4SJohn Marino /* Return the first occurrence of NEEDLE in HAYSTACK. Return HAYSTACK
36dc7c36e4SJohn Marino if NEEDLE is empty, otherwise NULL if NEEDLE is not found in
37dc7c36e4SJohn Marino HAYSTACK. */
38dc7c36e4SJohn Marino char *
strstr(const char * haystack_start,const char * needle_start)39dc7c36e4SJohn Marino strstr (const char *haystack_start, const char *needle_start)
40dc7c36e4SJohn Marino {
41dc7c36e4SJohn Marino const char *haystack = haystack_start;
42dc7c36e4SJohn Marino const char *needle = needle_start;
43dc7c36e4SJohn Marino size_t needle_len; /* Length of NEEDLE. */
44dc7c36e4SJohn Marino size_t haystack_len; /* Known minimum length of HAYSTACK. */
45dc7c36e4SJohn Marino bool ok = true; /* True if NEEDLE is prefix of HAYSTACK. */
46dc7c36e4SJohn Marino
47dc7c36e4SJohn Marino /* Determine length of NEEDLE, and in the process, make sure
48dc7c36e4SJohn Marino HAYSTACK is at least as long (no point processing all of a long
49dc7c36e4SJohn Marino NEEDLE if HAYSTACK is too short). */
50dc7c36e4SJohn Marino while (*haystack && *needle)
51dc7c36e4SJohn Marino ok &= *haystack++ == *needle++;
52dc7c36e4SJohn Marino if (*needle)
53dc7c36e4SJohn Marino return NULL;
54dc7c36e4SJohn Marino if (ok)
55dc7c36e4SJohn Marino return (char *) haystack_start;
56dc7c36e4SJohn Marino
57dc7c36e4SJohn Marino /* Reduce the size of haystack using strchr, since it has a smaller
58dc7c36e4SJohn Marino linear coefficient than the Two-Way algorithm. */
59dc7c36e4SJohn Marino needle_len = needle - needle_start;
60dc7c36e4SJohn Marino haystack = strchr (haystack_start + 1, *needle_start);
61dc7c36e4SJohn Marino if (!haystack || __builtin_expect (needle_len == 1, 0))
62dc7c36e4SJohn Marino return (char *) haystack;
63dc7c36e4SJohn Marino needle -= needle_len;
64dc7c36e4SJohn Marino haystack_len = (haystack > haystack_start + needle_len ? 1
65dc7c36e4SJohn Marino : needle_len + haystack_start - haystack);
66dc7c36e4SJohn Marino
67dc7c36e4SJohn Marino /* Perform the search. Abstract memory is considered to be an array
68dc7c36e4SJohn Marino of 'unsigned char' values, not an array of 'char' values. See
69dc7c36e4SJohn Marino ISO C 99 section 6.2.6.1. */
70dc7c36e4SJohn Marino if (needle_len < LONG_NEEDLE_THRESHOLD)
71dc7c36e4SJohn Marino return two_way_short_needle ((const unsigned char *) haystack,
72dc7c36e4SJohn Marino haystack_len,
73dc7c36e4SJohn Marino (const unsigned char *) needle, needle_len);
74dc7c36e4SJohn Marino return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
75dc7c36e4SJohn Marino (const unsigned char *) needle, needle_len);
76dc7c36e4SJohn Marino }
77dc7c36e4SJohn Marino
78dc7c36e4SJohn Marino #undef LONG_NEEDLE_THRESHOLD
79