Commit 40b45c4c authored by David Gibson's avatar David Gibson Committed by Rusty Russell

mem: Implement memrchr()

The memrchr() function, which works like memchr(), but searches from the
back of the region to the front is implemented in the GNU C library, but
isn't standard.

This patch adds an implementation of the function to the mem module, when
it's not available in the system C library.
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent 2ab3ac5b
......@@ -25,3 +25,18 @@ void *memmem(const void *haystack, size_t haystacklen,
return NULL;
}
#endif
#if !HAVE_MEMRCHR
void *memrchr(const void *s, int c, size_t n)
{
unsigned char *p = (unsigned char *)s;
while (n) {
if (p[n-1] == c)
return p + n - 1;
n--;
}
return NULL;
}
#endif
......@@ -11,4 +11,8 @@ void *memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
#endif
#if !HAVE_MEMRCHR
void *memrchr(const void *s, int c, size_t n);
#endif
#endif /* CCAN_MEM_H */
......@@ -10,7 +10,7 @@ int main(void)
char needle2[] = "d\0e";
/* This is how many tests you plan to run */
plan_tests(5);
plan_tests(19);
ok1(memmem(haystack1, sizeof(haystack1), needle1, 2) == haystack1);
ok1(memmem(haystack1, sizeof(haystack1), needle1, 3) == NULL);
......@@ -20,6 +20,23 @@ int main(void)
== haystack2);
ok1(memmem(haystack2, sizeof(haystack2), needle2, 3) == NULL);
ok1(memrchr(haystack1, 'a', sizeof(haystack1)) == haystack1);
ok1(memrchr(haystack1, 'b', sizeof(haystack1)) == haystack1 + 1);
ok1(memrchr(haystack1, 'c', sizeof(haystack1)) == haystack1 + 2);
ok1(memrchr(haystack1, 'd', sizeof(haystack1)) == haystack1 + 3);
ok1(memrchr(haystack1, 'e', sizeof(haystack1)) == haystack1 + 5);
ok1(memrchr(haystack1, 'f', sizeof(haystack1)) == haystack1 + 6);
ok1(memrchr(haystack1, 'g', sizeof(haystack1)) == haystack1 + 7);
ok1(memrchr(haystack1, 'h', sizeof(haystack1)) == haystack1 + 8);
ok1(memrchr(haystack1, '\0', sizeof(haystack1)) == haystack1 + 9);
ok1(memrchr(haystack1, 'i', sizeof(haystack1)) == NULL);
ok1(memrchr(haystack2, 'a', sizeof(haystack2)) == haystack2 + 9);
ok1(memrchr(haystack2, 'b', sizeof(haystack2)) == haystack2 + 10);
ok1(memrchr(haystack2, '\0', sizeof(haystack2)) == haystack2 + 11);
ok1(memrchr(needle1, '\0', 2) == NULL);
/* This exits depending on whether all tests passed */
return exit_status();
}
......@@ -214,6 +214,12 @@ static struct test tests[] = {
"static void *func(void *h, size_t hl, void *n, size_t nl) {\n"
"return memmem(h, hl, n, nl);"
"}\n", },
{ "HAVE_MEMRCHR", DEFINES_FUNC, NULL, NULL,
"#define _GNU_SOURCE\n"
"#include <string.h>\n"
"static void *func(void *s, int c, size_t n) {\n"
"return memrchr(s, c, n);"
"}\n", },
{ "HAVE_MMAP", DEFINES_FUNC, NULL, NULL,
"#include <sys/mman.h>\n"
"static void *func(int fd) {\n"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment