Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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