libreplace: some systems don't have memmem()
authorAndrew Tridgell <tridge@samba.org>
Fri, 1 Jan 2010 23:01:11 +0000 (10:01 +1100)
committerKarolin Seeger <kseeger@samba.org>
Fri, 14 Dec 2012 09:01:37 +0000 (10:01 +0100)
added rep_memmem() and a testsuite
(cherry picked from commit fef3c910da421e890925e5e61275fc457da87f6e)
(cherry picked from commit 42057793ebb3ccdc4e63f59753bca8dd677e9748)

lib/replace/libreplace.m4
lib/replace/replace.c
lib/replace/replace.h
lib/replace/test/testsuite.c

index af8587938d12ca16c1751b83e71f3fc92f1c6063..1353c1f7d2677c7e6106677af7e3446b120b42a3 100644 (file)
@@ -228,6 +228,8 @@ AC_HAVE_DECL(environ, [#include <unistd.h>])
 AC_CHECK_FUNCS(strnlen)
 AC_CHECK_FUNCS(strtoull __strtoull strtouq strtoll __strtoll strtoq)
 
+AC_CHECK_FUNCS(memmem)
+
 # this test disabled as we don't actually need __VA_ARGS__ yet
 AC_TRY_CPP([
 #define eprintf(...) fprintf(stderr, __VA_ARGS__)
index fc15717349e1d189dcd9494d1bc2dd61e12ca92c..17fd46bcc89828b5bd85ce7573c68fafe106c04c 100644 (file)
@@ -681,3 +681,26 @@ char *rep_realpath(const char *path, char *resolved_path)
        return NULL;
 }
 #endif
+
+
+#ifndef HAVE_MEMMEM
+void *rep_memmem(const void *haystack, size_t haystacklen,
+                const void *needle, size_t needlelen)
+{
+       if (needlelen == 0) {
+               return discard_const(haystack);
+       }
+       while (haystacklen >= needlelen) {
+               char *p = memchr(haystack, *(const char *)needle,
+                                haystacklen-(needlelen-1));
+               if (!p) return NULL;
+               if (memcmp(p, needle, needlelen) == 0) {
+                       return p;
+               }
+               haystack = p+1;
+               haystacklen -= (p - (const char *)haystack) + 1;
+       }
+       return NULL;
+}
+#endif
+
index 6424d10c0f9b9ed6f53f1740be6c97cf020e747b..baf2368130c6342af2d164c0442a88e5d2d59199 100644 (file)
@@ -140,6 +140,12 @@ char *rep_strdup(const char *s);
 void *rep_memmove(void *dest,const void *src,int size);
 #endif
 
+#ifndef HAVE_MEMMEM
+#define memmem rep_memmem
+void *rep_memmem(const void *haystack, size_t haystacklen,
+                const void *needle, size_t needlelen);
+#endif
+
 #ifndef HAVE_MKTIME
 #define mktime rep_mktime
 /* prototype is in "system/time.h" */
index 7929f11addf0a660ba9ca6e19ca4d02f420339eb..caa70d68e390b6a047bb4dd3bce0bb8a6c0b8535 100644 (file)
@@ -1015,6 +1015,42 @@ static int test_utimes(void)
        return true;
 }
 
+static int test_memmem(void)
+{
+       char *s;
+
+       printf("test: memmem\n");
+
+       s = memmem("foo", 3, "fo", 2);
+       if (strcmp(s, "foo") != 0) {
+               printf(__location__ ": Failed memmem\n");
+               return false;
+       }
+
+       s = memmem("foo", 3, "", 0);
+       if (strcmp(s, "foo") != 0) {
+               printf(__location__ ": Failed memmem\n");
+               return false;
+       }
+
+       s = memmem("foo", 4, "o", 1);
+       if (strcmp(s, "oo") != 0) {
+               printf(__location__ ": Failed memmem\n");
+               return false;
+       }
+
+       s = memmem("foobarfodx", 11, "fod", 3);
+       if (strcmp(s, "fodx") != 0) {
+               printf(__location__ ": Failed memmem\n");
+               return false;
+       }
+
+       printf("success: memmem\n");
+
+       return true;
+}
+
+
 struct torture_context;
 bool torture_local_replace(struct torture_context *ctx)
 {
@@ -1065,6 +1101,7 @@ bool torture_local_replace(struct torture_context *ctx)
        ret &= test_getifaddrs();
        ret &= test_utime();
        ret &= test_utimes();
+       ret &= test_memmem();
 
        return ret;
 }