Blame gl/memmem.c

Packit Service 4684c1
/* Copyright (C) 1991-1994, 1996-1998, 2000, 2004, 2007-2020 Free Software
Packit Service 4684c1
   Foundation, Inc.
Packit Service 4684c1
   This file is part of the GNU C Library.
Packit Service 4684c1
Packit Service 4684c1
   This program is free software; you can redistribute it and/or modify
Packit Service 4684c1
   it under the terms of the GNU Lesser General Public License as published by
Packit Service 4684c1
   the Free Software Foundation; either version 2.1, or (at your option)
Packit Service 4684c1
   any later version.
Packit Service 4684c1
Packit Service 4684c1
   This program is distributed in the hope that it will be useful,
Packit Service 4684c1
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 4684c1
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 4684c1
   GNU Lesser General Public License for more details.
Packit Service 4684c1
Packit Service 4684c1
   You should have received a copy of the GNU Lesser General Public License along
Packit Service 4684c1
   with this program; if not, see <https://www.gnu.org/licenses/>.  */
Packit Service 4684c1
Packit Service 4684c1
/* This particular implementation was written by Eric Blake, 2008.  */
Packit Service 4684c1
Packit Service 4684c1
#ifndef _LIBC
Packit Service 4684c1
# include <config.h>
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
/* Specification of memmem.  */
Packit Service 4684c1
#include <string.h>
Packit Service 4684c1
Packit Service 4684c1
#define RETURN_TYPE void *
Packit Service 4684c1
#define AVAILABLE(h, h_l, j, n_l) ((j) <= (h_l) - (n_l))
Packit Service 4684c1
#include "str-two-way.h"
Packit Service 4684c1
Packit Service 4684c1
/* Return the first occurrence of NEEDLE in HAYSTACK.  Return HAYSTACK
Packit Service 4684c1
   if NEEDLE_LEN is 0, otherwise NULL if NEEDLE is not found in
Packit Service 4684c1
   HAYSTACK.  */
Packit Service 4684c1
void *
Packit Service 4684c1
memmem (const void *haystack_start, size_t haystack_len,
Packit Service 4684c1
        const void *needle_start, size_t needle_len)
Packit Service 4684c1
{
Packit Service 4684c1
  /* Abstract memory is considered to be an array of 'unsigned char' values,
Packit Service 4684c1
     not an array of 'char' values.  See ISO C 99 section 6.2.6.1.  */
Packit Service 4684c1
  const unsigned char *haystack = (const unsigned char *) haystack_start;
Packit Service 4684c1
  const unsigned char *needle = (const unsigned char *) needle_start;
Packit Service 4684c1
Packit Service 4684c1
  if (needle_len == 0)
Packit Service 4684c1
    /* The first occurrence of the empty string is deemed to occur at
Packit Service 4684c1
       the beginning of the string.  */
Packit Service 4684c1
    return (void *) haystack;
Packit Service 4684c1
Packit Service 4684c1
  /* Sanity check, otherwise the loop might search through the whole
Packit Service 4684c1
     memory.  */
Packit Service 4684c1
  if (__builtin_expect (haystack_len < needle_len, 0))
Packit Service 4684c1
    return NULL;
Packit Service 4684c1
Packit Service 4684c1
  /* Use optimizations in memchr when possible, to reduce the search
Packit Service 4684c1
     size of haystack using a linear algorithm with a smaller
Packit Service 4684c1
     coefficient.  However, avoid memchr for long needles, since we
Packit Service 4684c1
     can often achieve sublinear performance.  */
Packit Service 4684c1
  if (needle_len < LONG_NEEDLE_THRESHOLD)
Packit Service 4684c1
    {
Packit Service 4684c1
      haystack = memchr (haystack, *needle, haystack_len);
Packit Service 4684c1
      if (!haystack || __builtin_expect (needle_len == 1, 0))
Packit Service 4684c1
        return (void *) haystack;
Packit Service 4684c1
      haystack_len -= haystack - (const unsigned char *) haystack_start;
Packit Service 4684c1
      if (haystack_len < needle_len)
Packit Service 4684c1
        return NULL;
Packit Service 4684c1
      return two_way_short_needle (haystack, haystack_len, needle, needle_len);
Packit Service 4684c1
    }
Packit Service 4684c1
  else
Packit Service 4684c1
    return two_way_long_needle (haystack, haystack_len, needle, needle_len);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
#undef LONG_NEEDLE_THRESHOLD