| // SPDX-License-Identifier: BSD-3-Clause |
| /* |
| * Copyright (c) 1994-2009 Red Hat, Inc. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * 3. Neither the name of the copyright holder nor the names of its |
| * contributors may be used to endorse or promote products derived from this |
| * software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /* |
| FUNCTION |
| <<strstr>>---find string segment |
| |
| INDEX |
| strstr |
| |
| ANSI_SYNOPSIS |
| #include <string.h> |
| char *strstr(const char *<[s1]>, const char *<[s2]>); |
| |
| TRAD_SYNOPSIS |
| #include <string.h> |
| char *strstr(<[s1]>, <[s2]>) |
| char *<[s1]>; |
| char *<[s2]>; |
| |
| DESCRIPTION |
| Locates the first occurrence in the string pointed to by <[s1]> of |
| the sequence of characters in the string pointed to by <[s2]> |
| (excluding the terminating null character). |
| |
| RETURNS |
| Returns a pointer to the located string segment, or a null |
| pointer if the string <[s2]> is not found. If <[s2]> points to |
| a string with zero length, <[s1]> is returned. |
| |
| PORTABILITY |
| <<strstr>> is ANSI C. |
| |
| <<strstr>> requires no supporting OS subroutines. |
| |
| QUICKREF |
| strstr ansi pure |
| */ |
| |
| #include "_ansi.h" |
| #include <string.h> |
| |
| #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) |
| # define RETURN_TYPE char * |
| # define AVAILABLE(h, h_l, j, n_l) \ |
| (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \ |
| && ((h_l) = (j) + (n_l))) |
| # include "str-two-way.h" |
| #endif |
| |
| char * |
| _DEFUN (strstr, (searchee, lookfor), |
| _CONST char *searchee _AND |
| _CONST char *lookfor) |
| { |
| #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) |
| |
| /* Less code size, but quadratic performance in the worst case. */ |
| if (*searchee == 0) |
| { |
| if (*lookfor) |
| return (char *) NULL; |
| return (char *) searchee; |
| } |
| |
| while (*searchee) |
| { |
| size_t i; |
| i = 0; |
| |
| while (1) |
| { |
| if (lookfor[i] == 0) |
| { |
| return (char *) searchee; |
| } |
| |
| if (lookfor[i] != searchee[i]) |
| { |
| break; |
| } |
| i++; |
| } |
| searchee++; |
| } |
| |
| return (char *) NULL; |
| |
| #else /* compilation for speed */ |
| |
| /* Larger code size, but guaranteed linear performance. */ |
| const char *haystack = searchee; |
| const char *needle = lookfor; |
| size_t needle_len; /* Length of NEEDLE. */ |
| size_t haystack_len; /* Known minimum length of HAYSTACK. */ |
| int ok = 1; /* True if NEEDLE is prefix of HAYSTACK. */ |
| |
| /* Determine length of NEEDLE, and in the process, make sure |
| HAYSTACK is at least as long (no point processing all of a long |
| NEEDLE if HAYSTACK is too short). */ |
| while (*haystack && *needle) |
| ok &= *haystack++ == *needle++; |
| if (*needle) |
| return NULL; |
| if (ok) |
| return (char *) searchee; |
| |
| /* Reduce the size of haystack using strchr, since it has a smaller |
| linear coefficient than the Two-Way algorithm. */ |
| needle_len = needle - lookfor; |
| haystack = strchr (searchee + 1, *lookfor); |
| if (!haystack || needle_len == 1) |
| return (char *) haystack; |
| haystack_len = (haystack > searchee + needle_len ? 1 |
| : needle_len + searchee - haystack); |
| |
| /* Perform the search. */ |
| if (needle_len < LONG_NEEDLE_THRESHOLD) |
| return two_way_short_needle ((const unsigned char *) haystack, |
| haystack_len, |
| (const unsigned char *) lookfor, needle_len); |
| return two_way_long_needle ((const unsigned char *) haystack, haystack_len, |
| (const unsigned char *) lookfor, needle_len); |
| #endif /* compilation for speed */ |
| } |