aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/rb3str.c
diff options
context:
space:
mode:
authorRobin Haberkorn <rhaberkorn@fmsbw.de>2026-10-14 01:54:14 +0200
committerRobin Haberkorn <rhaberkorn@fmsbw.de>2026-10-14 01:54:14 +0200
commit8b54d2c31410fcac43c8903007fe0738312834b0 (patch)
tree4d7e0291aa940d5f16d4d611b7315532907730c4 /src/rb3str.c
parent72968dd6c3fbedab848625af86f34be3d537c7b5 (diff)
help topics no longer need to be unique and can be toggled through with the `?$` command.
* This mirrors how the `FT$` command toggles through several results. * Some non-unique .SCITECO_TOPICs have been added to sciteco(1) and sciteco(7). * This works by inserting non-unique keys into the help topic RB tree - or rather by turning filename:pos also into keys since rb3ptr does not allow non-unique keys. When searching for a topic, we sort lower than any other entry with the same name. This way we can easily iterate all entries with the same name (search topic). The alternative would have been to maintain a linked list in each and every teco_help_topic_t. * teco_rb3str_auto_complete() now filters out possible duplicate keys. * Updated test case: check for non-unique topic names.
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;