X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftal%2Fstr%2Fstr.c;fp=ccan%2Ftal%2Fstr%2Fstr.c;h=0c07002b157404d4bf87e517a2de166802fb0216;hp=0000000000000000000000000000000000000000;hb=d873aaec1339baf45c37db7cbaa2d687656343ba;hpb=d379e0ae835bdd047a5d277f7ded41f180134e27;ds=sidebyside diff --git a/ccan/tal/str/str.c b/ccan/tal/str/str.c new file mode 100644 index 00000000..0c07002b --- /dev/null +++ b/ccan/tal/str/str.c @@ -0,0 +1,106 @@ +/* Licensed under BSD-MIT - see LICENSE file for details */ +#include +#include +#include +#include +#include +#include "str.h" +#include +#include +#include +#include +#include +#include + +char **strsplit(const void *ctx, const char *string, const char *delims, + enum strsplit flags) +{ + char **lines = NULL; + size_t max = 64, num = 0; + + lines = tal_arr(ctx, char *, max+1); + + if (flags == STR_NO_EMPTY) + string += strspn(string, delims); + + while (*string != '\0') { + size_t len = strcspn(string, delims), dlen; + + lines[num] = tal_arr(lines, char, len + 1); + memcpy(lines[num], string, len); + lines[num][len] = '\0'; + string += len; + dlen = strspn(string, delims); + if (flags == STR_EMPTY_OK && dlen) + dlen = 1; + string += dlen; + if (++num == max) + tal_resize(&lines, max*=2 + 1); + } + lines[num] = NULL; + return lines; +} + +char *strjoin(const void *ctx, char *strings[], const char *delim, + enum strjoin flags) +{ + unsigned int i; + char *ret = tal_strdup(ctx, ""); + size_t totlen = 0, dlen = strlen(delim); + + for (i = 0; strings[i]; i++) { + size_t len = strlen(strings[i]); + if (flags == STR_NO_TRAIL && !strings[i+1]) + dlen = 0; + tal_resize(&ret, 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 = tal_arr(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 = tal_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; + tal_free(matches); + regfree(&r); + return ret; +}