source: trunk/libs/newlib/src/newlib/libc/string/strstr.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: 2.8 KB
Line 
1/*
2FUNCTION
3        <<strstr>>---find string segment
4
5INDEX
6        strstr
7
8SYNOPSIS
9        #include <string.h>
10        char *strstr(const char *<[s1]>, const char *<[s2]>);
11
12DESCRIPTION
13        Locates the first occurrence in the string pointed to by <[s1]> of
14        the sequence of characters in the string pointed to by <[s2]>
15        (excluding the terminating null character).
16
17RETURNS
18        Returns a pointer to the located string segment, or a null
19        pointer if the string <[s2]> is not found. If <[s2]> points to
20        a string with zero length, <[s1]> is returned.
21
22PORTABILITY
23<<strstr>> is ANSI C.
24
25<<strstr>> requires no supporting OS subroutines.
26
27QUICKREF
28        strstr ansi pure
29*/
30
31#include <string.h>
32
33#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
34# define RETURN_TYPE char *
35# define AVAILABLE(h, h_l, j, n_l)                      \
36  (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l))     \
37   && ((h_l) = (j) + (n_l)))
38# include "str-two-way.h"
39#endif
40
41char *
42strstr (const char *searchee,
43        const char *lookfor)
44{
45#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
46
47  /* Less code size, but quadratic performance in the worst case.  */
48  if (*searchee == 0)
49    {
50      if (*lookfor)
51        return (char *) NULL;
52      return (char *) searchee;
53    }
54
55  while (*searchee)
56    {
57      size_t i;
58      i = 0;
59
60      while (1)
61        {
62          if (lookfor[i] == 0)
63            {
64              return (char *) searchee;
65            }
66
67          if (lookfor[i] != searchee[i])
68            {
69              break;
70            }
71          i++;
72        }
73      searchee++;
74    }
75
76  return (char *) NULL;
77
78#else /* compilation for speed */
79
80  /* Larger code size, but guaranteed linear performance.  */
81  const char *haystack = searchee;
82  const char *needle = lookfor;
83  size_t needle_len; /* Length of NEEDLE.  */
84  size_t haystack_len; /* Known minimum length of HAYSTACK.  */
85  int ok = 1; /* True if NEEDLE is prefix of HAYSTACK.  */
86
87  /* Determine length of NEEDLE, and in the process, make sure
88     HAYSTACK is at least as long (no point processing all of a long
89     NEEDLE if HAYSTACK is too short).  */
90  while (*haystack && *needle)
91    ok &= *haystack++ == *needle++;
92  if (*needle)
93    return NULL;
94  if (ok)
95    return (char *) searchee;
96
97  /* Reduce the size of haystack using strchr, since it has a smaller
98     linear coefficient than the Two-Way algorithm.  */
99  needle_len = needle - lookfor;
100  haystack = strchr (searchee + 1, *lookfor);
101  if (!haystack || needle_len == 1)
102    return (char *) haystack;
103  haystack_len = (haystack > searchee + needle_len ? 1
104                  : needle_len + searchee - haystack);
105
106  /* Perform the search.  */
107  if (needle_len < LONG_NEEDLE_THRESHOLD)
108    return two_way_short_needle ((const unsigned char *) haystack,
109                                 haystack_len,
110                                 (const unsigned char *) lookfor, needle_len);
111  return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
112                              (const unsigned char *) lookfor, needle_len);
113#endif /* compilation for speed */
114}
Note: See TracBrowser for help on using the repository browser.