tal/str: always create strings which have tal_count() == strlen() + 1.
[ccan] / ccan / tal / str / test / run-strreg.c
1 #include <ccan/tal/str/str.h>
2 #include <ccan/tal/str/str.c>
3 #include <ccan/tap/tap.h>
4 #include "helper.h"
5
6 static bool find_parent(tal_t *child, tal_t *parent)
7 {
8         tal_t *i;
9
10         for (i = child; i; i = tal_parent(i))
11                 if (i == parent)
12                         return true;
13
14         return false;
15 }
16
17 int main(void)
18 {
19         void *ctx = tal_strdup(NULL, "toplevel");
20         char *a, *b;
21         /* If it accesses this, it will crash. */
22         char **invalid = (char **)1L;
23
24         plan_tests(54);
25         /* Simple matching. */
26         ok1(tal_strreg(ctx, "hello world!", "hello") == true);
27         ok1(tal_strreg(ctx, "hello world!", "hi") == false);
28
29         /* No parentheses means we don't use any extra args. */
30         ok1(tal_strreg(ctx, "hello world!", "hello", invalid) == true);
31         ok1(tal_strreg(ctx, "hello world!", "hi", invalid) == false);
32
33         ok1(tal_strreg(ctx, "hello world!", "[a-z]+", invalid) == true);
34         ok1(tal_strreg(ctx, "hello world!", "([a-z]+)", &a, invalid) == true);
35         /* Found string */
36         ok1(streq(a, "hello"));
37         /* Allocated off ctx */
38         ok1(find_parent(a, ctx));
39         ok1(tal_count(a) == strlen(a) + 1);
40         tal_free(a);
41
42         ok1(tal_strreg(ctx, "hello world!", "([a-z]*) ([a-z]+)",
43                        &a, &b, invalid) == true);
44         ok1(streq(a, "hello"));
45         ok1(streq(b, "world"));
46         ok1(tal_count(a) == strlen(a) + 1);
47         ok1(tal_count(b) == strlen(b) + 1);
48         ok1(find_parent(a, ctx));
49         ok1(find_parent(b, ctx));
50         tal_free(a);
51         tal_free(b);
52
53         /* * after parentheses returns last match. */
54         ok1(tal_strreg(ctx, "hello world!", "([a-z])* ([a-z]+)",
55                        &a, &b, invalid) == true);
56         ok1(streq(a, "o"));
57         ok1(streq(b, "world"));
58         ok1(tal_count(a) == strlen(a) + 1);
59         ok1(tal_count(b) == strlen(b) + 1);
60         tal_free(a);
61         tal_free(b);
62
63         /* Nested parentheses are ordered by open brace. */
64         ok1(tal_strreg(ctx, "hello world!", "(([a-z]*) world)",
65                        &a, &b, invalid) == true);
66         ok1(streq(a, "hello world"));
67         ok1(streq(b, "hello"));
68         ok1(tal_count(a) == strlen(a) + 1);
69         ok1(tal_count(b) == strlen(b) + 1);
70         tal_free(a);
71         tal_free(b);
72
73         /* Nested parentheses are ordered by open brace. */
74         ok1(tal_strreg(ctx, "hello world!", "(([a-z]*) world)",
75                        &a, &b, invalid) == true);
76         ok1(streq(a, "hello world"));
77         ok1(streq(b, "hello"));
78         ok1(tal_count(a) == strlen(a) + 1);
79         ok1(tal_count(b) == strlen(b) + 1);
80         tal_free(a);
81         tal_free(b);
82
83         /* NULL means we're not interested. */
84         ok1(tal_strreg(ctx, "hello world!", "((hello|goodbye) world)",
85                        &a, NULL, invalid) == true);
86         ok1(streq(a, "hello world"));
87         ok1(tal_count(a) == strlen(a) + 1);
88         tal_free(a);
89
90         /* No leaks! */
91         ok1(no_children(ctx));
92
93         /* NULL arg with take means always fail. */
94         ok1(tal_strreg(ctx, take(NULL), "((hello|goodbye) world)",
95                        &b, NULL, invalid) == false);
96
97         /* Take string. */
98         a = tal_strdup(ctx, "hello world!");
99         ok1(tal_strreg(ctx, take(a), "([a-z]+)", &b, invalid) == true);
100         ok1(streq(b, "hello"));
101         ok1(tal_count(b) == strlen(b) + 1);
102         ok1(tal_parent(b) == ctx);
103         tal_free(b);
104         ok1(no_children(ctx));
105
106         /* Take regex. */
107         a = tal_strdup(ctx, "([a-z]+)");
108         ok1(tal_strreg(ctx, "hello world!", take(a), &b, invalid) == true);
109         ok1(streq(b, "hello"));
110         ok1(tal_count(b) == strlen(b) + 1);
111         ok1(tal_parent(b) == ctx);
112         tal_free(b);
113         ok1(no_children(ctx));
114
115         /* Take both. */
116         a = tal_strdup(ctx, "([a-z]+)");
117         ok1(tal_strreg(ctx, take(tal_strdup(ctx, "hello world!")),
118                        take(a), &b, invalid) == true);
119         ok1(streq(b, "hello"));
120         ok1(tal_count(b) == strlen(b) + 1);
121         ok1(tal_parent(b) == ctx);
122         tal_free(b);
123         ok1(no_children(ctx));
124
125         /* ... even if we fail to match. */
126         a = tal_strdup(ctx, "([a-z]+)");
127         ok1(tal_strreg(ctx, take(tal_strdup(ctx, "HELLO WORLD!")),
128                        take(a), &b, invalid) == false);
129         ok1(no_children(ctx));
130         tal_free(ctx);
131
132         /* Don't get fooled by \(! */
133         ok1(tal_strreg(ctx, "(hello) (world)!", "\\([a-z]*\\) \\([a-z]+\\)",
134                        invalid) == true);
135
136         return exit_status();
137 }