1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2016, Olivier MATZ <zer0@droids-corp.org>
10 #include <ecoli_log.h>
11 #include <ecoli_malloc.h>
12 #include <ecoli_test.h>
13 #include <ecoli_strvec.h>
14 #include <ecoli_node.h>
15 #include <ecoli_parsed.h>
16 #include <ecoli_completed.h>
17 #include <ecoli_node_str.h>
19 EC_LOG_TYPE_REGISTER(node_str);
28 ec_node_str_parse(const struct ec_node *gen_node,
29 struct ec_parsed *state,
30 const struct ec_strvec *strvec)
32 struct ec_node_str *node = (struct ec_node_str *)gen_node;
37 if (ec_strvec_len(strvec) == 0)
38 return EC_PARSED_NOMATCH;
40 str = ec_strvec_val(strvec, 0);
41 if (strcmp(str, node->string) != 0)
42 return EC_PARSED_NOMATCH;
48 ec_node_str_complete(const struct ec_node *gen_node,
49 struct ec_completed *completed,
50 const struct ec_strvec *strvec)
52 struct ec_node_str *node = (struct ec_node_str *)gen_node;
56 if (ec_strvec_len(strvec) != 1)
59 str = ec_strvec_val(strvec, 0);
60 for (n = 0; n < node->len; n++) {
61 if (str[n] != node->string[n])
67 return EC_PARSED_NOMATCH;
69 if (ec_completed_add_item(completed, gen_node, NULL, EC_COMP_FULL,
70 str, node->string) < 0)
76 static const char *ec_node_str_desc(const struct ec_node *gen_node)
78 struct ec_node_str *node = (struct ec_node_str *)gen_node;
83 static void ec_node_str_free_priv(struct ec_node *gen_node)
85 struct ec_node_str *node = (struct ec_node_str *)gen_node;
87 ec_free(node->string);
90 static struct ec_node_type ec_node_str_type = {
92 .parse = ec_node_str_parse,
93 .complete = ec_node_str_complete,
94 .desc = ec_node_str_desc,
95 .size = sizeof(struct ec_node_str),
96 .free_priv = ec_node_str_free_priv,
99 EC_NODE_TYPE_REGISTER(ec_node_str_type);
101 int ec_node_str_set_str(struct ec_node *gen_node, const char *str)
103 struct ec_node_str *node = (struct ec_node_str *)gen_node;
106 ret = ec_node_check_type(gen_node, &ec_node_str_type);
112 ec_free(node->string);
113 node->string = ec_strdup(str);
114 if (node->string == NULL)
117 node->len = strlen(node->string);
122 struct ec_node *ec_node_str(const char *id, const char *str)
124 struct ec_node *gen_node = NULL;
126 gen_node = __ec_node(&ec_node_str_type, id);
127 if (gen_node == NULL)
130 if (ec_node_str_set_str(gen_node, str) < 0)
136 ec_node_free(gen_node);
140 /* LCOV_EXCL_START */
141 static int ec_node_str_testcase(void)
143 struct ec_node *node;
146 node = ec_node_str(EC_NO_ID, "foo");
148 EC_LOG(EC_LOG_ERR, "cannot create node\n");
151 testres |= EC_TEST_CHECK(!strcmp(ec_node_desc(node), "foo"),
152 "Invalid node description.");
153 testres |= EC_TEST_CHECK_PARSE(node, 1, "foo");
154 testres |= EC_TEST_CHECK_PARSE(node, 1, "foo", "bar");
155 testres |= EC_TEST_CHECK_PARSE(node, -1, "foobar");
156 testres |= EC_TEST_CHECK_PARSE(node, -1, " foo");
157 testres |= EC_TEST_CHECK_PARSE(node, -1, "");
160 node = ec_node_str(EC_NO_ID, "Здравствуйте");
162 EC_LOG(EC_LOG_ERR, "cannot create node\n");
165 testres |= EC_TEST_CHECK_PARSE(node, 1, "Здравствуйте");
166 testres |= EC_TEST_CHECK_PARSE(node, 1, "Здравствуйте",
168 testres |= EC_TEST_CHECK_PARSE(node, -1, "foo");
169 testres |= EC_TEST_CHECK_PARSE(node, -1, "");
172 /* an empty string node always matches */
173 node = ec_node_str(EC_NO_ID, "");
175 EC_LOG(EC_LOG_ERR, "cannot create node\n");
178 testres |= EC_TEST_CHECK_PARSE(node, 1, "");
179 testres |= EC_TEST_CHECK_PARSE(node, 1, "", "foo");
180 testres |= EC_TEST_CHECK_PARSE(node, -1, "foo");
183 /* test completion */
184 node = ec_node_str(EC_NO_ID, "foo");
186 EC_LOG(EC_LOG_ERR, "cannot create node\n");
189 testres |= EC_TEST_CHECK_COMPLETE(node,
192 testres |= EC_TEST_CHECK_COMPLETE(node,
194 "foo", EC_NODE_ENDLIST);
195 testres |= EC_TEST_CHECK_COMPLETE(node,
196 "f", EC_NODE_ENDLIST,
197 "foo", EC_NODE_ENDLIST);
198 testres |= EC_TEST_CHECK_COMPLETE(node,
199 "foo", EC_NODE_ENDLIST,
200 "foo", EC_NODE_ENDLIST);
201 testres |= EC_TEST_CHECK_COMPLETE(node,
202 "x", EC_NODE_ENDLIST,
210 static struct ec_test ec_node_str_test = {
212 .test = ec_node_str_testcase,
215 EC_TEST_REGISTER(ec_node_str_test);