From de813c322c162c76be182e05aec99507860b6acd Mon Sep 17 00:00:00 2001 From: Rene Kita Date: Sun, 25 Dec 2022 15:32:49 +0100 Subject: [PATCH 1/5] Use 'goto fail' to remove code duplication --- history.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/history.c b/history.c index 514ae9a..4f6739c 100644 --- a/history.c +++ b/history.c @@ -65,26 +65,24 @@ saveHistory(Hist *hist, size_t size) if (hist == NULL || hist->list == NULL) return; tmpf = tmpfname(TMPF_HIST, NULL)->ptr; - if ((f = fopen(tmpf, "w")) == NULL) { - /* FIXME: gettextize? */ - disp_err_message("Can't open history", FALSE); - return; - } + if ((f = fopen(tmpf, "w")) == NULL) + goto fail; for (item = hist->list->first; item && hist->list->nitem > size; item = item->next) size++; for (; item; item = item->next) fprintf(f, "%s\n", (char *)item->ptr); - if (fclose(f) == EOF) { - /* FIXME: gettextize? */ - disp_err_message("Can't save history", FALSE); - return; - } + if (fclose(f) == EOF) + goto fail; rename_ret = rename(tmpf, rcFile(HISTORY_FILE)); - if (rename_ret != 0) { - disp_err_message("Can't save history", FALSE); - return; - } + if (rename_ret != 0) + goto fail; + + return; + +fail: + disp_err_message("Can't open history", FALSE); + return; } #endif /* USE_HISTORY */ From f186e8331f361a96c4fd9c2d0d2410cc8d84bccf Mon Sep 17 00:00:00 2001 From: Rene Kita Date: Mon, 5 Sep 2022 11:53:40 +0200 Subject: [PATCH 2/5] Let loadHistory return an error code This is in preparation for a following patch. --- history.c | 7 ++++--- proto.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/history.c b/history.c index 4f6739c..0aeae12 100644 --- a/history.c +++ b/history.c @@ -31,16 +31,16 @@ historyBuffer(Hist *hist) return loadHTMLString(src); } -void +int loadHistory(Hist *hist) { FILE *f; Str line; if (hist == NULL) - return; + return 1; if ((f = fopen(rcFile(HISTORY_FILE), "rt")) == NULL) - return; + return 1; while (!feof(f)) { line = Strfgets(f); @@ -52,6 +52,7 @@ loadHistory(Hist *hist) pushHist(hist, url_quote(line->ptr)); } fclose(f); + return 0; } void diff --git a/proto.h b/proto.h index 3be7d22..dd7a0eb 100644 --- a/proto.h +++ b/proto.h @@ -391,7 +391,7 @@ extern char *inputLineHistSearch(char *prompt, char *def_str, int flag, extern Str unescape_spaces(Str s); #ifdef USE_HISTORY extern Buffer *historyBuffer(Hist *hist); -extern void loadHistory(Hist *hist); +extern int loadHistory(Hist *hist); extern void saveHistory(Hist *hist, size_t size); extern void ldHist(void); #else /* not USE_HISTORY */ From 14c8274d16418369549d5ab90d6eee88cf92ad5f Mon Sep 17 00:00:00 2001 From: Rene Kita Date: Mon, 5 Sep 2022 08:20:08 +0200 Subject: [PATCH 3/5] Add comment to explain placement of the ifdef --- history.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/history.c b/history.c index 0aeae12..69eb3d8 100644 --- a/history.c +++ b/history.c @@ -87,6 +87,11 @@ fail: } #endif /* USE_HISTORY */ +/* + * The following functions are used for internal stuff, we need them regardless + * if history is used or not. + */ + Hist * newHist(void) { From e0c9a02784c6a430d9361e37c3df332adf5d524d Mon Sep 17 00:00:00 2001 From: Rene Kita Date: Mon, 5 Sep 2022 08:20:52 +0200 Subject: [PATCH 4/5] Move declarations to the appropriate header file --- history.h | 8 ++++++++ proto.h | 5 ----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/history.h b/history.h index a6468ec..d6791df 100644 --- a/history.h +++ b/history.h @@ -28,4 +28,12 @@ extern char *lastHist(Hist *hist); extern char *nextHist(Hist *hist); extern char *prevHist(Hist *hist); +#ifdef USE_HISTORY +extern int loadHistory(Hist *hist); +extern void saveHistory(Hist *hist, size_t size); +extern void ldHist(void); +#else /* not USE_HISTORY */ +#define ldHist nulcmd +#endif /* not USE_HISTORY */ + #endif /* HISTORY_H */ diff --git a/proto.h b/proto.h index dd7a0eb..0d1fa96 100644 --- a/proto.h +++ b/proto.h @@ -391,11 +391,6 @@ extern char *inputLineHistSearch(char *prompt, char *def_str, int flag, extern Str unescape_spaces(Str s); #ifdef USE_HISTORY extern Buffer *historyBuffer(Hist *hist); -extern int loadHistory(Hist *hist); -extern void saveHistory(Hist *hist, size_t size); -extern void ldHist(void); -#else /* not USE_HISTORY */ -#define ldHist nulcmd #endif /* not USE_HISTORY */ extern double log_like(int x); extern struct table *newTable(void); From c77029570dd49133f36e4e0ea5efbb64365fb6f5 Mon Sep 17 00:00:00 2001 From: Rene Kita Date: Sun, 25 Dec 2022 15:33:33 +0100 Subject: [PATCH 5/5] Merge history file if it was modified after start w3m reads the history file on startup and writes it on exit. That means if you open multiple instances of w3m, the history file will contain the history of the last instance closed. All other history changes are lost. Check if the modification time of the history file has changed before writing. If it has changed read the history file from the disk into a new history. Push the entries that are in the current history but not in the history file into the new history and write the new history to disk. --- history.c | 35 +++++++++++++++++++++++++++++++++++ history.h | 1 + 2 files changed, 36 insertions(+) diff --git a/history.c b/history.c index 69eb3d8..b5d0ac4 100644 --- a/history.c +++ b/history.c @@ -2,6 +2,19 @@ #include "fm.h" #ifdef USE_HISTORY +/* Merge entries from their history into ours */ +static int +mergeHistory(Hist *ours, Hist *theirs) +{ + HistItem *item; + + for (item = theirs->list->first; item; item = item->next) + if (!getHashHist(ours, item->ptr)) + pushHist(ours, (char *)item->ptr); + + return 0; +} + Buffer * historyBuffer(Hist *hist) { @@ -36,12 +49,19 @@ loadHistory(Hist *hist) { FILE *f; Str line; + struct stat st; if (hist == NULL) return 1; if ((f = fopen(rcFile(HISTORY_FILE), "rt")) == NULL) return 1; + if (fstat(fileno(f), &st) == -1) { + fclose(f); + return 1; + } + hist->mtime = (long long)st.st_mtim.tv_sec; + while (!feof(f)) { line = Strfgets(f); Strchop(line); @@ -59,12 +79,27 @@ void saveHistory(Hist *hist, size_t size) { FILE *f; + Hist *fhist; HistItem *item; + char *histf; char *tmpf; int rename_ret; + struct stat st; if (hist == NULL || hist->list == NULL) return; + + histf = rcFile(HISTORY_FILE); + if (stat(histf, &st) == -1) + goto fail; + if (hist->mtime != (long long)st.st_mtim.tv_sec) { + fhist = newHist(); + if (loadHistory(fhist) || mergeHistory(fhist, hist)) + disp_err_message("Can't merge history", FALSE); + else + hist = fhist; + } + tmpf = tmpfname(TMPF_HIST, NULL)->ptr; if ((f = fopen(tmpf, "w")) == NULL) goto fail; diff --git a/history.h b/history.h index d6791df..3f229f5 100644 --- a/history.h +++ b/history.h @@ -16,6 +16,7 @@ typedef struct { HistList *list; HistItem *current; Hash_sv *hash; + long long mtime; } Hist; extern Hist *newHist(void);