[ccan] [PATCH 1/2] memmem: Trivial module to provide memmem() function
David Gibson
david at gibson.dropbear.id.au
Sun Jun 15 02:11:25 EST 2014
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 at gibson.dropbear.id.au>
---
ccan/memmem/LICENSE | 1 +
ccan/memmem/_info | 28 ++++++++++++++++++++++++++++
ccan/memmem/memmem.c | 25 +++++++++++++++++++++++++
ccan/memmem/memmem.h | 14 ++++++++++++++
ccan/memmem/test/run.c | 20 ++++++++++++++++++++
5 files changed, 88 insertions(+)
create mode 120000 ccan/memmem/LICENSE
create mode 100644 ccan/memmem/_info
create mode 100644 ccan/memmem/memmem.c
create mode 100644 ccan/memmem/memmem.h
create mode 100644 ccan/memmem/test/run.c
diff --git a/ccan/memmem/LICENSE b/ccan/memmem/LICENSE
new file mode 120000
index 0000000..b7951da
--- /dev/null
+++ b/ccan/memmem/LICENSE
@@ -0,0 +1 @@
+../../licenses/CC0
\ No newline at end of file
diff --git a/ccan/memmem/_info b/ccan/memmem/_info
new file mode 100644
index 0000000..5c736a9
--- /dev/null
+++ b/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;
+}
diff --git a/ccan/memmem/memmem.c b/ccan/memmem/memmem.c
new file mode 100644
index 0000000..4d3c2e6
--- /dev/null
+++ b/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
diff --git a/ccan/memmem/memmem.h b/ccan/memmem/memmem.h
new file mode 100644
index 0000000..4da5394
--- /dev/null
+++ b/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 */
diff --git a/ccan/memmem/test/run.c b/ccan/memmem/test/run.c
new file mode 100644
index 0000000..af9aac5
--- /dev/null
+++ b/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();
+}
--
1.9.3
More information about the ccan
mailing list