]> git.ozlabs.org Git - ccan/blob - ccan/str_talloc/str_talloc.c
ccanlint: print coverage amount when -vv
[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 {
16         char **lines = NULL;
17         unsigned int max = 64, num = 0;
18
19         lines = talloc_array(ctx, char *, max+1);
20
21         while (*string != '\0') {
22                 unsigned int len = strcspn(string, delims);
23                 lines[num] = talloc_array(lines, char, len + 1);
24                 memcpy(lines[num], string, len);
25                 lines[num][len] = '\0';
26                 string += len;
27                 string += strspn(string, delims) ? 1 : 0;
28                 if (++num == max)
29                         lines = talloc_realloc(ctx, lines, char *, max*=2 + 1);
30         }
31         lines[num] = NULL;
32
33         /* Shrink, so talloc_get_size works */
34         return talloc_realloc(ctx, lines, char *, num+1);
35 }
36
37 char *strjoin(const void *ctx, char *strings[], const char *delim)
38 {
39         unsigned int i;
40         char *ret = talloc_strdup(ctx, "");
41
42         for (i = 0; strings[i]; i++) {
43                 ret = talloc_append_string(ret, strings[i]);
44                 ret = talloc_append_string(ret, delim);
45         }
46         return ret;
47 }
48
49 bool strreg(const void *ctx, const char *string, const char *regex, ...)
50 {
51         size_t nmatch = 1 + strcount(regex, "(");
52         regmatch_t *matches = talloc_array(ctx, regmatch_t, nmatch);
53         regex_t r;
54         bool ret;
55
56         if (!matches || regcomp(&r, regex, REG_EXTENDED) != 0)
57                 return false;
58
59         if (regexec(&r, string, nmatch, matches, 0) == 0) {
60                 unsigned int i;
61                 va_list ap;
62
63                 ret = true;
64                 va_start(ap, regex);
65                 for (i = 1; i < nmatch; i++) {
66                         char **arg;
67                         arg = va_arg(ap, char **);
68                         if (arg) {
69                                 /* eg. ([a-z])? can give "no match". */
70                                 if (matches[i].rm_so == -1)
71                                         *arg = NULL;
72                                 else {
73                                         *arg = talloc_strndup(ctx,
74                                                       string + matches[i].rm_so,
75                                                       matches[i].rm_eo
76                                                       - matches[i].rm_so);
77                                         if (!*arg) {
78                                                 ret = false;
79                                                 break;
80                                         }
81                                 }
82                         }
83                 }
84                 va_end(ap);
85         } else
86                 ret = false;
87         talloc_free(matches);
88         regfree(&r);
89         return ret;
90 }