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;
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",
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;
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;
}
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;
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))
return -ENOMEM;
}
- //printf("eval var %s %p\n", str, eval); //XXX
*result = eval;
return 0;
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;
/* 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;
}
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;
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;
unsigned int count = 0;
va_list ap;
- va_start(ap, tk);
+ va_start(ap, type);
/* build a string vector */
vec = ec_strvec();
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)
}
/* 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;
}
#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) \
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_; \
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) {