strstr.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /* Return the offset of one string within another.
  2. Copyright (C) 1994-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. /* This particular implementation was written by Eric Blake, 2008. */
  16. #ifndef _LIBC
  17. # include <config.h>
  18. #endif
  19. /* Specification of strstr. */
  20. #include <string.h>
  21. #include <stdbool.h>
  22. #ifndef _LIBC
  23. # define __builtin_expect(expr, val) (expr)
  24. #endif
  25. #define RETURN_TYPE char *
  26. #define AVAILABLE(h, h_l, j, n_l) \
  27. (((j) + (n_l) <= (h_l)) \
  28. || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \
  29. (j) + (n_l) <= (h_l)))
  30. #define CHECK_EOL (1)
  31. #define RET0_IF_0(a) if (!a) goto ret0
  32. #define FASTSEARCH(S,C,N) (void*) strchr ((void*)(S), (C))
  33. #include "str-two-way.h"
  34. #undef strstr
  35. #ifndef STRSTR
  36. #define STRSTR strstr
  37. #endif
  38. /* Return the first occurrence of NEEDLE in HAYSTACK. Return HAYSTACK
  39. if NEEDLE is empty, otherwise NULL if NEEDLE is not found in
  40. HAYSTACK. */
  41. char *
  42. STRSTR (const char *haystack, const char *needle)
  43. {
  44. size_t needle_len; /* Length of NEEDLE. */
  45. size_t haystack_len; /* Known minimum length of HAYSTACK. */
  46. /* Handle empty NEEDLE special case. */
  47. if (needle[0] == '\0')
  48. return (char *) haystack;
  49. /* Skip until we find the first matching char from NEEDLE. */
  50. haystack = strchr (haystack, needle[0]);
  51. if (haystack == NULL || needle[1] == '\0')
  52. return (char *) haystack;
  53. /* Ensure HAYSTACK length is at least as long as NEEDLE length.
  54. Since a match may occur early on in a huge HAYSTACK, use strnlen
  55. and read ahead a few cachelines for improved performance. */
  56. needle_len = strlen (needle);
  57. haystack_len = __strnlen (haystack, needle_len + 256);
  58. if (haystack_len < needle_len)
  59. return NULL;
  60. /* Check whether we have a match. This improves performance since we avoid
  61. the initialization overhead of the two-way algorithm. */
  62. if (memcmp (haystack, needle, needle_len) == 0)
  63. return (char *) haystack;
  64. /* Perform the search. Abstract memory is considered to be an array
  65. of 'unsigned char' values, not an array of 'char' values. See
  66. ISO C 99 section 6.2.6.1. */
  67. if (needle_len < LONG_NEEDLE_THRESHOLD)
  68. return two_way_short_needle ((const unsigned char *) haystack,
  69. haystack_len,
  70. (const unsigned char *) needle, needle_len);
  71. return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
  72. (const unsigned char *) needle, needle_len);
  73. }
  74. libc_hidden_builtin_def (strstr)
  75. #undef LONG_NEEDLE_THRESHOLD