|
|
sfeed_curses: cleanup code for handling read items from an URL file - sfeed - RSS and Atom parser |
|
|
 |
git clone git://git.codemadness.org/sfeed (git://git.codemadness.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
README |
|
|
 |
LICENSE |
|
|
|
--- |
|
|
 |
commit 59ba2ed29bcbe67de6e9ee1e7fb18744f7490c22 |
|
|
 |
parent 7b2bec5985b79a73613c0858a845b97ad614794d |
|
|
 |
Author: Hiltjo Posthuma <hiltjo@codemadness.org> (mailto://) |
application/vnd.lotus-organizer |
|
|
Date: Sun, 17 Jul 2022 12:46:34 +0200 |
|
|
|
|
|
|
|
sfeed_curses: cleanup code for handling read items from an URL file |
|
|
|
|
|
|
|
This makes it easier to reuse the code from reading plain-text list of items |
|
|
|
from a file and uses a struct urls to keep its state in a cleaner way. |
|
|
|
|
|
|
|
+ some small code-style improvements and reshuffling. |
|
|
|
|
|
|
|
Inspired by a question from NRK by mail about implementing a "read later" |
|
|
|
feature. |
|
|
|
|
|
|
|
(A quick local experiment shows it can be done in ~70 lines of added code). |
|
|
|
|
|
|
|
Diffstat: |
|
|
|
M sfeed_curses.c | 82 +++++++++++++++++-------------- |
|
|
|
|
|
|
|
1 file changed, 45 insertions(+), 37 deletions(-) |
|
|
|
--- |
|
|
 |
diff --git a/sfeed_curses.c b/sfeed_curses.c |
|
|
|
@@ -129,10 +129,16 @@ struct item { |
|
|
|
off_t offset; /* line offset in file for lazyload */ |
|
|
|
}; |
|
|
|
|
|
|
|
+struct urls { |
|
|
|
+ char **items; /* array of urls */ |
|
|
|
+ size_t len; /* amount of items */ |
|
|
|
+ size_t cap; /* available capacity */ |
|
|
|
+}; |
|
|
|
+ |
|
|
|
struct items { |
|
|
|
- struct item *items; /* array of items */ |
|
|
|
- size_t len; /* amount of items */ |
|
|
|
- size_t cap; /* available capacity */ |
|
|
|
+ struct item *items; /* array of items */ |
|
|
|
+ size_t len; /* amount of items */ |
|
|
|
+ size_t cap; /* available capacity */ |
|
|
|
}; |
|
|
|
|
|
|
|
void alldirty(void); |
|
|
|
@@ -144,9 +150,9 @@ void pane_draw(struct pane *); |
|
|
|
void sighandler(int); |
|
|
|
void updategeom(void); |
|
|
|
void updatesidebar(void); |
|
|
|
-void urls_free(void); |
|
|
|
-int urls_isnew(const char *); |
|
|
|
-void urls_read(void); |
|
|
|
+void urls_free(struct urls *); |
|
|
|
+int urls_hasmatch(struct urls *, const char *); |
|
|
|
+void urls_read(struct urls *, const char *); |
|
|
|
|
|
|
|
static struct linebar linebar; |
|
|
|
static struct statusbar statusbar; |
|
|
|
@@ -169,8 +175,8 @@ static struct feed *feeds; |
|
|
|
static struct feed *curfeed; |
|
|
|
static size_t nfeeds; /* amount of feeds */ |
|
|
|
static time_t comparetime; |
|
|
|
-static char *urlfile, **urls; |
|
|
|
-static size_t nurls; |
|
|
|
+struct urls urls; |
|
|
|
+static char *urlfile; |
|
|
|
|
|
|
|
volatile sig_atomic_t state_sigchld = 0, state_sighup = 0, state_sigint = 0; |
|
|
|
volatile sig_atomic_t state_sigterm = 0, state_sigwinch = 0; |
|
|
|
@@ -1197,9 +1203,9 @@ feed_items_get(struct feed *f, FILE *fp, struct items *itemsret) |
|
|
|
if (n <= 0 || feof(fp)) |
|
|
|
break; |
|
|
|
} |
|
|
|
- itemsret->cap = cap; |
|
|
|
itemsret->items = items; |
|
|
|
itemsret->len = nitems; |
|
|
|
+ itemsret->cap = cap; |
|
|
|
free(line); |
|
|
|
} |
|
|
|
|
|
|
|
@@ -1218,7 +1224,7 @@ updatenewitems(struct feed *f) |
|
|
|
row = &(p->rows[i]); /* do not use pane_row_get() */ |
|
|
|
item = row->data; |
|
|
|
if (urlfile) |
|
|
|
- item->isnew = urls_isnew(item->matchnew); |
|
|
|
+ item->isnew = !urls_hasmatch(&urls, item->matchnew); |
|
|
|
else |
|
|
|
item->isnew = (item->timeok && item->timestamp >= comparetime); |
|
|
|
row->bold = item->isnew; |
|
|
|
@@ -1264,7 +1270,7 @@ feed_count(struct feed *f, FILE *fp) |
|
|
|
parseline(line, fields); |
|
|
|
|
|
|
|
if (urlfile) { |
|
|
|
- f->totalnew += urls_isnew(fields[fields[FieldLink][0] ? FieldLink : FieldId]); |
|
|
|
+ f->totalnew += !urls_hasmatch(&urls, fields[fields[FieldLink][0] ? FieldLink : FieldId]); |
|
|
|
} else { |
|
|
|
parsedtime = 0; |
|
|
|
if (!strtotime(fields[FieldUnixTimestamp], &parsedtime)) |
|
|
|
@@ -1383,9 +1389,9 @@ feeds_reloadall(void) |
|
|
|
|
|
|
|
pos = panes[PaneItems].pos; /* store numeric item position */ |
|
|
|
feeds_set(curfeed); /* close and reopen feed if possible */ |
|
|
|
- urls_read(); |
|
|
|
+ urls_read(&urls, urlfile); |
|
|
|
feeds_load(feeds, nfeeds); |
|
|
|
- urls_free(); |
|
|
|
+ urls_free(&urls); |
|
|
|
/* restore numeric item position */ |
|
|
|
pane_setpos(&panes[PaneItems], pos); |
|
|
|
updatesidebar(); |
|
|
|
@@ -1408,10 +1414,10 @@ feed_open_selected(struct pane *p) |
|
|
|
return; |
|
|
|
f = row->data; |
|
|
|
feeds_set(f); |
|
|
|
- urls_read(); |
|
|
|
+ urls_read(&urls, urlfile); |
|
|
|
if (f->fp) |
|
|
|
feed_load(f, f->fp); |
|
|
|
- urls_free(); |
|
|
|
+ urls_free(&urls); |
|
|
|
/* redraw row: counts could be changed */ |
|
|
|
updatesidebar(); |
|
|
|
updatetitle(); |
|
|
|
@@ -1901,32 +1907,34 @@ urls_cmp(const void *v1, const void *v2) |
|
|
|
return strcmp(*((char **)v1), *((char **)v2)); |
|
|
|
} |
|
|
|
|
|
|
|
-int |
|
|
|
-urls_isnew(const char *url) |
|
|
|
+void |
|
|
|
+urls_free(struct urls *urls) |
|
|
|
{ |
|
|
|
- return (!nurls || |
|
|
|
- bsearch(&url, urls, nurls, sizeof(char *), urls_cmp) == NULL); |
|
|
|
+ while (urls->len > 0) { |
|
|
|
+ urls->len--; |
|
|
|
+ free(urls->items[urls->len]); |
|
|
|
+ } |
|
|
|
+ urls->items = NULL; |
|
|
|
+ urls->len = 0; |
|
|
|
+ urls->cap = 0; |
|
|
|
} |
|
|
|
|
|
|
|
-void |
|
|
|
-urls_free(void) |
|
|
|
+int |
|
|
|
+urls_hasmatch(struct urls *urls, const char *url) |
|
|
|
{ |
|
|
|
- while (nurls > 0) |
|
|
|
- free(urls[--nurls]); |
|
|
|
- free(urls); |
|
|
|
- urls = NULL; |
|
|
|
- nurls = 0; |
|
|
|
+ return (urls->len && |
|
|
|
+ bsearch(&url, urls->items, urls->len, sizeof(char *), urls_cmp)); |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
-urls_read(void) |
|
|
|
+urls_read(struct urls *urls, const char *urlfile) |
|
|
|
{ |
|
|
|
FILE *fp; |
|
|
|
char *line = NULL; |
|
|
|
- size_t linesiz = 0, cap = 0; |
|
|
|
+ size_t linesiz = 0; |
|
|
|
ssize_t n; |
|
|
|
|
|
|
|
- urls_free(); |
|
|
|
+ urls_free(urls); |
|
|
|
|
|
|
|
if (!urlfile) |
|
|
|
return; |
|
|
|
@@ -1936,19 +1944,19 @@ urls_read(void) |
|
|
|
while ((n = getline(&line, &linesiz, fp)) > 0) { |
|
|
|
if (line[n - 1] == '\n') |
|
|
|
line[--n] = '\0'; |
|
|
|
- if (nurls + 1 >= cap) { |
|
|
|
- cap = cap ? cap * 2 : 16; |
|
|
|
- urls = erealloc(urls, cap * sizeof(char *)); |
|
|
|
+ if (urls->len + 1 >= urls->cap) { |
|
|
|
+ urls->cap = urls->cap ? urls->cap * 2 : 16; |
|
|
|
+ urls->items = erealloc(urls->items, urls->cap * sizeof(char *)); |
|
|
|
} |
|
|
|
- urls[nurls++] = estrdup(line); |
|
|
|
+ urls->items[urls->len++] = estrdup(line); |
|
|
|
} |
|
|
|
if (ferror(fp)) |
|
|
|
die("getline: %s", urlfile); |
|
|
|
fclose(fp); |
|
|
|
free(line); |
|
|
|
|
|
|
|
- if (nurls > 0) |
|
|
|
- qsort(urls, nurls, sizeof(char *), urls_cmp); |
|
|
|
+ if (urls->len > 0) |
|
|
|
+ qsort(urls->items, urls->len, sizeof(char *), urls_cmp); |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
@@ -2016,9 +2024,9 @@ main(int argc, char *argv[]) |
|
|
|
nfeeds = argc - 1; |
|
|
|
} |
|
|
|
feeds_set(&feeds[0]); |
|
|
|
- urls_read(); |
|
|
|
+ urls_read(&urls, urlfile); |
|
|
|
feeds_load(feeds, nfeeds); |
|
|
|
- urls_free(); |
|
|
|
+ urls_free(&urls); |
|
|
|
|
|
|
|
if (!isatty(0)) { |
|
|
|
if ((fd = open("/dev/tty", O_RDONLY)) == -1) |
|