iremove overly generic code - iomenu - interactive terminal-based selection menu Err bitreich.org 70 hgit clone git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu URL:git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu bitreich.org 70 1Log /scm/iomenu/log.gph bitreich.org 70 1Files /scm/iomenu/files.gph bitreich.org 70 1Refs /scm/iomenu/refs.gph bitreich.org 70 1Tags /scm/iomenu/tag bitreich.org 70 1README /scm/iomenu/file/README.gph bitreich.org 70 1LICENSE /scm/iomenu/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit 774936ea25643995d42c2ca1cd7052875fc35573 /scm/iomenu/commit/774936ea25643995d42c2ca1cd7052875fc35573.gph bitreich.org 70 1parent f099742c20929af4c304bb477ad8ec42e0bb6f17 /scm/iomenu/commit/f099742c20929af4c304bb477ad8ec42e0bb6f17.gph bitreich.org 70 hAuthor: Josuah Demangeon URL:mailto:me@josuah.net bitreich.org 70 iDate: Tue, 27 Oct 2020 22:34:48 +0100 Err bitreich.org 70 i Err bitreich.org 70 iremove overly generic code Err bitreich.org 70 i Err bitreich.org 70 iGeneric library-style code is good for larger projects that have an interest Err bitreich.org 70 iat putting in common a lot of code. Err bitreich.org 70 i Err bitreich.org 70 iNarrowing the scope to just the problem to solve makes the implementation simpler. Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M Makefile | 9 ++++----- Err bitreich.org 70 i A compat.c | 59 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i R src/compat.h -> compat.h | 0 Err bitreich.org 70 i M iomenu.c | 129 +++++++++++++++++++------------ Err bitreich.org 70 i D src/compat/strcasestr.c | 25 ------------------------- Err bitreich.org 70 i D src/compat/strlcpy.c | 15 --------------- Err bitreich.org 70 i D src/compat/strsep.c | 23 ----------------------- Err bitreich.org 70 i D src/log.c | 72 ------------------------------- Err bitreich.org 70 i D src/log.h | 14 -------------- Err bitreich.org 70 i D src/mem.c | 160 ------------------------------- Err bitreich.org 70 i D src/mem.h | 59 ------------------------------- Err bitreich.org 70 i D src/term.c | 107 ------------------------------- Err bitreich.org 70 i D src/term.h | 39 ------------------------------- Err bitreich.org 70 i A term.c | 107 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i A term.h | 38 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i R src/utf8.c -> utf8.c | 0 Err bitreich.org 70 i R src/utf8.h -> utf8.h | 0 Err bitreich.org 70 i R src/compat/wcwidth.c -> wcwidth.c | 0 Err bitreich.org 70 i A wcwidth.h | 13 +++++++++++++ Err bitreich.org 70 i Err bitreich.org 70 i19 files changed, 299 insertions(+), 570 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/Makefile b/Makefile /scm/iomenu/file/Makefile.gph bitreich.org 70 i@@ -1,12 +1,11 @@ Err bitreich.org 70 i NAME = iomenu Err bitreich.org 70 i VERSION = 0.1 Err bitreich.org 70 i Err bitreich.org 70 i-SRC = src/utf8.c src/log.c src/mem.c src/compat/strcasestr.c \ Err bitreich.org 70 i- src/compat/strsep.c src/compat/strlcpy.c src/compat/wcwidth.c src/term.c Err bitreich.org 70 i-HDR = src/mem.h src/compat.h src/log.h src/term.h src/utf8.h Err bitreich.org 70 i+SRC = utf8.c compat.c wcwidth.c term.c Err bitreich.org 70 i+HDR = utf8.h compat.h wcwidth.h term.h Err bitreich.org 70 i+OBJ = ${SRC:.c=.o} Err bitreich.org 70 i BIN = iomenu Err bitreich.org 70 i MAN1 = ${BIN:=.1} Err bitreich.org 70 i-OBJ = ${SRC:.c=.o} Err bitreich.org 70 i LIB = Err bitreich.org 70 i Err bitreich.org 70 i W = -Wall -Wextra -std=c99 --pedantic Err bitreich.org 70 i@@ -28,7 +27,7 @@ ${BIN}: ${OBJ} ${BIN:=.o} Err bitreich.org 70 i ${CC} ${LDFLAGS} -o $@ $@.o ${OBJ} ${LIB} Err bitreich.org 70 i Err bitreich.org 70 i clean: Err bitreich.org 70 i- rm -rf *.o */*.o ${BIN} ${NAME}-${VERSION} *.gz Err bitreich.org 70 i+ rm -rf *.o ${BIN} ${NAME}-${VERSION} *.gz Err bitreich.org 70 i Err bitreich.org 70 i install: Err bitreich.org 70 i mkdir -p ${DESTDIR}${PREFIX}/bin Err bitreich.org 70 1diff --git a/compat.c b/compat.c /scm/iomenu/file/compat.c.gph bitreich.org 70 i@@ -0,0 +1,59 @@ Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i+#include "compat.h" Err bitreich.org 70 i+ Err bitreich.org 70 i+char * Err bitreich.org 70 i+strcasestr(const char *str1, const char *str2) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ const char *s1; Err bitreich.org 70 i+ const char *s2; Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (;;) { Err bitreich.org 70 i+ s1 = str1; Err bitreich.org 70 i+ s2 = str2; Err bitreich.org 70 i+ while (*s1 != '\0' && tolower(*s1) == tolower(*s2)) Err bitreich.org 70 i+ s1++, s2++; Err bitreich.org 70 i+ if (*s2 == '\0') Err bitreich.org 70 i+ return (char *) str1; Err bitreich.org 70 i+ if (*s1 == '\0') Err bitreich.org 70 i+ return NULL; Err bitreich.org 70 i+ str1++; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ return NULL; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+size_t Err bitreich.org 70 i+strlcpy(char *buf, char const *str, size_t sz) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ size_t len, cpy; Err bitreich.org 70 i+ Err bitreich.org 70 i+ len = strlen(str); Err bitreich.org 70 i+ cpy = (len > sz) ? (sz) : (len); Err bitreich.org 70 i+ memcpy(buf, str, cpy + 1); Err bitreich.org 70 i+ buf[sz - 1] = '\0'; Err bitreich.org 70 i+ return len; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+char * Err bitreich.org 70 i+strsep(char **str_p, char const *sep) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ char *s, *prev; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (*str_p == NULL) Err bitreich.org 70 i+ return NULL; Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (s = prev = *str_p; strchr(sep, *s) == NULL; s++) Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (*s == '\0') { Err bitreich.org 70 i+ *str_p = NULL; Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ *s = '\0'; Err bitreich.org 70 i+ *str_p = s + 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ return prev; Err bitreich.org 70 i+} Err bitreich.org 70 1diff --git a/src/compat.h b/compat.h /scm/iomenu/file/compat.h.gph bitreich.org 70 1diff --git a/iomenu.c b/iomenu.c /scm/iomenu/file/iomenu.c.gph bitreich.org 70 i@@ -10,23 +10,21 @@ Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i+#include Err bitreich.org 70 i Err bitreich.org 70 i #include "compat.h" Err bitreich.org 70 i-#include "log.h" Err bitreich.org 70 i-#include "mem.h" Err bitreich.org 70 i #include "term.h" Err bitreich.org 70 i #include "utf8.h" Err bitreich.org 70 i Err bitreich.org 70 i struct { Err bitreich.org 70 i- FILE *tty; Err bitreich.org 70 i char input[LINE_MAX]; Err bitreich.org 70 i size_t cur; Err bitreich.org 70 i Err bitreich.org 70 i char **lines_buf; Err bitreich.org 70 i- size_t lines_len; Err bitreich.org 70 i+ size_t lines_count; Err bitreich.org 70 i Err bitreich.org 70 i char **match_buf; Err bitreich.org 70 i- size_t match_len; Err bitreich.org 70 i+ size_t match_count; Err bitreich.org 70 i } ctx; Err bitreich.org 70 i Err bitreich.org 70 i int opt_comment; Err bitreich.org 70 i@@ -51,20 +49,44 @@ match_line(char *line, char **tokv) Err bitreich.org 70 i * error message. Err bitreich.org 70 i */ Err bitreich.org 70 i static void Err bitreich.org 70 i-goodbye(const char *s) Err bitreich.org 70 i+die(const char *msg) Err bitreich.org 70 i { Err bitreich.org 70 i int e = errno; Err bitreich.org 70 i Err bitreich.org 70 i term_raw_off(2); Err bitreich.org 70 i+ Err bitreich.org 70 i+ fprintf(stderr, "iomenu: "); Err bitreich.org 70 i errno = e; Err bitreich.org 70 i- die("%s", s); Err bitreich.org 70 i+ perror(msg); Err bitreich.org 70 i+ Err bitreich.org 70 i+ exit(1); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void * Err bitreich.org 70 i+xrealloc(void *ptr, size_t sz) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ ptr = realloc(ptr, sz); Err bitreich.org 70 i+ if (ptr == NULL) Err bitreich.org 70 i+ die("realloc"); Err bitreich.org 70 i+ return ptr; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void * Err bitreich.org 70 i+xmalloc(size_t sz) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ void *ptr; Err bitreich.org 70 i+ Err bitreich.org 70 i+ ptr = malloc(sz); Err bitreich.org 70 i+ if (ptr == NULL) Err bitreich.org 70 i+ die("malloc"); Err bitreich.org 70 i+ return ptr; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i do_move(int sign) Err bitreich.org 70 i { Err bitreich.org 70 i /* integer overflow will do what we need */ Err bitreich.org 70 i- for (size_t i = ctx.cur + sign; i < ctx.match_len; i += sign) { Err bitreich.org 70 i+ for (size_t i = ctx.cur + sign; i < ctx.match_count; i += sign) { Err bitreich.org 70 i if (opt_comment == 0 || ctx.match_buf[i][0] != '#') { Err bitreich.org 70 i ctx.cur = i; Err bitreich.org 70 i break; Err bitreich.org 70 i@@ -78,7 +100,7 @@ do_move(int sign) Err bitreich.org 70 i * of `searchv' of size `searchc' Err bitreich.org 70 i */ Err bitreich.org 70 i static void Err bitreich.org 70 i-do_filter(char **search_buf, size_t search_len) Err bitreich.org 70 i+do_filter(char **search_buf, size_t search_count) Err bitreich.org 70 i { Err bitreich.org 70 i char **t, *tokv[(sizeof ctx.input + 1) * sizeof(char *)]; Err bitreich.org 70 i char *b, buf[sizeof ctx.input]; Err bitreich.org 70 i@@ -89,10 +111,10 @@ do_filter(char **search_buf, size_t search_len) Err bitreich.org 70 i continue; Err bitreich.org 70 i *t = NULL; Err bitreich.org 70 i Err bitreich.org 70 i- ctx.cur = ctx.match_len = 0; Err bitreich.org 70 i- for (size_t n = 0; n < search_len; n++) Err bitreich.org 70 i+ ctx.cur = ctx.match_count = 0; Err bitreich.org 70 i+ for (size_t n = 0; n < search_count; n++) Err bitreich.org 70 i if (match_line(search_buf[n], tokv)) Err bitreich.org 70 i- ctx.match_buf[ctx.match_len++] = search_buf[n]; Err bitreich.org 70 i+ ctx.match_buf[ctx.match_count++] = search_buf[n]; Err bitreich.org 70 i if (opt_comment && ctx.match_buf[ctx.cur][0] == '#') Err bitreich.org 70 i do_move(+1); Err bitreich.org 70 i } Err bitreich.org 70 i@@ -103,7 +125,7 @@ do_move_page(signed int sign) Err bitreich.org 70 i int rows = term.winsize.ws_row - 1; Err bitreich.org 70 i size_t i = ctx.cur - ctx.cur % rows + rows * sign; Err bitreich.org 70 i Err bitreich.org 70 i- if (i >= ctx.match_len) Err bitreich.org 70 i+ if (i >= ctx.match_count) Err bitreich.org 70 i return; Err bitreich.org 70 i ctx.cur = i - 1; Err bitreich.org 70 i Err bitreich.org 70 i@@ -120,7 +142,7 @@ do_move_header(signed int sign) Err bitreich.org 70 i for (ctx.cur += sign;; ctx.cur += sign) { Err bitreich.org 70 i char *cur = ctx.match_buf[ctx.cur]; Err bitreich.org 70 i Err bitreich.org 70 i- if (ctx.cur >= ctx.match_len) { Err bitreich.org 70 i+ if (ctx.cur >= ctx.match_count) { Err bitreich.org 70 i ctx.cur--; Err bitreich.org 70 i break; Err bitreich.org 70 i } Err bitreich.org 70 i@@ -142,7 +164,7 @@ do_remove_word(void) Err bitreich.org 70 i len = strlen(ctx.input) - 1; Err bitreich.org 70 i for (i = len; i >= 0 && !isspace(ctx.input[i]); i--) Err bitreich.org 70 i ctx.input[i] = '\0'; Err bitreich.org 70 i- do_filter(ctx.lines_buf, ctx.lines_len); Err bitreich.org 70 i+ do_filter(ctx.lines_buf, ctx.lines_count); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i@@ -157,7 +179,7 @@ do_add_char(char c) Err bitreich.org 70 i ctx.input[len] = c; Err bitreich.org 70 i ctx.input[len + 1] = '\0'; Err bitreich.org 70 i } Err bitreich.org 70 i- do_filter(ctx.match_buf, ctx.match_len); Err bitreich.org 70 i+ do_filter(ctx.match_buf, ctx.match_count); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i@@ -175,7 +197,7 @@ do_print_selection(void) Err bitreich.org 70 i fprintf(stdout, "%c", '\t'); Err bitreich.org 70 i } Err bitreich.org 70 i term_raw_off(2); Err bitreich.org 70 i- if (ctx.match_len == 0 Err bitreich.org 70 i+ if (ctx.match_count == 0 Err bitreich.org 70 i || (opt_comment && ctx.match_buf[ctx.cur][0] == '#')) Err bitreich.org 70 i fprintf(stdout, "%s\n", ctx.input); Err bitreich.org 70 i else Err bitreich.org 70 i@@ -204,7 +226,7 @@ key_action(void) Err bitreich.org 70 i return -1; Err bitreich.org 70 i case TERM_KEY_CTRL('U'): Err bitreich.org 70 i ctx.input[0] = '\0'; Err bitreich.org 70 i- do_filter(ctx.lines_buf, ctx.lines_len); Err bitreich.org 70 i+ do_filter(ctx.lines_buf, ctx.lines_count); Err bitreich.org 70 i break; Err bitreich.org 70 i case TERM_KEY_CTRL('W'): Err bitreich.org 70 i do_remove_word(); Err bitreich.org 70 i@@ -212,7 +234,7 @@ key_action(void) Err bitreich.org 70 i case TERM_KEY_DELETE: Err bitreich.org 70 i case TERM_KEY_BACKSPACE: Err bitreich.org 70 i ctx.input[strlen(ctx.input) - 1] = '\0'; Err bitreich.org 70 i- do_filter(ctx.lines_buf, ctx.lines_len); Err bitreich.org 70 i+ do_filter(ctx.lines_buf, ctx.lines_count); Err bitreich.org 70 i break; Err bitreich.org 70 i case TERM_KEY_ARROW_UP: Err bitreich.org 70 i case TERM_KEY_CTRL('P'): Err bitreich.org 70 i@@ -237,10 +259,10 @@ key_action(void) Err bitreich.org 70 i do_move_page(+1); Err bitreich.org 70 i break; Err bitreich.org 70 i case TERM_KEY_TAB: Err bitreich.org 70 i- if (ctx.match_len == 0) Err bitreich.org 70 i+ if (ctx.match_count == 0) Err bitreich.org 70 i break; Err bitreich.org 70 i strlcpy(ctx.input, ctx.match_buf[ctx.cur], sizeof(ctx.input)); Err bitreich.org 70 i- do_filter(ctx.match_buf, ctx.match_len); Err bitreich.org 70 i+ do_filter(ctx.match_buf, ctx.match_count); Err bitreich.org 70 i break; Err bitreich.org 70 i case TERM_KEY_ENTER: Err bitreich.org 70 i case TERM_KEY_CTRL('M'): Err bitreich.org 70 i@@ -281,7 +303,7 @@ do_print_screen(void) Err bitreich.org 70 i i = ctx.cur - ctx.cur % rows; Err bitreich.org 70 i m = ctx.match_buf + i; Err bitreich.org 70 i fprintf(stderr, "\x1b[2J"); Err bitreich.org 70 i- while (p < rows && i < ctx.match_len) { Err bitreich.org 70 i+ while (p < rows && i < ctx.match_count) { Err bitreich.org 70 i print_line(*m, i == ctx.cur); Err bitreich.org 70 i p++, i++, m++; Err bitreich.org 70 i } Err bitreich.org 70 i@@ -294,7 +316,7 @@ static void Err bitreich.org 70 i sig_winch(int sig) Err bitreich.org 70 i { Err bitreich.org 70 i if (ioctl(STDERR_FILENO, TIOCGWINSZ, &term.winsize) == -1) Err bitreich.org 70 i- goodbye("ioctl"); Err bitreich.org 70 i+ die("ioctl"); Err bitreich.org 70 i do_print_screen(); Err bitreich.org 70 i signal(sig, sig_winch); Err bitreich.org 70 i } Err bitreich.org 70 i@@ -306,15 +328,25 @@ usage(char const *arg0) Err bitreich.org 70 i exit(1); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-static void Err bitreich.org 70 i-read_stdin(char **buf, struct mem_pool *pool) Err bitreich.org 70 i+static int Err bitreich.org 70 i+read_stdin(char **buf) Err bitreich.org 70 i { Err bitreich.org 70 i- if (mem_read((void **)buf, pool) < 0) Err bitreich.org 70 i- goodbye("reading standard input"); Err bitreich.org 70 i- if (memchr(*buf, '\0', mem_length(*buf)) != NULL) Err bitreich.org 70 i- goodbye("'\\0' byte in input"); Err bitreich.org 70 i- if (mem_append((void **)buf, "", 1) < 0) Err bitreich.org 70 i- goodbye("adding '\\0' terminator"); Err bitreich.org 70 i+ size_t len = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ assert(*buf == NULL); Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (int c; (c = fgetc(stdin)) != EOF;) { Err bitreich.org 70 i+ if (c == '\0') { Err bitreich.org 70 i+ fprintf(stderr, "iomenu: ignoring '\\0' byte in input\r\n"); Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ *buf = xrealloc(*buf, sizeof *buf + len + 1); Err bitreich.org 70 i+ (*buf)[len++] = c; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ *buf = xrealloc(*buf, sizeof *buf + len + 1); Err bitreich.org 70 i+ (*buf)[len] = '\0'; Err bitreich.org 70 i+ Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i /* Err bitreich.org 70 i@@ -322,27 +354,24 @@ read_stdin(char **buf, struct mem_pool *pool) Err bitreich.org 70 i * line, but using the input buffer and replacing '\n' by '\0'. Err bitreich.org 70 i */ Err bitreich.org 70 i static void Err bitreich.org 70 i-split_lines(char *s, struct mem_pool *pool) Err bitreich.org 70 i+split_lines(char *s) Err bitreich.org 70 i { Err bitreich.org 70 i- ctx.lines_buf = mem_alloc(pool, 0); Err bitreich.org 70 i- if (ctx.lines_buf == NULL) Err bitreich.org 70 i- goodbye("initializing full lines buffer"); Err bitreich.org 70 i+ size_t sz; Err bitreich.org 70 i Err bitreich.org 70 i- ctx.lines_len = 0; Err bitreich.org 70 i+ ctx.lines_count = 0; Err bitreich.org 70 i for (;;) { Err bitreich.org 70 i- if (mem_append((void **)&ctx.lines_buf, &s, sizeof s) < 0) Err bitreich.org 70 i- goodbye("adding line to array"); Err bitreich.org 70 i- ctx.lines_len++; Err bitreich.org 70 i+ sz = (ctx.lines_count + 1) * sizeof s; Err bitreich.org 70 i+ ctx.lines_buf = xrealloc(ctx.lines_buf, sz); Err bitreich.org 70 i+ ctx.lines_buf[ctx.lines_count++] = s; Err bitreich.org 70 i Err bitreich.org 70 i s = strchr(s, '\n'); Err bitreich.org 70 i if (s == NULL) Err bitreich.org 70 i break; Err bitreich.org 70 i *s++ = '\0'; Err bitreich.org 70 i } Err bitreich.org 70 i- Err bitreich.org 70 i- ctx.match_buf = mem_alloc(pool, mem_length(ctx.lines_buf)); Err bitreich.org 70 i- if (ctx.match_buf == NULL) Err bitreich.org 70 i- goodbye("initializing matching lines buffer"); Err bitreich.org 70 i+ sz = ctx.lines_count * sizeof s; Err bitreich.org 70 i+ ctx.match_buf = xmalloc(sz); Err bitreich.org 70 i+ memcpy(ctx.match_buf, ctx.lines_buf, sz); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i /* Err bitreich.org 70 i@@ -353,8 +382,7 @@ split_lines(char *s, struct mem_pool *pool) Err bitreich.org 70 i int Err bitreich.org 70 i main(int argc, char *argv[]) Err bitreich.org 70 i { Err bitreich.org 70 i- struct mem_pool pool = {0}; Err bitreich.org 70 i- char *buf; Err bitreich.org 70 i+ char *buf = NULL, *arg0; Err bitreich.org 70 i Err bitreich.org 70 i arg0 = *argv; Err bitreich.org 70 i for (int opt; (opt = getopt(argc, argv, "#v")) > 0;) { Err bitreich.org 70 i@@ -372,17 +400,17 @@ main(int argc, char *argv[]) Err bitreich.org 70 i argc -= optind; Err bitreich.org 70 i argv += optind; Err bitreich.org 70 i Err bitreich.org 70 i- read_stdin(&buf, &pool); Err bitreich.org 70 i- split_lines(buf, &pool); Err bitreich.org 70 i+ read_stdin(&buf); Err bitreich.org 70 i+ split_lines(buf); Err bitreich.org 70 i Err bitreich.org 70 i- do_filter(ctx.lines_buf, ctx.lines_len); Err bitreich.org 70 i+ do_filter(ctx.lines_buf, ctx.lines_count); Err bitreich.org 70 i Err bitreich.org 70 i if (!isatty(2)) Err bitreich.org 70 i- goodbye("file descriptor 2 (stderr)"); Err bitreich.org 70 i+ die("file descriptor 2 (stderr)"); Err bitreich.org 70 i Err bitreich.org 70 i freopen("/dev/tty", "w+", stderr); Err bitreich.org 70 i if (stderr == NULL) Err bitreich.org 70 i- goodbye("re-opening standard error read/write"); Err bitreich.org 70 i+ die("re-opening standard error read/write"); Err bitreich.org 70 i Err bitreich.org 70 i term_raw_on(2); Err bitreich.org 70 i sig_winch(SIGWINCH); Err bitreich.org 70 i@@ -396,6 +424,5 @@ main(int argc, char *argv[]) Err bitreich.org 70 i Err bitreich.org 70 i term_raw_off(2); Err bitreich.org 70 i Err bitreich.org 70 i- mem_free(&pool); Err bitreich.org 70 i return 0; Err bitreich.org 70 i } Err bitreich.org 70 1diff --git a/src/compat/strcasestr.c b/src/compat/strcasestr.c /scm/iomenu/file/src/compat/strcasestr.c.gph bitreich.org 70 i@@ -1,25 +0,0 @@ Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-#include "compat.h" Err bitreich.org 70 i- Err bitreich.org 70 i-char * Err bitreich.org 70 i-strcasestr(const char *str1, const char *str2) Err bitreich.org 70 i-{ Err bitreich.org 70 i- const char *s1; Err bitreich.org 70 i- const char *s2; Err bitreich.org 70 i- Err bitreich.org 70 i- for (;;) { Err bitreich.org 70 i- s1 = str1; Err bitreich.org 70 i- s2 = str2; Err bitreich.org 70 i- while (*s1 != '\0' && tolower(*s1) == tolower(*s2)) Err bitreich.org 70 i- s1++, s2++; Err bitreich.org 70 i- if (*s2 == '\0') Err bitreich.org 70 i- return (char *) str1; Err bitreich.org 70 i- if (*s1 == '\0') Err bitreich.org 70 i- return NULL; Err bitreich.org 70 i- str1++; Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- return NULL; Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/src/compat/strlcpy.c b/src/compat/strlcpy.c /scm/iomenu/file/src/compat/strlcpy.c.gph bitreich.org 70 i@@ -1,15 +0,0 @@ Err bitreich.org 70 i-#include "compat.h" Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-size_t Err bitreich.org 70 i-strlcpy(char *buf, char const *str, size_t sz) Err bitreich.org 70 i-{ Err bitreich.org 70 i- size_t len, cpy; Err bitreich.org 70 i- Err bitreich.org 70 i- len = strlen(str); Err bitreich.org 70 i- cpy = (len > sz) ? (sz) : (len); Err bitreich.org 70 i- memcpy(buf, str, cpy + 1); Err bitreich.org 70 i- buf[sz - 1] = '\0'; Err bitreich.org 70 i- return len; Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/src/compat/strsep.c b/src/compat/strsep.c /scm/iomenu/file/src/compat/strsep.c.gph bitreich.org 70 i@@ -1,23 +0,0 @@ Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-#include "compat.h" Err bitreich.org 70 i- Err bitreich.org 70 i-char * Err bitreich.org 70 i-strsep(char **str_p, char const *sep) Err bitreich.org 70 i-{ Err bitreich.org 70 i- char *s, *prev; Err bitreich.org 70 i- Err bitreich.org 70 i- if (*str_p == NULL) Err bitreich.org 70 i- return NULL; Err bitreich.org 70 i- Err bitreich.org 70 i- for (s = prev = *str_p; strchr(sep, *s) == NULL; s++) Err bitreich.org 70 i- continue; Err bitreich.org 70 i- Err bitreich.org 70 i- if (*s == '\0') { Err bitreich.org 70 i- *str_p = NULL; Err bitreich.org 70 i- } else { Err bitreich.org 70 i- *s = '\0'; Err bitreich.org 70 i- *str_p = s + 1; Err bitreich.org 70 i- } Err bitreich.org 70 i- return prev; Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/src/log.c b/src/log.c /scm/iomenu/file/src/log.c.gph bitreich.org 70 i@@ -1,72 +0,0 @@ Err bitreich.org 70 i-#include "log.h" Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-#ifndef LOG_DEFAULT Err bitreich.org 70 i-#define LOG_DEFAULT 3 /* info */ Err bitreich.org 70 i-#endif Err bitreich.org 70 i- Err bitreich.org 70 i-char *arg0 = NULL; Err bitreich.org 70 i-static int log_level = -1; Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-log_vprintf(int level, char const *flag, char const *fmt, va_list va) Err bitreich.org 70 i-{ Err bitreich.org 70 i- char *env; Err bitreich.org 70 i- int old_errno = errno; Err bitreich.org 70 i- Err bitreich.org 70 i- if (log_level < 0) { Err bitreich.org 70 i- env = getenv("LOG"); Err bitreich.org 70 i- log_level = (env == NULL) ? 0 : atoi(env); Err bitreich.org 70 i- if (log_level == 0) Err bitreich.org 70 i- log_level = LOG_DEFAULT; Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- if (log_level < level) Err bitreich.org 70 i- return; Err bitreich.org 70 i- Err bitreich.org 70 i- if (arg0 != NULL) Err bitreich.org 70 i- fprintf(stderr, "%s: ", arg0); Err bitreich.org 70 i- Err bitreich.org 70 i- fprintf(stderr, "%s: ", flag); Err bitreich.org 70 i- vfprintf(stderr, fmt, va); Err bitreich.org 70 i- Err bitreich.org 70 i- if (old_errno != 0) Err bitreich.org 70 i- fprintf(stderr, ": %s", strerror(old_errno)); Err bitreich.org 70 i- Err bitreich.org 70 i- fprintf(stderr, "\n"); Err bitreich.org 70 i- fflush(stderr); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-die(char const *fmt, ...) Err bitreich.org 70 i-{ Err bitreich.org 70 i- va_list va; Err bitreich.org 70 i- va_start(va, fmt); log_vprintf(1, "error", fmt, va); va_end(va); Err bitreich.org 70 i- exit(1); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-warn(char const *fmt, ...) Err bitreich.org 70 i-{ Err bitreich.org 70 i- va_list va; Err bitreich.org 70 i- va_start(va, fmt); log_vprintf(2, "warn", fmt, va); va_end(va); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-info(char const *fmt, ...) Err bitreich.org 70 i-{ Err bitreich.org 70 i- va_list va; Err bitreich.org 70 i- va_start(va, fmt); log_vprintf(3, "info", fmt, va); va_end(va); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-debug(char const *fmt, ...) Err bitreich.org 70 i-{ Err bitreich.org 70 i- va_list va; Err bitreich.org 70 i- va_start(va, fmt); log_vprintf(4, "debug", fmt, va); va_end(va); Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/src/log.h b/src/log.h /scm/iomenu/file/src/log.h.gph bitreich.org 70 i@@ -1,14 +0,0 @@ Err bitreich.org 70 i-#ifndef LOG_H Err bitreich.org 70 i-#define LOG_H Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-/** src/log.c **/ Err bitreich.org 70 i-char *arg0; Err bitreich.org 70 i-void log_vprintf(int level, char const *flag, char const *fmt, va_list va); Err bitreich.org 70 i-void die(char const *fmt, ...); Err bitreich.org 70 i-void warn(char const *fmt, ...); Err bitreich.org 70 i-void info(char const *fmt, ...); Err bitreich.org 70 i-void debug(char const *fmt, ...); Err bitreich.org 70 i- Err bitreich.org 70 i-#endif Err bitreich.org 70 1diff --git a/src/mem.c b/src/mem.c /scm/iomenu/file/src/mem.c.gph bitreich.org 70 i@@ -1,160 +0,0 @@ Err bitreich.org 70 i-#include "mem.h" Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-static struct mem_block * Err bitreich.org 70 i-mem_block(void **memp) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct mem_block *block = (void *)((char *)memp - sizeof *block); Err bitreich.org 70 i- Err bitreich.org 70 i- assert(memcmp(block->magic, MEM_BLOCK_MAGIC, 8) == 0); Err bitreich.org 70 i- return block; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void * Err bitreich.org 70 i-mem_alloc(struct mem_pool *pool, size_t len) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct mem_block *block; Err bitreich.org 70 i- Err bitreich.org 70 i- block = calloc(1, sizeof *block + len); Err bitreich.org 70 i- if (block == NULL) Err bitreich.org 70 i- return NULL; Err bitreich.org 70 i- memcpy(block->magic, MEM_BLOCK_MAGIC, 8); Err bitreich.org 70 i- Err bitreich.org 70 i- block->len = len; Err bitreich.org 70 i- block->pool = pool; Err bitreich.org 70 i- block->prev = NULL; Err bitreich.org 70 i- block->next = pool->head; Err bitreich.org 70 i- if (pool->head != NULL) Err bitreich.org 70 i- pool->head->prev = block; Err bitreich.org 70 i- pool->head = block; Err bitreich.org 70 i- Err bitreich.org 70 i- return block->buf; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-mem_resize(void **memp, size_t len) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct mem_block *block = mem_block(*memp); Err bitreich.org 70 i- int is_first = (block == block->pool->head); Err bitreich.org 70 i- int is_same; Err bitreich.org 70 i- void *v; Err bitreich.org 70 i- Err bitreich.org 70 i- v = realloc(block, sizeof *block + len); Err bitreich.org 70 i- if (v == NULL) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- is_same = (block == v); Err bitreich.org 70 i- block = v; Err bitreich.org 70 i- Err bitreich.org 70 i- block->len = len; Err bitreich.org 70 i- Err bitreich.org 70 i- if (is_same) Err bitreich.org 70 i- return 0; Err bitreich.org 70 i- Err bitreich.org 70 i- if (block->prev != NULL) Err bitreich.org 70 i- block->prev->next = v; Err bitreich.org 70 i- if (block->next != NULL) Err bitreich.org 70 i- block->next->prev = v; Err bitreich.org 70 i- if (is_first) Err bitreich.org 70 i- block->pool->head = v; Err bitreich.org 70 i- *memp = block->buf; Err bitreich.org 70 i- Err bitreich.org 70 i- assert(memcmp(block->magic, MEM_BLOCK_MAGIC, 8) == 0); Err bitreich.org 70 i- return 0; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-mem_grow(void **memp, size_t len) Err bitreich.org 70 i-{ Err bitreich.org 70 i- assert(SIZE_MAX - len >= mem_block(*memp)->len); Err bitreich.org 70 i- Err bitreich.org 70 i- return mem_resize(memp, mem_length(*memp) + len); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-mem_shrink(void **memp, size_t len) Err bitreich.org 70 i-{ Err bitreich.org 70 i- assert(mem_block(*memp)->len >= len); Err bitreich.org 70 i- Err bitreich.org 70 i- return mem_resize(memp, mem_length(*memp) - len); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-size_t Err bitreich.org 70 i-mem_length(void *mem) Err bitreich.org 70 i-{ Err bitreich.org 70 i- return mem_block(mem)->len; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-mem_append(void **memp, void const *buf, size_t len) Err bitreich.org 70 i-{ Err bitreich.org 70 i- size_t old_len = mem_length(*memp); Err bitreich.org 70 i- struct mem_block *block; Err bitreich.org 70 i- Err bitreich.org 70 i- if (mem_grow(memp, len) < 0) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- block = mem_block(*memp); Err bitreich.org 70 i- memcpy((char *)block->buf + old_len, buf, len); Err bitreich.org 70 i- Err bitreich.org 70 i- assert(memcmp(block->magic, MEM_BLOCK_MAGIC, 8) == 0); Err bitreich.org 70 i- return 0; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-mem_read(void **memp, struct mem_pool *pool) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct mem_block *block; Err bitreich.org 70 i- ssize_t sz = 0; Err bitreich.org 70 i- void *mem; Err bitreich.org 70 i- Err bitreich.org 70 i- mem = mem_alloc(pool, 0); Err bitreich.org 70 i- if (mem == NULL) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- Err bitreich.org 70 i- for (ssize_t r = 1; r > 0; sz += r) { Err bitreich.org 70 i- if (mem_resize(&mem, sz + 2048) < 0) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- Err bitreich.org 70 i- r = read(0, (char *)mem + sz, 2048); Err bitreich.org 70 i- if (r < 0) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- } Err bitreich.org 70 i- block = mem_block(mem); Err bitreich.org 70 i- block->len = sz; Err bitreich.org 70 i- Err bitreich.org 70 i- *memp = mem; Err bitreich.org 70 i- assert(memcmp(block->magic, MEM_BLOCK_MAGIC, 8) == 0); Err bitreich.org 70 i- return 0; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-mem_delete(void *mem) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct mem_block *block = mem_block(mem);; Err bitreich.org 70 i- Err bitreich.org 70 i- if (block == block->pool->head) Err bitreich.org 70 i- block->pool->head = block->next; Err bitreich.org 70 i- if (block->next != NULL) Err bitreich.org 70 i- block->next->prev = block->prev; Err bitreich.org 70 i- if (block->prev != NULL) Err bitreich.org 70 i- block->prev->next = block->next; Err bitreich.org 70 i- memset(block, 0, sizeof *block); Err bitreich.org 70 i- free(block); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-mem_free(struct mem_pool *pool) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct mem_block *block, *next; Err bitreich.org 70 i- Err bitreich.org 70 i- for (block = pool->head; block != NULL; block = next) { Err bitreich.org 70 i- next = block->next; Err bitreich.org 70 i- memset(block, 0, sizeof *block); Err bitreich.org 70 i- free(block); Err bitreich.org 70 i- } Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/src/mem.h b/src/mem.h /scm/iomenu/file/src/mem.h.gph bitreich.org 70 i@@ -1,59 +0,0 @@ Err bitreich.org 70 i-#ifndef MEM_H Err bitreich.org 70 i-#define MEM_H Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Lightweight wrapper over malloc, that permit to define a memory pool of Err bitreich.org 70 i- * multiple buffers, and free them all at once. Err bitreich.org 70 i- * Err bitreich.org 70 i- * *──────────┐ Err bitreich.org 70 i- * │ mem_pool │ Err bitreich.org 70 i- * ├──────────┤ Err bitreich.org 70 i- * │*head │ Err bitreich.org 70 i- * └┬─────────┘ Err bitreich.org 70 i- * v Err bitreich.org 70 i- * NULL< *───────────┐< >*───────────┐< >*───────────┐< >*───────────┐ >NULL Err bitreich.org 70 i- * \ │ mem_block │ \/ │ mem_block │ \/ │ mem_block │ \/ │ mem_block │ / Err bitreich.org 70 i- * \ ├───────────┤ /\ ├───────────┤ /\ ├───────────┤ /\ ├───────────┤ / Err bitreich.org 70 i- * `┤*prev *next├' `┤*prev *next├' `┤*prev *next├' `┤*prev *next├' Err bitreich.org 70 i- * │len │ │len │ │len │ │len │ Err bitreich.org 70 i- * ├─┴─magic───┤ ├─┴─magic───┤ ├─┴─magic───┤ ├─┴─magic───┤ Err bitreich.org 70 i- * │///////////│ │///////////│ │///////////│ │///////////│ Err bitreich.org 70 i- * │///////////│ │///////////│ │///////////│ │///////////│ Err bitreich.org 70 i- * │///////////│ │///////////│ │///////////│ └───────────┘ Err bitreich.org 70 i- * └───────────┘ │///////////│ │///////////│ Err bitreich.org 70 i- * │///////////│ └───────────┘ Err bitreich.org 70 i- * └───────────┘ Err bitreich.org 70 i- * Err bitreich.org 70 i- * This permits the type checker to still work on all operations while Err bitreich.org 70 i- * providing generic memory management functions for all types of data Err bitreich.org 70 i- * structures and keep track of each object's length. Err bitreich.org 70 i- */ Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-#define MEM_BLOCK_MAGIC "\xcc\x68\x23\xd7\x9b\x7d\x39\xb9" Err bitreich.org 70 i- Err bitreich.org 70 i-struct mem_pool { Err bitreich.org 70 i- struct mem_block *head; Err bitreich.org 70 i-}; Err bitreich.org 70 i- Err bitreich.org 70 i-struct mem_block { Err bitreich.org 70 i- struct mem_pool *pool; Err bitreich.org 70 i- struct mem_block *prev, *next; Err bitreich.org 70 i- size_t len; Err bitreich.org 70 i- char magic[8]; /* at the end to detect buffer underflow */ Err bitreich.org 70 i- char buf[]; Err bitreich.org 70 i-}; Err bitreich.org 70 i- Err bitreich.org 70 i-/** src/mem.c **/ Err bitreich.org 70 i-void * mem_alloc(struct mem_pool *pool, size_t len); Err bitreich.org 70 i-int mem_resize(void **memp, size_t len); Err bitreich.org 70 i-int mem_grow(void **memp, size_t len); Err bitreich.org 70 i-int mem_shrink(void **memp, size_t len); Err bitreich.org 70 i-size_t mem_length(void *mem); Err bitreich.org 70 i-int mem_append(void **memp, void const *buf, size_t len); Err bitreich.org 70 i-int mem_read(void **memp, struct mem_pool *pool); Err bitreich.org 70 i-void mem_delete(void *mem); Err bitreich.org 70 i-void mem_free(struct mem_pool *pool); Err bitreich.org 70 i- Err bitreich.org 70 i-#endif Err bitreich.org 70 1diff --git a/src/term.c b/src/term.c /scm/iomenu/file/src/term.c.gph bitreich.org 70 i@@ -1,107 +0,0 @@ Err bitreich.org 70 i-#include "term.h" Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-#include "compat.h" Err bitreich.org 70 i-#include "utf8.h" Err bitreich.org 70 i- Err bitreich.org 70 i-struct term term = {0}; Err bitreich.org 70 i- Err bitreich.org 70 i-static int Err bitreich.org 70 i-term_codepoint_width(uint32_t codepoint, int pos) Err bitreich.org 70 i-{ Err bitreich.org 70 i- if (codepoint == '\t') Err bitreich.org 70 i- return 8 - pos % 8; Err bitreich.org 70 i- return wcwidth(codepoint); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-term_at_width(char const *s, int width, int pos) Err bitreich.org 70 i-{ Err bitreich.org 70 i- char const *beg = s; Err bitreich.org 70 i- Err bitreich.org 70 i- for (uint32_t state = 0, codepoint; *s != '\0'; s++) { Err bitreich.org 70 i- if (utf8_decode(&state, &codepoint, *s) == UTF8_ACCEPT) { Err bitreich.org 70 i- pos += term_codepoint_width(codepoint, pos); Err bitreich.org 70 i- if (pos > width) Err bitreich.org 70 i- break; Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i- return s - beg; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-term_raw_on(int fd) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct termios new_termios = {0}; Err bitreich.org 70 i- char *seq = "\x1b[s\x1b[?1049h\x1b[H"; Err bitreich.org 70 i- ssize_t len = strlen(seq); Err bitreich.org 70 i- Err bitreich.org 70 i- if (write(fd, seq, len) < len) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- Err bitreich.org 70 i- if (tcgetattr(fd, &term.old_termios) < 0) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- memcpy(&new_termios, &term.old_termios, sizeof new_termios); Err bitreich.org 70 i- Err bitreich.org 70 i- new_termios.c_lflag &= ~(ICANON | ECHO | IEXTEN | IGNBRK | ISIG); Err bitreich.org 70 i- if (tcsetattr(fd, TCSANOW, &new_termios) == -1) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- return 0; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-term_raw_off(int fd) Err bitreich.org 70 i-{ Err bitreich.org 70 i- char *seq = "\x1b[2J\x1b[u\033[?1049l"; Err bitreich.org 70 i- ssize_t len = strlen(seq); Err bitreich.org 70 i- Err bitreich.org 70 i- if (tcsetattr(fd, TCSANOW, &term.old_termios) < 0) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- if (write(fd, seq, len) < len) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- return 0; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-term_get_key(FILE *fp) Err bitreich.org 70 i-{ Err bitreich.org 70 i- int key, num; Err bitreich.org 70 i- Err bitreich.org 70 i- key = fgetc(fp); Err bitreich.org 70 i-top: Err bitreich.org 70 i- switch (key) { Err bitreich.org 70 i- case EOF: Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- case TERM_KEY_ALT('['): Err bitreich.org 70 i- key = getc(fp); Err bitreich.org 70 i- if (key == EOF) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- Err bitreich.org 70 i- for (num = 0; isdigit(key);) { Err bitreich.org 70 i- num *= 10; Err bitreich.org 70 i- num += key - '0'; Err bitreich.org 70 i- Err bitreich.org 70 i- key = fgetc(fp); Err bitreich.org 70 i- if (key == EOF) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- key = TERM_KEY_CSI(key, num); Err bitreich.org 70 i- Err bitreich.org 70 i- goto top; Err bitreich.org 70 i- case TERM_KEY_ESC: Err bitreich.org 70 i- key = getc(fp); Err bitreich.org 70 i- if (key == EOF) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- key = TERM_KEY_ALT(key); Err bitreich.org 70 i- goto top; Err bitreich.org 70 i- default: Err bitreich.org 70 i- return key; Err bitreich.org 70 i- } Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/src/term.h b/src/term.h /scm/iomenu/file/src/term.h.gph bitreich.org 70 i@@ -1,39 +0,0 @@ Err bitreich.org 70 i-#ifndef TERM_H Err bitreich.org 70 i-#define TERM_H Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-#define TERM_KEY_CTRL(c) ((c) & ~0x40) Err bitreich.org 70 i-#define TERM_KEY_ALT(c) (0x100 + (c)) Err bitreich.org 70 i-#define TERM_KEY_CSI(c, i) (0x100 + (c) * 0x100 + (i)) Err bitreich.org 70 i- Err bitreich.org 70 i-enum term_key { Err bitreich.org 70 i- TERM_KEY_ESC = 0x1b, Err bitreich.org 70 i- TERM_KEY_DELETE = 127, Err bitreich.org 70 i- TERM_KEY_BACKSPACE = TERM_KEY_CTRL('H'), Err bitreich.org 70 i- TERM_KEY_TAB = TERM_KEY_CTRL('I'), Err bitreich.org 70 i- TERM_KEY_ENTER = TERM_KEY_CTRL('J'), Err bitreich.org 70 i- TERM_KEY_ARROW_UP = TERM_KEY_CSI('A', 0), Err bitreich.org 70 i- TERM_KEY_ARROW_DOWN = TERM_KEY_CSI('B', 0), Err bitreich.org 70 i- TERM_KEY_PAGE_UP = TERM_KEY_CSI('~', 5), Err bitreich.org 70 i- TERM_KEY_PAGE_DOWN = TERM_KEY_CSI('~', 6), Err bitreich.org 70 i-}; Err bitreich.org 70 i- Err bitreich.org 70 i-struct term { Err bitreich.org 70 i- struct winsize winsize; Err bitreich.org 70 i- struct termios old_termios; Err bitreich.org 70 i-}; Err bitreich.org 70 i- Err bitreich.org 70 i-/** src/term.c **/ Err bitreich.org 70 i-struct term term; Err bitreich.org 70 i-int term_width_at_pos(uint32_t codepoint, int pos); Err bitreich.org 70 i-int term_at_width(char const *s, int width, int pos); Err bitreich.org 70 i-int term_raw_on(int fd); Err bitreich.org 70 i-int term_raw_off(int fd); Err bitreich.org 70 i-int term_get_key(FILE *fp); Err bitreich.org 70 i- Err bitreich.org 70 i-#endif Err bitreich.org 70 1diff --git a/term.c b/term.c /scm/iomenu/file/term.c.gph bitreich.org 70 i@@ -0,0 +1,107 @@ Err bitreich.org 70 i+#include "term.h" Err bitreich.org 70 i+ Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i+#include "wcwidth.h" Err bitreich.org 70 i+#include "utf8.h" Err bitreich.org 70 i+ Err bitreich.org 70 i+struct term term = {0}; Err bitreich.org 70 i+ Err bitreich.org 70 i+static int Err bitreich.org 70 i+term_codepoint_width(uint32_t codepoint, int pos) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ if (codepoint == '\t') Err bitreich.org 70 i+ return 8 - pos % 8; Err bitreich.org 70 i+ return wcwidth(codepoint); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+term_at_width(char const *s, int width, int pos) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ char const *beg = s; Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (uint32_t state = 0, codepoint; *s != '\0'; s++) { Err bitreich.org 70 i+ if (utf8_decode(&state, &codepoint, *s) == UTF8_ACCEPT) { Err bitreich.org 70 i+ pos += term_codepoint_width(codepoint, pos); Err bitreich.org 70 i+ if (pos > width) Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ return s - beg; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+term_raw_on(int fd) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ struct termios new_termios = {0}; Err bitreich.org 70 i+ char *seq = "\x1b[s\x1b[?1049h\x1b[H"; Err bitreich.org 70 i+ ssize_t len = strlen(seq); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (write(fd, seq, len) < len) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (tcgetattr(fd, &term.old_termios) < 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ memcpy(&new_termios, &term.old_termios, sizeof new_termios); Err bitreich.org 70 i+ Err bitreich.org 70 i+ new_termios.c_lflag &= ~(ICANON | ECHO | IEXTEN | IGNBRK | ISIG); Err bitreich.org 70 i+ if (tcsetattr(fd, TCSANOW, &new_termios) == -1) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+term_raw_off(int fd) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ char *seq = "\x1b[2J\x1b[u\033[?1049l"; Err bitreich.org 70 i+ ssize_t len = strlen(seq); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (tcsetattr(fd, TCSANOW, &term.old_termios) < 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ if (write(fd, seq, len) < len) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+term_get_key(FILE *fp) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ int key, num; Err bitreich.org 70 i+ Err bitreich.org 70 i+ key = fgetc(fp); Err bitreich.org 70 i+top: Err bitreich.org 70 i+ switch (key) { Err bitreich.org 70 i+ case EOF: Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ case TERM_KEY_ALT('['): Err bitreich.org 70 i+ key = getc(fp); Err bitreich.org 70 i+ if (key == EOF) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (num = 0; isdigit(key);) { Err bitreich.org 70 i+ num *= 10; Err bitreich.org 70 i+ num += key - '0'; Err bitreich.org 70 i+ Err bitreich.org 70 i+ key = fgetc(fp); Err bitreich.org 70 i+ if (key == EOF) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ key = TERM_KEY_CSI(key, num); Err bitreich.org 70 i+ Err bitreich.org 70 i+ goto top; Err bitreich.org 70 i+ case TERM_KEY_ESC: Err bitreich.org 70 i+ key = getc(fp); Err bitreich.org 70 i+ if (key == EOF) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ key = TERM_KEY_ALT(key); Err bitreich.org 70 i+ goto top; Err bitreich.org 70 i+ default: Err bitreich.org 70 i+ return key; Err bitreich.org 70 i+ } Err bitreich.org 70 i+} Err bitreich.org 70 1diff --git a/term.h b/term.h /scm/iomenu/file/term.h.gph bitreich.org 70 i@@ -0,0 +1,38 @@ Err bitreich.org 70 i+#ifndef TERM_H Err bitreich.org 70 i+#define TERM_H Err bitreich.org 70 i+ Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i+#define TERM_KEY_CTRL(c) ((c) & ~0x40) Err bitreich.org 70 i+#define TERM_KEY_ALT(c) (0x100 + (c)) Err bitreich.org 70 i+#define TERM_KEY_CSI(c, i) (0x100 + (c) * 0x100 + (i)) Err bitreich.org 70 i+ Err bitreich.org 70 i+enum term_key { Err bitreich.org 70 i+ TERM_KEY_ESC = 0x1b, Err bitreich.org 70 i+ TERM_KEY_DELETE = 127, Err bitreich.org 70 i+ TERM_KEY_BACKSPACE = TERM_KEY_CTRL('H'), Err bitreich.org 70 i+ TERM_KEY_TAB = TERM_KEY_CTRL('I'), Err bitreich.org 70 i+ TERM_KEY_ENTER = TERM_KEY_CTRL('J'), Err bitreich.org 70 i+ TERM_KEY_ARROW_UP = TERM_KEY_CSI('A', 0), Err bitreich.org 70 i+ TERM_KEY_ARROW_DOWN = TERM_KEY_CSI('B', 0), Err bitreich.org 70 i+ TERM_KEY_PAGE_UP = TERM_KEY_CSI('~', 5), Err bitreich.org 70 i+ TERM_KEY_PAGE_DOWN = TERM_KEY_CSI('~', 6), Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+struct term { Err bitreich.org 70 i+ struct winsize winsize; Err bitreich.org 70 i+ struct termios old_termios; Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+struct term term; Err bitreich.org 70 i+int term_width_at_pos(uint32_t codepoint, int pos); Err bitreich.org 70 i+int term_at_width(char const *s, int width, int pos); Err bitreich.org 70 i+int term_raw_on(int fd); Err bitreich.org 70 i+int term_raw_off(int fd); Err bitreich.org 70 i+int term_get_key(FILE *fp); Err bitreich.org 70 i+ Err bitreich.org 70 i+#endif Err bitreich.org 70 1diff --git a/src/utf8.c b/utf8.c /scm/iomenu/file/utf8.c.gph bitreich.org 70 1diff --git a/src/utf8.h b/utf8.h /scm/iomenu/file/utf8.h.gph bitreich.org 70 1diff --git a/src/compat/wcwidth.c b/wcwidth.c /scm/iomenu/file/wcwidth.c.gph bitreich.org 70 1diff --git a/wcwidth.h b/wcwidth.h /scm/iomenu/file/wcwidth.h.gph bitreich.org 70 i@@ -0,0 +1,13 @@ Err bitreich.org 70 i+#ifndef WCWIDTH_H Err bitreich.org 70 i+#define WCWIDTH_H Err bitreich.org 70 i+ Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i+#define wcwidth(c) mk_wcwidth_cjk(c) Err bitreich.org 70 i+ Err bitreich.org 70 i+int mk_wcwidth(wchar_t ucs); Err bitreich.org 70 i+int mk_wcswidth(const wchar_t *pwcs, size_t n); Err bitreich.org 70 i+int mk_wcwidth_cjk(wchar_t ucs); Err bitreich.org 70 i+int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n); Err bitreich.org 70 i+ Err bitreich.org 70 i+#endif Err bitreich.org 70 .