[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