Browse Source

str: strcount

Useful routine to count number of matches in a string.
Rusty Russell 15 years ago
parent
commit
053f9398c5
4 changed files with 41 additions and 2 deletions
  1. 12 0
      ccan/str/str.c
  2. 12 0
      ccan/str/str.h
  3. 16 2
      ccan/str/test/run.c
  4. 1 0
      tools/ccanlint/Makefile

+ 12 - 0
ccan/str/str.c

@@ -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;
+}

+ 12 - 0
ccan/str/str.h

@@ -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 */

+ 16 - 2
ccan/str/test/run.c

@@ -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();
 }				

+ 1 - 0
tools/ccanlint/Makefile

@@ -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 \