From 51c92f94ff2728a6db539a82fb4c501f45118062 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Mon, 11 Jan 2021 18:05:22 -0500 Subject: Save and load the URL ring in the save file --- chat.h | 2 ++ ui.c | 40 ++++++++++++++++++++++++++-------------- url.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/chat.h b/chat.h index 41a3683..b5e546a 100644 --- a/chat.h +++ b/chat.h @@ -356,6 +356,8 @@ void urlScan(uint id, const char *nick, const char *mesg); void urlOpenCount(uint id, uint count); void urlOpenMatch(uint id, const char *str); void urlCopyMatch(uint id, const char *str); +int urlSave(FILE *file); +void urlLoad(FILE *file, size_t version); enum { IgnoreCap = 64 }; extern struct Ignore { diff --git a/ui.c b/ui.c index 2958c30..0a0342e 100644 --- a/ui.c +++ b/ui.c @@ -946,7 +946,8 @@ static const time_t Signatures[] = { 0x6C72696774616302, // no self.pos 0x6C72696774616303, // no buffer line heat 0x6C72696774616304, // no mute - 0x6C72696774616305, + 0x6C72696774616305, // no URLs + 0x6C72696774616306, }; static size_t signatureVersion(time_t signature) { @@ -967,25 +968,35 @@ int uiSave(const char *name) { FILE *file = dataOpen(name, "w"); if (!file) return -1; - if (writeTime(file, Signatures[4])) return -1; - if (writeTime(file, self.pos)) return -1; + int error = 0 + || writeTime(file, Signatures[5]) + || writeTime(file, self.pos); + if (error) return error; for (uint num = 0; num < windows.len; ++num) { const struct Window *window = windows.ptrs[num]; - if (writeString(file, idNames[window->id])) return -1; - if (writeTime(file, window->mute)) return -1; - if (writeTime(file, window->heat)) return -1; - if (writeTime(file, window->unreadSoft)) return -1; - if (writeTime(file, window->unreadWarm)) return -1; + error = 0 + || writeString(file, idNames[window->id]) + || writeTime(file, window->mute) + || writeTime(file, window->heat) + || writeTime(file, window->unreadSoft) + || writeTime(file, window->unreadWarm); + if (error) return error; for (size_t i = 0; i < BufferCap; ++i) { const struct Line *line = bufferSoft(window->buffer, i); if (!line) continue; - if (writeTime(file, line->time)) return -1; - if (writeTime(file, line->heat)) return -1; - if (writeString(file, line->str)) return -1; + error = 0 + || writeTime(file, line->time) + || writeTime(file, line->heat) + || writeString(file, line->str); + if (error) return error; } - if (writeTime(file, 0)) return -1; + error = writeTime(file, 0); + if (error) return error; } - return fclose(file); + return 0 + || writeString(file, "") + || urlSave(file) + || fclose(file); } static time_t readTime(FILE *file) { @@ -1026,7 +1037,7 @@ void uiLoad(const char *name) { char *buf = NULL; size_t cap = 0; - while (0 < readString(file, &buf, &cap)) { + while (0 < readString(file, &buf, &cap) && buf[0]) { struct Window *window = windows.ptrs[windowFor(idFor(buf))]; if (version > 3) window->mute = readTime(file); if (version > 0) { @@ -1045,6 +1056,7 @@ void uiLoad(const char *name) { window->buffer, COLS, window->ignore, window->unreadSoft ); } + urlLoad(file, version); free(buf); fclose(file); diff --git a/url.c b/url.c index 53fe271..21f946c 100644 --- a/url.c +++ b/url.c @@ -230,3 +230,47 @@ void urlCopyMatch(uint id, const char *str) { } } } + +static int writeString(FILE *file, const char *str) { + return (fwrite(str, strlen(str) + 1, 1, file) ? 0 : -1); +} +static ssize_t readString(FILE *file, char **buf, size_t *cap) { + ssize_t len = getdelim(buf, cap, '\0', file); + if (len < 0 && !feof(file)) err(EX_IOERR, "getdelim"); + return len; +} + +int urlSave(FILE *file) { + for (size_t i = 0; i < Cap; ++i) { + const struct URL *url = &ring.urls[(ring.len + i) % Cap]; + if (!url->url) continue; + int error = 0 + || writeString(file, idNames[url->id]) + || writeString(file, (url->nick ?: "")) + || writeString(file, url->url); + if (error) return error; + } + return writeString(file, ""); +} + +void urlLoad(FILE *file, size_t version) { + if (version < 5) return; + size_t cap = 0; + char *buf = NULL; + while (0 < readString(file, &buf, &cap) && buf[0]) { + struct URL *url = &ring.urls[ring.len++ % Cap]; + free(url->nick); + free(url->url); + url->id = idFor(buf); + url->nick = NULL; + readString(file, &buf, &cap); + if (buf[0]) { + url->nick = strdup(buf); + if (!url->nick) err(EX_OSERR, "strdup"); + } + readString(file, &buf, &cap); + url->url = strdup(buf); + if (!url->url) err(EX_OSERR, "strdup"); + } + free(buf); +} -- cgit 1.4.1