fix file node
authorOlivier Matz <zer0@droids-corp.org>
Thu, 8 Mar 2018 21:25:46 +0000 (22:25 +0100)
committerOlivier Matz <zer0@droids-corp.org>
Thu, 8 Mar 2018 21:25:46 +0000 (22:25 +0100)
lib/ecoli_completed.c
lib/ecoli_completed.h
lib/ecoli_node_cmd.c
lib/ecoli_node_file.c
lib/ecoli_test.c
lib/ecoli_test.h
lib/main-readline.c

index e44ba9e..4113ef3 100644 (file)
@@ -355,10 +355,13 @@ ec_completed_item_add(struct ec_completed *completed,
 
        switch (item->type) {
        case EC_COMP_UNKNOWN:
+               completed->count_unknown++;
                break;
        case EC_COMP_FULL:
+               completed->count_full++;
+               break;
        case EC_COMP_PARTIAL:
-               completed->count_match++; //XXX
+               completed->count_partial++;
                break;
        default:
                return -EINVAL;
@@ -521,8 +524,9 @@ void ec_completed_dump(FILE *out, const struct ec_completed *completed)
                return;
        }
 
-       fprintf(out, "completion: count=%u match=%u\n",
-               completed->count, completed->count_match);
+       fprintf(out, "completion: count=%u full=%u full=%u unknown=%u\n",
+               completed->count, completed->count_full,
+               completed->count_partial,  completed->count_unknown);
 
        TAILQ_FOREACH(grp, &completed->groups, next) {
                fprintf(out, "node=%p, node_type=%s\n",
@@ -555,7 +559,9 @@ int ec_completed_merge(struct ec_completed *to,
                TAILQ_INSERT_TAIL(&to->groups, grp, next);
        }
        to->count += from->count;
-       to->count_match += from->count_match;
+       to->count_full += from->count_full;
+       to->count_partial += from->count_partial;
+       to->count_unknown += from->count_unknown;
 
        ec_completed_free(from);
        return 0;
@@ -571,9 +577,11 @@ unsigned int ec_completed_count(
                return count;
 
        if (type & EC_COMP_FULL)
-               count += completed->count_match;
+               count += completed->count_full;
+       if (type & EC_COMP_PARTIAL)
+               count += completed->count_partial;
        if (type & EC_COMP_UNKNOWN)
-               count += (completed->count - completed->count_match); //XXX
+               count += completed->count_unknown;
 
        return count;
 }
index 9eed0cb..c7a6a62 100644 (file)
@@ -66,7 +66,9 @@ TAILQ_HEAD(ec_completed_group_list, ec_completed_group);
 
 struct ec_completed {
        unsigned count;
-       unsigned count_match;
+       unsigned count_full;
+       unsigned count_partial;
+       unsigned count_unknown;
        struct ec_parsed *cur_state;
        struct ec_completed_group *cur_group;
        struct ec_completed_group_list groups;
index ba1469b..9653c0e 100644 (file)
@@ -85,7 +85,6 @@ ec_node_cmd_eval_var(void **result, void *userctx,
 
        for (i = 0; i < node->len; i++) {
                id = ec_node_id(node->table[i]);
-               //printf("i=%d id=%s\n", i, id);
                if (id == NULL)
                        continue;
                if (strcmp(str, id))
@@ -104,7 +103,6 @@ ec_node_cmd_eval_var(void **result, void *userctx,
                        return -ENOMEM;
        }
 
-       //printf("eval var %s %p\n", str, eval); //XXX
        *result = eval;
 
        return 0;
index fbba156..8af484b 100644 (file)
@@ -120,7 +120,7 @@ ec_node_file_complete(const struct ec_node *gen_node,
        char *dname = NULL, *bname = NULL, *effective_dir;
        struct ec_completed_item *item = NULL;
        enum ec_completed_type type;
-       struct stat st;
+       struct stat st, st2;
        const char *input;
        size_t bname_len;
        struct dirent *de = NULL;
@@ -194,7 +194,19 @@ ec_node_file_complete(const struct ec_node *gen_node,
                /* add '/' if it's a dir */
                if (de->d_type == DT_DIR) {
                        is_dir = 1;
-               } else if (de->d_type == DT_UNKNOWN) { // XXX todo
+               } else if (de->d_type == DT_UNKNOWN) {
+                       int dir_fd = dirfd(dir);
+
+                       if (dir_fd < 0)
+                               goto out;
+                       ret = fstatat(dir_fd, de->d_name, &st2, 0);
+                       if (ret != 0) {
+                               ret = -errno;
+                               goto out;
+                       }
+                       if (!S_ISDIR(st2.st_mode))
+                               goto out;
+                       is_dir = 1;
                } else {
                        is_dir = 0;
                }
@@ -278,26 +290,22 @@ static int ec_node_file_testcase(void)
        ret |= EC_TEST_CHECK_PARSE(node, -1);
 
        /* test completion */
-#if 0 // XXX how to properly test file completion?
        ret |= EC_TEST_CHECK_COMPLETE(node,
                EC_NODE_ENDLIST,
                EC_NODE_ENDLIST);
        ret |= EC_TEST_CHECK_COMPLETE(node,
-               "", EC_NODE_ENDLIST,
+               "/tmp/toto/t", EC_NODE_ENDLIST,
                EC_NODE_ENDLIST);
+       ret |= EC_TEST_CHECK_COMPLETE_PARTIAL(node,
+               "/tmp/toto/t", EC_NODE_ENDLIST,
+               "/tmp/toto/titi/", EC_NODE_ENDLIST);
        ret |= EC_TEST_CHECK_COMPLETE(node,
-               "/", EC_NODE_ENDLIST,
-               EC_NODE_ENDLIST);
-       ret |= EC_TEST_CHECK_COMPLETE(node,
-               "/tmp", EC_NODE_ENDLIST,
-               EC_NODE_ENDLIST);
+               "/tmp/toto/f", EC_NODE_ENDLIST,
+               "/tmp/toto/foo", EC_NODE_ENDLIST);
        ret |= EC_TEST_CHECK_COMPLETE(node,
-               "/tmp/", EC_NODE_ENDLIST,
-               EC_NODE_ENDLIST);
-       ret |= EC_TEST_CHECK_COMPLETE(node,
-               "/tmp/.", EC_NODE_ENDLIST,
-               EC_NODE_ENDLIST);
-#endif
+               "/tmp/toto/b", EC_NODE_ENDLIST,
+               "/tmp/toto/bar", "/tmp/toto/bar2", EC_NODE_ENDLIST);
+
        ec_node_free(node);
 
        return ret;
index 6b168d6..4a915f1 100644 (file)
@@ -99,7 +99,7 @@ out:
        return ret;
 }
 
-int ec_test_check_complete(struct ec_node *tk, ...)
+int ec_test_check_complete(struct ec_node *tk, enum ec_completed_type type, ...)
 {
        struct ec_completed *c = NULL;
        struct ec_strvec *vec = NULL;
@@ -108,7 +108,7 @@ int ec_test_check_complete(struct ec_node *tk, ...)
        unsigned int count = 0;
        va_list ap;
 
-       va_start(ap, tk);
+       va_start(ap, type);
 
        /* build a string vector */
        vec = ec_strvec();
@@ -146,7 +146,7 @@ int ec_test_check_complete(struct ec_node *tk, ...)
                count++;
 
                /* only check matching completions */
-               iter = ec_completed_iter(c, EC_COMP_FULL);
+               iter = ec_completed_iter(c, type);
                while ((item = ec_completed_iter_next(iter)) != NULL) {
                        const char *str = ec_completed_item_get_str(item);
                        if (str != NULL && strcmp(str, s) == 0)
@@ -162,10 +162,10 @@ int ec_test_check_complete(struct ec_node *tk, ...)
        }
 
        /* check if we have more completions (or less) than expected */
-       if (count != ec_completed_count(c, EC_COMP_FULL)) {
+       if (count != ec_completed_count(c, type)) {
                EC_LOG(EC_LOG_ERR,
                        "nb_completion (%d) does not match (%d)\n",
-                       count, ec_completed_count(c, EC_COMP_FULL));
+                       count, ec_completed_count(c, type));
                ec_completed_dump(stdout, c);
                ret = -1;
        }
index fa3fe6c..90159f1 100644 (file)
@@ -31,7 +31,9 @@
 #include <sys/queue.h>
 
 #include <ecoli_log.h>
-#include <ecoli_node.h>
+
+struct ec_node;
+enum ec_completed_type;
 
 // XXX check if already exists?
 #define EC_TEST_REGISTER(t)                                            \
@@ -96,10 +98,18 @@ int ec_test_check_parse(struct ec_node *node, int expected, ...);
        ret_;                                                           \
 })
 
-int ec_test_check_complete(struct ec_node *node, ...);
+int ec_test_check_complete(struct ec_node *node,
+                       enum ec_completed_type type, ...);
 
 #define EC_TEST_CHECK_COMPLETE(node, args...) ({                       \
-       int ret_ = ec_test_check_complete(node, args);                  \
+       int ret_ = ec_test_check_complete(node, EC_COMP_FULL, args);    \
+       if (ret_)                                                       \
+               EC_TEST_ERR("complete test failed");                    \
+       ret_;                                                           \
+})
+
+#define EC_TEST_CHECK_COMPLETE_PARTIAL(node, args...) ({               \
+       int ret_ = ec_test_check_complete(node, EC_COMP_PARTIAL, args); \
        if (ret_)                                                       \
                EC_TEST_ERR("complete test failed");                    \
        ret_;                                                           \
index 304b074..a8a5840 100644 (file)
@@ -93,7 +93,7 @@ static char *my_completion_entry(const char *s, int state)
                return NULL;
 
        item_str = ec_completed_item_get_str(item);
-       if (c->count_match == 1) {
+       if (c->count_full == 1) {
 
                /* don't add the trailing space for partial completions */
                if (state == 0) {