1 /* Licensed under BSD-MIT - see LICENSE file for details */
12 #include <ccan/str/str.h>
13 #include <ccan/tal/tal.h>
14 #include <ccan/take/take.h>
16 char **strsplit(const tal_t *ctx,
17 const char *string, const char *delims, enum strsplit flags)
20 size_t max = 64, num = 0;
22 parts = tal_arr(ctx, char *, max + 1);
23 if (unlikely(!parts)) {
30 str = tal_strdup(parts, string);
33 if (unlikely(!delims) && is_taken(delims))
36 if (flags == STR_NO_EMPTY)
37 str += strspn(str, delims);
39 while (*str != '\0') {
40 size_t len = strcspn(str, delims), dlen;
43 dlen = strspn(str + len, delims);
44 parts[num][len] = '\0';
45 if (flags == STR_EMPTY_OK && dlen)
48 if (++num == max && !tal_resize(&parts, max*=2 + 1))
63 char *strjoin(const tal_t *ctx,
64 char *strings[], const char *delim, enum strjoin flags)
68 size_t totlen = 0, dlen;
70 if (unlikely(!strings) && is_taken(strings))
73 if (unlikely(!delim) && is_taken(delim))
77 ret = tal_arr(ctx, char, dlen*2+1);
82 for (i = 0; strings[i]; i++) {
83 size_t len = strlen(strings[i]);
85 if (flags == STR_NO_TRAIL && !strings[i+1])
87 if (!tal_resize(&ret, totlen + len + dlen + 1))
89 memcpy(ret + totlen, strings[i], len);
91 memcpy(ret + totlen, delim, dlen);
106 bool strreg(const tal_t *ctx, const char *string, const char *regex, ...)
108 size_t nmatch = 1 + strcount(regex, "(");
109 regmatch_t matches[nmatch];
115 if (unlikely(!regex) && is_taken(regex))
118 if (regcomp(&r, regex, REG_EXTENDED) != 0)
121 if (unlikely(!string) && is_taken(string))
124 if (regexec(&r, string, nmatch, matches, 0) != 0)
129 for (i = 1; i < nmatch; i++) {
130 char **arg = va_arg(ap, char **);
132 /* eg. ([a-z])? can give "no match". */
133 if (matches[i].rm_so == -1)
136 *arg = tal_strndup(ctx,
137 string + matches[i].rm_so,
140 /* FIXME: If we fail, we set some and leak! */