str: strcount
authorRusty Russell <rusty@rustcorp.com.au>
Fri, 7 Jan 2011 23:47:37 +0000 (10:17 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Fri, 7 Jan 2011 23:47:37 +0000 (10:17 +1030)
Useful routine to count number of matches in a string.

ccan/str/str.c [new file with mode: 0644]
ccan/str/str.h
ccan/str/test/run.c
tools/ccanlint/Makefile

diff --git a/ccan/str/str.c b/ccan/str/str.c
new file mode 100644 (file)
index 0000000..fa9809f
--- /dev/null
@@ -0,0 +1,12 @@
+#include <ccan/str/str.h>
+
+size_t strcount(const char *haystack, const char *needle)
+{
+       size_t i = 0, nlen = strlen(needle);
+
+       while ((haystack = strstr(haystack, needle)) != NULL) {
+               i++;
+               haystack += nlen;
+       }
+       return i;
+}
index 8cfd7f29a5626cb7ca3a3196e545f35c3a74c0be..770a40fd1f4dca3fe599cfdee109fe9fa581b861 100644 (file)
@@ -55,4 +55,16 @@ static inline bool strends(const char *str, const char *postfix)
 #define stringify(expr)                stringify_1(expr)
 /* Double-indirection required to stringify expansions */
 #define stringify_1(expr)      #expr
+
+/**
+ * strcount - Count number of (non-overlapping) occurrences of a substring.
+ * @haystack: a C string
+ * @needle: a substring
+ *
+ * Example:
+ *     #define PRINT_COND_IF_FALSE(cond) \
+ *             ((cond) || printf("%s is false!", stringify(cond)))
+ */
+size_t strcount(const char *haystack, const char *needle);
+
 #endif /* CCAN_STR_H */
index 4648692be655165413d5cc250844df35f4553ccb..3ccadbe5df89c17ad6c1487657e0e5e032108eb8 100644 (file)
@@ -1,9 +1,9 @@
 #include <ccan/str/str.h>
+#include <ccan/str/str.c>
 #include <stdlib.h>
 #include <stdio.h>
 #include <ccan/tap/tap.h>
 
-/* FIXME: ccanize */
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
 
 static char *substrings[] = { "far", "bar", "baz", "b", "ba", "z", "ar", NULL };
@@ -35,7 +35,7 @@ int main(int argc, char *argv[])
                }
        }
 
-       plan_tests(n * n * 5 + 3);
+       plan_tests(n * n * 5 + 16);
        for (i = 0; i < n; i++) {
                for (j = 0; j < n; j++) {
                        unsigned int k, identical = 0;
@@ -87,5 +87,19 @@ int main(int argc, char *argv[])
                  "(sizeof(substrings) / sizeof(substrings[0]))"));
        ok1(streq(stringify(i == 0), "i == 0"));
 
+       ok1(strcount("aaaaaa", "b") == 0);
+       ok1(strcount("aaaaaa", "a") == 6);
+       ok1(strcount("aaaaaa", "aa") == 3);
+       ok1(strcount("aaaaaa", "aaa") == 2);
+       ok1(strcount("aaaaaa", "aaaa") == 1);
+       ok1(strcount("aaaaaa", "aaaaa") == 1);
+       ok1(strcount("aaaaaa", "aaaaaa") == 1);
+       ok1(strcount("aaa aaa", "b") == 0);
+       ok1(strcount("aaa aaa", "a") == 6);
+       ok1(strcount("aaa aaa", "aa") == 2);
+       ok1(strcount("aaa aaa", "aaa") == 2);
+       ok1(strcount("aaa aaa", "aaaa") == 0);
+       ok1(strcount("aaa aaa", "aaaaa") == 0);
+
        return exit_status();
 }                              
index 854564aa8b159a0e32958a61c8890026afeacc92..043c3fd2c7d17b82063350fa7c0fb52a67ee789e 100644 (file)
@@ -9,6 +9,7 @@ CORE_OBJS := tools/ccanlint/ccanlint.o \
        tools/tools.o \
        tools/compile.o \
        ccan/str_talloc/str_talloc.o ccan/grab_file/grab_file.o \
+       ccan/str/str.o \
        ccan/asort/asort.o \
        ccan/btree/btree.o \
        ccan/talloc/talloc.o ccan/noerr/noerr.o \