/* if result is not the best, ignore */
if (result.parsed_len < best_result.parsed_len) {
- struct ec_parsed *child_parsed;
-
memset(&result, 0, sizeof(result));
- child_parsed = ec_parsed_get_last_child(state);
- ec_parsed_del_child(state, child_parsed);
- ec_parsed_free(child_parsed);
+ ec_parsed_del_last_child(state);
continue;
}
return ret;
}
-static struct ec_completed *
+static int
__ec_node_subset_complete(struct ec_node **table, size_t table_len,
- const struct ec_strvec *strvec)
+ struct ec_completed *completed,
+ struct ec_parsed *parsed,
+ const struct ec_strvec *strvec)
{
- struct ec_completed *completed = NULL;
- struct ec_completed *child_completed = NULL;
struct ec_strvec *childvec = NULL;
- struct ec_parsed *parsed = NULL;
struct ec_node *save;
size_t i, len;
+ int ret;
/*
* example with table = [a, b, c]
* + __subset_complete([a, b], childvec) if c matches
*/
- completed = ec_completed();
- if (completed == NULL)
- goto fail;
-
/* first, try to complete with each node of the table */
for (i = 0; i < table_len; i++) {
if (table[i] == NULL)
continue;
- child_completed = ec_node_complete_strvec(table[i],
- strvec);
-
- if (child_completed == NULL)
+ ret = ec_node_complete_child(table[i],
+ completed, parsed, strvec);
+ if (ret < 0)
goto fail;
-
- ec_completed_merge(completed, child_completed);
- child_completed = NULL;
}
/* then, if a node matches, advance in strvec and try to complete with
if (table[i] == NULL)
continue;
- parsed = ec_node_parse_strvec(table[i], strvec);
- if (parsed == NULL)
- goto fail;
-
- if (!ec_parsed_matches(parsed)) {
- ec_parsed_free(parsed);
- parsed = NULL;
+ ret = ec_node_parse_child(table[i], parsed, strvec);
+ if (ret == EC_PARSED_NOMATCH)
continue;
- }
+ else if (ret < 0)
+ goto fail;
- len = ec_parsed_len(parsed);
+ len = ret;
childvec = ec_strvec_ndup(strvec, len,
ec_strvec_len(strvec) - len);
- if (childvec == NULL)
+ if (childvec == NULL) {
+ ec_parsed_del_last_child(parsed);
goto fail;
+ }
save = table[i];
table[i] = NULL;
- child_completed = __ec_node_subset_complete(table,
- table_len, childvec);
+ ret = __ec_node_subset_complete(table, table_len,
+ completed, parsed, childvec);
table[i] = save;
ec_strvec_free(childvec);
childvec = NULL;
+ ec_parsed_del_last_child(parsed);
- if (child_completed == NULL)
+ if (ret < 0)
goto fail;
-
- ec_completed_merge(completed, child_completed);
- child_completed = NULL;
-
- ec_parsed_free(parsed);
- parsed = NULL;
}
- return completed;
-fail:
- ec_parsed_free(parsed);
- ec_completed_free(child_completed);
- ec_completed_free(completed);
+ return 0;
- return NULL;
+fail:
+ return -1;
}
-static struct ec_completed *ec_node_subset_complete(const struct ec_node *gen_node,
- const struct ec_strvec *strvec)
+static int
+ec_node_subset_complete(const struct ec_node *gen_node,
+ struct ec_completed *completed,
+ struct ec_parsed *parsed,
+ const struct ec_strvec *strvec)
{
struct ec_node_subset *node = (struct ec_node_subset *)gen_node;
- return __ec_node_subset_complete(node->table, node->len, strvec);
+ return __ec_node_subset_complete(node->table, node->len, completed,
+ parsed, strvec);
}
static void ec_node_subset_free_priv(struct ec_node *gen_node)
return NULL;
}
+/* LCOV_EXCL_START */
static int ec_node_subset_testcase(void)
{
struct ec_node *node;
return ret;
}
+/* LCOV_EXCL_STOP */
static struct ec_test ec_node_subset_test = {
.name = "node_subset",