e2d12df8791942744f3dec63f2e9a18284198a4d
[ccan] / ccan / str_talloc / str_talloc.c
1 #include <unistd.h>
2 #include <stdint.h>
3 #include <string.h>
4 #include <limits.h>
5 #include <stdlib.h>
6 #include "str_talloc.h"
7 #include <sys/types.h>
8 #include <regex.h>
9 #include <stdarg.h>
10 #include <unistd.h>
11 #include <ccan/talloc/talloc.h>
12 #include <ccan/str/str.h>
13
14 char **strsplit(const void *ctx, const char *string, const char *delims,
15                  unsigned int *nump)
16 {
17         char **lines = NULL;
18         unsigned int max = 64, num = 0;
19
20         lines = talloc_array(ctx, char *, max+1);
21
22         while (*string != '\0') {
23                 unsigned int len = strcspn(string, delims);
24                 lines[num] = talloc_array(lines, char, len + 1);
25                 memcpy(lines[num], string, len);
26                 lines[num][len] = '\0';
27                 string += len;
28                 string += strspn(string, delims) ? 1 : 0;
29                 if (++num == max)
30                         lines = talloc_realloc(ctx, lines, char *, max*=2 + 1);
31         }
32         lines[num] = NULL;
33         if (nump)
34                 *nump = num;
35         return lines;
36 }
37
38 char *strjoin(const void *ctx, char *strings[], const char *delim)
39 {
40         unsigned int i;
41         char *ret = talloc_strdup(ctx, "");
42
43         for (i = 0; strings[i]; i++) {
44                 ret = talloc_append_string(ret, strings[i]);
45                 ret = talloc_append_string(ret, delim);
46         }
47         return ret;
48 }
49
50 bool strreg(const void *ctx, const char *string, const char *regex, ...)
51 {
52         size_t nmatch = 1 + strcount(regex, "(");
53         regmatch_t *matches = talloc_array(ctx, regmatch_t, nmatch);
54         regex_t r;
55         bool ret;
56
57         if (!matches || regcomp(&r, regex, REG_EXTENDED) != 0)
58                 return false;
59
60         if (regexec(&r, string, nmatch, matches, 0) == 0) {
61                 unsigned int i;
62                 va_list ap;
63
64                 ret = true;
65                 va_start(ap, regex);
66                 for (i = 1; i < nmatch; i++) {
67                         char **arg;
68                         arg = va_arg(ap, char **);
69                         if (arg) {
70                                 /* eg. ([a-z])? can give "no match". */
71                                 if (matches[i].rm_so == -1)
72                                         *arg = NULL;
73                                 else {
74                                         *arg = talloc_strndup(ctx,
75                                                       string + matches[i].rm_so,
76                                                       matches[i].rm_eo
77                                                       - matches[i].rm_so);
78                                         if (!*arg) {
79                                                 ret = false;
80                                                 break;
81                                         }
82                                 }
83                         }
84                 }
85                 va_end(ap);
86         } else
87                 ret = false;
88         talloc_free(matches);
89         regfree(&r);
90         return ret;
91 }