Back to index

nagios-plugins  1.4.16
strstr.c
Go to the documentation of this file.
00001 /* Copyright (C) 1991, 1992, 1993, 1994, 1996, 1997, 1998, 2000, 2004, 2007,
00002    2008, 2009, 2010 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    This program is free software; you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 3, or (at your option)
00008    any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License along
00016    with this program; if not, write to the Free Software Foundation,
00017    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
00018 
00019 /* This particular implementation was written by Eric Blake, 2008.  */
00020 
00021 #ifndef _LIBC
00022 # include <config.h>
00023 #endif
00024 
00025 /* Specification of strstr.  */
00026 #include <string.h>
00027 
00028 #include <stdbool.h>
00029 
00030 #ifndef _LIBC
00031 # define __builtin_expect(expr, val)   (expr)
00032 #endif
00033 
00034 #define RETURN_TYPE char *
00035 #define AVAILABLE(h, h_l, j, n_l)                       \
00036   (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l))     \
00037    && ((h_l) = (j) + (n_l)))
00038 #include "str-two-way.h"
00039 
00040 /* Return the first occurrence of NEEDLE in HAYSTACK.  Return HAYSTACK
00041    if NEEDLE is empty, otherwise NULL if NEEDLE is not found in
00042    HAYSTACK.  */
00043 char *
00044 strstr (const char *haystack_start, const char *needle_start)
00045 {
00046   const char *haystack = haystack_start;
00047   const char *needle = needle_start;
00048   size_t needle_len; /* Length of NEEDLE.  */
00049   size_t haystack_len; /* Known minimum length of HAYSTACK.  */
00050   bool ok = true; /* True if NEEDLE is prefix of HAYSTACK.  */
00051 
00052   /* Determine length of NEEDLE, and in the process, make sure
00053      HAYSTACK is at least as long (no point processing all of a long
00054      NEEDLE if HAYSTACK is too short).  */
00055   while (*haystack && *needle)
00056     ok &= *haystack++ == *needle++;
00057   if (*needle)
00058     return NULL;
00059   if (ok)
00060     return (char *) haystack_start;
00061 
00062   /* Reduce the size of haystack using strchr, since it has a smaller
00063      linear coefficient than the Two-Way algorithm.  */
00064   needle_len = needle - needle_start;
00065   haystack = strchr (haystack_start + 1, *needle_start);
00066   if (!haystack || __builtin_expect (needle_len == 1, 0))
00067     return (char *) haystack;
00068   needle -= needle_len;
00069   haystack_len = (haystack > haystack_start + needle_len ? 1
00070                   : needle_len + haystack_start - haystack);
00071 
00072   /* Perform the search.  Abstract memory is considered to be an array
00073      of 'unsigned char' values, not an array of 'char' values.  See
00074      ISO C 99 section 6.2.6.1.  */
00075   if (needle_len < LONG_NEEDLE_THRESHOLD)
00076     return two_way_short_needle ((const unsigned char *) haystack,
00077                                  haystack_len,
00078                                  (const unsigned char *) needle, needle_len);
00079   return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
00080                               (const unsigned char *) needle, needle_len);
00081 }
00082 
00083 #undef LONG_NEEDLE_THRESHOLD