save
authorOlivier Matz <zer0@droids-corp.org>
Tue, 12 Sep 2017 16:28:34 +0000 (18:28 +0200)
committerOlivier Matz <zer0@droids-corp.org>
Tue, 12 Sep 2017 16:28:34 +0000 (18:28 +0200)
lib/ecoli_completed.c
lib/ecoli_completed.h
lib/ecoli_node_subset.c
lib/ecoli_test.c

index 15f3dc9..a600902 100644 (file)
@@ -48,7 +48,6 @@ struct ec_completed *ec_completed(void)
                return NULL;
 
        TAILQ_INIT(&completed->nodes);
-       TAILQ_INIT(&completed->matches);
 
        return completed;
 }
@@ -83,12 +82,12 @@ ec_node_complete_child(struct ec_node *node,
        child_state->node = node;
        ec_parsed_add_child(parsed_state, child_state);
 
-       ret = ec_completed_add_node(completed, child_state, node);
+       ret = ec_completed_add_node(completed, node);
        if (ret < 0)
                return ret;
 
        ret = node->type->complete(node, completed,
-                                       child_state, strvec);
+                               child_state, strvec);
        if (ret < 0)
                return ret;
 
@@ -174,11 +173,26 @@ static size_t strcmp_count(const char *s1, const char *s2)
        return i;
 }
 
-static struct ec_completed_item *
-ec_completed_item(enum ec_completed_type type, struct ec_parsed *state,
+static struct ec_completed_node *
+ec_completed_node(const struct ec_node *node)
+{
+       struct ec_completed_node *compnode = NULL;
+
+       compnode = ec_calloc(1, sizeof(*compnode));
+       if (compnode == NULL)
+               return NULL;
+
+       compnode->node = node;
+       TAILQ_INIT(&compnode->matches);
+
+       return compnode;
+}
+
+static struct ec_completed_match *
+ec_completed_match(enum ec_completed_type type, struct ec_parsed *state,
                const struct ec_node *node, const char *add)
 {
-       struct ec_completed_item *item = NULL;
+       struct ec_completed_match *item = NULL;
 
        item = ec_calloc(1, sizeof(*item));
        if (item == NULL)
@@ -221,7 +235,7 @@ fail:
                ec_free(item->path);
                ec_free(item->add);
        }
-       ec_completed_item_free(item);
+       ec_completed_match_free(item);
 
        return NULL;
 }
@@ -231,11 +245,19 @@ ec_completed_add_match(struct ec_completed *completed,
                struct ec_parsed *parsed_state,
                const struct ec_node *node, const char *add)
 {
-       struct ec_completed_item *item = NULL;
+       struct ec_completed_node *compnode = NULL;
+       struct ec_completed_match *item = NULL;
        int ret = -ENOMEM;
        size_t n;
 
-       item = ec_completed_item(EC_MATCH, parsed_state, node, add);
+       TAILQ_FOREACH(compnode, &completed->nodes, next) {
+               if (compnode->node == node)
+                       break;
+       }
+       if (compnode == NULL)
+               return -ENOENT;
+
+       item = ec_completed_match(EC_MATCH, parsed_state, node, add);
        if (item == NULL)
                goto fail;
 
@@ -252,42 +274,31 @@ ec_completed_add_match(struct ec_completed *completed,
                completed->count_match++;
        }
 
-       TAILQ_INSERT_TAIL(&completed->matches, item, next);
+       TAILQ_INSERT_TAIL(&compnode->matches, item, next);
        completed->count++;
 
        return 0;
 
 fail:
-       ec_completed_item_free(item);
+       ec_completed_match_free(item);
        return ret;
 }
 
 int
 ec_completed_add_node(struct ec_completed *completed,
-               struct ec_parsed *parsed_state,
                const struct ec_node *node)
 {
-#if 0
-       struct ec_completed_item *item = NULL;
-       int ret;
+       struct ec_completed_node *item = NULL;
 
-       item = ec_completed_item(EC_NO_MATCH, parsed_state, node, NULL);
+       item = ec_completed_node(node);
        if (item == NULL)
                return -ENOMEM;
 
-       ret = ec_completed_add_item(completed, item);
-       if (ret < 0) {
-               ec_completed_item_free(item);
-               return ret;
-       }
-#endif
-       (void)completed;
-       (void)parsed_state;
-       (void)node;
+       TAILQ_INSERT_TAIL(&completed->nodes, item, next);
        return 0;
 }
 
-void ec_completed_item_free(struct ec_completed_item *item)
+void ec_completed_match_free(struct ec_completed_match *item)
 {
        ec_free(item->add);
        ec_free(item->path);
@@ -301,45 +312,34 @@ ec_node_default_complete(const struct ec_node *gen_node,
                        struct ec_parsed *parsed,
                        const struct ec_strvec *strvec)
 {
-       (void)strvec;
+       (void)gen_node;
+       (void)completed;
+       (void)parsed;
 
        if (ec_strvec_len(strvec) != 1) //XXX needed?
                return 0;
 
-       if (ec_completed_add_node(completed, parsed, gen_node) < 0)
-               return -1;
-
        return 0;
 }
 
-void ec_completed_merge(struct ec_completed *completed1,
-       struct ec_completed *completed2)
-{
-       struct ec_completed_item *item;
-
-       assert(completed1 != NULL);
-       assert(completed2 != NULL);
-
-       while (!TAILQ_EMPTY(&completed2->matches)) {
-               item = TAILQ_FIRST(&completed2->matches);
-               TAILQ_REMOVE(&completed2->matches, item, next);
-               //ec_completed_add_item(completed1, item);
-       }
-
-       ec_completed_free(completed2);
-}
-
 void ec_completed_free(struct ec_completed *completed)
 {
-       struct ec_completed_item *item;
+       struct ec_completed_node *compnode;
+       struct ec_completed_match *item;
 
        if (completed == NULL)
                return;
 
-       while (!TAILQ_EMPTY(&completed->matches)) {
-               item = TAILQ_FIRST(&completed->matches);
-               TAILQ_REMOVE(&completed->matches, item, next);
-               ec_completed_item_free(item);
+       while (!TAILQ_EMPTY(&completed->nodes)) {
+               compnode = TAILQ_FIRST(&completed->nodes);
+               TAILQ_REMOVE(&completed->nodes, compnode, next);
+
+               while (!TAILQ_EMPTY(&compnode->matches)) {
+                       item = TAILQ_FIRST(&compnode->matches);
+                       TAILQ_REMOVE(&compnode->matches, item, next);
+                       ec_completed_match_free(item);
+               }
+               ec_free(compnode);
        }
        ec_free(completed->smallest_start);
        ec_free(completed);
@@ -347,7 +347,8 @@ void ec_completed_free(struct ec_completed *completed)
 
 void ec_completed_dump(FILE *out, const struct ec_completed *completed)
 {
-       struct ec_completed_item *item;
+       struct ec_completed_node *compnode;
+       struct ec_completed_match *item;
 
        if (completed == NULL || completed->count == 0) {
                fprintf(out, "no completion\n");
@@ -358,9 +359,12 @@ void ec_completed_dump(FILE *out, const struct ec_completed *completed)
                completed->count, completed->count_match,
                completed->smallest_start);
 
-       TAILQ_FOREACH(item, &completed->matches, next) {
-               fprintf(out, "add=<%s>, node=%p, node_type=%s\n",
-                       item->add, item->node, item->node->type->name);
+       TAILQ_FOREACH(compnode, &completed->nodes, next) {
+               fprintf(out, "node=%p, node_type=%s\n",
+                       compnode->node, compnode->node->type->name);
+               TAILQ_FOREACH(item, &compnode->matches, next) {
+                       fprintf(out, "add=<%s>\n", item->add); /* XXX comp type */
+               }
        }
 }
 
@@ -402,39 +406,53 @@ ec_completed_iter(struct ec_completed *completed,
 
        iter->completed = completed;
        iter->type = type;
-       iter->cur_item = NULL;
+       iter->cur_node = NULL;
+       iter->cur_match = NULL;
 
        return iter;
 }
 
-const struct ec_completed_item *ec_completed_iter_next(
+const struct ec_completed_match *ec_completed_iter_next(
        struct ec_completed_iter *iter)
 {
        const struct ec_completed *completed = iter->completed;
+       const struct ec_completed_node *cur_node;
+       const struct ec_completed_match *cur_match;
 
        if (completed == NULL)
                return NULL;
 
-       do {
-               if (iter->cur_item == NULL)
-                       iter->cur_item = TAILQ_FIRST(&completed->matches);
-               else
-                       iter->cur_item = TAILQ_NEXT(iter->cur_item, next);
+       cur_node = iter->cur_node;
+       cur_match = iter->cur_match;
 
-               if (iter->cur_item == NULL)
-                       break;
-
-               if (iter->cur_item->add == NULL &&
-                               (iter->type & EC_NO_MATCH))
-                       break;
-
-               if (iter->cur_item->add != NULL &&
-                               (iter->type & EC_MATCH))
-                       break;
+       /* first call */
+       if (cur_node == NULL) {
+               TAILQ_FOREACH(cur_node, &completed->nodes, next) {
+                       TAILQ_FOREACH(cur_match, &cur_node->matches, next) {
+                               if (cur_match != NULL)
+                                       goto found;
+                       }
+               }
+               return NULL;
+       } else {
+               cur_match = TAILQ_NEXT(cur_match, next);
+               if (cur_match != NULL)
+                       goto found;
+               cur_node = TAILQ_NEXT(cur_node, next);
+               while (cur_node != NULL) {
+                       cur_match = TAILQ_FIRST(&cur_node->matches);
+                       if (cur_match != NULL)
+                               goto found;
+                       cur_node = TAILQ_NEXT(cur_node, next);
+               }
+               return NULL;
+       }
 
-       } while (iter->cur_item != NULL);
+found:
+       iter->cur_node = cur_node;
+       iter->cur_match = cur_match;
 
-       return iter->cur_item;
+       return iter->cur_match;
 }
 
 void ec_completed_iter_free(struct ec_completed_iter *iter)
index 85601f7..6da00af 100644 (file)
@@ -40,8 +40,8 @@ enum ec_completed_type {
        EC_PARTIAL,
 };
 
-struct ec_completed_item {
-       TAILQ_ENTRY(ec_completed_item) next;
+struct ec_completed_match {
+       TAILQ_ENTRY(ec_completed_match) next;
        enum ec_completed_type type;
        const struct ec_node *node;
        char *add;
@@ -51,10 +51,12 @@ struct ec_completed_item {
        size_t pathlen;
 };
 
-TAILQ_HEAD(ec_completed_item_list, ec_completed_item);
+TAILQ_HEAD(ec_completed_match_list, ec_completed_match);
 
 struct ec_completed_node {
+       TAILQ_ENTRY(ec_completed_node) next;
        const struct ec_node *node;
+       struct ec_completed_match_list matches;
 };
 
 TAILQ_HEAD(ec_completed_node_list, ec_completed_node);
@@ -64,7 +66,6 @@ struct ec_completed {
        unsigned count_match;
        char *smallest_start;
        struct ec_completed_node_list nodes;
-       struct ec_completed_item_list matches;
 };
 
 /*
@@ -88,14 +89,12 @@ int ec_completed_add_match(struct ec_completed *completed,
                        struct ec_parsed *state,
                        const struct ec_node *node, const char *add);
 int ec_completed_add_node(struct ec_completed *completed,
-                       struct ec_parsed *state, const struct ec_node *node);
+                       const struct ec_node *node);
 int ec_completed_add_partial(struct ec_completed *completed,
                        struct ec_parsed *state, const struct ec_node *node,
                        const char *add);
 
-void ec_completed_item_free(struct ec_completed_item *item);
-void ec_completed_merge(struct ec_completed *completed1,
-       struct ec_completed *completed2);
+void ec_completed_match_free(struct ec_completed_match *item);
 void ec_completed_free(struct ec_completed *completed);
 void ec_completed_dump(FILE *out,
        const struct ec_completed *completed);
@@ -116,14 +115,15 @@ unsigned int ec_completed_count(
 struct ec_completed_iter {
        enum ec_completed_type type;
        const struct ec_completed *completed;
-       const struct ec_completed_item *cur_item;
+       const struct ec_completed_node *cur_node;
+       const struct ec_completed_match *cur_match;
 };
 
 struct ec_completed_iter *
 ec_completed_iter(struct ec_completed *completed,
        enum ec_completed_type type);
 
-const struct ec_completed_item *ec_completed_iter_next(
+const struct ec_completed_match *ec_completed_iter_next(
        struct ec_completed_iter *iter);
 
 void ec_completed_iter_free(struct ec_completed_iter *iter);
index 02b3c28..615abd5 100644 (file)
@@ -387,6 +387,10 @@ static int ec_node_subset_testcase(void)
                "", EC_NODE_ENDLIST,
                "foo", "bar", "bar2", "toto", "titi", EC_NODE_ENDLIST,
                "");
+       ret |= EC_TEST_CHECK_COMPLETE(node,
+               "", EC_NODE_ENDLIST,
+               "bar2", "bar", "foo", "toto", "titi", EC_NODE_ENDLIST,
+               "");
        ret |= EC_TEST_CHECK_COMPLETE(node,
                "bar", "bar2", "", EC_NODE_ENDLIST,
                "foo", "toto", "titi", EC_NODE_ENDLIST,
index 9b05575..efe4c04 100644 (file)
@@ -135,7 +135,7 @@ int ec_test_check_complete(struct ec_node *tk, ...)
             s != EC_NODE_ENDLIST;
             s = va_arg(ap, const char *)) {
                struct ec_completed_iter *iter;
-               const struct ec_completed_item *item;
+               const struct ec_completed_match *item;
 
                if (s == NULL) {
                        ret = -1;