source: trunk/libs/newlib/src/newlib/libc/string/memmem.c @ 577

Last change on this file since 577 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 3.0 KB
Line 
1/* Byte-wise substring search, using the Two-Way algorithm.
2 * Copyright (C) 2008 Eric Blake
3 * Permission to use, copy, modify, and distribute this software
4 * is freely granted, provided that this notice is preserved.
5 */
6
7/*
8FUNCTION
9        <<memmem>>---find memory segment
10
11INDEX
12        memmem
13
14SYNOPSIS
15        #include <string.h>
16        char *memmem(const void *<[s1]>, size_t <[l1]>, const void *<[s2]>,
17                     size_t <[l2]>);
18
19DESCRIPTION
20
21        Locates the first occurrence in the memory region pointed to
22        by <[s1]> with length <[l1]> of the sequence of bytes pointed
23        to by <[s2]> of length <[l2]>.  If you already know the
24        lengths of your haystack and needle, <<memmem>> can be much
25        faster than <<strstr>>.
26
27RETURNS
28        Returns a pointer to the located segment, or a null pointer if
29        <[s2]> is not found. If <[l2]> is 0, <[s1]> is returned.
30
31PORTABILITY
32<<memmem>> is a newlib extension.
33
34<<memmem>> requires no supporting OS subroutines.
35
36QUICKREF
37        memmem pure
38*/
39
40#include <string.h>
41
42#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
43# define RETURN_TYPE void *
44# define AVAILABLE(h, h_l, j, n_l) ((j) <= (h_l) - (n_l))
45# include "str-two-way.h"
46#endif
47
48void *
49memmem (const void *haystack_start,
50        size_t haystack_len,
51        const void *needle_start,
52        size_t needle_len)
53{
54  /* Abstract memory is considered to be an array of 'unsigned char' values,
55     not an array of 'char' values.  See ISO C 99 section 6.2.6.1.  */
56  const unsigned char *haystack = (const unsigned char *) haystack_start;
57  const unsigned char *needle = (const unsigned char *) needle_start;
58
59  if (needle_len == 0)
60    /* The first occurrence of the empty string is deemed to occur at
61       the beginning of the string.  */
62    return (void *) haystack;
63
64#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
65
66  /* Less code size, but quadratic performance in the worst case.  */
67  while (needle_len <= haystack_len)
68    {
69      if (!memcmp (haystack, needle, needle_len))
70        return (void *) haystack;
71      haystack++;
72      haystack_len--;
73    }
74  return NULL;
75
76#else /* compilation for speed */
77
78  /* Larger code size, but guaranteed linear performance.  */
79
80  /* Sanity check, otherwise the loop might search through the whole
81     memory.  */
82  if (haystack_len < needle_len)
83    return NULL;
84
85  /* Use optimizations in memchr when possible, to reduce the search
86     size of haystack using a linear algorithm with a smaller
87     coefficient.  However, avoid memchr for long needles, since we
88     can often achieve sublinear performance.  */
89  if (needle_len < LONG_NEEDLE_THRESHOLD)
90    {
91      haystack = memchr (haystack, *needle, haystack_len);
92      if (!haystack || needle_len == 1)
93        return (void *) haystack;
94      haystack_len -= haystack - (const unsigned char *) haystack_start;
95      if (haystack_len < needle_len)
96        return NULL;
97      return two_way_short_needle (haystack, haystack_len, needle, needle_len);
98    }
99  return two_way_long_needle (haystack, haystack_len, needle, needle_len);
100#endif /* compilation for speed */
101}
Note: See TracBrowser for help on using the repository browser.