save
authorOlivier Matz <zer0@droids-corp.org>
Thu, 24 Aug 2017 19:28:41 +0000 (21:28 +0200)
committerOlivier Matz <zer0@droids-corp.org>
Thu, 24 Aug 2017 19:28:41 +0000 (21:28 +0200)
18 files changed:
lib/Makefile
lib/ecoli_completed.c
lib/ecoli_completed.h
lib/ecoli_node.h
lib/ecoli_node_cmd.c
lib/ecoli_node_expr.c
lib/ecoli_node_many.c
lib/ecoli_node_once.c
lib/ecoli_node_option.c
lib/ecoli_node_or.c
lib/ecoli_node_seq.c
lib/ecoli_node_sh_lex.c
lib/ecoli_node_str.c
lib/ecoli_node_subset.c
lib/ecoli_node_weakref.c
lib/ecoli_parsed.h
lib/ecoli_test.c
lib/main-readline.c

index 107cb80..29df719 100644 (file)
@@ -76,7 +76,7 @@ ldflags-$(O)test = -rdynamic
 exe-y-$(O)test = $(srcs) main.c
 
 ldflags-$(O)readline = -lreadline -ltermcap
-exe-y-$(O)readline = $(srcs) main-readline.c
+#exe-y-$(O)readline = $(srcs) main-readline.c
 
 include $(ECOLI)/mk/ecoli-post.mk
 
index 0b0e641..15f3dc9 100644 (file)
@@ -53,68 +53,88 @@ struct ec_completed *ec_completed(void)
        return completed;
 }
 
-struct ec_completed *
+/* XXX on error, states are not freed ?
+ * they can be left in a bad state and should not be reused */
+int
 ec_node_complete_child(struct ec_node *node,
-               struct ec_parsed *state,
+               struct ec_completed *completed,
+               struct ec_parsed *parsed_state,
                const struct ec_strvec *strvec)
 {
-       struct ec_completed *completed;
-       struct ec_parsed *child;
+       struct ec_parsed *child_state = NULL;
        int ret;
 
        /* build the node if required */
        if (node->type->build != NULL) {
                if ((node->flags & EC_NODE_F_BUILT) == 0) {
                        ret = node->type->build(node);
-                       if (ret < 0) {
-                               errno = -ret;
-                               return NULL;
-                       }
+                       if (ret < 0)
+                               return ret;
                }
        }
        node->flags |= EC_NODE_F_BUILT;
 
-       if (node->type->complete == NULL) {
-               errno = ENOTSUP;
-               return NULL;
-       }
+       if (node->type->complete == NULL)
+               return -ENOTSUP;
 
-       child = ec_parsed();
-       if (child == NULL)
-               return NULL;
+       child_state = ec_parsed();
+       if (child_state == NULL)
+               return -ENOMEM;
+       child_state->node = node;
+       ec_parsed_add_child(parsed_state, child_state);
+
+       ret = ec_completed_add_node(completed, child_state, node);
+       if (ret < 0)
+               return ret;
 
-       child->node = node;
-       ec_parsed_add_child(state, child);
-       completed = node->type->complete(node, child, strvec);
+       ret = node->type->complete(node, completed,
+                                       child_state, strvec);
+       if (ret < 0)
+               return ret;
 
 #if 0 // XXX dump
        printf("----------------------------------------------------------\n");
        ec_node_dump(stdout, node);
        ec_strvec_dump(stdout, strvec);
        ec_completed_dump(stdout, completed);
-       ec_parsed_dump(stdout, state);
+       ec_parsed_dump(stdout, parsed_state);
 #endif
 
-       ec_parsed_del_child(state, child);
-       assert(TAILQ_EMPTY(&child->children));
-       ec_parsed_free(child);
+       ec_parsed_del_child(parsed_state, child_state);
+       assert(TAILQ_EMPTY(&child_state->children));
+       ec_parsed_free(child_state);
 
-       return completed;
+       return 0;
 }
 
 struct ec_completed *ec_node_complete_strvec(struct ec_node *node,
        const struct ec_strvec *strvec)
 {
-       struct ec_parsed *state = ec_parsed();
-       struct ec_completed *completed;
+       struct ec_parsed *parsed_state = NULL;
+       struct ec_completed *completed = NULL;
+       int ret;
 
-       if (state == NULL)
-               return NULL;
+       parsed_state = ec_parsed();
+       if (parsed_state == NULL)
+               goto fail;
 
-       completed = ec_node_complete_child(node, state, strvec);
-       ec_parsed_free(state);
+       completed = ec_completed();
+       if (completed == NULL)
+               goto fail;
+
+       ret = ec_node_complete_child(node, completed,
+                               parsed_state, strvec);
+       if (ret < 0)
+               goto fail;
+
+       ec_parsed_free(parsed_state);
 
        return completed;
+
+fail:
+       ec_parsed_free(parsed_state);
+       ec_completed_free(completed);
+       return NULL;
 }
 
 struct ec_completed *ec_node_complete(struct ec_node *node,
@@ -206,16 +226,24 @@ fail:
        return NULL;
 }
 
-static int ec_completed_add_item(struct ec_completed *completed,
-                               struct ec_completed_item *item)
+int
+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;
+       int ret = -ENOMEM;
        size_t n;
 
+       item = ec_completed_item(EC_MATCH, parsed_state, node, add);
+       if (item == NULL)
+               goto fail;
+
        if (item->add != NULL) {
                if (completed->smallest_start == NULL) {
                        completed->smallest_start = ec_strdup(item->add);
                        if (completed->smallest_start == NULL)
-                               return -ENOMEM;
+                               goto fail;
                } else {
                        n = strcmp_count(item->add,
                                completed->smallest_start);
@@ -228,35 +256,22 @@ static int ec_completed_add_item(struct ec_completed *completed,
        completed->count++;
 
        return 0;
-}
 
-int ec_completed_add_match(struct ec_completed *completed,
-                       struct ec_parsed *state,
-                       const struct ec_node *node, const char *add)
-{
-       struct ec_completed_item *item;
-       int ret;
-
-       item = ec_completed_item(EC_MATCH, state, node, add);
-       if (item == NULL)
-               return -ENOMEM;
-
-       ret = ec_completed_add_item(completed, item);
-       if (ret < 0) {
-               ec_completed_item_free(item);
-               return ret;
-       }
-
-       return 0;
+fail:
+       ec_completed_item_free(item);
+       return ret;
 }
 
-int ec_completed_add_no_match(struct ec_completed *completed,
-                       struct ec_parsed *state, const struct ec_node *node)
+int
+ec_completed_add_node(struct ec_completed *completed,
+               struct ec_parsed *parsed_state,
+               const struct ec_node *node)
 {
-       struct ec_completed_item *item;
+#if 0
+       struct ec_completed_item *item = NULL;
        int ret;
 
-       item = ec_completed_item(EC_NO_MATCH, state, node, NULL);
+       item = ec_completed_item(EC_NO_MATCH, parsed_state, node, NULL);
        if (item == NULL)
                return -ENOMEM;
 
@@ -265,7 +280,10 @@ int ec_completed_add_no_match(struct ec_completed *completed,
                ec_completed_item_free(item);
                return ret;
        }
-
+#endif
+       (void)completed;
+       (void)parsed_state;
+       (void)node;
        return 0;
 }
 
@@ -276,29 +294,22 @@ void ec_completed_item_free(struct ec_completed_item *item)
        ec_free(item);
 }
 
-/* default completion function: return a no-match element */
-struct ec_completed *ec_node_default_complete(const struct ec_node *gen_node,
-                                       struct ec_parsed *state,
-                                       const struct ec_strvec *strvec)
+/* default completion function: return a no-item element */
+int
+ec_node_default_complete(const struct ec_node *gen_node,
+                       struct ec_completed *completed,
+                       struct ec_parsed *parsed,
+                       const struct ec_strvec *strvec)
 {
-       struct ec_completed *completed;
-
        (void)strvec;
-       (void)state;
 
-       completed = ec_completed();
-       if (completed == NULL)
-               return NULL;
+       if (ec_strvec_len(strvec) != 1) //XXX needed?
+               return 0;
 
-       if (ec_strvec_len(strvec) != 1)
-               return completed;
+       if (ec_completed_add_node(completed, parsed, gen_node) < 0)
+               return -1;
 
-       if (ec_completed_add_no_match(completed, state, gen_node) < 0) {
-               ec_completed_free(completed);
-               return NULL;
-       }
-
-       return completed;
+       return 0;
 }
 
 void ec_completed_merge(struct ec_completed *completed1,
@@ -312,7 +323,7 @@ void ec_completed_merge(struct ec_completed *completed1,
        while (!TAILQ_EMPTY(&completed2->matches)) {
                item = TAILQ_FIRST(&completed2->matches);
                TAILQ_REMOVE(&completed2->matches, item, next);
-               ec_completed_add_item(completed1, item);
+               //ec_completed_add_item(completed1, item);
        }
 
        ec_completed_free(completed2);
index 4d0045e..85601f7 100644 (file)
@@ -35,9 +35,9 @@
 struct ec_node;
 
 enum ec_completed_type {
-       EC_NO_MATCH = 1,
-       EC_MATCH = 2,
-       EC_PARTIAL = 4,
+       EC_NO_MATCH,
+       EC_MATCH,
+       EC_PARTIAL,
 };
 
 struct ec_completed_item {
@@ -77,17 +77,21 @@ struct ec_completed *ec_node_complete_strvec(struct ec_node *node,
        const struct ec_strvec *strvec);
 
 /* internal: used by nodes */
-struct ec_completed *ec_node_complete_child(struct ec_node *node,
-                                       struct ec_parsed *state,
-                                       const struct ec_strvec *strvec);
+int ec_node_complete_child(struct ec_node *node,
+                       struct ec_completed *completed,
+                       struct ec_parsed *parsed_state,
+                       const struct ec_strvec *strvec);
 
 struct ec_completed *ec_completed(void);
 
 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_no_match(struct ec_completed *completed,
+int ec_completed_add_node(struct ec_completed *completed,
                        struct ec_parsed *state, 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,
@@ -95,9 +99,11 @@ void ec_completed_merge(struct ec_completed *completed1,
 void ec_completed_free(struct ec_completed *completed);
 void ec_completed_dump(FILE *out,
        const struct ec_completed *completed);
-struct ec_completed *ec_node_default_complete(const struct ec_node *gen_node,
-                                       struct ec_parsed *state,
-                                       const struct ec_strvec *strvec);
+int
+ec_node_default_complete(const struct ec_node *gen_node,
+                       struct ec_completed *completed,
+                       struct ec_parsed *state,
+                       const struct ec_strvec *strvec);
 
 /* cannot return NULL */
 const char *ec_completed_smallest_start(
index 2c3501e..b5a424b 100644 (file)
@@ -57,9 +57,10 @@ typedef int (*ec_node_build_t)(struct ec_node *node);
 typedef int (*ec_node_parse_t)(const struct ec_node *node,
                        struct ec_parsed *state,
                        const struct ec_strvec *strvec);
-typedef struct ec_completed *(*ec_node_complete_t)(const struct ec_node *node,
-                                               struct ec_parsed *state,
-                                               const struct ec_strvec *strvec);
+typedef int (*ec_node_complete_t)(const struct ec_node *node,
+                               struct ec_completed *completed_state,
+                               struct ec_parsed *parsed_state,
+                               const struct ec_strvec *strvec);
 typedef size_t (*ec_node_get_max_parse_len_t)(const struct ec_node *node);
 typedef const char * (*ec_node_desc_t)(const struct ec_node *);
 typedef void (*ec_node_init_priv_t)(struct ec_node *);
index 123c0a8..1f40b0f 100644 (file)
@@ -246,22 +246,24 @@ static const struct ec_node_expr_eval_ops test_ops = {
        .eval_free = ec_node_cmd_eval_free,
 };
 
-static int ec_node_cmd_parse(const struct ec_node *gen_node,
-                       struct ec_parsed *state,
-                       const struct ec_strvec *strvec)
+static int
+ec_node_cmd_parse(const struct ec_node *gen_node, struct ec_parsed *state,
+               const struct ec_strvec *strvec)
 {
        struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
 
        return ec_node_parse_child(node->cmd, state, strvec);
 }
 
-static struct ec_completed *ec_node_cmd_complete(const struct ec_node *gen_node,
-                                               struct ec_parsed *state,
-                                               const struct ec_strvec *strvec)
+static int
+ec_node_cmd_complete(const struct ec_node *gen_node,
+               struct ec_completed *completed,
+               struct ec_parsed *parsed,
+               const struct ec_strvec *strvec)
 {
        struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
 
-       return ec_node_complete_child(node->cmd, state, strvec);
+       return ec_node_complete_child(node->cmd, completed, parsed, strvec);
 }
 
 static void ec_node_cmd_free_priv(struct ec_node *gen_node)
index cbc9441..e15c296 100644 (file)
@@ -75,13 +75,15 @@ static int ec_node_expr_parse(const struct ec_node *gen_node,
        return ec_node_parse_child(node->child, state, strvec);
 }
 
-static struct ec_completed *ec_node_expr_complete(const struct ec_node *gen_node,
-                                               struct ec_parsed *state,
-                                               const struct ec_strvec *strvec)
+static int
+ec_node_expr_complete(const struct ec_node *gen_node,
+               struct ec_completed *completed,
+               struct ec_parsed *parsed,
+               const struct ec_strvec *strvec)
 {
        struct ec_node_expr *node = (struct ec_node_expr *)gen_node;
 
-       return ec_node_complete_child(node->child, state, strvec);
+       return ec_node_complete_child(node->child, completed, parsed, strvec);
 }
 
 static void ec_node_expr_free_priv(struct ec_node *gen_node)
index 7e1582c..4d748f8 100644 (file)
@@ -100,29 +100,24 @@ fail:
        return ret;
 }
 
-static struct ec_completed *
+static int
 __ec_node_many_complete(struct ec_node_many *node, unsigned int max,
-                       struct ec_parsed *state, const struct ec_strvec *strvec)
+                       struct ec_completed *completed,
+                       struct ec_parsed *parsed,
+                       const struct ec_strvec *strvec)
 {
-       struct ec_completed *completed, *child_completed;
        struct ec_strvec *childvec = NULL;
        unsigned int i;
        int ret;
 
-       completed = ec_completed();
-       if (completed == NULL)
-               return NULL;
-
        /* first, try to complete with the child node */
-       child_completed = ec_node_complete_child(node->child, state, strvec);
-       if (child_completed == NULL)
+       ret = ec_node_complete_child(node->child, completed, parsed, strvec);
+       if (ret < 0)
                goto fail;
-       ec_completed_merge(completed, child_completed);
-       child_completed = NULL;
 
        /* we're done, we reached the max number of nodes */
        if (max == 1)
-               return completed;
+               return 0;
 
        /* if there is a maximum, decrease it before recursion */
        if (max != 0)
@@ -135,7 +130,7 @@ __ec_node_many_complete(struct ec_node_many *node, unsigned int max,
                if (childvec == NULL)
                        goto fail;
 
-               ret = ec_node_parse_child(node->child, state, childvec);
+               ret = ec_node_parse_child(node->child, parsed, childvec);
                if (ret < 0 && ret != EC_PARSED_NOMATCH)
                        goto fail;
 
@@ -144,46 +139,43 @@ __ec_node_many_complete(struct ec_node_many *node, unsigned int max,
 
                if ((unsigned int)ret != i) {
                        if (ret != EC_PARSED_NOMATCH)
-                               ec_parsed_del_last_child(state);
+                               ec_parsed_del_last_child(parsed);
                        continue;
                }
 
                childvec = ec_strvec_ndup(strvec, i, ec_strvec_len(strvec) - i);
                if (childvec == NULL) {
-                       ec_parsed_del_last_child(state);
+                       ec_parsed_del_last_child(parsed);
                        goto fail;
                }
 
-               child_completed = __ec_node_many_complete(node, max,
-                                                       state, childvec);
-               ec_parsed_del_last_child(state);
+               ret = __ec_node_many_complete(node, max, completed,
+                                       parsed, childvec);
+               ec_parsed_del_last_child(parsed);
                ec_strvec_free(childvec);
                childvec = NULL;
 
-               if (child_completed == NULL)
+               if (ret < 0)
                        goto fail;
-
-               ec_completed_merge(completed, child_completed);
-               child_completed = NULL;
        }
 
-       return completed;
+       return 0;
 
 fail:
        ec_strvec_free(childvec);
-       ec_completed_free(child_completed);
-       ec_completed_free(completed);
-       return NULL;
+       return -1;
 }
 
-static struct ec_completed *
+static int
 ec_node_many_complete(const struct ec_node *gen_node,
-               struct ec_parsed *state,
+               struct ec_completed *completed,
+               struct ec_parsed *parsed,
                const struct ec_strvec *strvec)
 {
        struct ec_node_many *node = (struct ec_node_many *)gen_node;
 
-       return __ec_node_many_complete(node, node->max, state, strvec);
+       return __ec_node_many_complete(node, node->max, completed,
+                               parsed, strvec);
 }
 
 static void ec_node_many_free_priv(struct ec_node *gen_node)
index b89b80e..fd427b9 100644 (file)
@@ -85,36 +85,28 @@ ec_node_once_parse(const struct ec_node *gen_node,
        return ec_node_parse_child(node->child, state, strvec);
 }
 
-static struct ec_completed *
+static int
 ec_node_once_complete(const struct ec_node *gen_node,
-               struct ec_parsed *state,
+               struct ec_completed *completed,
+               struct ec_parsed *parsed,
                const struct ec_strvec *strvec)
 {
        struct ec_node_once *node = (struct ec_node_once *)gen_node;
-       struct ec_completed *completed = NULL, *child_completed = NULL;
        unsigned int count;
-
-       completed = ec_completed();
-       if (completed == NULL)
-               goto fail;
+       int ret;
 
        /* count the number of occurences of the node: if already parsed,
         * do not match
         */
-       count = count_node(ec_parsed_get_root(state), node->child); //XXX
+       count = count_node(ec_parsed_get_root(parsed), node->child); //XXX
        if (count > 0)
-               return completed;
-
-       child_completed = ec_node_complete_child(node->child, state, strvec);
-       if (child_completed == NULL)
-               goto fail;
+               return 0;
 
-       ec_completed_merge(completed, child_completed);
-       return completed;
+       ret = ec_node_complete_child(node->child, completed, parsed, strvec);
+       if (ret < 0)
+               return ret;
 
-fail:
-       ec_completed_free(completed);
-       return NULL;
+       return 0;
 }
 
 static void ec_node_once_free_priv(struct ec_node *gen_node)
index 4b52814..4610a46 100644 (file)
@@ -63,14 +63,15 @@ ec_node_option_parse(const struct ec_node *gen_node,
        return ret;
 }
 
-static struct ec_completed *
+static int
 ec_node_option_complete(const struct ec_node *gen_node,
-                       struct ec_parsed *state,
+                       struct ec_completed *completed,
+                       struct ec_parsed *parsed,
                        const struct ec_strvec *strvec)
 {
        struct ec_node_option *node = (struct ec_node_option *)gen_node;
 
-       return ec_node_complete_child(node->child, state, strvec);
+       return ec_node_complete_child(node->child, completed, parsed, strvec);
 }
 
 static void ec_node_option_free_priv(struct ec_node *gen_node)
index dcd811b..c1b808f 100644 (file)
@@ -67,30 +67,24 @@ ec_node_or_parse(const struct ec_node *gen_node,
        return EC_PARSED_NOMATCH;
 }
 
-static struct ec_completed *
+static int
 ec_node_or_complete(const struct ec_node *gen_node,
-               struct ec_parsed *state,
+               struct ec_completed *completed,
+               struct ec_parsed *parsed,
                const struct ec_strvec *strvec)
 {
        struct ec_node_or *node = (struct ec_node_or *)gen_node;
-       struct ec_completed *completed, *child_completed;
+       int ret;
        size_t n;
 
-       completed = ec_completed();
-       if (completed == NULL)
-               return NULL;
-
        for (n = 0; n < node->len; n++) {
-               child_completed = ec_node_complete_child(node->table[n],
-                       state, strvec);
-
-               if (child_completed == NULL) // XXX fail instead?
-                       continue;
-
-               ec_completed_merge(completed, child_completed);
+               ret = ec_node_complete_child(node->table[n],
+                                       completed, parsed, strvec);
+               if (ret < 0)
+                       return ret;
        }
 
-       return completed;
+       return 0;
 }
 
 static size_t ec_node_or_get_max_parse_len(const struct ec_node *gen_node)
index 9fa2d1a..d6338e9 100644 (file)
@@ -91,21 +91,18 @@ fail:
        return ret;
 }
 
-static struct ec_completed *
+static int
 __ec_node_seq_complete(struct ec_node **table, size_t table_len,
-               struct ec_parsed *state, const struct ec_strvec *strvec)
+               struct ec_completed *completed,
+               struct ec_parsed *parsed,
+               const struct ec_strvec *strvec)
 {
-       struct ec_completed *completed, *child_completed;
        struct ec_strvec *childvec = NULL;
        unsigned int i;
        int ret;
 
-       completed = ec_completed();
-       if (completed == NULL)
-               return NULL;
-
        if (table_len == 0)
-               return completed;
+               return 0;
 
        /*
         * Example of completion for a sequence node = [n1,n2] and an
@@ -119,13 +116,10 @@ __ec_node_seq_complete(struct ec_node **table, size_t table_len,
         */
 
        /* first, try to complete with the first node of the table */
-       child_completed = ec_node_complete_child(table[0], state, strvec);
-       if (child_completed == NULL)
+       ret = ec_node_complete_child(table[0], completed, parsed, strvec);
+       if (ret < 0)
                goto fail;
 
-       ec_completed_merge(completed, child_completed);
-       child_completed = NULL;
-
        /* then, if the first node of the table matches the beginning of the
         * strvec, try to complete the rest */
        for (i = 0; i < ec_strvec_len(strvec); i++) {
@@ -133,7 +127,7 @@ __ec_node_seq_complete(struct ec_node **table, size_t table_len,
                if (childvec == NULL)
                        goto fail;
 
-               ret = ec_node_parse_child(table[0], state, childvec);
+               ret = ec_node_parse_child(table[0], parsed, childvec);
                if (ret < 0 && ret != EC_PARSED_NOMATCH)
                        goto fail;
 
@@ -142,47 +136,44 @@ __ec_node_seq_complete(struct ec_node **table, size_t table_len,
 
                if ((unsigned int)ret != i) {
                        if (ret != EC_PARSED_NOMATCH)
-                               ec_parsed_del_last_child(state);
+                               ec_parsed_del_last_child(parsed);
                        continue;
                }
 
                childvec = ec_strvec_ndup(strvec, i, ec_strvec_len(strvec) - i);
                if (childvec == NULL) {
-                       ec_parsed_del_last_child(state);
+                       ec_parsed_del_last_child(parsed);
                        goto fail;
                }
 
-               child_completed = __ec_node_seq_complete(&table[1],
-                                                       table_len - 1,
-                                                       state, childvec);
-               ec_parsed_del_last_child(state);
+               ret = __ec_node_seq_complete(&table[1],
+                                       table_len - 1,
+                                       completed, parsed, childvec);
+               ec_parsed_del_last_child(parsed);
                ec_strvec_free(childvec);
                childvec = NULL;
 
-               if (child_completed == NULL)
+               if (ret < 0)
                        goto fail;
-
-               ec_completed_merge(completed, child_completed);
-               child_completed = NULL;
        }
 
-       return completed;
+       return 0;
 
 fail:
        ec_strvec_free(childvec);
-       ec_completed_free(child_completed);
-       ec_completed_free(completed);
-       return NULL;
+       return -1;
 }
 
-static struct ec_completed *
+static int
 ec_node_seq_complete(const struct ec_node *gen_node,
-               struct ec_parsed *state,
+               struct ec_completed *completed,
+               struct ec_parsed *parsed,
                const struct ec_strvec *strvec)
 {
        struct ec_node_seq *node = (struct ec_node_seq *)gen_node;
 
-       return __ec_node_seq_complete(node->table, node->len, state, strvec);
+       return __ec_node_seq_complete(node->table, node->len, completed,
+                               parsed, strvec);
 }
 
 static size_t ec_node_seq_get_max_parse_len(const struct ec_node *gen_node)
index 0ce54fe..59b917f 100644 (file)
@@ -279,46 +279,37 @@ ec_node_sh_lex_parse(const struct ec_node *gen_node,
        return ret;
 }
 
-static struct ec_completed *
+static int
 ec_node_sh_lex_complete(const struct ec_node *gen_node,
-                       struct ec_parsed *state,
+                       struct ec_completed *completed,
+                       struct ec_parsed *parsed,
                        const struct ec_strvec *strvec)
 {
        struct ec_node_sh_lex *node = (struct ec_node_sh_lex *)gen_node;
-       struct ec_completed *completed, *child_completed = NULL;
        struct ec_strvec *new_vec = NULL;
        const char *str;
        char missing_quote;
-
-//     printf("==================\n");
-       completed = ec_completed();
-       if (completed == NULL)
-               return NULL;
+       int ret;
 
        if (ec_strvec_len(strvec) != 1)
-               return completed;
+               return 0;
 
        str = ec_strvec_val(strvec, 0);
        new_vec = tokenize(str, 1, 1, &missing_quote);
        if (new_vec == NULL)
                goto fail;
 
-//     ec_strvec_dump(new_vec, stdout);
-
-       child_completed = ec_node_complete_child(node->child, state, new_vec);
-       if (child_completed == NULL)
+       ret = ec_node_complete_child(node->child, completed, parsed, new_vec);
+       if (ret < 0)
                goto fail;
 
        ec_strvec_free(new_vec);
-       new_vec = NULL;
-       ec_completed_merge(completed, child_completed);
 
-       return completed;
+       return 0;
 
  fail:
        ec_strvec_free(new_vec);
-       ec_completed_free(completed);
-       return NULL;
+       return -1;
 }
 
 static void ec_node_sh_lex_free_priv(struct ec_node *gen_node)
index 4a9ee82..30e1a1a 100644 (file)
@@ -65,24 +65,20 @@ ec_node_str_parse(const struct ec_node *gen_node,
        return 1;
 }
 
-static struct ec_completed *
+static int
 ec_node_str_complete(const struct ec_node *gen_node,
-               struct ec_parsed *state,
+               struct ec_completed *completed,
+               struct ec_parsed *parsed,
                const struct ec_strvec *strvec)
 {
        struct ec_node_str *node = (struct ec_node_str *)gen_node;
-       struct ec_completed *completed;
        const char *str;
        size_t n = 0;
 
-       (void)state;
-
-       completed = ec_completed();
-       if (completed == NULL)
-               return NULL;
+       (void)parsed;
 
        if (ec_strvec_len(strvec) != 1)
-               return completed;
+               return 0;
 
        str = ec_strvec_val(strvec, 0);
        for (n = 0; n < node->len; n++) {
@@ -90,20 +86,13 @@ ec_node_str_complete(const struct ec_node *gen_node,
                        break;
        }
 
-       if (str[n] != '\0') {
-               if (ec_completed_add_no_match(completed, state, gen_node) < 0) {
-                       ec_completed_free(completed);
-                       return NULL;
-               }
-       } else {
-               if (ec_completed_add_match(completed, state, gen_node,
-                                               node->string + n) < 0) {
-                       ec_completed_free(completed);
-                       return NULL;
-               }
+       if (str[n] == '\0') {
+               if (ec_completed_add_match(completed, parsed, gen_node,
+                                               node->string + n) < 0)
+                       return -1;
        }
 
-       return completed;
+       return 0;
 }
 
 static const char *ec_node_str_desc(const struct ec_node *gen_node)
index 599c761..02b3c28 100644 (file)
@@ -173,14 +173,13 @@ ec_node_subset_parse(const struct ec_node *gen_node,
        return ret;
 }
 
-static struct ec_completed *
+static int
 __ec_node_subset_complete(struct ec_node **table, size_t table_len,
-                       struct ec_parsed *state, 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;
@@ -194,23 +193,15 @@ __ec_node_subset_complete(struct ec_node **table, size_t table_len,
         *   + __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_child(table[i],
-                       state, 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
@@ -219,7 +210,7 @@ __ec_node_subset_complete(struct ec_node **table, size_t table_len,
                if (table[i] == NULL)
                        continue;
 
-               ret = ec_node_parse_child(table[i], state, strvec);
+               ret = ec_node_parse_child(table[i], parsed, strvec);
                if (ret == EC_PARSED_NOMATCH)
                        continue;
                else if (ret < 0)
@@ -229,46 +220,39 @@ __ec_node_subset_complete(struct ec_node **table, size_t table_len,
                childvec = ec_strvec_ndup(strvec, len,
                                        ec_strvec_len(strvec) - len);
                if (childvec == NULL) {
-                       ec_parsed_del_last_child(state);
+                       ec_parsed_del_last_child(parsed);
                        goto fail;
                }
 
                save = table[i];
                table[i] = NULL;
-               child_completed = __ec_node_subset_complete(table, table_len,
-                                                       state, 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(state);
+               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 *
+static int
 ec_node_subset_complete(const struct ec_node *gen_node,
-                       struct ec_parsed *state,
+                       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, state, 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)
index 3e202d3..73da26b 100644 (file)
@@ -58,14 +58,15 @@ ec_node_weakref_parse(const struct ec_node *gen_node,
        return ec_node_parse_child(node->child, state, strvec);
 }
 
-static struct ec_completed *
+static int
 ec_node_weakref_complete(const struct ec_node *gen_node,
-                       struct ec_parsed *state,
+                       struct ec_completed *completed,
+                       struct ec_parsed *parsed,
                        const struct ec_strvec *strvec)
 {
        struct ec_node_weakref *node = (struct ec_node_weakref *)gen_node;
 
-       return ec_node_complete_child(node->child, state, strvec);
+       return ec_node_complete_child(node->child, completed, parsed, strvec);
 }
 
 static struct ec_node_type ec_node_weakref_type = {
index df24f05..637059a 100644 (file)
@@ -80,6 +80,7 @@ struct ec_parsed *ec_node_parse_strvec(struct ec_node *node,
  * EC_PARSED_NOMATCH (negative) if it does not match
  * any other negative value (-errno) for other errors
  * the number of matched strings in strvec
+ * XXX state is not freed on error ?
  */
 int ec_node_parse_child(struct ec_node *node,
                        struct ec_parsed *state,
index 31f2c37..9b05575 100644 (file)
@@ -101,7 +101,6 @@ out:
 int ec_test_check_complete(struct ec_node *tk, ...)
 {
        struct ec_completed *c = NULL;
-       struct ec_completed_item *item;
        struct ec_strvec *vec = NULL;
        const char *s, *expected;
        int ret = 0;
@@ -131,17 +130,23 @@ int ec_test_check_complete(struct ec_node *tk, ...)
                goto out;
        }
 
+       /* for each expected completion, check it is there */
        for (s = va_arg(ap, const char *);
             s != EC_NODE_ENDLIST;
             s = va_arg(ap, const char *)) {
+               struct ec_completed_iter *iter;
+               const struct ec_completed_item *item;
+
                if (s == NULL) {
                        ret = -1;
                        goto out;
                }
 
                count++;
-               TAILQ_FOREACH(item, &c->matches, next) {
-                       /* only check matching completions */
+
+               /* only check matching completions */
+               iter = ec_completed_iter(c, EC_MATCH);
+               while ((item = ec_completed_iter_next(iter)) != NULL) {
                        if (item->add != NULL && strcmp(item->add, s) == 0)
                                break;
                }
@@ -151,8 +156,10 @@ int ec_test_check_complete(struct ec_node *tk, ...)
                                "completion <%s> not in list\n", s);
                        ret = -1;
                }
+               ec_completed_iter_free(iter);
        }
 
+       /* check if we have more completions (or less) than expected */
        if (count != ec_completed_count(c, EC_MATCH)) {
                ec_log(EC_LOG_ERR,
                        "nb_completion (%d) does not match (%d)\n",
@@ -161,7 +168,7 @@ int ec_test_check_complete(struct ec_node *tk, ...)
                ret = -1;
        }
 
-
+       /* check the expected smallest start */
        expected = va_arg(ap, const char *);
        s = ec_completed_smallest_start(c);
        if (strcmp(s, expected)) {
index b147e8a..b8c6459 100644 (file)
@@ -79,11 +79,11 @@ static char *my_completion_entry(const char *s, int state)
                        return NULL;
        }
 
-       item = ec_completed_iter_next(iter);
-       if (item == NULL)
+       elt = ec_completed_iter_next(iter);
+       if (elt == NULL)
                return NULL;
 
-       if (asprintf(&out_string, "%s%s", s, item->add) < 0)
+       if (asprintf(&out_string, "%s%s", s, elt->add) < 0)
                return NULL;
 
        return out_string;
@@ -101,7 +101,7 @@ static char **my_attempted_completion(const char *text, int start, int end)
 }
 
 /* this function builds the help string */
-static char *get_node_help(const struct ec_completed_item *item)
+static char *get_node_help(const struct ec_completed_elt *elt)
 {
        const struct ec_node *node;
        char *help = NULL;
@@ -109,8 +109,8 @@ static char *get_node_help(const struct ec_completed_item *item)
        const char *node_desc = NULL;
        size_t i;
 
-       for (i = 0; i < item->pathlen; i++) {
-               node = item->path[i];
+       for (i = 0; i < elt->pathlen; i++) {
+               node = elt->path[i];
                if (node_help == NULL)
                        node_help = ec_keyval_get(ec_node_attrs(node), "help");
                if (node_desc == NULL)