diff --git a/src/strbuf.c b/src/strbuf.c index 9e291f9..89c8e1f 100644 --- a/src/strbuf.c +++ b/src/strbuf.c @@ -71,6 +71,18 @@ void strbuf_free(strbuf_t *s) { strbuf_init(s); } +void strbuf_free_list(strbuf_t **s) { + + strbuf_t **list = s; + + while(*s) { + if ((*s)->alloc_size) + xfree((*s)->buf); + xfree(*s++); + } + xfree(list); +} + void strbuf_attach(strbuf_t *s, void *buf, size_t len, size_t alloc_size) { strbuf_free(s); @@ -184,3 +196,28 @@ void strbuf_squeeze(strbuf_t *s, char ch) { } } } + +strbuf_t** strbuf_explode(const strbuf_t *s, char sep) { + + int i = 0, count = 2; + char *p; + strbuf_t *tmp, **list; + + list = xmallocz(sizeof(strbuf_t *) * count); + + p = s->buf; + while(p < s->buf + s->len) { + char *d = memchr(p, sep, s->len - (p - s->buf)); + if (!d) + d = s->buf + s->len; + if (i + 1 >= count) + list = xrealloc(list, sizeof(strbuf_t *) * (count += 4)); + tmp = xmalloc(sizeof(strbuf_t)); + strbuf_init(tmp); + strbuf_append(tmp, p, d - p); + list[i] = tmp; + list[++i] = NULL; + p = ++d; + } + return list; +} diff --git a/src/strbuf.h b/src/strbuf.h index 46dcb8c..ad33ff7 100644 --- a/src/strbuf.h +++ b/src/strbuf.h @@ -33,6 +33,8 @@ char* strbuf_release(strbuf_t *s); void strbuf_free(strbuf_t *s); +void strbuf_free_list(strbuf_t **s); + void strbuf_attach(strbuf_t *s, void *str, size_t len, size_t alloc_size); void strbuf_append(strbuf_t *s, const void *ptr, size_t len); @@ -57,4 +59,6 @@ void strbuf_rev(strbuf_t *s); void strbuf_squeeze(strbuf_t *s, char ch); +strbuf_t **strbuf_explode(const strbuf_t *s, char sep); + #endif /* __STRBUF_H */ diff --git a/test/t_strbuf.c b/test/t_strbuf.c index ef55786..61ed4c9 100644 --- a/test/t_strbuf.c +++ b/test/t_strbuf.c @@ -161,6 +161,27 @@ void test_reduce() { strbuf_free(&b); } +void test_explode() { + + strbuf_t **list, **ptr; + strbuf_t b = STRBUF_INIT; + + strbuf_append_str(&b, "item1,item2,item3,item4"); + + list = ptr = strbuf_explode(&b, ','); + while(*ptr) + print_strbuf(*ptr++); + strbuf_free_list(list); + + strbuf_free(&b); + + list = strbuf_explode(&b, ','); + + assert(*list == NULL); + + strbuf_free_list(list); +} + void test_free_empty() { strbuf_t b = STRBUF_INIT; @@ -178,6 +199,7 @@ int main() { test_trim(); test_term(); test_chop(); + test_explode(); test_free_empty(); return 0;