iUnicode support using str->wcs and char->wchar_t - 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 b29fc218d36185be00fbb8952e26264d0d61508a /scm/iomenu/commit/b29fc218d36185be00fbb8952e26264d0d61508a.gph bitreich.org 70 1parent 04f14a2a3fbe38525721285139ebf8af4350876f /scm/iomenu/commit/04f14a2a3fbe38525721285139ebf8af4350876f.gph bitreich.org 70 hAuthor: Josuah Demangeonā  ā µ URL:mailto:mail@josuah.net bitreich.org 70 iDate: Fri, 24 Mar 2017 22:45:33 +0100 Err bitreich.org 70 i Err bitreich.org 70 iUnicode support using str->wcs and char->wchar_t Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M iomenu.c | 127 ++++++++++++++++--------------- Err bitreich.org 70 i Err bitreich.org 70 i1 file changed, 67 insertions(+), 60 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@@ -1,10 +1,12 @@ 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 #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@@ -22,11 +24,11 @@ static struct termios termios; Err bitreich.org 70 i FILE *tty_fp = NULL; Err bitreich.org 70 i int tty_fd; Err bitreich.org 70 i Err bitreich.org 70 i-static char input[BUFSIZ], formatted[BUFSIZ * 8]; 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 int opt_l = 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 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; Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i@@ -73,45 +75,45 @@ set_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- char buffer[BUFSIZ]; Err bitreich.org 70 i+ wchar_t buffer[BUFSIZ]; Err bitreich.org 70 i int size = 1 << 6; Err bitreich.org 70 i 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+ linev = malloc(sizeof (wchar_t **) * size); Err bitreich.org 70 i+ matchv = malloc(sizeof (wchar_t **) * 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 (; fgets(buffer, sizeof buffer, stdin); linec++, matchc++) { Err bitreich.org 70 i- int len = strlen(buffer); 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 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 (char **) * size); Err bitreich.org 70 i- matchv = realloc(matchv, sizeof (char **) * size); 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 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); Err bitreich.org 70 i+ linev[linec] = matchv[matchc] = malloc(len * sizeof (wchar_t)); 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- strcpy(linev[linec], buffer); Err bitreich.org 70 i+ wcscpy(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-match_line(char *line, char **tokv, int tokc) Err bitreich.org 70 i+match_line(wchar_t *line, wchar_t **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 (strstr(line, tokv[i]) == NULL) Err bitreich.org 70 i+ if (wcsstr(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@@ -119,45 +121,46 @@ match_line(char *line, char **tokv, int tokc) Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i-screen_width(char *str) Err bitreich.org 70 i+screen_width(wchar_t *wcs) 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; str[i]; i++, len++) Err bitreich.org 70 i- if (str[i] == '\t') 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 len += (len + 7) % 8; Err bitreich.org 70 i Err bitreich.org 70 i return len; Err bitreich.org 70 i } Err bitreich.org 70 i 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+static wchar_t * Err bitreich.org 70 i+format(wchar_t *wcs, 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; str[i] && j < cols; i++) { Err bitreich.org 70 i+ for (int i = 0; wcs[i] && j < cols; i++) { Err bitreich.org 70 i Err bitreich.org 70 i- if (str[i] == '\t') { Err bitreich.org 70 i+ if (wcs[i] == L'\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++] = ' '; Err bitreich.org 70 i+ formatted[j++] = L' '; Err bitreich.org 70 i } else { Err bitreich.org 70 i- formatted[j++] = str[i]; Err bitreich.org 70 i+ formatted[j++] = wcs[i]; Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- formatted[j] = '\0'; Err bitreich.org 70 i+ formatted[j] = L'\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(char *str, int current) Err bitreich.org 70 i+print_string(wchar_t *wcs, int current) Err bitreich.org 70 i { 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- fprintf(stderr, "%s \033[m", format(str, ws.ws_col - 2)); 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 } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i@@ -168,12 +171,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- fputc('\n', stderr); Err bitreich.org 70 i+ fputwc(L'\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- fputs("\n\033[K", stderr); Err bitreich.org 70 i+ fputws(L"\n\033[K", stderr); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i@@ -210,13 +213,13 @@ 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- fputs(offset > 0 ? "< " : " ", stderr); Err bitreich.org 70 i+ fputws(offset > 0 ? L"< " : L" ", 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- fprintf(stderr, "\033[%dC>", ws.ws_col - OFFSET); Err bitreich.org 70 i+ fwprintf(stderr, L"\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@@ -230,42 +233,45 @@ print_screen(void) Err bitreich.org 70 i Err bitreich.org 70 i count = MIN(opt_l, ws.ws_row - 2); Err bitreich.org 70 i Err bitreich.org 70 i- fputs("\r\033[K", stderr); Err bitreich.org 70 i+ fputws(L"\r\033[K", stderr); Err bitreich.org 70 i Err bitreich.org 70 i if (opt_l) { Err bitreich.org 70 i print_lines(count); Err bitreich.org 70 i- fprintf(stderr, "\033[%dA", count + 1); Err bitreich.org 70 i+ fwprintf(stderr, L"\033[%dA", count + 1); Err bitreich.org 70 i Err bitreich.org 70 i } else { Err bitreich.org 70 i- fputs("\033[30C", stderr); Err bitreich.org 70 i+ fputws(L"\033[30C", stderr); Err bitreich.org 70 i print_columns(); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i format(input, opt_l || matchc == 0 ? ws.ws_col : OFFSET - 3); Err bitreich.org 70 i- fprintf(stderr, "\r %s", formatted); Err bitreich.org 70 i+ fputws(L"\r ", stderr); Err bitreich.org 70 i+ fputws(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 void Err bitreich.org 70 i-print_clear(int lines) Err bitreich.org 70 i+clear(int lines) Err bitreich.org 70 i { Err bitreich.org 70 i for (int i = 0; i < lines + 1; i++) Err bitreich.org 70 i- fputs("\r\033[K\n", stderr); Err bitreich.org 70 i- fprintf(stderr, "\033[%dA", lines + 1); Err bitreich.org 70 i+ fputws(L"\r\033[K\n", stderr); Err bitreich.org 70 i+ fwprintf(stderr, L"\033[%dA", lines + 1); 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 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+ wchar_t **tokv = NULL, *tok, *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- strcpy(buffer, input); Err bitreich.org 70 i+ wcscpy(buffer, input); Err bitreich.org 70 i Err bitreich.org 70 i- for (s = strtok(buffer, " "); s; s = strtok(NULL, " "), tokc++) { Err bitreich.org 70 i+ for (s = wcstok(buffer, L" ", &tok); s; s = wcstok(NULL, L" ", &tok), 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@@ -289,13 +295,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 = wcslen(input) - 1; 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 (int i = len; i >= 0 && iswspace(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+ len = wcslen(input) - 1; Err bitreich.org 70 i+ for (int i = len; i >= 0 && !iswspace(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@@ -305,9 +311,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 = strlen(input); Err bitreich.org 70 i+ int len = wcslen(input); Err bitreich.org 70 i Err bitreich.org 70 i- if (isprint(key)) { Err bitreich.org 70 i+ if (iswprint(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@@ -319,8 +325,8 @@ 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- fputs("\r\033[K", stderr); Err bitreich.org 70 i- puts(matchc > 0 ? matchv[current] : input); 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 } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i@@ -330,12 +336,12 @@ print_selection(void) 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- char key = fgetc(tty_fp); Err bitreich.org 70 i+ wchar_t key = fgetwc(tty_fp); Err bitreich.org 70 i Err bitreich.org 70 i switch (key) { Err bitreich.org 70 i Err bitreich.org 70 i case CONTROL('C'): Err bitreich.org 70 i- print_clear(opt_l); Err bitreich.org 70 i+ clear(opt_l); Err bitreich.org 70 i return EXIT_FAILURE; Err bitreich.org 70 i Err bitreich.org 70 i case CONTROL('U'): Err bitreich.org 70 i@@ -349,7 +355,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[strlen(input) - 1] = '\0'; Err bitreich.org 70 i+ input[wcslen(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@@ -363,7 +369,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- strcpy(input, matchv[current]); Err bitreich.org 70 i+ wcscpy(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@@ -408,7 +414,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 [-l lines]\n", stderr); Err bitreich.org 70 i+ fputws(L"usage: iomenu [-l lines]\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@@ -433,6 +439,7 @@ main(int argc, char *argv[]) Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+ setlocale(LC_ALL, ""); Err bitreich.org 70 i read_lines(); Err bitreich.org 70 i Err bitreich.org 70 i tty_fp = fopen("/dev/tty", "r"); Err bitreich.org 70 i@@ -442,7 +449,7 @@ main(int argc, char *argv[]) Err bitreich.org 70 i exit_code = input_get(); Err bitreich.org 70 i Err bitreich.org 70 i tcsetattr(tty_fd, TCSANOW, &termios); Err bitreich.org 70 i- print_clear(opt_l); Err bitreich.org 70 i+ clear(opt_l); Err bitreich.org 70 i fclose(tty_fp); Err bitreich.org 70 i close(tty_fd); Err bitreich.org 70 i free_all(); Err bitreich.org 70 .