aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/rb3str.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rb3str.c')
-rw-r--r--src/rb3str.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/src/rb3str.c b/src/rb3str.c
index f4c16fa..367ff83 100644
--- a/src/rb3str.c
+++ b/src/rb3str.c
@@ -60,32 +60,37 @@ teco_rb3str_find(teco_rb3str_tree_t *tree, gboolean case_sensitive, const gchar
return (teco_rb3str_head_t *)rb3_find(tree, cmp, &data);
}
-/** @memberof teco_rb3str_tree_t */
-teco_rb3str_head_t *
-teco_rb3str_nfind(teco_rb3str_tree_t *tree, gboolean case_sensitive, const gchar *str, gsize len)
+/*
+ * This is based on rb3_INLINE_find() in rb3ptr.h.
+ * FIXME: Should perhaps be in rb3ptr.c.
+ */
+struct rb3_head *
+rb3_nfind(struct rb3_tree *tree, rb3_cmp cmp, void *data)
{
- rb3_cmp *cmp = case_sensitive ? (rb3_cmp *)teco_rb3str_cmp : (rb3_cmp *)teco_rb3str_casecmp;
- teco_string_t data = {(gchar *)str, len};
-
- /*
- * This is based on rb3_INLINE_find() in rb3ptr.h.
- * Alternatively, we might adapt/wrap teco_rb3str_cmp() in order to store
- * the last element > data.
- */
struct rb3_head *parent = rb3_get_base(tree);
struct rb3_head *res = NULL;
int dir = RB3_LEFT;
+
while (rb3_has_child(parent, dir)) {
parent = rb3_get_child(parent, dir);
- int r = cmp(parent, &data);
+ int r = cmp(parent, data);
if (r == 0)
- return (teco_rb3str_head_t *)parent;
- dir = (r < 0) ? RB3_RIGHT : RB3_LEFT;
+ return parent;
+ dir = r < 0 ? RB3_RIGHT : RB3_LEFT;
if (dir == RB3_LEFT)
res = parent;
}
- return (teco_rb3str_head_t *)res;
+ return res;
+}
+
+/** @memberof teco_rb3str_tree_t */
+teco_rb3str_head_t *
+teco_rb3str_nfind(teco_rb3str_tree_t *tree, gboolean case_sensitive, const gchar *str, gsize len)
+{
+ rb3_cmp *cmp = case_sensitive ? (rb3_cmp *)teco_rb3str_cmp : (rb3_cmp *)teco_rb3str_casecmp;
+ teco_string_t data = {(gchar *)str, len};
+ return (teco_rb3str_head_t *)rb3_nfind(tree, cmp, &data);
}
/**
@@ -133,9 +138,14 @@ teco_rb3str_auto_complete(teco_rb3str_tree_t *tree, gboolean case_sensitive,
if (prefix_len > 0) {
teco_string_init(insert, first->key.data + str_len, prefix_len);
} else if (prefixed_entries > 1) {
+ teco_rb3str_head_t *next;
for (teco_rb3str_head_t *cur = first;
cur && cur->key.len >= str_len && diff(cur->key, str, str_len) == str_len;
- cur = teco_rb3str_get_next(cur)) {
+ cur = next) {
+ next = teco_rb3str_get_next(cur);
+ if (next && !teco_string_cmp(next->key, cur->key.data, cur->key.len))
+ /* filter out duplicates */
+ continue;
if (restrict_len && g_utf8_strlen(cur->key.data, cur->key.len) != restrict_len)
continue;