ic89 - 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 f979f7c13ea6a13dfda617bc70e2e4cff9bd3879 /scm/iomenu/commit/f979f7c13ea6a13dfda617bc70e2e4cff9bd3879.gph bitreich.org 70 1parent 831d075aa676cd1905db7374143f296b211ae4e5 /scm/iomenu/commit/831d075aa676cd1905db7374143f296b211ae4e5.gph bitreich.org 70 hAuthor: Josuah Demangeon URL:mailto:mail@josuah.net bitreich.org 70 iDate: Sun, 16 Apr 2017 13:03:15 +0200 Err bitreich.org 70 i Err bitreich.org 70 ic89 Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M Makefile | 2 +- Err bitreich.org 70 i M iomenu.1 | 4 +++- Err bitreich.org 70 i M iomenu.c | 101 +++++++++++++++++++------------ Err bitreich.org 70 i Err bitreich.org 70 i3 files changed, 67 insertions(+), 40 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,4 +1,4 @@ Err bitreich.org 70 i-CFLAGS = -std=c99 -Wpedantic -Wall -Wextra -g # -static Err bitreich.org 70 i+CFLAGS = -std=c89 -Wpedantic -Wall -Wextra -g # -static Err bitreich.org 70 i OBJ = ${SRC:.c=.o} Err bitreich.org 70 i Err bitreich.org 70 i all: clean iomenu Err bitreich.org 70 1diff --git a/iomenu.1 b/iomenu.1 /scm/iomenu/file/iomenu.1.gph bitreich.org 70 i@@ -14,7 +14,9 @@ Err bitreich.org 70 i . Err bitreich.org 70 i . Err bitreich.org 70 i .Nm Err bitreich.org 70 i-.Op Fl tbs Err bitreich.org 70 i+.Op Fl t Err bitreich.org 70 i+.Op Fl b Err bitreich.org 70 i+.Op Fl s Err bitreich.org 70 i .Op Fl l Ar lines Err bitreich.org 70 i .Op Fl p Ar prompt Err bitreich.org 70 i . Err bitreich.org 70 1diff --git a/iomenu.c b/iomenu.c /scm/iomenu/file/iomenu.c.gph bitreich.org 70 i@@ -12,19 +12,20 @@ Err bitreich.org 70 i Err bitreich.org 70 i #define CONTINUE 2 /* as opposed to EXIT_SUCCESS and EXIT_FAILURE */ Err bitreich.org 70 i Err bitreich.org 70 i-#define CONTROL(char) (char ^ 0x40) Err bitreich.org 70 i-#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) Err bitreich.org 70 i+#define CONTROL(char) (char ^ 0x40) Err bitreich.org 70 i+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) Err bitreich.org 70 i+ Err bitreich.org 70 i Err bitreich.org 70 i static struct winsize ws; Err bitreich.org 70 i static struct termios termios; Err bitreich.org 70 i int tty_fd; Err bitreich.org 70 i Err bitreich.org 70 i-static int current = 0, offset = 0, prev = 0, next = 0; Err bitreich.org 70 i-static int linec = 0, matchc = 0; Err bitreich.org 70 i-static char **linev = NULL, **matchv = NULL; Err bitreich.org 70 i-static char input[BUFSIZ], formatted[BUFSIZ * 8]; Err bitreich.org 70 i-static int opt_tb = 0, opt_l = 255; Err bitreich.org 70 i-static char *opt_p = "", opt_s = '\0'; Err bitreich.org 70 i+static int current = 0, offset = 0, prev = 0, next = 0; Err bitreich.org 70 i+static int linec = 0, matchc = 0; Err bitreich.org 70 i+static char **linev = NULL, **matchv = NULL; Err bitreich.org 70 i+static char input[BUFSIZ], formatted[BUFSIZ * 8]; Err bitreich.org 70 i+static int opt_tb = 0, opt_l = 255, opt_h = 0; Err bitreich.org 70 i+static char *argv0, *opt_p = "", opt_s = '\0'; Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i@@ -87,8 +88,10 @@ reset_terminal(void) Err bitreich.org 70 i extern struct termios termios; Err bitreich.org 70 i extern struct winsize ws; Err bitreich.org 70 i Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ Err bitreich.org 70 i /* clear terminal */ Err bitreich.org 70 i- for (int i = 0; i < opt_l + 1; i++) Err bitreich.org 70 i+ for (i = 0; i < opt_l + 1; i++) Err bitreich.org 70 i fputs("\r\033[K\n", stderr); Err bitreich.org 70 i Err bitreich.org 70 i /* reset cursor position */ Err bitreich.org 70 i@@ -136,20 +139,18 @@ read_lines(void) 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- * Prepare a string for printing. Err bitreich.org 70 i- */ Err bitreich.org 70 i static char * Err bitreich.org 70 i format(char *str, int cols) Err bitreich.org 70 i { Err bitreich.org 70 i extern char formatted[BUFSIZ * 8]; Err bitreich.org 70 i Err bitreich.org 70 i- int j = 0; Err bitreich.org 70 i+ int i, j; Err bitreich.org 70 i Err bitreich.org 70 i- for (int i = 0; str[i] && j < cols; i++) { Err bitreich.org 70 i+ for (i = j = 0; str[i] && j < cols; i++) { Err bitreich.org 70 i Err bitreich.org 70 i if (str[i] == '\t') { Err bitreich.org 70 i- for (int t = (j + 7) % 8 + 1; t > 0 && j < cols; t--) Err bitreich.org 70 i+ int t = (j + 7) % 8 + 1; Err bitreich.org 70 i+ while (t-- > 0 && j < cols) Err bitreich.org 70 i formatted[j++] = ' '; Err bitreich.org 70 i Err bitreich.org 70 i } else if (isprint(str[i])) { Err bitreich.org 70 i@@ -172,10 +173,9 @@ print_lines(int count) Err bitreich.org 70 i extern int opt_l; Err bitreich.org 70 i extern char opt_s; Err bitreich.org 70 i Err bitreich.org 70 i- int p = 0; /* amount of lines printed */ Err bitreich.org 70 i- offset = current / count * count; Err bitreich.org 70 i+ int printed = 0, i = current / count * count; Err bitreich.org 70 i Err bitreich.org 70 i- for (int i = offset; p < count && i < matchc; p++, i++) { Err bitreich.org 70 i+ while (printed++ < count && i < matchc) { Err bitreich.org 70 i char *s = format(matchv[i], ws.ws_col - 1); Err bitreich.org 70 i Err bitreich.org 70 i if (opt_s && matchv[i][0] == '#') { Err bitreich.org 70 i@@ -185,9 +185,11 @@ print_lines(int count) Err bitreich.org 70 i } else { Err bitreich.org 70 i fprintf(stderr, "\n\033[K %s\033[m", s); Err bitreich.org 70 i } Err bitreich.org 70 i+ Err bitreich.org 70 i+ i++; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- while (p++ < count) Err bitreich.org 70 i+ while (printed++ < count) Err bitreich.org 70 i fputs("\n\033[K", stderr); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -197,12 +199,12 @@ print_screen(void) Err bitreich.org 70 i { Err bitreich.org 70 i extern char formatted[BUFSIZ * 8]; Err bitreich.org 70 i Err bitreich.org 70 i- int cols = ws.ws_col - 1; Err bitreich.org 70 i+ int cols = ws.ws_col - 1, i; Err bitreich.org 70 i+ int count = MIN(opt_l, ws.ws_row - 1); Err bitreich.org 70 i Err bitreich.org 70 i fputs("\r\033[K", stderr); Err bitreich.org 70 i Err bitreich.org 70 i /* items */ Err bitreich.org 70 i- int count = MIN(opt_l, ws.ws_row - 1); Err bitreich.org 70 i print_lines(count); Err bitreich.org 70 i fprintf(stderr, "\033[%dA", count); Err bitreich.org 70 i Err bitreich.org 70 i@@ -212,7 +214,7 @@ print_screen(void) Err bitreich.org 70 i if (opt_p[0] != '\0') { Err bitreich.org 70 i format(opt_p, cols); Err bitreich.org 70 i fputs("\033[30;47m ", stderr); Err bitreich.org 70 i- for (int i = 0; formatted[i]; i++) Err bitreich.org 70 i+ for (i = 0; formatted[i]; i++) Err bitreich.org 70 i fputc(formatted[i], stderr); Err bitreich.org 70 i fputs(" \033[m", stderr); Err bitreich.org 70 i cols -= strlen(formatted) + 1; Err bitreich.org 70 i@@ -233,8 +235,8 @@ match_line(char *line, char **tokv, int tokc) Err bitreich.org 70 i if (opt_s && line[0] == opt_s) Err bitreich.org 70 i return 2; Err bitreich.org 70 i Err bitreich.org 70 i- for (int i = 0; i < tokc; i++) Err bitreich.org 70 i- if (strstr(line, tokv[i]) == NULL) Err bitreich.org 70 i+ while (tokc-- > 0) Err bitreich.org 70 i+ if (strstr(line, tokv[tokc]) == NULL) Err bitreich.org 70 i return 0; Err bitreich.org 70 i Err bitreich.org 70 i return 1; Err bitreich.org 70 i@@ -247,7 +249,9 @@ move_line(signed int count) Err bitreich.org 70 i extern int current; Err bitreich.org 70 i extern char **matchv; Err bitreich.org 70 i Err bitreich.org 70 i- for (int i = current + count; 0 <= i && i < matchc; i += count) { Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (i = current + count; 0 <= i && i < matchc; i += count) { Err bitreich.org 70 i if (!opt_s || matchv[i][0] != opt_s) { Err bitreich.org 70 i current = i; Err bitreich.org 70 i break; Err bitreich.org 70 i@@ -260,7 +264,7 @@ static void Err bitreich.org 70 i filter_lines(void) Err bitreich.org 70 i { Err bitreich.org 70 i char **tokv = NULL, *s, buffer[sizeof (input)]; Err bitreich.org 70 i- int tokc = 0, n = 0; Err bitreich.org 70 i+ int tokc = 0, n = 0, i; Err bitreich.org 70 i Err bitreich.org 70 i current = offset = prev = next = 0; Err bitreich.org 70 i Err bitreich.org 70 i@@ -279,7 +283,7 @@ filter_lines(void) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i matchc = 0; Err bitreich.org 70 i- for (int i = 0; i < linec; i++) Err bitreich.org 70 i+ for (i = 0; i < linec; i++) Err bitreich.org 70 i if (match_line(linev[i], tokv, tokc)) Err bitreich.org 70 i matchv[matchc++] = linev[i]; Err bitreich.org 70 i Err bitreich.org 70 i@@ -293,13 +297,13 @@ filter_lines(void) Err bitreich.org 70 i static void Err bitreich.org 70 i remove_word_input() Err bitreich.org 70 i { Err bitreich.org 70 i- int len = strlen(input) - 1; Err bitreich.org 70 i+ int len = strlen(input) - 1, i; Err bitreich.org 70 i Err bitreich.org 70 i- for (int i = len; i >= 0 && isspace(input[i]); i--) Err bitreich.org 70 i+ for (i = len; i >= 0 && isspace(input[i]); i--) Err bitreich.org 70 i input[i] = '\0'; Err bitreich.org 70 i Err bitreich.org 70 i len = strlen(input) - 1; Err bitreich.org 70 i- for (int i = len; i >= 0 && !isspace(input[i]); i--) Err bitreich.org 70 i+ for (i = len; i >= 0 && !isspace(input[i]); i--) Err bitreich.org 70 i input[i] = '\0'; Err bitreich.org 70 i Err bitreich.org 70 i filter_lines(); Err bitreich.org 70 i@@ -326,13 +330,28 @@ print_selection(void) Err bitreich.org 70 i extern int current; Err bitreich.org 70 i extern char **matchv, input[BUFSIZ]; Err bitreich.org 70 i Err bitreich.org 70 i- fputs("\r\033[K", stderr); Err bitreich.org 70 i+ /* header */ Err bitreich.org 70 i+ if (opt_h && opt_s) { Err bitreich.org 70 i+ char **match = matchv + current; Err bitreich.org 70 i Err bitreich.org 70 i+ while (--match >= matchv) { Err bitreich.org 70 i+ if ((*match)[0] == opt_s) { Err bitreich.org 70 i+ fputs(*match, stdout); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ putchar('\t'); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* input or selection */ Err bitreich.org 70 i if (matchc == 0 || (opt_s && matchv[current][0] == opt_s)) { Err bitreich.org 70 i puts(input); Err bitreich.org 70 i } else { Err bitreich.org 70 i puts(matchv[current]); Err bitreich.org 70 i } Err bitreich.org 70 i+ Err bitreich.org 70 i+ fputs("\r\033[K", stderr); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i@@ -415,7 +434,7 @@ input_get(void) Err bitreich.org 70 i static void Err bitreich.org 70 i usage(void) Err bitreich.org 70 i { Err bitreich.org 70 i- fputs("usage: iomenu [-b] [-t] [-s] [-l lines] [-p prompt]\n", stderr); Err bitreich.org 70 i+ fprintf(stderr, "%s [-b] [-t] [-s] [-l lines] [-p prompt]\n", argv0); Err bitreich.org 70 i Err bitreich.org 70 i exit(EXIT_FAILURE); Err bitreich.org 70 i } Err bitreich.org 70 i@@ -429,13 +448,14 @@ main(int argc, char *argv[]) Err bitreich.org 70 i Err bitreich.org 70 i int exit_code; Err bitreich.org 70 i Err bitreich.org 70 i- for (int i = 1; i < argc; i++) { Err bitreich.org 70 i- if (argv[i][0] != '-' || strlen(argv[i]) != 2) Err bitreich.org 70 i+ for (argv0 = argv[0], argv++, argc--; argc > 0; argv++, argc++) { Err bitreich.org 70 i+ if ((*argv)[0] != '-' || (*argv)[1] == '\0' || (*argv)[2] != '\0') Err bitreich.org 70 i usage(); Err bitreich.org 70 i Err bitreich.org 70 i- switch (argv[i][1]) { Err bitreich.org 70 i+ switch ((*argv)[1]) { Err bitreich.org 70 i case 'l': Err bitreich.org 70 i- if (++i >= argc || sscanf(argv[i], "%d", &opt_l) <= 0) Err bitreich.org 70 i+ argv++; argc--; Err bitreich.org 70 i+ if (argc == 0 || sscanf(*argv, "%d", &opt_l) <= 0) Err bitreich.org 70 i usage(); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i@@ -443,15 +463,20 @@ main(int argc, char *argv[]) Err bitreich.org 70 i case 'b': opt_tb = 'b'; break; Err bitreich.org 70 i Err bitreich.org 70 i case 'p': Err bitreich.org 70 i- if (++i >= argc) Err bitreich.org 70 i+ argc--; argv++; Err bitreich.org 70 i+ if (argc == 0) Err bitreich.org 70 i usage(); Err bitreich.org 70 i- opt_p = argv[i]; Err bitreich.org 70 i+ opt_p = *argv; Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i case 's': Err bitreich.org 70 i opt_s = '#'; Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i+ case 'h': Err bitreich.org 70 i+ opt_h = 1; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ Err bitreich.org 70 i default: Err bitreich.org 70 i usage(); Err bitreich.org 70 i } Err bitreich.org 70 .