aboutsummaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorRené Scharfe <rene.scharfe@lsrfire.ath.cx>2007-09-07 00:32:54 +0200
committerJunio C Hamano <gitster@pobox.com>2007-09-06 22:46:00 -0700
commitb21b9f1de313acb5550c070911ae58c735cdb451 (patch)
tree1c271b15eff9d772828cd634f3a1f6303bc49726 /compat
parent89b4256cfbb8d878cc4cd1104ac4865ba1f2a58e (diff)
downloadgit-b21b9f1de313acb5550c070911ae58c735cdb451.tar.gz
git-b21b9f1de313acb5550c070911ae58c735cdb451.tar.xz
add memmem()
memmem() is a nice GNU extension for searching a length limited string in another one. This compat version is based on the version found in glibc 2.2 (GPL 2); I only removed the optimization of checking the first char by hand, and generally tried to keep the code simple. We can add it back if memcmp shows up high in a profile, but for now I prefer to keep it (almost trivially) simple. Since I don't really know which platforms beside those with a glibc have their own memmem(), I used a heuristic: if NO_STRCASESTR is set, then NO_MEMMEM is set, too. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'compat')
-rw-r--r--compat/memmem.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/compat/memmem.c b/compat/memmem.c
new file mode 100644
index 000000000..cd0d87736
--- /dev/null
+++ b/compat/memmem.c
@@ -0,0 +1,29 @@
+#include "../git-compat-util.h"
+
+void *gitmemmem(const void *haystack, size_t haystack_len,
+ const void *needle, size_t needle_len)
+{
+ const char *begin = haystack;
+ const char *last_possible = begin + haystack_len - needle_len;
+
+ /*
+ * The first occurrence of the empty string is deemed to occur at
+ * the beginning of the string.
+ */
+ if (needle_len == 0)
+ return (void *)begin;
+
+ /*
+ * Sanity check, otherwise the loop might search through the whole
+ * memory.
+ */
+ if (haystack_len < needle_len)
+ return NULL;
+
+ for (; begin <= last_possible; begin++) {
+ if (!memcmp(begin, needle, needle_len))
+ return (void *)begin;
+ }
+
+ return NULL;
+}