completion type
authorOlivier Matz <zer0@droids-corp.org>
Fri, 4 Aug 2017 12:45:51 +0000 (14:45 +0200)
committerOlivier Matz <zer0@droids-corp.org>
Fri, 18 Aug 2017 20:49:39 +0000 (22:49 +0200)
lib/ecoli_completed.c
lib/ecoli_completed.h
lib/ecoli_node_str.c

index 5e79ac2..4547e62 100644 (file)
@@ -143,31 +143,6 @@ struct ec_completed *ec_node_complete(struct ec_node *node,
        return NULL;
 }
 
-/* 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)
-{
-       struct ec_completed *completed;
-
-       (void)strvec;
-       (void)state;
-
-       completed = ec_completed();
-       if (completed == NULL)
-               return NULL;
-
-       if (ec_strvec_len(strvec) != 1)
-               return completed;
-
-       if (ec_completed_add_elt(completed, state, gen_node, NULL) < 0) {
-               ec_completed_free(completed);
-               return NULL;
-       }
-
-       return completed;
-}
-
 /* count the number of identical chars at the beginning of 2 strings */
 static size_t strcmp_count(const char *s1, const char *s2)
 {
@@ -180,7 +155,7 @@ static size_t strcmp_count(const char *s1, const char *s2)
 }
 
 static struct ec_completed_elt *
-ec_completed_elt(struct ec_parsed *parsed,
+ec_completed_elt(enum ec_completed_type type, struct ec_parsed *state,
                const struct ec_node *node, const char *add)
 {
        struct ec_completed_elt *elt = NULL;
@@ -189,12 +164,13 @@ ec_completed_elt(struct ec_parsed *parsed,
        if (elt == NULL)
                return NULL;
 
-       if (parsed != NULL) {
+       /* XXX can state be NULL? */
+       if (state != NULL) {
                struct ec_parsed *p;
                size_t len;
 
                /* get path len */
-               for (p = parsed, len = 0; p != NULL;
+               for (p = state, len = 0; p != NULL;
                     p = ec_parsed_get_parent(p), len++)
                        ;
 
@@ -205,11 +181,12 @@ ec_completed_elt(struct ec_parsed *parsed,
                elt->pathlen = len;
 
                /* write path in array */
-               for (p = parsed, len = 0; p != NULL;
+               for (p = state, len = 0; p != NULL;
                     p = ec_parsed_get_parent(p), len++)
                        elt->path[len] = p->node;
        }
 
+       elt->type = type;
        elt->node = node;
        if (add != NULL) {
                elt->add = ec_strdup(add);
@@ -229,38 +206,66 @@ fail:
        return NULL;
 }
 
-static int __ec_completed_add_elt(struct ec_completed *completed,
+static int ec_completed_add_elt(struct ec_completed *completed,
                                struct ec_completed_elt *elt)
 {
        size_t n;
 
-       TAILQ_INSERT_TAIL(&completed->elts, elt, next);
-       completed->count++;
        if (elt->add != NULL) {
-               completed->count_match++;
                if (completed->smallest_start == NULL) {
                        completed->smallest_start = ec_strdup(elt->add);
+                       if (completed->smallest_start == NULL)
+                               return -ENOMEM;
                } else {
                        n = strcmp_count(elt->add,
                                completed->smallest_start);
                        completed->smallest_start[n] = '\0';
                }
+               completed->count_match++;
        }
+       TAILQ_INSERT_TAIL(&completed->elts, elt, next);
+       completed->count++;
 
        return 0;
 }
 
-int ec_completed_add_elt(struct ec_completed *completed,
-                       struct ec_parsed *parsed,
+int ec_completed_add_match(struct ec_completed *completed,
+                       struct ec_parsed *state,
                        const struct ec_node *node, const char *add)
 {
        struct ec_completed_elt *elt;
+       int ret;
+
+       elt = ec_completed_elt(EC_MATCH, state, node, add);
+       if (elt == NULL)
+               return -ENOMEM;
+
+       ret = ec_completed_add_elt(completed, elt);
+       if (ret < 0) {
+               ec_completed_elt_free(elt);
+               return ret;
+       }
+
+       return 0;
+}
+
+int ec_completed_add_no_match(struct ec_completed *completed,
+                       struct ec_parsed *state, const struct ec_node *node)
+{
+       struct ec_completed_elt *elt;
+       int ret;
 
-       elt = ec_completed_elt(parsed, node, add);
+       elt = ec_completed_elt(EC_NO_MATCH, state, node, NULL);
        if (elt == NULL)
                return -ENOMEM;
 
-       return __ec_completed_add_elt(completed, elt);
+       ret = ec_completed_add_elt(completed, elt);
+       if (ret < 0) {
+               ec_completed_elt_free(elt);
+               return ret;
+       }
+
+       return 0;
 }
 
 void ec_completed_elt_free(struct ec_completed_elt *elt)
@@ -270,6 +275,31 @@ void ec_completed_elt_free(struct ec_completed_elt *elt)
        ec_free(elt);
 }
 
+/* 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)
+{
+       struct ec_completed *completed;
+
+       (void)strvec;
+       (void)state;
+
+       completed = ec_completed();
+       if (completed == NULL)
+               return NULL;
+
+       if (ec_strvec_len(strvec) != 1)
+               return completed;
+
+       if (ec_completed_add_no_match(completed, state, gen_node) < 0) {
+               ec_completed_free(completed);
+               return NULL;
+       }
+
+       return completed;
+}
+
 void ec_completed_merge(struct ec_completed *completed1,
        struct ec_completed *completed2)
 {
@@ -281,7 +311,7 @@ void ec_completed_merge(struct ec_completed *completed1,
        while (!TAILQ_EMPTY(&completed2->elts)) {
                elt = TAILQ_FIRST(&completed2->elts);
                TAILQ_REMOVE(&completed2->elts, elt, next);
-               __ec_completed_add_elt(completed1, elt);
+               ec_completed_add_elt(completed1, elt);
        }
 
        ec_completed_free(completed2);
@@ -333,16 +363,16 @@ const char *ec_completed_smallest_start(
 
 unsigned int ec_completed_count(
        const struct ec_completed *completed,
-       enum ec_completed_filter_flags flags)
+       enum ec_completed_type type)
 {
        unsigned int count = 0;
 
        if (completed == NULL)
                return count;
 
-       if (flags & EC_MATCH)
+       if (type & EC_MATCH)
                count += completed->count_match;
-       if (flags & EC_NO_MATCH)
+       if (type & EC_NO_MATCH)
                count += (completed->count - completed->count_match); //XXX
 
        return count;
@@ -350,7 +380,7 @@ unsigned int ec_completed_count(
 
 struct ec_completed_iter *
 ec_completed_iter(struct ec_completed *completed,
-       enum ec_completed_filter_flags flags)
+       enum ec_completed_type type)
 {
        struct ec_completed_iter *iter;
 
@@ -359,7 +389,7 @@ ec_completed_iter(struct ec_completed *completed,
                return NULL;
 
        iter->completed = completed;
-       iter->flags = flags;
+       iter->type = type;
        iter->cur = NULL;
 
        return iter;
@@ -381,11 +411,11 @@ const struct ec_completed_elt *ec_completed_iter_next(
                        break;
 
                if (iter->cur->add == NULL &&
-                               (iter->flags & EC_NO_MATCH))
+                               (iter->type & EC_NO_MATCH))
                        break;
 
                if (iter->cur->add != NULL &&
-                               (iter->flags & EC_MATCH))
+                               (iter->type & EC_MATCH))
                        break;
 
        } while (iter->cur != NULL);
index 26ac77a..70c0b98 100644 (file)
 
 struct ec_node;
 
+enum ec_completed_type {
+       EC_NO_MATCH = 1,
+       EC_MATCH = 2,
+       EC_PARTIAL = 4,
+};
+
 struct ec_completed_elt {
        TAILQ_ENTRY(ec_completed_elt) next;
+       enum ec_completed_type type;
        const struct ec_node *node;
        char *add;
 
@@ -69,10 +76,12 @@ struct ec_completed *ec_node_complete_child(struct ec_node *node,
 
 struct ec_completed *ec_completed(void);
 
-/* XXX add completion type: full, partial, none */
-int ec_completed_add_elt(struct ec_completed *completed,
-                       struct ec_parsed *parsed,
+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,
+                       struct ec_parsed *state, const struct ec_node *node);
+
 void ec_completed_elt_free(struct ec_completed_elt *elt);
 void ec_completed_merge(struct ec_completed *completed1,
        struct ec_completed *completed2);
@@ -87,24 +96,19 @@ struct ec_completed *ec_node_default_complete(const struct ec_node *gen_node,
 const char *ec_completed_smallest_start(
        const struct ec_completed *completed);
 
-enum ec_completed_filter_flags {
-       EC_MATCH = 1,
-       EC_NO_MATCH = 2,
-};
-
 unsigned int ec_completed_count(
        const struct ec_completed *completed,
-       enum ec_completed_filter_flags flags);
+       enum ec_completed_type flags);
 
 struct ec_completed_iter {
-       enum ec_completed_filter_flags flags;
+       enum ec_completed_type type;
        const struct ec_completed *completed;
        const struct ec_completed_elt *cur;
 };
 
 struct ec_completed_iter *
 ec_completed_iter(struct ec_completed *completed,
-       enum ec_completed_filter_flags flags);
+       enum ec_completed_type type);
 
 const struct ec_completed_elt *ec_completed_iter_next(
        struct ec_completed_iter *iter);
index a388841..4a9ee82 100644 (file)
@@ -72,7 +72,7 @@ ec_node_str_complete(const struct ec_node *gen_node,
 {
        struct ec_node_str *node = (struct ec_node_str *)gen_node;
        struct ec_completed *completed;
-       const char *str, *add;
+       const char *str;
        size_t n = 0;
 
        (void)state;
@@ -90,14 +90,17 @@ ec_node_str_complete(const struct ec_node *gen_node,
                        break;
        }
 
-       if (str[n] != '\0')
-               add = NULL;
-       else
-               add = node->string + n;
-
-       if (ec_completed_add_elt(completed, state, gen_node, add) < 0) {
-               ec_completed_free(completed);
-               return NULL;
+       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;
+               }
        }
 
        return completed;