summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chat.h1
-rw-r--r--handle.c3
-rw-r--r--tab.c31
3 files changed, 26 insertions, 9 deletions
diff --git a/chat.h b/chat.h
index 4ec5dcd..781d25a 100644
--- a/chat.h
+++ b/chat.h
@@ -142,6 +142,7 @@ const wchar_t *editHead(void);
const wchar_t *editTail(void);
void tabTouch(struct Tag tag, const char *word);
+void tabAdd(struct Tag tag, const char *word);
void tabRemove(struct Tag tag, const char *word);
void tabReplace(struct Tag tag, const char *prev, const char *next);
void tabClear(struct Tag tag);
diff --git a/handle.c b/handle.c
index 0036100..07c5a62 100644
--- a/handle.c
+++ b/handle.c
@@ -308,8 +308,7 @@ static void handleReplyWho(char *prefix, char *params) {
);
struct Tag tag = tagFor(chan);
- // FIXME: Don't clobber order if they already exist.
- tabTouch(tag, nick);
+ tabAdd(tag, nick);
size_t cap = sizeof(who.buf) - who.len;
int len = snprintf(
diff --git a/tab.c b/tab.c
index 87e4f02..a242365 100644
--- a/tab.c
+++ b/tab.c
@@ -47,14 +47,16 @@ static void touch(struct Entry *entry) {
prepend(entry);
}
-void tabTouch(struct Tag tag, const char *word) {
+static struct Entry *find(struct Tag tag, const char *word) {
for (struct Entry *entry = head; entry; entry = entry->next) {
if (entry->tag.id != tag.id) continue;
if (strcmp(entry->word, word)) continue;
- touch(entry);
- return;
+ return entry;
}
+ return NULL;
+}
+static void add(struct Tag tag, const char *word) {
struct Entry *entry = malloc(sizeof(*entry));
if (!entry) err(EX_OSERR, "malloc");
@@ -65,11 +67,26 @@ void tabTouch(struct Tag tag, const char *word) {
prepend(entry);
}
+void tabTouch(struct Tag tag, const char *word) {
+ struct Entry *entry = find(tag, word);
+ if (entry) {
+ touch(entry);
+ } else {
+ add(tag, word);
+ }
+}
+
+void tabAdd(struct Tag tag, const char *word) {
+ if (!find(tag, word)) add(tag, word);
+}
+
void tabReplace(struct Tag tag, const char *prev, const char *next) {
- tabTouch(tag, prev);
- free(head->word);
- head->word = strdup(next);
- if (!head->word) err(EX_OSERR, "strdup");
+ struct Entry *entry = find(tag, prev);
+ if (!entry) return;
+ touch(entry);
+ free(entry->word);
+ entry->word = strdup(next);
+ if (!entry->word) err(EX_OSERR, "strdup");
}
static struct Entry *iter;