[ccan] [PATCH 3/3] memfuncs: Implement memrchr()

Rusty Russell rusty at rustcorp.com.au
Wed Oct 22 15:32:13 AEDT 2014


David Gibson <david at gibson.dropbear.id.au> writes:
> On Tue, Oct 21, 2014 at 11:18:00AM +1030, Paul 'Rusty' Russell wrote:
>> Rusty Russell <rusty at rustcorp.com.au> writes:
>> > David Gibson <david at gibson.dropbear.id.au> writes:
>> >> On Sun, Oct 19, 2014 at 05:00:45PM +0300, Ran Benita wrote:
>> >>> 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.
>> >>
>> >> Good point.  More importantly, the fact that my testcases did
>> >> terminate indicates that they're not actually testing the local
>> >> implementations :(.
>> >
>> > Yes, that's weird.  ccanlint's "tests_pass_without_features" *should*
>> > have caught this.
>> >
>> > Let me check...
>> > Rusty.
>> 
>> Ah, fascinating.  You got the builtin memrchr because your run.c
>> included the header only, not the .c file.
>> 
>> You could rename run.c to api.c, or "#include <ccan/memfuncs/memfuncs.c>"
>> instead of "#include <ccan/memfuncs/memfuncs.h>".
>
> Hmm.. so I tried both of those, and it still doesn't fail..

Me too.  But I figured it out like so:

$ ccanlint -t tests_pass_without_features -k
Total score: 10/14
You can find ccanlint working files in '/tmp/ccanlint-27451.1804289383'
$ ls -l /tmp/ccanlint-27451.1804289383/
total 876
-rwxr-xr-x 1 rusty rusty  32381 Oct 22 14:59 info
-rwxr-xr-x 1 rusty rusty  32381 Oct 22 14:59 info-1
-rw------- 1 rusty rusty   1030 Oct 22 14:59 _info-1.c
-rwxr-xr-x 1 rusty rusty  32331 Oct 22 14:59 info-2
-rw------- 1 rusty rusty   1350 Oct 22 14:59 _info-2.c
-rw------- 1 rusty rusty    558 Oct 22 14:59 _info.c
-rw-r--r-- 1 rusty rusty  35920 Oct 22 14:59 memfuncs
-rw-r--r-- 1 rusty rusty  37144 Oct 22 14:59 memfuncs-1
-rw-r--r-- 1 rusty rusty  35941 Oct 22 14:59 memfuncs.o
drwx------ 2 rusty rusty   4096 Oct 22 14:59 reduced-features
-rwxr-xr-x 1 rusty rusty  77797 Oct 22 14:59 run
-rwxr-xr-x 1 rusty rusty  78132 Oct 22 14:59 run-1
-rw-r--r-- 1 rusty rusty 124680 Oct 22 14:59 tap
-rw-r--r-- 1 rusty rusty 125176 Oct 22 14:59 tap-1
-rw-r--r-- 1 rusty rusty 125199 Oct 22 14:59 tap-1.o
-rw-r--r-- 1 rusty rusty 124709 Oct 22 14:59 tap.o
lrwxrwxrwx 1 rusty rusty     45 Oct 22 14:59 test -> /home/rusty/devel/cvs/ccan/ccan/memfuncs/test
$ gdb /tmp/ccanlint-27451.1804289383/run-1 

(I knew it was run-1, since ccanlint names them consecutively, so that
was the last binary it generated).

Cheers,
Rusty.

diff --git a/ccan/memfuncs/test/run.c b/ccan/memfuncs/test/run.c
index b6f1833..92a1b9e 100644
--- a/ccan/memfuncs/test/run.c
+++ b/ccan/memfuncs/test/run.c
@@ -1,5 +1,5 @@
 #include <ccan/array_size/array_size.h>
-#include <ccan/memfuncs/memfuncs.h>
+#include <ccan/memfuncs/memfuncs.c>
 #include <ccan/tap/tap.h>
 
 int main(void)
@@ -10,7 +10,7 @@ int main(void)
 	char needle2[] = "d\0e";
 
 	/* This is how many tests you plan to run */
-	plan_tests(17);
+	plan_tests(19);
 
 	ok1(memmem(haystack1, sizeof(haystack1), needle1, 2) == haystack1);
 	ok1(memmem(haystack1, sizeof(haystack1), needle1, 3) == NULL);
@@ -29,10 +29,12 @@ int main(void)
 	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(haystack2, 'c', sizeof(haystack2)) == NULL);
 
 	/* This exits depending on whether all tests passed */
 	return exit_status();


More information about the ccan mailing list