diff options
author | wrmr | 2025-06-24 21:52:55 -0400 |
---|---|---|
committer | wrmr | 2025-06-24 21:52:55 -0400 |
commit | b0b005472fa0ec0d22fc2ed06cd7378a6ef68e9b (patch) | |
tree | 062e26aee30906b6da2838eb884def4259c79743 /main.c | |
parent | aaa94bac44546589e422748477edb8446efe41e2 (diff) |
tagline with three levels (ok, warn, err), post index profiling
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 112 |
1 files changed, 98 insertions, 14 deletions
diff --git a/main.c b/main.c index 7d0ab9b..84c9e98 100644 --- a/main.c +++ b/main.c @@ -14,6 +14,8 @@ #define _POSIX_C_SOURCE 202506L +/* includes */ + #include <stdio.h> #include <locale.h> #include <stdlib.h> @@ -50,6 +52,9 @@ #define CPAIR_TIME 2 #define CPAIR_MENTION 3 #define CPAIR_BORDER 4 +#define CPAIR_TAGLINE_OK 5 +#define CPAIR_TAGLINE_WARN 6 +#define CPAIR_TAGLINE_ERR 7 /* dynamic arrays */ @@ -80,15 +85,45 @@ regex_t re_mention; +#define TAGLINE_MAX 1024 +char tagline[TAGLINE_MAX] = { 0 }; +enum { + TAGLINE_OK, + TAGLINE_WARN, + TAGLINE_ERR +} tagline_status = TAGLINE_OK; + /* logging */ /* TODO: change to put in a proper log file or something */ +void tagline_set(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + vsnprintf(tagline, TAGLINE_MAX - 1, fmt, ap); + va_end(ap); + tagline_status = TAGLINE_OK; +} + void log_warn(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); + beep(); + flash(); + vsnprintf(tagline, TAGLINE_MAX - 1, fmt, ap); va_end(ap); + tagline_status = TAGLINE_WARN; +} + +void log_err(const char *fmt, ...) { + beep(); + flash(); + va_list ap; + va_start(ap, fmt); + vsnprintf(tagline, TAGLINE_MAX - 1, fmt, ap); + size_t n = strlen(tagline); + snprintf(tagline + n, TAGLINE_MAX - n - 1, ": %s", strerror(errno)); + va_end(ap); + tagline_status = TAGLINE_ERR; } /* string conversion */ @@ -128,6 +163,12 @@ typedef struct { ptrdiff_t len, cap; } PostList; +typedef struct { + size_t user_count, post_count, gather_ns; + struct timespec time_start, time_end; + int err; +} PostStats; + /* sorting */ int ts_cmp(const struct timespec *a, const struct timespec *b) { @@ -144,6 +185,26 @@ int post_cmp(const void *a, const void *b) { /* post indexing */ +PostStats post_stats = { 0 }; + +void post_stats_init(PostStats *ps) { + memset(ps, 0, sizeof(PostStats)); + if (clock_gettime(CLOCK_REALTIME, &ps->time_start)) { + log_warn("clock error!"); + ps->err = 1; + } +} + +void post_stats_fini(PostStats *ps) { + if (clock_gettime(CLOCK_REALTIME, &ps->time_end)) { + log_warn("clock error!"); + ps->err = 1; + } + int64_t diff_sec = ps->time_end.tv_sec - ps->time_start.tv_sec; + int64_t diff_nsec = ps->time_end.tv_nsec - ps->time_start.tv_nsec; + ps->gather_ns = (diff_sec * 1000000000) + diff_nsec; +} + /* @path must be both * (a) absolute; and * (b) allocated either statically or within arena @a @@ -151,6 +212,7 @@ int post_cmp(const void *a, const void *b) { void posts_gather_from(PostList *posts, Str username, const char *path, Arena *a) { DIR *d = opendir(path); if (!d) return; + post_stats.user_count++; for (struct dirent *de; (de = readdir(d)); ) { if (*de->d_name == '.') continue; Post p = { 0 }; @@ -176,17 +238,18 @@ void posts_gather(PostList *posts, Arena *a) { } void posts_load(PostList *posts, Arena *a) { + post_stats.post_count = posts->len; qsort(posts->data, posts->len, sizeof(Post), post_cmp); if (posts->len > POST_LIMIT) posts->len = POST_LIMIT; for (int i = 0; i < posts->len; i++) { Post *p = &posts->data[i]; FILE *f = fopen(p->path, "r/o"); if (!f) { - log_warn("couldn't open %s", p->path); + log_err("couldn't open %s", p->path); continue; } if (read_all(f, &p->text, a)) { - log_warn("couldn't read %s", p->path); + log_err("couldn't read %s", p->path); fclose(f); continue; } @@ -196,8 +259,10 @@ void posts_load(PostList *posts, Arena *a) { void posts_refresh(PostList *posts, Arena *a) { posts->len = 0; + post_stats_init(&post_stats); posts_gather(posts, a); posts_load(posts, a); + post_stats_fini(&post_stats); } /* word wrapping */ @@ -379,7 +444,10 @@ void new_post(Arena *temp) { /* create and edit post in a temp file */ - if (clock_gettime(CLOCK_REALTIME, &ts)) err(1, "clock_gettime failure"); + if (clock_gettime(CLOCK_REALTIME, &ts)) { + log_err("clock failure"); + return; + } const char *tmpf = cstr_fmt(temp, "/tmp/cbink_%s_%U%09u.txt", getlogin(), (uint64_t)ts.tv_sec, (uint32_t)ts.tv_nsec); @@ -390,27 +458,30 @@ void new_post(Arena *temp) { if (!f) return; if (read_all(f, &body, temp)) { fclose(f); - log_warn("couldn't read %s", tmpf); + log_err("couldn't read %s", tmpf); return; } fclose(f); - if (remove(tmpf)) log_warn("failed to remove %s", tmpf); + if (remove(tmpf)) log_err("failed to remove %s", tmpf); body = str_trim(body); if (body.n < 1) return; /* write it to .bink (with updated timestamp) */ - if (clock_gettime(CLOCK_REALTIME, &ts)) err(1, "clock_gettime failure"); + if (clock_gettime(CLOCK_REALTIME, &ts)) { + log_err("clock failure"); + return; + } const char *outf = cstr_fmt(temp, "/home/%s/.bink/%U%09u", getlogin(), (uint64_t)ts.tv_sec, (uint32_t)ts.tv_nsec); f = fopen(outf, "w/o"); if (!f) { - log_warn("failed to open %s", outf); + log_err("failed to open %s", outf); return; } if (fwrite(body.s, 1, body.n, f) != (size_t)body.n) { - err(1, "write error in %s", outf); + log_err("write error in %s", outf); fclose(f); return; } @@ -430,6 +501,9 @@ void init_curses(void) { keypad(stdscr, TRUE); curs_set(0); + init_pair(CPAIR_TAGLINE_OK, COLOR_GREEN, COLOR_BLACK); + init_pair(CPAIR_TAGLINE_WARN, COLOR_YELLOW, COLOR_BLACK); + init_pair(CPAIR_TAGLINE_ERR, COLOR_RED, COLOR_BLACK); init_pair(CPAIR_BORDER, COLOR_BLUE, COLOR_BLACK); init_pair(CPAIR_USER, COLOR_YELLOW, COLOR_BLACK); init_pair(CPAIR_TIME, COLOR_BLUE, COLOR_BLACK); @@ -475,6 +549,13 @@ int main(void) { arena_reset(&temp_arena); gfx_draw(&gfx, cur); + switch (tagline_status) { + case TAGLINE_OK: color_set(CPAIR_TAGLINE_OK, 0); break; + case TAGLINE_WARN: color_set(CPAIR_TAGLINE_WARN, 0); break; + case TAGLINE_ERR: color_set(CPAIR_TAGLINE_ERR, 0); break; + } + mvaddstr(getmaxy(stdscr) - 1, getmaxx(stdscr) - strlen(tagline), tagline); + tagline[0] = '\0'; int ch = getch(); if (ch == 'q') break; @@ -516,19 +597,22 @@ int main(void) { fini_curses(); edit_post(&posts.data[cur], &temp_arena); init_curses(); + goto refresh; } else { - beep(); - flash(); + log_warn("not your post to edit!"); + break; } - goto refresh; case 'c': fini_curses(); new_post(&temp_arena); init_curses(); /* fallthrough */ case 'r': -refresh: arena_reset(&post_arena); +refresh: + arena_reset(&post_arena); posts_refresh(&posts, &post_arena); + tagline_set("%lu users, %lu posts, %lums", post_stats.user_count, post_stats.post_count, + post_stats.gather_ns / 1000000); /* fallthrough */ case KEY_RESIZE: arena_reset(&gfx_arena); |