[ccan] [PATCH 06/11] bytestring: Implement bytestring_spn()
David Gibson
david at gibson.dropbear.id.au
Sun Oct 12 03:43:31 AEDT 2014
Add bytestring_spn() and bytestring_cspn() functions which, in analogy to
strspn() and strcspn() return the lengths of initial sub-bytestrings which
either contain only a given set of bytes, or anything except a given set
of bytes.
Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
---
Makefile-ccan | 2 +-
ccan/bytestring/bytestring.c | 26 ++++++++++++++++++++++++++
ccan/bytestring/bytestring.h | 20 ++++++++++++++++++++
ccan/bytestring/test/run.c | 14 +++++++++++++-
4 files changed, 60 insertions(+), 2 deletions(-)
create mode 100644 ccan/bytestring/bytestring.c
diff --git a/Makefile-ccan b/Makefile-ccan
index 1388f89..67245ef 100644
--- a/Makefile-ccan
+++ b/Makefile-ccan
@@ -13,7 +13,6 @@ MODS_NO_SRC := alignof \
asearch \
bitmap \
build_assert \
- bytestring \
cast \
check_type \
compiler \
@@ -40,6 +39,7 @@ MODS_WITH_SRC := antithread \
block_pool \
breakpoint \
btree \
+ bytestring \
ccan_tokenizer \
charset \
ciniparser \
diff --git a/ccan/bytestring/bytestring.c b/ccan/bytestring/bytestring.c
new file mode 100644
index 0000000..2e205b7
--- /dev/null
+++ b/ccan/bytestring/bytestring.c
@@ -0,0 +1,26 @@
+/* Licensed under LGPLv2+ - see LICENSE file for details */
+#include "config.h"
+
+#include <ccan/bytestring/bytestring.h>
+
+size_t bytestring_spn(struct bytestring s, struct bytestring accept)
+{
+ size_t i;
+
+ for (i = 0; i < s.len; i++)
+ if (bytestring_chr(accept, s.ptr[i]) == NULL)
+ return i;
+
+ return s.len;
+}
+
+size_t bytestring_cspn(struct bytestring s, struct bytestring reject)
+{
+ size_t i;
+
+ for (i = 0; i < s.len; i++)
+ if (bytestring_chr(reject, s.ptr[i]) != NULL)
+ return i;
+
+ return s.len;
+}
diff --git a/ccan/bytestring/bytestring.h b/ccan/bytestring/bytestring.h
index 02e926e..6ca7197 100644
--- a/ccan/bytestring/bytestring.h
+++ b/ccan/bytestring/bytestring.h
@@ -181,4 +181,24 @@ static inline struct bytestring bytestring_bytestring(struct bytestring haystack
return bytestring_NULL;
}
+/**
+ * bytestring_spn - search a bytestring for a set of bytes
+ * @s: a bytestring
+ * @accept: a bytestring containing a set of bytes to accept
+ *
+ * Returns the length, in bytes, of the initial segment of @s which
+ * consists entirely of characters in @accept.
+ */
+size_t bytestring_spn(struct bytestring s, struct bytestring accept);
+
+/**
+ * bytestring_cspn - search a bytestring for a set of bytes (complemented)
+ * @s: a bytestring
+ * @reject: a bytestring containing a set of bytes to reject
+ *
+ * Returns the length, in bytes, of the initial segment of @s which
+ * consists entirely of characters not in @reject.
+ */
+size_t bytestring_cspn(struct bytestring s, struct bytestring reject);
+
#endif /* CCAN_BYTESTRING_H_ */
diff --git a/ccan/bytestring/test/run.c b/ccan/bytestring/test/run.c
index 3da86eb..0f9ceaa 100644
--- a/ccan/bytestring/test/run.c
+++ b/ccan/bytestring/test/run.c
@@ -3,6 +3,8 @@
#include <ccan/bytestring/bytestring.h>
#include <ccan/tap/tap.h>
+#include <ccan/bytestring/bytestring.c>
+
#define TEST_STRING "test string"
#define TEST_STRING_2 "abc\0def"
@@ -14,7 +16,7 @@ int main(void)
struct bytestring bs, bs1, bs2, bs3, bs4, bs5, bs6;
/* This is how many tests you plan to run */
- plan_tests(40);
+ plan_tests(46);
bs = bytestring(str1, sizeof(str1) - 1);
ok1(bs.ptr == str1);
@@ -80,6 +82,16 @@ int main(void)
ok1(bytestring_eq(bytestring_bytestring(bs2, bytestring_NULL),
bytestring(bs2.ptr, 0)));
+
+ ok1(bytestring_spn(bs1, BYTESTRING("est")) == 4);
+ ok1(bytestring_cspn(bs1, BYTESTRING(" ")) == 4);
+
+ ok1(bytestring_spn(bs2, BYTESTRING("z")) == 0);
+ ok1(bytestring_cspn(bs2, BYTESTRING("\0")) == 3);
+
+ ok1(bytestring_spn(bs1, BYTESTRING("eginrst ")) == bs1.len);
+ ok1(bytestring_cspn(bs2, BYTESTRING("z")) == bs2.len);
+
/* This exits depending on whether all tests passed */
return exit_status();
}
--
1.9.3
More information about the ccan
mailing list