X-Git-Url: http://git.droids-corp.org/?p=protos%2Flibecoli.git;a=blobdiff_plain;f=src%2Fecoli_node_sh_lex.c;h=3f5abbc1e5e79d7c574724b5956e1b1495387b84;hp=e27f21bdb1135635c3a5a83aca54751fe2571dab;hb=HEAD;hpb=18d03456d96f7a086a2ccc82ce97fcf056848d90 diff --git a/src/ecoli_node_sh_lex.c b/src/ecoli_node_sh_lex.c index e27f21b..3f5abbc 100644 --- a/src/ecoli_node_sh_lex.c +++ b/src/ecoli_node_sh_lex.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,6 @@ EC_LOG_TYPE_REGISTER(node_sh_lex); struct ec_node_sh_lex { - struct ec_node gen; struct ec_node *child; }; @@ -213,13 +213,13 @@ static struct ec_strvec *tokenize(const char *str, int completion, } static int -ec_node_sh_lex_parse(const struct ec_node *gen_node, - struct ec_parse *state, +ec_node_sh_lex_parse(const struct ec_node *node, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { - struct ec_node_sh_lex *node = (struct ec_node_sh_lex *)gen_node; + struct ec_node_sh_lex *priv = ec_node_priv(node); struct ec_strvec *new_vec = NULL; - struct ec_parse *child_parse; + struct ec_pnode *child_parse; const char *str; int ret; @@ -234,16 +234,16 @@ ec_node_sh_lex_parse(const struct ec_node *gen_node, if (new_vec == NULL) goto fail; - ret = ec_node_parse_child(node->child, state, new_vec); + ret = ec_parse_child(priv->child, pstate, new_vec); if (ret < 0) goto fail; if ((unsigned)ret == ec_strvec_len(new_vec)) { ret = 1; } else if (ret != EC_PARSE_NOMATCH) { - child_parse = ec_parse_get_last_child(state); - ec_parse_unlink_child(state, child_parse); - ec_parse_free(child_parse); + child_parse = ec_pnode_get_last_child(pstate); + ec_pnode_unlink_child(child_parse); + ec_pnode_free(child_parse); ret = EC_PARSE_NOMATCH; } @@ -258,15 +258,14 @@ ec_node_sh_lex_parse(const struct ec_node *gen_node, } static int -ec_node_sh_lex_complete(const struct ec_node *gen_node, +ec_node_sh_lex_complete(const struct ec_node *node, struct ec_comp *comp, const struct ec_strvec *strvec) { - struct ec_node_sh_lex *node = (struct ec_node_sh_lex *)gen_node; - struct ec_comp *tmp_comp = NULL; + struct ec_node_sh_lex *priv = ec_node_priv(node); struct ec_strvec *new_vec = NULL; - struct ec_comp_iter *iter = NULL; struct ec_comp_item *item = NULL; + struct ec_htable *htable = NULL; char *new_str = NULL; const char *str; char missing_quote = '\0'; @@ -280,22 +279,27 @@ ec_node_sh_lex_complete(const struct ec_node *gen_node, if (new_vec == NULL) goto fail; - /* we will store the completions in a temporary struct, because - * we want to update them (ex: add missing quotes) */ - tmp_comp = ec_comp(ec_comp_get_state(comp)); - if (tmp_comp == NULL) + /* let's store the existing full completions in a htable */ + htable = ec_htable(); + if (htable == NULL) goto fail; - ret = ec_node_complete_child(node->child, tmp_comp, new_vec); + EC_COMP_FOREACH(item, comp, EC_COMP_FULL) { + if (ec_htable_set(htable, &item, sizeof(item), NULL, NULL) < 0) + goto fail; + } + + /* do the completion */ + ret = ec_complete_child(priv->child, comp, new_vec); if (ret < 0) goto fail; - /* add missing quote for full completions */ + /* add missing quote for any new full completions */ if (missing_quote != '\0') { - iter = ec_comp_iter(tmp_comp, EC_COMP_FULL); - if (iter == NULL) - goto fail; - while ((item = ec_comp_iter_next(iter)) != NULL) { + EC_COMP_FOREACH(item, comp, EC_COMP_FULL) { + if (ec_htable_has_key(htable, &item, sizeof(item))) + continue; + str = ec_comp_item_get_str(item); if (ec_asprintf(&new_str, "%c%s%c", missing_quote, str, missing_quote) < 0) { @@ -320,50 +324,47 @@ ec_node_sh_lex_complete(const struct ec_node *gen_node, } } - ec_comp_iter_free(iter); ec_strvec_free(new_vec); - - ec_comp_merge(comp, tmp_comp); + ec_htable_free(htable); return 0; fail: - ec_comp_free(tmp_comp); - ec_comp_iter_free(iter); ec_strvec_free(new_vec); ec_free(new_str); + ec_htable_free(htable); return -1; } -static void ec_node_sh_lex_free_priv(struct ec_node *gen_node) +static void ec_node_sh_lex_free_priv(struct ec_node *node) { - struct ec_node_sh_lex *node = (struct ec_node_sh_lex *)gen_node; + struct ec_node_sh_lex *priv = ec_node_priv(node); - ec_node_free(node->child); + ec_node_free(priv->child); } static size_t -ec_node_sh_lex_get_children_count(const struct ec_node *gen_node) +ec_node_sh_lex_get_children_count(const struct ec_node *node) { - struct ec_node_sh_lex *node = (struct ec_node_sh_lex *)gen_node; + struct ec_node_sh_lex *priv = ec_node_priv(node); - if (node->child) + if (priv->child) return 1; return 0; } static int -ec_node_sh_lex_get_child(const struct ec_node *gen_node, size_t i, +ec_node_sh_lex_get_child(const struct ec_node *node, size_t i, struct ec_node **child, unsigned int *refs) { - struct ec_node_sh_lex *node = (struct ec_node_sh_lex *)gen_node; + struct ec_node_sh_lex *priv = ec_node_priv(node); if (i >= 1) return -1; *refs = 1; - *child = node->child; + *child = priv->child; return 0; } @@ -381,20 +382,22 @@ EC_NODE_TYPE_REGISTER(ec_node_sh_lex_type); struct ec_node *ec_node_sh_lex(const char *id, struct ec_node *child) { - struct ec_node_sh_lex *node = NULL; + struct ec_node *node = NULL; + struct ec_node_sh_lex *priv; if (child == NULL) return NULL; - node = (struct ec_node_sh_lex *)ec_node_from_type(&ec_node_sh_lex_type, id); + node = ec_node_from_type(&ec_node_sh_lex_type, id); if (node == NULL) { ec_node_free(child); return NULL; } - node->child = child; + priv = ec_node_priv(node); + priv->child = child; - return &node->gen; + return node; } /* LCOV_EXCL_START */ @@ -439,44 +442,44 @@ static int ec_node_sh_lex_testcase(void) return -1; } testres |= EC_TEST_CHECK_COMPLETE(node, - "", EC_NODE_ENDLIST, - "foo", EC_NODE_ENDLIST); + "", EC_VA_END, + "foo", EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - " ", EC_NODE_ENDLIST, - "foo", EC_NODE_ENDLIST); + " ", EC_VA_END, + "foo", EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - "f", EC_NODE_ENDLIST, - "foo", EC_NODE_ENDLIST); + "f", EC_VA_END, + "foo", EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - "foo", EC_NODE_ENDLIST, - "foo", EC_NODE_ENDLIST); + "foo", EC_VA_END, + "foo", EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - "foo ", EC_NODE_ENDLIST, - "bar", "toto", EC_NODE_ENDLIST); + "foo ", EC_VA_END, + "bar", "toto", EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - "foo t", EC_NODE_ENDLIST, - "toto", EC_NODE_ENDLIST); + "foo t", EC_VA_END, + "toto", EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - "foo b", EC_NODE_ENDLIST, - "bar", EC_NODE_ENDLIST); + "foo b", EC_VA_END, + "bar", EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - "foo bar", EC_NODE_ENDLIST, - "bar", EC_NODE_ENDLIST); + "foo bar", EC_VA_END, + "bar", EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - "foo bar ", EC_NODE_ENDLIST, - "titi", EC_NODE_ENDLIST); + "foo bar ", EC_VA_END, + "titi", EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - "foo toto bar ", EC_NODE_ENDLIST, - "titi", EC_NODE_ENDLIST); + "foo toto bar ", EC_VA_END, + "titi", EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - "x", EC_NODE_ENDLIST, - EC_NODE_ENDLIST); + "x", EC_VA_END, + EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - "foo barx", EC_NODE_ENDLIST, - EC_NODE_ENDLIST); + "foo barx", EC_VA_END, + EC_VA_END); testres |= EC_TEST_CHECK_COMPLETE(node, - "foo 'b", EC_NODE_ENDLIST, - "'bar'", EC_NODE_ENDLIST); + "foo 'b", EC_VA_END, + "'bar'", EC_VA_END); ec_node_free(node); return testres;