#include <ecoli_malloc.h>
#include <ecoli_string.h>
#include <ecoli_strvec.h>
-#include <ecoli_keyval.h>
+#include <ecoli_dict.h>
#include <ecoli_log.h>
#include <ecoli_test.h>
#include <ecoli_node.h>
char *full; /* the full token after completion */
char *completion; /* chars that are added, NULL if not applicable */
char *display; /* what should be displayed by help/completers */
- struct ec_keyval *attrs;
+ struct ec_dict *attrs;
};
-struct ec_comp *ec_comp(struct ec_parse *state)
+TAILQ_HEAD(ec_comp_item_list, ec_comp_item);
+
+struct ec_comp_group {
+ /* XXX counts ? */
+ TAILQ_ENTRY(ec_comp_group) next;
+ const struct ec_node *node;
+ struct ec_comp_item_list items;
+ struct ec_pnode *state;
+ struct ec_dict *attrs;
+};
+
+TAILQ_HEAD(ec_comp_group_list, ec_comp_group);
+
+struct ec_comp {
+ unsigned count;
+ unsigned count_full;
+ unsigned count_partial;
+ unsigned count_unknown;
+ struct ec_pnode *cur_state;
+ struct ec_comp_group *cur_group;
+ struct ec_comp_group_list groups;
+ struct ec_dict *attrs;
+};
+
+struct ec_comp *ec_comp(struct ec_pnode *state)
{
struct ec_comp *comp = NULL;
if (comp == NULL)
goto fail;
- comp->attrs = ec_keyval();
+ comp->attrs = ec_dict();
if (comp->attrs == NULL)
goto fail;
fail:
if (comp != NULL)
- ec_keyval_free(comp->attrs);
+ ec_dict_free(comp->attrs);
ec_free(comp);
return NULL;
}
-struct ec_parse *ec_comp_get_state(struct ec_comp *comp)
+struct ec_pnode *ec_comp_get_state(const struct ec_comp *comp)
{
return comp->cur_state;
}
+struct ec_comp_group *ec_comp_get_group(const struct ec_comp *comp)
+{
+ return comp->cur_group;
+}
+
+struct ec_dict *ec_comp_get_attrs(const struct ec_comp *comp)
+{
+ return comp->attrs;
+}
+
int
-ec_node_complete_child(const struct ec_node *node,
+ec_complete_child(const struct ec_node *node,
struct ec_comp *comp,
const struct ec_strvec *strvec)
{
- struct ec_parse *child_state, *cur_state;
+ struct ec_pnode *child_state, *cur_state;
struct ec_comp_group *cur_group;
int ret;
+ //XXX call ec_complete_unknown() instead, as
+ //described in API doc.
if (ec_node_type(node)->complete == NULL) {
errno = ENOTSUP;
return -1;
/* save previous parse state, prepare child state */
cur_state = comp->cur_state;
- child_state = ec_parse(node);
+ child_state = ec_pnode(node);
if (child_state == NULL)
return -1;
if (cur_state != NULL)
- ec_parse_link_child(cur_state, child_state);
+ ec_pnode_link_child(cur_state, child_state);
comp->cur_state = child_state;
cur_group = comp->cur_group;
comp->cur_group = NULL;
/* restore parent parse state */
if (cur_state != NULL) {
- ec_parse_unlink_child(cur_state, child_state);
- assert(!ec_parse_has_child(child_state));
+ ec_pnode_unlink_child(cur_state, child_state);
+ assert(!ec_pnode_has_child(child_state));
}
- ec_parse_free(child_state);
+ ec_pnode_free(child_state);
comp->cur_state = cur_state;
comp->cur_group = cur_group;
return 0;
}
-struct ec_comp *ec_node_complete_strvec(const struct ec_node *node,
+struct ec_comp *ec_complete_strvec(const struct ec_node *node,
const struct ec_strvec *strvec)
{
struct ec_comp *comp = NULL;
if (comp == NULL)
goto fail;
- ret = ec_node_complete_child(node, comp, strvec);
+ ret = ec_complete_child(node, comp, strvec);
if (ret < 0)
goto fail;
return NULL;
}
-struct ec_comp *ec_node_complete(const struct ec_node *node,
+struct ec_comp *ec_complete(const struct ec_node *node,
const char *str)
{
struct ec_strvec *strvec = NULL;
if (ec_strvec_add(strvec, str) < 0)
goto fail;
- comp = ec_node_complete_strvec(node, strvec);
+ comp = ec_complete_strvec(node, strvec);
if (comp == NULL)
goto fail;
}
static struct ec_comp_group *
-ec_comp_group(const struct ec_node *node, struct ec_parse *parse)
+ec_comp_group(const struct ec_node *node, struct ec_pnode *parse)
{
struct ec_comp_group *grp = NULL;
if (grp == NULL)
return NULL;
- grp->attrs = ec_keyval();
+ grp->attrs = ec_dict();
if (grp->attrs == NULL)
goto fail;
- grp->state = ec_parse_dup(parse);
+ grp->state = ec_pnode_dup(parse);
if (grp->state == NULL)
goto fail;
fail:
if (grp != NULL) {
- ec_parse_free(grp->state);
- ec_keyval_free(grp->attrs);
+ ec_pnode_free(grp->state);
+ ec_dict_free(grp->attrs);
}
ec_free(grp);
return NULL;
const char *start, const char *full)
{
struct ec_comp_item *item = NULL;
- struct ec_keyval *attrs = NULL;
+ struct ec_dict *attrs = NULL;
char *comp_cp = NULL, *start_cp = NULL;
char *full_cp = NULL, *display_cp = NULL;
if (item == NULL)
goto fail;
- attrs = ec_keyval();
+ attrs = ec_dict();
if (attrs == NULL)
goto fail;
return item;
fail:
- ec_keyval_free(attrs);
+ ec_dict_free(attrs);
ec_free(comp_cp);
ec_free(start_cp);
ec_free(full_cp);
ec_free(item->start);
ec_free(item->completion);
ec_free(item->display);
- ec_keyval_free(item->attrs);
+ ec_dict_free(item->attrs);
ec_free(item);
}
return -1;
}
+/* XXX move in helpers + rename ? */
/* return a completion item of type "unknown" */
int
-ec_node_complete_unknown(const struct ec_node *gen_node,
+ec_complete_unknown(const struct ec_node *gen_node,
struct ec_comp *comp,
const struct ec_strvec *strvec)
{
TAILQ_REMOVE(&grp->items, item, next);
ec_comp_item_free(item);
}
- ec_parse_free(ec_parse_get_root(grp->state));
- ec_keyval_free(grp->attrs);
+ ec_pnode_free(ec_pnode_get_root(grp->state));
+ ec_dict_free(grp->attrs);
ec_free(grp);
}
+const struct ec_node *
+ec_comp_group_get_node(const struct ec_comp_group *grp)
+{
+ return grp->node;
+}
+
+const struct ec_pnode *
+ec_comp_group_get_state(const struct ec_comp_group *grp)
+{
+ return grp->state;
+}
+
+const struct ec_dict *
+ec_comp_group_get_attrs(const struct ec_comp_group *grp)
+{
+ return grp->attrs;
+}
+
void ec_comp_free(struct ec_comp *comp)
{
struct ec_comp_group *grp;
TAILQ_REMOVE(&comp->groups, grp, next);
ec_comp_group_free(grp);
}
- ec_keyval_free(comp->attrs);
+ ec_dict_free(comp->attrs);
ec_free(comp);
}
if (node == NULL)
goto fail;
- c = ec_node_complete(node, "xcdscds");
+ c = ec_complete(node, "xcdscds");
testres |= EC_TEST_CHECK(
c != NULL && ec_comp_count(c, EC_COMP_ALL) == 0,
"complete count should is not 0\n");
ec_comp_free(c);
- c = ec_node_complete(node, "x");
+ c = ec_complete(node, "x");
testres |= EC_TEST_CHECK(
c != NULL && ec_comp_count(c, EC_COMP_ALL) == 1,
"complete count should is not 1\n");
ec_comp_free(c);
- c = ec_node_complete(node, "");
+ c = ec_complete(node, "");
testres |= EC_TEST_CHECK(
c != NULL && ec_comp_count(c, EC_COMP_ALL) == 2,
"complete count should is not 2\n");