X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fstr_talloc%2Fstr_talloc.c;h=88e02ef2edfc58bab2a33c1abad4b9000a19fc61;hp=d1d2f44de4b875b994b4cd8e5899981a759bf44e;hb=156e5eb92f1d986957cb081b58320579c6e366dd;hpb=a8b248ea9de55316cac4423a99a727ca7b54e0fc diff --git a/ccan/str_talloc/str_talloc.c b/ccan/str_talloc/str_talloc.c index d1d2f44d..88e02ef2 100644 --- a/ccan/str_talloc/str_talloc.c +++ b/ccan/str_talloc/str_talloc.c @@ -4,10 +4,14 @@ #include #include #include "str_talloc.h" +#include +#include +#include +#include #include +#include -char **strsplit(const void *ctx, const char *string, const char *delims, - unsigned int *nump) +char **strsplit(const void *ctx, const char *string, const char *delims) { char **lines = NULL; unsigned int max = 64, num = 0; @@ -25,19 +29,68 @@ char **strsplit(const void *ctx, const char *string, const char *delims, lines = talloc_realloc(ctx, lines, char *, max*=2 + 1); } lines[num] = NULL; - if (nump) - *nump = num; - return lines; + + /* Shrink, so talloc_get_size works */ + return talloc_realloc(ctx, lines, char *, num+1); } char *strjoin(const void *ctx, char *strings[], const char *delim) { unsigned int i; char *ret = talloc_strdup(ctx, ""); + size_t totlen = 0, dlen = strlen(delim); for (i = 0; strings[i]; i++) { - ret = talloc_append_string(ret, strings[i]); - ret = talloc_append_string(ret, delim); + size_t len = strlen(strings[i]); + ret = talloc_realloc(ctx, ret, char, totlen + len + dlen + 1); + memcpy(ret + totlen, strings[i], len); + totlen += len; + memcpy(ret + totlen, delim, dlen); + totlen += dlen; } + ret[totlen] = '\0'; + return ret; +} + +bool strreg(const void *ctx, const char *string, const char *regex, ...) +{ + size_t nmatch = 1 + strcount(regex, "("); + regmatch_t *matches = talloc_array(ctx, regmatch_t, nmatch); + regex_t r; + bool ret; + + if (!matches || regcomp(&r, regex, REG_EXTENDED) != 0) + return false; + + if (regexec(&r, string, nmatch, matches, 0) == 0) { + unsigned int i; + va_list ap; + + ret = true; + va_start(ap, regex); + for (i = 1; i < nmatch; i++) { + char **arg; + arg = va_arg(ap, char **); + if (arg) { + /* eg. ([a-z])? can give "no match". */ + if (matches[i].rm_so == -1) + *arg = NULL; + else { + *arg = talloc_strndup(ctx, + string + matches[i].rm_so, + matches[i].rm_eo + - matches[i].rm_so); + if (!*arg) { + ret = false; + break; + } + } + } + } + va_end(ap); + } else + ret = false; + talloc_free(matches); + regfree(&r); return ret; }