diff options
-rw-r--r-- | chat.h | 1 | ||||
-rw-r--r-- | handle.c | 3 | ||||
-rw-r--r-- | tab.c | 31 |
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; |