summaryrefslogtreecommitdiff
path: root/lib/memmem.c
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2004-10-04 11:25:57 +0000
committerBruno Haible <bruno@clisp.org>2004-10-04 11:25:57 +0000
commitec03ca352064740b271b27e0be2b562b687b4554 (patch)
treeda053ebccecbb395eda5724aad74d00d3a961a6c /lib/memmem.c
parent6c84ec765f4d737b28b2016fa273f8db6213b726 (diff)
downloadgnulib-ec03ca352064740b271b27e0be2b562b687b4554.tar.gz
New module 'memmem', from Simon Josefsson.
Diffstat (limited to 'lib/memmem.c')
-rw-r--r--lib/memmem.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/lib/memmem.c b/lib/memmem.c
new file mode 100644
index 0000000000..7a6e116fc4
--- /dev/null
+++ b/lib/memmem.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1991,92,93,94,96,97,98,2000,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <string.h>
+
+#ifndef _LIBC
+# define __builtin_expect(expr, val) (expr)
+#endif
+
+#undef memmem
+
+/* Return the first occurrence of NEEDLE in HAYSTACK. */
+void *
+memmem (haystack, haystack_len, needle, needle_len)
+ const void *haystack;
+ size_t haystack_len;
+ const void *needle;
+ size_t needle_len;
+{
+ const char *begin;
+ const char *const last_possible
+ = (const char *) haystack + haystack_len - needle_len;
+
+ if (needle_len == 0)
+ /* The first occurrence of the empty string is deemed to occur at
+ the beginning of the string. */
+ return (void *) haystack;
+
+ /* Sanity check, otherwise the loop might search through the whole
+ memory. */
+ if (__builtin_expect (haystack_len < needle_len, 0))
+ return NULL;
+
+ for (begin = (const char *) haystack; begin <= last_possible; ++begin)
+ if (begin[0] == ((const char *) needle)[0] &&
+ !memcmp ((const void *) &begin[1],
+ (const void *) ((const char *) needle + 1),
+ needle_len - 1))
+ return (void *) begin;
+
+ return NULL;
+}