iBack to ASCII - 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 f85d89ea704e25328a41b5c4ba3d115d1c997131 /scm/iomenu/commit/f85d89ea704e25328a41b5c4ba3d115d1c997131.gph bitreich.org 70 1parent 08cb917454e93c473c31b5628c5ed2876e9aad0d /scm/iomenu/commit/08cb917454e93c473c31b5628c5ed2876e9aad0d.gph bitreich.org 70 hAuthor: Josuah Demangeon URL:mailto:mail@josuah.net bitreich.org 70 iDate: Tue, 11 Apr 2017 22:03:26 +0200 Err bitreich.org 70 i Err bitreich.org 70 iBack to ASCII Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M iomenu.c | 145 +++++++++++++++---------------- Err bitreich.org 70 i Err bitreich.org 70 i1 file changed, 71 insertions(+), 74 deletions(-) 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@@ -5,8 +5,7 @@ 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 Err bitreich.org 70 i Err bitreich.org 70 i@@ -23,12 +22,12 @@ 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 wchar_t **linev = NULL, **matchv = NULL; Err bitreich.org 70 i-static wchar_t input[BUFSIZ], formatted[BUFSIZ * 8]; Err bitreich.org 70 i-static int opt_l = 0, opt_tb = 0; Err bitreich.org 70 i-static wchar_t opt_p[BUFSIZ]; 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_l = 0, opt_tb = 0; Err bitreich.org 70 i+static char *opt_p = ""; Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i@@ -65,12 +64,12 @@ set_terminal(void) Err bitreich.org 70 i die("ioctl"); Err bitreich.org 70 i Err bitreich.org 70 i /* save cursor postition */ Err bitreich.org 70 i- fputws(L"\033[s", stderr); Err bitreich.org 70 i+ fputs("\033[s", stderr); Err bitreich.org 70 i Err bitreich.org 70 i /* put cursor at the top / bottom */ Err bitreich.org 70 i switch (opt_tb) { Err bitreich.org 70 i- case 't': fputws(L"\033[H", stderr); break; Err bitreich.org 70 i- case 'b': fwprintf(stderr, L"\033[%dH", ws.ws_row - opt_l); break; Err bitreich.org 70 i+ case 't': fputs("\033[H", stderr); break; Err bitreich.org 70 i+ case 'b': fprintf(stderr, "\033[%dH", ws.ws_row - opt_l); break; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i /* save attributes to `termios` */ Err bitreich.org 70 i@@ -93,10 +92,10 @@ reset_terminal(void) 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- fputws(L"\r\033[K\n", stderr); 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- fputws(L"\033[u", stderr); Err bitreich.org 70 i+ fputs("\033[u", stderr); Err bitreich.org 70 i Err bitreich.org 70 i /* set terminal back to normal mode */ Err bitreich.org 70 i tcsetattr(tty_fd, TCSANOW, &termios); Err bitreich.org 70 i@@ -106,47 +105,47 @@ reset_terminal(void) Err bitreich.org 70 i static void Err bitreich.org 70 i read_lines(void) Err bitreich.org 70 i { Err bitreich.org 70 i- wchar_t buffer[BUFSIZ]; Err bitreich.org 70 i+ char buffer[BUFSIZ]; Err bitreich.org 70 i int size = 1 << 6; Err bitreich.org 70 i Err bitreich.org 70 i- linev = malloc(sizeof (wchar_t **) * size); Err bitreich.org 70 i- matchv = malloc(sizeof (wchar_t **) * size); Err bitreich.org 70 i+ linev = malloc(sizeof (char **) * size); Err bitreich.org 70 i+ matchv = malloc(sizeof (char **) * size); Err bitreich.org 70 i if (linev == NULL || matchv == NULL) Err bitreich.org 70 i die("malloc"); Err bitreich.org 70 i Err bitreich.org 70 i linev[0] = matchv[0] = NULL; Err bitreich.org 70 i Err bitreich.org 70 i /* read the file into an array of lines */ Err bitreich.org 70 i- for (; fgetws(buffer, sizeof buffer, stdin); linec++, matchc++) { Err bitreich.org 70 i- int len = wcslen(buffer); Err bitreich.org 70 i+ for (; fgets(buffer, sizeof buffer, stdin); linec++, matchc++) { Err bitreich.org 70 i+ int len = strlen(buffer); Err bitreich.org 70 i Err bitreich.org 70 i if (len > 0 && buffer[len - 1] == '\n') Err bitreich.org 70 i buffer[len - 1] = '\0'; Err bitreich.org 70 i Err bitreich.org 70 i if (linec >= size) { Err bitreich.org 70 i size *= 2; Err bitreich.org 70 i- linev = realloc(linev, sizeof (wchar_t **) * size); Err bitreich.org 70 i- matchv = realloc(matchv, sizeof (wchar_t **) * size); Err bitreich.org 70 i+ linev = realloc(linev, sizeof (char **) * size); Err bitreich.org 70 i+ matchv = realloc(matchv, sizeof (char **) * size); Err bitreich.org 70 i if (linev == NULL || matchv == NULL) Err bitreich.org 70 i die("realloc"); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- linev[linec] = matchv[matchc] = malloc(len * sizeof (wchar_t)); Err bitreich.org 70 i+ linev[linec] = matchv[matchc] = malloc(len); Err bitreich.org 70 i if (linev[linec] == NULL) Err bitreich.org 70 i die("malloc"); Err bitreich.org 70 i Err bitreich.org 70 i- wcscpy(linev[linec], buffer); Err bitreich.org 70 i+ strcpy(linev[linec], buffer); 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 static int Err bitreich.org 70 i-string_width(wchar_t *wcs) Err bitreich.org 70 i+string_width(char *str) Err bitreich.org 70 i { Err bitreich.org 70 i int len = 0; Err bitreich.org 70 i Err bitreich.org 70 i- for (int i = 0; wcs[i]; i++, len++) Err bitreich.org 70 i- if (wcs[i] == '\t') Err bitreich.org 70 i+ for (int i = 0; str[i]; i++, len++) Err bitreich.org 70 i+ if (str[i] == '\t') Err bitreich.org 70 i len += (len + 7) % 8; Err bitreich.org 70 i Err bitreich.org 70 i return len; Err bitreich.org 70 i@@ -156,34 +155,34 @@ string_width(wchar_t *wcs) 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 wchar_t * Err bitreich.org 70 i-format(wchar_t *wcs, int cols) 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 int j = 0; Err bitreich.org 70 i Err bitreich.org 70 i- for (int i = 0; wcs[i] && j < cols; i++) { Err bitreich.org 70 i+ for (int i = 0; str[i] && j < cols; i++) { Err bitreich.org 70 i Err bitreich.org 70 i- if (wcs[i] == L'\t') { 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- formatted[j++] = L' '; Err bitreich.org 70 i+ formatted[j++] = ' '; Err bitreich.org 70 i } else { Err bitreich.org 70 i- formatted[j++] = wcs[i]; Err bitreich.org 70 i+ formatted[j++] = str[i]; Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- formatted[j] = L'\0'; Err bitreich.org 70 i+ formatted[j] = '\0'; Err bitreich.org 70 i Err bitreich.org 70 i return formatted; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i-print_string(wchar_t *wcs, int current) Err bitreich.org 70 i+print_string(char *str, int current) Err bitreich.org 70 i { Err bitreich.org 70 i- fputws(current ? L"\033[30;47m" : L"", stderr); Err bitreich.org 70 i- fputws(opt_l ? L"\033[K " : L" ", stderr); Err bitreich.org 70 i- fputws(format(wcs, ws.ws_col - 2), stderr); Err bitreich.org 70 i- fputws(L" \033[m", stderr); Err bitreich.org 70 i+ fputs(current ? "\033[30;47m" : "", stderr); Err bitreich.org 70 i+ fputs(opt_l ? "\033[K " : " ", stderr); Err bitreich.org 70 i+ fputs(format(str, ws.ws_col - 2), stderr); Err bitreich.org 70 i+ fputs(" \033[m", stderr); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i@@ -194,12 +193,12 @@ print_lines(int count) Err bitreich.org 70 i offset = 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- fputwc(L'\n', stderr); Err bitreich.org 70 i+ fputc('\n', stderr); Err bitreich.org 70 i print_string(matchv[i], i == current); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i while (p++ <= count) Err bitreich.org 70 i- fputws(L"\n\033[K", stderr); 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 Err bitreich.org 70 i@@ -236,62 +235,62 @@ print_columns(void) Err bitreich.org 70 i next = next_page(offset, ws.ws_col - OFFSET - 4); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- fputws(offset > 0 ? L"< " : L" ", stderr); Err bitreich.org 70 i+ fputs(offset > 0 ? "< " : " ", stderr); Err bitreich.org 70 i Err bitreich.org 70 i for (int i = offset; i < next && i < matchc; i++) Err bitreich.org 70 i print_string(matchv[i], i == current); Err bitreich.org 70 i Err bitreich.org 70 i if (next < matchc) Err bitreich.org 70 i- fwprintf(stderr, L"\033[%dC>", ws.ws_col - OFFSET); Err bitreich.org 70 i+ fprintf(stderr, "\033[%dC>", ws.ws_col - OFFSET); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i print_screen(void) Err bitreich.org 70 i { Err bitreich.org 70 i- extern wchar_t formatted[BUFSIZ * 8]; Err bitreich.org 70 i+ extern char formatted[BUFSIZ * 8]; Err bitreich.org 70 i Err bitreich.org 70 i int cols = opt_l || matchc == 0 ? ws.ws_col - 2 : OFFSET - 3; Err bitreich.org 70 i Err bitreich.org 70 i- fputws(L"\r\033[K", stderr); 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 if (opt_l) { Err bitreich.org 70 i int count = MIN(opt_l, ws.ws_row - 2); Err bitreich.org 70 i print_lines(count); Err bitreich.org 70 i- fwprintf(stderr, L"\033[%dA", count + 1); Err bitreich.org 70 i+ fprintf(stderr, "\033[%dA", count + 1); Err bitreich.org 70 i } else { Err bitreich.org 70 i- fwprintf(stderr, L"\033[%dC", OFFSET); Err bitreich.org 70 i+ fprintf(stderr, "\033[%dC", OFFSET); Err bitreich.org 70 i print_columns(); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- fputws(L"\r", stderr); Err bitreich.org 70 i+ fputs("\r", stderr); Err bitreich.org 70 i Err bitreich.org 70 i /* prompt */ Err bitreich.org 70 i if (opt_p[0] != '\0') { Err bitreich.org 70 i format(opt_p, cols); Err bitreich.org 70 i- fputws(L"\033[30;47m ", stderr); 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- fputwc(formatted[i], stderr); Err bitreich.org 70 i- fputws(L" \033[m", stderr); Err bitreich.org 70 i- cols -= wcslen(formatted) + 1; 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 } Err bitreich.org 70 i Err bitreich.org 70 i- fputwc(L' ', stderr); Err bitreich.org 70 i+ fputc(' ', stderr); Err bitreich.org 70 i Err bitreich.org 70 i /* input */ Err bitreich.org 70 i format(input, cols); Err bitreich.org 70 i- fputws(formatted, stderr); Err bitreich.org 70 i+ fputs(formatted, stderr); Err bitreich.org 70 i Err bitreich.org 70 i fflush(stderr); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i static int Err bitreich.org 70 i-match_line(wchar_t *line, wchar_t **tokv, int tokc) Err bitreich.org 70 i+match_line(char *line, char **tokv, int tokc) Err bitreich.org 70 i { Err bitreich.org 70 i for (int i = 0; i < tokc; i++) Err bitreich.org 70 i- if (wcsstr(line, tokv[i]) == NULL) Err bitreich.org 70 i+ if (strstr(line, tokv[i]) == 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@@ -301,14 +300,14 @@ match_line(wchar_t *line, wchar_t **tokv, int tokc) Err bitreich.org 70 i static void Err bitreich.org 70 i filter_lines(void) Err bitreich.org 70 i { Err bitreich.org 70 i- wchar_t **tokv = NULL, *tok, *s, buffer[sizeof (input)]; 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 Err bitreich.org 70 i current = offset = prev = next = 0; Err bitreich.org 70 i Err bitreich.org 70 i- wcscpy(buffer, input); Err bitreich.org 70 i+ strcpy(buffer, input); Err bitreich.org 70 i Err bitreich.org 70 i- for (s = wcstok(buffer, L" ", &tok); s; s = wcstok(NULL, L" ", &tok), tokc++) { Err bitreich.org 70 i+ for (s = strtok(buffer, " "); s; s = strtok(NULL, " "), tokc++) { Err bitreich.org 70 i Err bitreich.org 70 i if (tokc >= n) { Err bitreich.org 70 i tokv = realloc(tokv, ++n * sizeof (*tokv)); Err bitreich.org 70 i@@ -332,13 +331,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 = wcslen(input) - 1; Err bitreich.org 70 i+ int len = strlen(input) - 1; Err bitreich.org 70 i Err bitreich.org 70 i- for (int i = len; i >= 0 && iswspace(input[i]); i--) Err bitreich.org 70 i+ for (int 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 = wcslen(input) - 1; Err bitreich.org 70 i- for (int i = len; i >= 0 && !iswspace(input[i]); 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 input[i] = '\0'; Err bitreich.org 70 i Err bitreich.org 70 i filter_lines(); Err bitreich.org 70 i@@ -348,9 +347,9 @@ remove_word_input() Err bitreich.org 70 i static void Err bitreich.org 70 i add_character(char key) Err bitreich.org 70 i { Err bitreich.org 70 i- int len = wcslen(input); Err bitreich.org 70 i+ int len = strlen(input); Err bitreich.org 70 i Err bitreich.org 70 i- if (iswprint(key)) { Err bitreich.org 70 i+ if (isprint(key)) { Err bitreich.org 70 i input[len] = key; Err bitreich.org 70 i input[len + 1] = '\0'; Err bitreich.org 70 i } Err bitreich.org 70 i@@ -362,16 +361,16 @@ add_character(char key) Err bitreich.org 70 i static void Err bitreich.org 70 i print_selection(void) Err bitreich.org 70 i { Err bitreich.org 70 i- fputws(L"\r\033[K", stderr); Err bitreich.org 70 i- fputws(matchc > 0 ? matchv[current] : input, stdout); Err bitreich.org 70 i- fputwc(L'\n', stdout); Err bitreich.org 70 i+ fputs("\r\033[K", stderr); Err bitreich.org 70 i+ fputs(matchc > 0 ? matchv[current] : input, stdout); Err bitreich.org 70 i+ fputc('\n', stdout); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i static int Err bitreich.org 70 i input_key(void) Err bitreich.org 70 i { Err bitreich.org 70 i- wchar_t key = fgetwc(stdin); Err bitreich.org 70 i+ char key = fgetc(stdin); Err bitreich.org 70 i Err bitreich.org 70 i switch (key) { Err bitreich.org 70 i Err bitreich.org 70 i@@ -389,7 +388,7 @@ input_key(void) Err bitreich.org 70 i Err bitreich.org 70 i case 127: Err bitreich.org 70 i case CONTROL('H'): /* backspace */ Err bitreich.org 70 i- input[wcslen(input) - 1] = '\0'; Err bitreich.org 70 i+ input[strlen(input) - 1] = '\0'; Err bitreich.org 70 i filter_lines(); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i@@ -403,7 +402,7 @@ input_key(void) Err bitreich.org 70 i Err bitreich.org 70 i case CONTROL('I'): /* tab */ Err bitreich.org 70 i if (linec > 0) Err bitreich.org 70 i- wcscpy(input, matchv[current]); Err bitreich.org 70 i+ strcpy(input, matchv[current]); Err bitreich.org 70 i filter_lines(); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i@@ -447,7 +446,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- fputws(L"usage: iomenu [-b] [-t] [-l lines] [-p prompt]\n", stderr); Err bitreich.org 70 i+ fputs("usage: iomenu [-b] [-t] [-l lines] [-p prompt]\n", stderr); Err bitreich.org 70 i Err bitreich.org 70 i exit(EXIT_FAILURE); Err bitreich.org 70 i } Err bitreich.org 70 i@@ -456,12 +455,10 @@ usage(void) 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- extern wchar_t opt_p[BUFSIZ]; Err bitreich.org 70 i+ extern char *opt_p; Err bitreich.org 70 i Err bitreich.org 70 i int exit_code; Err bitreich.org 70 i Err bitreich.org 70 i- opt_p[0] = '\0'; 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 usage(); Err bitreich.org 70 i@@ -478,7 +475,7 @@ main(int argc, char *argv[]) Err bitreich.org 70 i case 'p': Err bitreich.org 70 i if (++i >= argc) Err bitreich.org 70 i usage(); Err bitreich.org 70 i- mbstowcs(opt_p, argv[i], BUFSIZ); Err bitreich.org 70 i+ opt_p = argv[i]; Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i default: Err bitreich.org 70 .