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 **tal_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))
53 /* Ensure that tal_count() is correct. */
54 if (unlikely(!tal_resize(&parts, num+1)))
68 char *tal_strjoin(const tal_t *ctx,
69 char *strings[], const char *delim, enum strjoin flags)
73 size_t totlen = 0, dlen;
75 if (unlikely(!strings) && is_taken(strings))
78 if (unlikely(!delim) && is_taken(delim))
82 ret = tal_arr(ctx, char, dlen*2+1);
87 for (i = 0; strings[i]; i++) {
88 size_t len = strlen(strings[i]);
90 if (flags == STR_NO_TRAIL && !strings[i+1])
92 if (!tal_resize(&ret, totlen + len + dlen + 1))
94 memcpy(ret + totlen, strings[i], len);
96 memcpy(ret + totlen, delim, dlen);
111 bool tal_strreg(const tal_t *ctx, const char *string, const char *regex, ...)
113 size_t nmatch = 1 + strcount(regex, "(");
114 regmatch_t matches[nmatch];
120 if (unlikely(!regex) && is_taken(regex))
123 if (regcomp(&r, regex, REG_EXTENDED) != 0)
126 if (unlikely(!string) && is_taken(string))
129 if (regexec(&r, string, nmatch, matches, 0) != 0)
134 for (i = 1; i < nmatch; i++) {
135 char **arg = va_arg(ap, char **);
137 /* eg. ([a-z])? can give "no match". */
138 if (matches[i].rm_so == -1)
141 *arg = tal_strndup(ctx,
142 string + matches[i].rm_so,
145 /* FIXME: If we fail, we set some and leak! */