Browse Source

memmem: Trivial module to provide memmem() function

glibc includes a memmem() function which, by analogy with strstr()
searches for a byte sequence within a larger byte sequence.  The function
isn't standard, however, so other C libraries may not include it.

This adds a trivial module providing the memmem() function, if the C
library doesn't already do so.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
David Gibson 11 years ago
parent
commit
1db16ab68e
6 changed files with 89 additions and 0 deletions
  1. 1 0
      Makefile-ccan
  2. 1 0
      ccan/memmem/LICENSE
  3. 28 0
      ccan/memmem/_info
  4. 25 0
      ccan/memmem/memmem.c
  5. 14 0
      ccan/memmem/memmem.h
  6. 20 0
      ccan/memmem/test/run.c

+ 1 - 0
Makefile-ccan

@@ -68,6 +68,7 @@ MODS_WITH_SRC := antithread \
 	likely \
 	likely \
 	list \
 	list \
 	md4 \
 	md4 \
+	memmem \
 	net \
 	net \
 	nfs \
 	nfs \
 	noerr \
 	noerr \

+ 1 - 0
ccan/memmem/LICENSE

@@ -0,0 +1 @@
+../../licenses/CC0

+ 28 - 0
ccan/memmem/_info

@@ -0,0 +1,28 @@
+#include <string.h>
+#include "config.h"
+
+/**
+ * memmem - Trivial module providing a memmem() implementation
+ *
+ * This code implements memmem() if it's not alreayd available in the
+ * C library.
+ *
+ * License: CC0
+ */
+int main(int argc, char *argv[])
+{
+	/* Expect exactly one argument */
+	if (argc != 2)
+		return 1;
+
+	if (strcmp(argv[1], "depends") == 0) {
+		return 0;
+	}
+
+	if (strcmp(argv[1], "testdepends") == 0) {
+		printf("ccan/array_size");
+		return 0;
+	}
+
+	return 1;
+}

+ 25 - 0
ccan/memmem/memmem.c

@@ -0,0 +1,25 @@
+/* CC0 (Public domain) - see LICENSE file for details */
+
+#include <string.h>
+#include <ccan/memmem/memmem.h>
+
+#if !HAVE_MEMMEM
+void *memmem(const void *haystack, size_t haystacklen,
+	     const void *needle, size_t needlelen)
+{
+	const char *p;
+
+	if (needlelen > haystacklen)
+		return NULL;
+
+	p = haystack;
+
+	for (p = haystack;
+	     (p + needlelen) <= (haystack + haystacklen);
+	     p++)
+		if (memcmp(p, needle, needlelen) == 0)
+			return (void *)p;
+
+	return NULL;
+}
+#endif

+ 14 - 0
ccan/memmem/memmem.h

@@ -0,0 +1,14 @@
+/* CC0 (Public domain) - see LICENSE file for details */
+#ifndef CCAN_MEMMEM_H
+#define CCAN_MEMMEM_H
+
+#include "config.h"
+
+#include <string.h>
+
+#if !HAVE_MEMMEM
+void *memmem(const void *haystack, size_t haystacklen,
+	     const void *needle, size_t needlelen);
+#endif
+
+#endif /* CCAN_MEMMEM_H */

+ 20 - 0
ccan/memmem/test/run.c

@@ -0,0 +1,20 @@
+#include <ccan/array_size/array_size.h>
+#include <ccan/memmem/memmem.h>
+#include <ccan/tap/tap.h>
+
+int main(void)
+{
+	char haystack1[] = "abcd\0efgh";
+	char needle1[] = "ab";
+	char needle2[] = "d\0e";
+
+	/* This is how many tests you plan to run */
+	plan_tests(3);
+
+	ok1(memmem(haystack1, sizeof(haystack1), needle1, 2) == haystack1);
+	ok1(memmem(haystack1, sizeof(haystack1), needle1, 3) == NULL);
+	ok1(memmem(haystack1, sizeof(haystack1), needle2, 3) == (haystack1 + 3));
+
+	/* This exits depending on whether all tests passed */
+	return exit_status();
+}