[ccan] [PATCH 3/3] memfuncs: Implement memrchr()
Ran Benita
ran234 at gmail.com
Mon Oct 20 01:00:45 AEDT 2014
On Sun, Oct 19, 2014 at 02:07:46PM +0200, David Gibson wrote:
> 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 memfuncs module,
> when it's not available in the system C library.
>
> Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
> ---
> ccan/memfuncs/memfuncs.c | 14 ++++++++++++++
> ccan/memfuncs/memfuncs.h | 4 ++++
> ccan/memfuncs/test/run.c | 16 +++++++++++++++-
> tools/configurator/configurator.c | 6 ++++++
> 4 files changed, 39 insertions(+), 1 deletion(-)
>
> diff --git a/ccan/memfuncs/memfuncs.c b/ccan/memfuncs/memfuncs.c
> index c80b862..2674f41 100644
> --- a/ccan/memfuncs/memfuncs.c
> +++ b/ccan/memfuncs/memfuncs.c
> @@ -25,3 +25,17 @@ 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;
> + size_t i;
This needs to be ssize_t, otherwise the loop doesn't end.
> +
> + for (i = n - 1; i >= 0; i--)
> + if (p[i] == c)
> + return p + i;
> +
> + return NULL;
> +}
> +#endif
> diff --git a/ccan/memfuncs/memfuncs.h b/ccan/memfuncs/memfuncs.h
> index bbc19c9..4b6d9fe 100644
> --- a/ccan/memfuncs/memfuncs.h
> +++ b/ccan/memfuncs/memfuncs.h
> @@ -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_MEMFUNCS_H */
> diff --git a/ccan/memfuncs/test/run.c b/ccan/memfuncs/test/run.c
> index 0e2e903..b6f1833 100644
> --- a/ccan/memfuncs/test/run.c
> +++ b/ccan/memfuncs/test/run.c
> @@ -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(17);
>
> ok1(memmem(haystack1, sizeof(haystack1), needle1, 2) == haystack1);
> ok1(memmem(haystack1, sizeof(haystack1), needle1, 3) == NULL);
> @@ -20,6 +20,20 @@ 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(haystack2, 'a', sizeof(haystack2)) == haystack2 + 9);
> + ok1(memrchr(haystack2, 'b', sizeof(haystack2)) == haystack2 + 10);
> + ok1(memrchr(haystack2, '\0', sizeof(haystack2)) == haystack2 + 11);
> +
> /* This exits depending on whether all tests passed */
> return exit_status();
> }
> diff --git a/tools/configurator/configurator.c b/tools/configurator/configurator.c
> index d1aa5c6..0c4b0f1 100644
> --- a/tools/configurator/configurator.c
> +++ b/tools/configurator/configurator.c
> @@ -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"
> --
> 1.9.3
>
> _______________________________________________
> ccan mailing list
> ccan at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/ccan
More information about the ccan
mailing list