9d6d5d599819055eac5bd67e0878745a64457538
[protos/libecoli.git] / libecoli / ecoli_parse.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2016, Olivier MATZ <zer0@droids-corp.org>
3  */
4
5 /**
6  * Node parse API.
7  *
8  * The parse operation is to check if an input (a string or vector of
9  * strings) matches the node tree. On success, the result is stored in a
10  * tree that describes which part of the input matches which node.
11  */
12
13 #ifndef ECOLI_PARSE_
14 #define ECOLI_PARSE_
15
16 #include <sys/queue.h>
17 #include <sys/types.h>
18 #include <limits.h>
19 #include <stdio.h>
20 #include <stdbool.h>
21
22 struct ec_node;
23 struct ec_parse;
24
25 /**
26  * Create an empty parse tree.
27  *
28  * @return
29  *   The empty parse tree.
30  */
31 struct ec_parse *ec_parse(const struct ec_node *node);
32
33 /**
34  *
35  *
36  *
37  */
38 void ec_parse_free(struct ec_parse *parse);
39
40 /**
41  *
42  *
43  *
44  */
45 void ec_parse_free_children(struct ec_parse *parse);
46
47 /**
48  *
49  *
50  *
51  */
52 struct ec_parse *ec_parse_dup(const struct ec_parse *parse);
53
54 /**
55  *
56  *
57  *
58  */
59 const struct ec_strvec *ec_parse_strvec(const struct ec_parse *parse);
60
61 /* a NULL return value is an error, with errno set
62   ENOTSUP: no ->parse() operation
63 */
64 /**
65  *
66  *
67  *
68  */
69 struct ec_parse *ec_node_parse(const struct ec_node *node, const char *str);
70
71 /**
72  *
73  *
74  *
75  */
76 struct ec_parse *ec_node_parse_strvec(const struct ec_node *node,
77                                 const struct ec_strvec *strvec);
78
79 /**
80  *
81  *
82  *
83  */
84 #define EC_PARSE_NOMATCH INT_MAX
85
86 /* internal: used by nodes
87  *
88  * state is the current parse tree, which is built piece by piece while
89  *   parsing the node tree: ec_node_parse_child() creates a new child in
90  *   this state parse tree, and calls the parse() method for the child
91  *   node, with state pointing to this new child. If it does not match,
92  *   the child is removed in the state, else it is kept, with its
93  *   possible descendants.
94  *
95  * return:
96  * the number of matched strings in strvec on success
97  * EC_PARSE_NOMATCH (positive) if it does not match
98  * -1 on error, and errno is set
99  */
100 int ec_node_parse_child(const struct ec_node *node,
101                         struct ec_parse *state,
102                         const struct ec_strvec *strvec);
103
104 /**
105  *
106  *
107  *
108  */
109 void ec_parse_link_child(struct ec_parse *parse,
110                         struct ec_parse *child);
111 /**
112  *
113  *
114  *
115  */
116 void ec_parse_unlink_child(struct ec_parse *parse,
117                         struct ec_parse *child);
118
119 /* keep the const */
120 #define ec_parse_get_root(parse) ({                             \
121         const struct ec_parse *p_ = parse; /* check type */     \
122         struct ec_parse *parse_ = (struct ec_parse *)parse;     \
123         typeof(parse) res_;                                     \
124         (void)p_;                                               \
125         res_ = __ec_parse_get_root(parse_);                     \
126         res_;                                                   \
127 })
128
129 /**
130  *
131  *
132  *
133  */
134 struct ec_parse *__ec_parse_get_root(struct ec_parse *parse);
135
136 /**
137  *
138  *
139  *
140  */
141 struct ec_parse *ec_parse_get_parent(const struct ec_parse *parse);
142
143 /**
144  * Get the first child of a tree.
145  *
146  */
147 struct ec_parse *ec_parse_get_first_child(const struct ec_parse *parse);
148
149 /**
150  *
151  *
152  *
153  */
154 struct ec_parse *ec_parse_get_last_child(const struct ec_parse *parse);
155
156 /**
157  *
158  *
159  *
160  */
161 struct ec_parse *ec_parse_get_next(const struct ec_parse *parse);
162
163 /**
164  *
165  *
166  *
167  */
168 #define EC_PARSE_FOREACH_CHILD(child, parse)                    \
169         for (child = ec_parse_get_first_child(parse);           \
170                 child != NULL;                                  \
171                 child = ec_parse_get_next(child))               \
172
173 /**
174  *
175  *
176  *
177  */
178 bool ec_parse_has_child(const struct ec_parse *parse);
179
180 /**
181  *
182  *
183  *
184  */
185 const struct ec_node *ec_parse_get_node(const struct ec_parse *parse);
186
187 /**
188  *
189  *
190  *
191  */
192 void ec_parse_del_last_child(struct ec_parse *parse);
193
194 /**
195  *
196  *
197  *
198  */
199 struct ec_keyval *ec_parse_get_attrs(struct ec_parse *parse);
200
201 /**
202  *
203  *
204  *
205  */
206 void ec_parse_dump(FILE *out, const struct ec_parse *parse);
207
208 /**
209  *
210  *
211  *
212  */
213 struct ec_parse *ec_parse_find_first(struct ec_parse *parse,
214         const char *id);
215
216 /**
217  * Iterate among parse tree
218  *
219  * Use it with:
220  * for (iter = state; iter != NULL; iter = ec_parse_iter_next(iter))
221  */
222 struct ec_parse *ec_parse_iter_next(struct ec_parse *parse);
223
224 /**
225  *
226  *
227  *
228  */
229 size_t ec_parse_len(const struct ec_parse *parse);
230
231 /**
232  *
233  *
234  *
235  */
236 size_t ec_parse_matches(const struct ec_parse *parse);
237
238 #endif