// 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 <>---find string segment INDEX strstr ANSI_SYNOPSIS #include char *strstr(const char *<[s1]>, const char *<[s2]>); TRAD_SYNOPSIS #include 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 <> is ANSI C. <> requires no supporting OS subroutines. QUICKREF strstr ansi pure */ #include "_ansi.h" #include #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 */ }