readr

Minimal RSS reader (WIP)
Log | Files | Refs | README | LICENSE

commit 669430aabaab0a7dd64b2445d906ef00d74c767d
parent f2ba00300f4fa81398c6e1237e0e158a2590f499
Author: citbl <citbl@citbl.org>
Date:   Fri, 10 Oct 2025 19:10:51 +1000

fix proper allocation for sqlite content

Diffstat:
Mdb.c | 36++++++++++++++++++++----------------
Mdb.h | 2+-
Mkeys.c | 26+++++++++++++-------------
Mreadr.h | 2+-
Mrender.c | 10+++++-----
5 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/db.c b/db.c @@ -140,19 +140,14 @@ db_fetch_posts(const char* feed_url) sqlite3_bind_int(st, 2, MAX_POST_PER_FEED); int len = 0, cap = 0; - db_post_t* rows = NULL; + db_post_t** rows = NULL; while (sqlite3_step(st) == SQLITE_ROW) { - if (len == cap) { - cap = cap ? cap * 2 : MAX_POST_PER_FEED; - db_post_t* tmp = (db_post_t*)realloc(rows, (size_t)cap * sizeof(*rows)); - if (!tmp) { - fprintf(stderr, "could not reallocate for list of posts fetch from db\n"); - break; - } - rows = tmp; + db_post_t* p = calloc(1, sizeof(db_post_t)); + if (p == NULL) { + fprintf(stderr, "could not allocate post out of db\n"); + break; } - db_post_t* p = &rows[len++]; p->id = sqlite3_column_int(st, 0); p->title = dup_col(st, 1); p->link = dup_col(st, 2); @@ -161,6 +156,15 @@ db_fetch_posts(const char* feed_url) p->pub_date = dup_col(st, 5); p->summary = dup_col(st, 6); p->seen = sqlite3_column_int(st, 7); + if (len == cap) { + cap = cap ? cap * 2 : MAX_POST_PER_FEED; + rows = (db_post_t**)realloc(rows, sizeof(db_post_t*) * cap); + if (rows == NULL) { + fprintf(stderr, "could not reallocate for list of posts fetch from db\n"); + break; + } + } + rows[len++] = p; } int rc = sqlite3_finalize(st); @@ -168,12 +172,12 @@ db_fetch_posts(const char* feed_url) if (rc != SQLITE_OK) { fprintf(stderr, "finalize: %s\n", sqlite3_errmsg(db)); for (int i = 0; i < len; i++) { - free(rows[i].title); - free(rows[i].link); - free(rows[i].feed_url); - free(rows[i].comments); - free(rows[i].pub_date); - free(rows[i].summary); + free(rows[i]->title); + free(rows[i]->link); + free(rows[i]->feed_url); + free(rows[i]->comments); + free(rows[i]->pub_date); + free(rows[i]->summary); } free(rows); return (db_fetch_post_t) { .success = 0 }; diff --git a/db.h b/db.h @@ -12,7 +12,7 @@ typedef struct db_post_t { } db_post_t; typedef struct db_fetch_post_t { - db_post_t* posts; + db_post_t** posts; int count; int success; } db_fetch_post_t; diff --git a/keys.c b/keys.c @@ -41,15 +41,15 @@ handle_key(app_t* app, struct tb_event ev) case TB_KEY_ENTER: { if (app->selected_panel == 1) { char url[URL_CAP] = { 0 }; - db_post_t post = app->feeds[app->selected_feed]->posts[app->selected_post]; - size_t len = MIN(URL_CAP, strlen(post.link)); + db_post_t* post = app->feeds[app->selected_feed]->posts[app->selected_post]; + size_t len = MIN(URL_CAP, strlen(post->link)); if (len == 0) return; - strncpy(url, post.link, len); + strncpy(url, post->link, len); url[len] = '\0'; - if (db_mark_as_seen(post.id)) { - fprintf(stderr, "could not mark post as seen, id %d\n", post.id); - } - post.seen = 1; + if (db_mark_as_seen(post->id)) { + fprintf(stderr, "could not mark post as seen, id %d\n", post->id); + }; + post->seen = 1; open_url(url); } break; @@ -61,15 +61,15 @@ handle_key(app_t* app, struct tb_event ev) if (ev.ch == ' ') { // TB_KEY_SPACE for some reason doesn't work /shrug if (app->selected_panel == 1) { char url[URL_CAP] = { 0 }; - db_post_t post = app->feeds[app->selected_feed]->posts[app->selected_post]; - size_t len = MIN(URL_CAP, strlen(post.comments)); + db_post_t* post = app->feeds[app->selected_feed]->posts[app->selected_post]; + size_t len = MIN(URL_CAP, strlen(post->comments)); if (len == 0) return; - strncpy(url, post.comments, len); + strncpy(url, post->comments, len); url[len] = '\0'; - if (db_mark_as_seen(post.id)) { - fprintf(stderr, "could not mark post as seen, id %d\n", post.id); + if (db_mark_as_seen(post->id)) { + fprintf(stderr, "could not mark post as seen, id %d\n", post->id); } - post.seen = 1; + post->seen = 1; open_url(url); } } diff --git a/readr.h b/readr.h @@ -21,7 +21,7 @@ typedef struct { typedef struct { const char* url; char* title; - db_post_t* posts; + db_post_t** posts; int posts_len; } feed_t; diff --git a/render.c b/render.c @@ -62,7 +62,7 @@ render(app_t* app) uintattr_t color; size_t title_len; char title[TITLE_CAP] = { 0 }; - db_post_t post; + db_post_t* post; feed_t* feed; feed_t* selected_feed = app->feeds[app->selected_feed]; @@ -84,16 +84,16 @@ render(app_t* app) for (i = 0; i < selected_feed->posts_len; i++) { post = selected_feed->posts[i]; - title_len = MIN(TITLE_CAP, strlen(post.title)); - strncpy(title, post.title, title_len); + title_len = MIN(TITLE_CAP, strlen(post->title)); + strncpy(title, post->title, title_len); title[title_len] = '\0'; if (app->selected_panel == 1 && i == app->selected_post) - if (post.seen) + if (post->seen) color = (POST_COLOR | TB_REVERSE | TB_DIM); else color = (POST_COLOR | TB_REVERSE | TB_BRIGHT | TB_BOLD); - else if (post.seen) + else if (post->seen) color = (SEEN_COLOR); else color = (POST_COLOR);