1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2016, Olivier MATZ <zer0@droids-corp.org>
6 * @defgroup grammar_tree Grammar Tree
9 * @brief Libecoli grammar nodes.
11 * The grammar node is a main structure of the ecoli library, used to define
12 * how to match and complete the input tokens. A node is a generic object
14 * - a parse(node, input) method: check if an input matches
15 * - a complete(node, input) method: return possible completions for
17 * - some other methods to initialize, free, ...
19 * One basic example is the string node (ec_node_str). A node
20 * ec_node_str("foo") will match any token list starting with "foo",
23 * - ["foo", "bar", ...]
28 * A node ec_node_str("foo") will complete with "foo" if the input
29 * contains one token, with the same beginning than "foo":
34 * But it will not complete:
40 * A node can have child nodes. For instance, a sequence node
41 * ec_node_seq(ec_node_str("foo"), ec_node_str("bar")) will match
48 #include <sys/queue.h>
49 #include <sys/types.h>
53 * Node has no identifier.
55 #define EC_NO_ID "no-id"
63 struct ec_config_schema;
66 * Register a node type at library load.
68 * The node type is registered in a function that has the the
69 * constructor attribute: the function is called at library load.
72 * The name of the ec_node_type structure variable.
74 #define EC_NODE_TYPE_REGISTER(t) \
75 static void ec_node_init_##t(void); \
76 static void __attribute__((constructor, used)) \
77 ec_node_init_##t(void) \
79 if (ec_node_type_register(&t) < 0) \
81 "cannot register node type %s\n", \
86 * A list of node types.
88 TAILQ_HEAD(ec_node_type_list, ec_node_type);
91 * Function type used to configure a node.
93 * The function pointer is not called directly, the helper
94 * @ec_node_set_config() should be used instead.
97 * The node to configure.
99 * The configuration to apply to the node.
101 * 0 on success, negative on error (errno is set).
103 typedef int (*ec_node_set_config_t)(struct ec_node *node,
104 const struct ec_config *config);
107 * Parse a string vector using the given grammar tree.
109 * The function pointer is not called directly, the helpers @ec_parse(),
110 * ec_parse_strvec() or ec_parse_child() should be used instead.
112 * The implementation of this method for a node that manages children
113 * will call ec_parse_child(child, state, child_strvec).
116 * The root node of the grammar tree.
118 * A pointer to the leaf being parsed in the parsing tree. It can be
119 * used by a node to retrieve information from the current parsing
120 * tree. To get the root of the tree, @ec_pnode_get_root(state) should
123 * The string vector to be parsed.
125 * On success, return the number of consumed items in the string vector
126 * (can be 0) or EC_PARSE_NOMATCH if the node cannot parse the string
127 * vector. On error, a negative value is returned and errno is set.
129 typedef int (*ec_parse_t)(const struct ec_node *node,
130 struct ec_pnode *state,
131 const struct ec_strvec *strvec);
134 * Get completion items using the given grammar tree.
136 * The function pointer is not called directly, the helpers @ec_complete(),
137 * ec_complete_strvec() or ec_complete_child() should be used instead.
139 * This function completes the last element of the string vector.
140 * For instance, node.type->complete(node, comp, ["ls"]) will
141 * list all commands that starts with "ls", while
142 * node.type->complete(node, comp, ["ls", ""]) will list all
143 * possible values for the next argument.
145 * The implementation of this function is supposed to either:
146 * - call @ec_comp_add_item(node, comp, ...) for each completion item
147 * that should be added to the list. This is done in terminal nodes,
148 * for example in ec_node_str or ec_node_file.
149 * - call @ec_complete_child(child, comp, child_strvec) to let
150 * the children nodes add their own completion. This is the
151 * case of ec_node_or which trivially calls @ec_complete_child()
152 * on all its children, and of ec_node_seq, which has to
153 * do a more complex job (parsing strvec).
155 * A node that does not provide any method for the completion
156 * will fallback to ec_complete_unknown(): this helper returns
157 * a completion item of type EC_COMP_UNKNOWN, just to indicate
158 * that everything before the last element of the string vector
159 * has been parsed successfully, but we don't know how to
160 * complete the last element.
163 * The root node of the grammar tree.
165 * The current list of completion items, to be filled by the
166 * node.type->complete() method.
168 * The string vector to be completed.
170 * 0 on success, or a negative value on error (errno is set).
172 typedef int (*ec_complete_t)(const struct ec_node *node,
173 struct ec_comp *comp,
174 const struct ec_strvec *strvec);
179 typedef const char * (*ec_node_desc_t)(const struct ec_node *);
180 typedef int (*ec_node_init_priv_t)(struct ec_node *);
181 typedef void (*ec_node_free_priv_t)(struct ec_node *);
182 typedef size_t (*ec_node_get_children_count_t)(const struct ec_node *);
183 typedef int (*ec_node_get_child_t)(const struct ec_node *,
184 size_t i, struct ec_node **child, unsigned int *refs);
187 * A structure describing a node type.
189 struct ec_node_type {
190 TAILQ_ENTRY(ec_node_type) next; /**< Next in list. */
191 const char *name; /**< Node type name. */
192 /** Configuration schema array, must be terminated by a sentinel
193 * (.type = EC_CONFIG_TYPE_NONE). */
194 const struct ec_config_schema *schema;
195 ec_node_set_config_t set_config; /* validate/ack a config change */
197 ec_complete_t complete;
200 ec_node_init_priv_t init_priv;
201 ec_node_free_priv_t free_priv;
202 ec_node_get_children_count_t get_children_count;
203 ec_node_get_child_t get_child;
207 * Register a node type.
210 * A pointer to a ec_test structure describing the test
213 * 0 on success, negative value on error.
215 int ec_node_type_register(struct ec_node_type *type);
218 * Lookup node type by name
221 * The name of the node type to search.
223 * The node type if found, or NULL on error.
225 const struct ec_node_type *ec_node_type_lookup(const char *name);
228 * Dump registered log types
230 void ec_node_type_dump(FILE *out);
233 * Get the config schema of a node type.
235 const struct ec_config_schema *
236 ec_node_type_schema(const struct ec_node_type *type);
239 * Get the name of a node type.
242 ec_node_type_name(const struct ec_node_type *type);
244 enum ec_node_free_state {
245 EC_NODE_FREE_STATE_NONE,
246 EC_NODE_FREE_STATE_TRAVERSED,
247 EC_NODE_FREE_STATE_FREEABLE,
248 EC_NODE_FREE_STATE_NOT_FREEABLE,
249 EC_NODE_FREE_STATE_FREEING,
252 /* create a new node when the type is known, typically called from the node
254 struct ec_node *ec_node_from_type(const struct ec_node_type *type, const char *id);
256 /* create a new node */
257 struct ec_node *ec_node(const char *typename, const char *id);
259 struct ec_node *ec_node_clone(struct ec_node *node);
260 void ec_node_free(struct ec_node *node);
262 /* set configuration of a node
263 * after a call to this function, the config is
264 * owned by the node and must not be used by the caller
265 * on error, the config is freed. */
266 int ec_node_set_config(struct ec_node *node, struct ec_config *config);
268 /* get the current node configuration. Return NULL if no configuration. */
269 const struct ec_config *ec_node_get_config(struct ec_node *node);
271 size_t ec_node_get_children_count(const struct ec_node *node);
273 ec_node_get_child(const struct ec_node *node, size_t i,
274 struct ec_node **child, unsigned int *refs);
276 /* XXX add more accessors */
277 const struct ec_node_type *ec_node_type(const struct ec_node *node);
278 struct ec_dict *ec_node_attrs(const struct ec_node *node);
279 const char *ec_node_id(const struct ec_node *node);
280 const char *ec_node_desc(const struct ec_node *node);
282 void ec_node_dump(FILE *out, const struct ec_node *node);
283 struct ec_node *ec_node_find(struct ec_node *node, const char *id);
285 /* check the type of a node */
286 int ec_node_check_type(const struct ec_node *node,
287 const struct ec_node_type *type);
289 const char *ec_node_get_type_name(const struct ec_node *node);
292 * Get the pointer to the node private area.
297 * The pointer to the node private area.
299 void *ec_node_priv(const struct ec_node *node);