[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