iit is not that big, a single file will do - 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 251f7a6436516116e1dc7c9e674a9be1f58eb1b7 /scm/iomenu/commit/251f7a6436516116e1dc7c9e674a9be1f58eb1b7.gph bitreich.org 70 1parent b69d6f5982f4c2b96f8dee1369c48180ed31b035 /scm/iomenu/commit/b69d6f5982f4c2b96f8dee1369c48180ed31b035.gph bitreich.org 70 hAuthor: Josuah Demangeon URL:mailto:mail@josuah.net bitreich.org 70 iDate: Thu, 16 Nov 2017 11:09:25 +0100 Err bitreich.org 70 i Err bitreich.org 70 iit is not that big, a single file will do Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M Makefile | 20 +++++++++++--------- Err bitreich.org 70 i D buffer.c | 155 ------------------------------- Err bitreich.org 70 i D buffer.h | 3 --- Err bitreich.org 70 i D control.c | 152 ------------------------------- Err bitreich.org 70 i D control.h | 4 ---- Err bitreich.org 70 i D display.c | 120 ------------------------------- Err bitreich.org 70 i D display.h | 2 -- Err bitreich.org 70 i A iomenu.c | 532 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i D iomenu.h | 18 ------------------ Err bitreich.org 70 i D main.c | 151 ------------------------------- Err bitreich.org 70 i D main.h | 1 - Err bitreich.org 70 i Err bitreich.org 70 i11 files changed, 543 insertions(+), 615 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,22 +1,24 @@ Err bitreich.org 70 i CFLAGS = -std=c89 -pedantic -Wall -Wextra -g -D_POSIX_C_SOURCE=200809L Err bitreich.org 70 i Err bitreich.org 70 i-OBJ = buffer.o control.o display.o main.o utf8.o Err bitreich.org 70 i-INC = buffer.h control.h display.h main.h utf8.h iomenu.h Err bitreich.org 70 i+OBJ = iomenu.o utf8.o Err bitreich.org 70 i Err bitreich.org 70 i all: iomenu Err bitreich.org 70 i Err bitreich.org 70 i-iomenu: $(OBJ) Err bitreich.org 70 i- $(CC) $(LDFLAGS) $(OBJ) -o $@ Err bitreich.org 70 i+.c.o: Err bitreich.org 70 i+ ${CC} -c -o $@ ${CFLAGS} $< Err bitreich.org 70 i Err bitreich.org 70 i-$(OBJ): $(INC) Err bitreich.org 70 i+iomenu: ${OBJ} Err bitreich.org 70 i+ ${CC} -o $@ ${LDFLAGS} ${OBJ} Err bitreich.org 70 i+ Err bitreich.org 70 i+${OBJ}: utf8.h Err bitreich.org 70 i Err bitreich.org 70 i clean: Err bitreich.org 70 i rm -f *.o *.core iomenu Err bitreich.org 70 i Err bitreich.org 70 i install: iomenu Err bitreich.org 70 i- mkdir -p $(PREFIX)/share/man/man1 Err bitreich.org 70 i- cp *.1 $(PREFIX)/share/man/man1 Err bitreich.org 70 i- mkdir -p $(PREFIX)/bin Err bitreich.org 70 i- cp iomenu $(PREFIX)/bin Err bitreich.org 70 i+ mkdir -p ${PREFIX}/share/man/man1 Err bitreich.org 70 i+ cp *.1 ${PREFIX}/share/man/man1 Err bitreich.org 70 i+ mkdir -p ${PREFIX}/bin Err bitreich.org 70 i+ cp iomenu ${PREFIX}/bin Err bitreich.org 70 i Err bitreich.org 70 i .PHONY: all clean install Err bitreich.org 70 1diff --git a/buffer.c b/buffer.c /scm/iomenu/file/buffer.c.gph bitreich.org 70 i@@ -1,155 +0,0 @@ Err bitreich.org 70 i-#include 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-#include "iomenu.h" Err bitreich.org 70 i-#include "buffer.h" Err bitreich.org 70 i-#include "main.h" Err bitreich.org 70 i-#include "control.h" Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Keep the line if it match every token (in no particular order, and allowed to Err bitreich.org 70 i- * be overlapping). 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-{ Err bitreich.org 70 i- if (opt['#'] && line[0] == '#') Err bitreich.org 70 i- return 2; 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- return 1; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * As we use a single buffer for the whole stdin, we only need to free it once Err bitreich.org 70 i- * and it will free all the lines. Err bitreich.org 70 i- */ Err bitreich.org 70 i-void Err bitreich.org 70 i-free_lines(void) Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern char **linev; Err bitreich.org 70 i- extern char **matchv; Err bitreich.org 70 i- Err bitreich.org 70 i- if (linev) { Err bitreich.org 70 i- free(linev[0]); Err bitreich.org 70 i- free(linev); Err bitreich.org 70 i- } Err bitreich.org 70 i- if (matchv) Err bitreich.org 70 i- free(matchv); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Split a buffer into an array of lines, without allocating memory for every Err bitreich.org 70 i- * line, but using the input buffer and replacing characters. Err bitreich.org 70 i- */ Err bitreich.org 70 i-void Err bitreich.org 70 i-split_lines(char *buf) Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern char **linev; Err bitreich.org 70 i- extern char **matchv; Err bitreich.org 70 i- extern int linec; Err bitreich.org 70 i- Err bitreich.org 70 i- char *b; Err bitreich.org 70 i- char **lv; Err bitreich.org 70 i- char **mv; Err bitreich.org 70 i- Err bitreich.org 70 i- linec = 0; Err bitreich.org 70 i- b = buf; Err bitreich.org 70 i- while ((b = strchr(b + 1, '\n'))) Err bitreich.org 70 i- linec++; Err bitreich.org 70 i- if (!linec) Err bitreich.org 70 i- linec = 1; Err bitreich.org 70 i- if (!(lv = linev = calloc(linec + 1, sizeof (char **)))) Err bitreich.org 70 i- die("calloc"); Err bitreich.org 70 i- if (!(mv = matchv = calloc(linec + 1, sizeof (char **)))) { Err bitreich.org 70 i- free(linev); Err bitreich.org 70 i- die("calloc"); Err bitreich.org 70 i- } Err bitreich.org 70 i- *mv = *lv = b = buf; Err bitreich.org 70 i- while ((b = strchr(b, '\n'))) { Err bitreich.org 70 i- *b = '\0'; Err bitreich.org 70 i- mv++, lv++; Err bitreich.org 70 i- *mv = *lv = ++b; 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- * Read stdin in a single malloc-ed buffer, realloc-ed to twice its size every Err bitreich.org 70 i- * time the previous buffer is filled. Err bitreich.org 70 i- */ Err bitreich.org 70 i-void Err bitreich.org 70 i-read_stdin(void) Err bitreich.org 70 i-{ Err bitreich.org 70 i- size_t size; Err bitreich.org 70 i- size_t len; Err bitreich.org 70 i- size_t off; Err bitreich.org 70 i- char *buf; Err bitreich.org 70 i- char *b; Err bitreich.org 70 i- Err bitreich.org 70 i- size = BUFSIZ; Err bitreich.org 70 i- off = 0; Err bitreich.org 70 i- buf = malloc(size); Err bitreich.org 70 i- while ((len = read(STDIN_FILENO, buf + off, size - off)) > 0) { Err bitreich.org 70 i- off += len; Err bitreich.org 70 i- if (off >= size >> 1) { Err bitreich.org 70 i- size <<= 1; Err bitreich.org 70 i- if (!(b = realloc(buf, size + 1))) { Err bitreich.org 70 i- free(buf); Err bitreich.org 70 i- die("realloc"); Err bitreich.org 70 i- } Err bitreich.org 70 i- buf = b; Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i- buf[off] = '\0'; Err bitreich.org 70 i- split_lines(buf); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * First split input into token, then match every token independently against Err bitreich.org 70 i- * every line. The matching lines fills matchv. Err bitreich.org 70 i- */ Err bitreich.org 70 i-void Err bitreich.org 70 i-filter(void) Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern char **linev; Err bitreich.org 70 i- extern char **matchv; Err bitreich.org 70 i- extern int linec; Err bitreich.org 70 i- extern int matchc; Err bitreich.org 70 i- extern int current; Err bitreich.org 70 i- Err bitreich.org 70 i- int tokc; Err bitreich.org 70 i- int n; Err bitreich.org 70 i- char **tokv; Err bitreich.org 70 i- char *s; Err bitreich.org 70 i- char buf[sizeof (input)]; Err bitreich.org 70 i- Err bitreich.org 70 i- tokv = NULL; Err bitreich.org 70 i- current = 0; Err bitreich.org 70 i- strcpy(buf, input); Err bitreich.org 70 i- tokc = 0; Err bitreich.org 70 i- n = 0; Err bitreich.org 70 i- s = strtok(buf, " "); Err bitreich.org 70 i- while (s) { Err bitreich.org 70 i- if (tokc >= n) { Err bitreich.org 70 i- tokv = realloc(tokv, ++n * sizeof (*tokv)); Err bitreich.org 70 i- if (tokv == NULL) Err bitreich.org 70 i- die("realloc"); Err bitreich.org 70 i- } Err bitreich.org 70 i- tokv[tokc] = s; Err bitreich.org 70 i- s = strtok(NULL, " "); Err bitreich.org 70 i- tokc++; Err bitreich.org 70 i- } Err bitreich.org 70 i- matchc = 0; Err bitreich.org 70 i- for (n = 0; n < linec; n++) Err bitreich.org 70 i- if (match_line(linev[n], tokv, tokc)) Err bitreich.org 70 i- matchv[matchc++] = linev[n]; Err bitreich.org 70 i- free(tokv); Err bitreich.org 70 i- if (opt['#'] && matchv[current][0] == '#') Err bitreich.org 70 i- move(+1); Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/buffer.h b/buffer.h /scm/iomenu/file/buffer.h.gph bitreich.org 70 i@@ -1,3 +0,0 @@ Err bitreich.org 70 i-void free_lines(void); Err bitreich.org 70 i-void read_stdin(void); Err bitreich.org 70 i-void filter(void); Err bitreich.org 70 1diff --git a/control.c b/control.c /scm/iomenu/file/control.c.gph bitreich.org 70 i@@ -1,152 +0,0 @@ Err bitreich.org 70 i-#include 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-#include "iomenu.h" Err bitreich.org 70 i-#include "buffer.h" Err bitreich.org 70 i-#include "control.h" Err bitreich.org 70 i-#include "display.h" Err bitreich.org 70 i- Err bitreich.org 70 i-#define CTL(char) ((char) ^ 0x40) Err bitreich.org 70 i-#define ALT(char) ((char) + 0x80) Err bitreich.org 70 i-#define CSI(char) ((char) + 0x80 + 0x80) Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-move(signed int sign) Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern char **matchv; Err bitreich.org 70 i- extern int matchc; Err bitreich.org 70 i- Err bitreich.org 70 i- int i; Err bitreich.org 70 i- Err bitreich.org 70 i- for (i = current + sign; 0 <= i && i < matchc; i += sign) { Err bitreich.org 70 i- if (!opt['#'] || matchv[i][0] != '#') { Err bitreich.org 70 i- current = i; 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- Err bitreich.org 70 i-static void Err bitreich.org 70 i-move_page(signed int sign) Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern struct winsize ws; Err bitreich.org 70 i- extern int matchc; Err bitreich.org 70 i- Err bitreich.org 70 i- int i; Err bitreich.org 70 i- int rows; Err bitreich.org 70 i- Err bitreich.org 70 i- rows = ws.ws_row - 1; Err bitreich.org 70 i- i = current - current % rows + rows * sign; Err bitreich.org 70 i- if (!(0 <= i && i < matchc)) Err bitreich.org 70 i- return; Err bitreich.org 70 i- current = i - 1; Err bitreich.org 70 i- move(+1); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-static void Err bitreich.org 70 i-remove_word() Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern char input[LINE_MAX]; Err bitreich.org 70 i- Err bitreich.org 70 i- int len; Err bitreich.org 70 i- int i; Err bitreich.org 70 i- Err bitreich.org 70 i- len = strlen(input) - 1; 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- len = strlen(input) - 1; 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- filter(); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-static void Err bitreich.org 70 i-add_char(char c) Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern char input[LINE_MAX]; Err bitreich.org 70 i- Err bitreich.org 70 i- int len; Err bitreich.org 70 i- Err bitreich.org 70 i- len = strlen(input); Err bitreich.org 70 i- if (isprint(c)) { Err bitreich.org 70 i- input[len] = c; Err bitreich.org 70 i- input[len + 1] = '\0'; Err bitreich.org 70 i- } Err bitreich.org 70 i- filter(); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Big case table, that calls itself back for with ALT (aka ESC), CSI Err bitreich.org 70 i- * (aka ESC + [). These last two have values above the range of ASCII. Err bitreich.org 70 i- */ Err bitreich.org 70 i-int Err bitreich.org 70 i-key(int k) Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern char **matchv; Err bitreich.org 70 i- extern char input[LINE_MAX]; Err bitreich.org 70 i- extern int linec; Err bitreich.org 70 i- Err bitreich.org 70 i-top: Err bitreich.org 70 i- switch (k) { Err bitreich.org 70 i- case CTL('C'): Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- case CTL('U'): Err bitreich.org 70 i- input[0] = '\0'; Err bitreich.org 70 i- filter(); Err bitreich.org 70 i- break; Err bitreich.org 70 i- case CTL('W'): Err bitreich.org 70 i- remove_word(); Err bitreich.org 70 i- break; Err bitreich.org 70 i- case 127: Err bitreich.org 70 i- case CTL('H'): /* backspace */ Err bitreich.org 70 i- input[strlen(input) - 1] = '\0'; Err bitreich.org 70 i- filter(); Err bitreich.org 70 i- break; Err bitreich.org 70 i- case CSI('A'): /* up */ Err bitreich.org 70 i- case CTL('P'): Err bitreich.org 70 i- move(-1); Err bitreich.org 70 i- break; Err bitreich.org 70 i- case CSI('B'): /* down */ Err bitreich.org 70 i- case CTL('N'): Err bitreich.org 70 i- move(+1); Err bitreich.org 70 i- break; Err bitreich.org 70 i- case CSI('5'): /* page up */ Err bitreich.org 70 i- if (fgetc(stdin) != '~') Err bitreich.org 70 i- break; Err bitreich.org 70 i- /* FALLTHROUGH */ Err bitreich.org 70 i- case ALT('v'): Err bitreich.org 70 i- move_page(-1); Err bitreich.org 70 i- break; Err bitreich.org 70 i- case CSI('6'): /* page down */ Err bitreich.org 70 i- if (fgetc(stdin) != '~') Err bitreich.org 70 i- break; Err bitreich.org 70 i- /* FALLTHROUGH */ Err bitreich.org 70 i- case CTL('V'): Err bitreich.org 70 i- move_page(+1); Err bitreich.org 70 i- break; Err bitreich.org 70 i- case CTL('I'): /* tab */ Err bitreich.org 70 i- if (linec > 0) Err bitreich.org 70 i- strcpy(input, matchv[current]); Err bitreich.org 70 i- filter(); Err bitreich.org 70 i- break; Err bitreich.org 70 i- case CTL('J'): /* enter */ Err bitreich.org 70 i- case CTL('M'): Err bitreich.org 70 i- print_selection(); Err bitreich.org 70 i- return 0; Err bitreich.org 70 i- case ALT('['): Err bitreich.org 70 i- k = CSI(fgetc(stdin)); Err bitreich.org 70 i- goto top; Err bitreich.org 70 i- case 0x1b: /* escape / alt */ Err bitreich.org 70 i- k = ALT(fgetc(stdin)); Err bitreich.org 70 i- goto top; Err bitreich.org 70 i- default: Err bitreich.org 70 i- add_char((char) k); Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- return 1; Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/control.h b/control.h /scm/iomenu/file/control.h.gph bitreich.org 70 i@@ -1,4 +0,0 @@ Err bitreich.org 70 i-int prev_page(int); Err bitreich.org 70 i-int next_page(int); Err bitreich.org 70 i-void move(signed int); Err bitreich.org 70 i-int key(int); Err bitreich.org 70 1diff --git a/display.c b/display.c /scm/iomenu/file/display.c.gph bitreich.org 70 i@@ -1,120 +0,0 @@ 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 "iomenu.h" Err bitreich.org 70 i-#include "utf8.h" Err bitreich.org 70 i-#include "control.h" Err bitreich.org 70 i-#include "display.h" 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 struct winsize ws; Err bitreich.org 70 i- Err bitreich.org 70 i- int col = 0; Err bitreich.org 70 i- long rune = 0; Err bitreich.org 70 i- char *fmt = formatted; Err bitreich.org 70 i- Err bitreich.org 70 i- while (*str && col < cols) { Err bitreich.org 70 i- if (*str == '\t') { Err bitreich.org 70 i- int t = 8 - col % 8; Err bitreich.org 70 i- while (t-- && col < cols) { Err bitreich.org 70 i- *fmt++ = ' '; Err bitreich.org 70 i- col++; Err bitreich.org 70 i- } Err bitreich.org 70 i- str++; Err bitreich.org 70 i- } else if (utf8_to_rune(&rune, str) && utf8_is_print(rune)) { Err bitreich.org 70 i- int i = utf8_len(str); Err bitreich.org 70 i- while (i--) Err bitreich.org 70 i- *fmt++ = *str++; Err bitreich.org 70 i- col++; Err bitreich.org 70 i- } else { Err bitreich.org 70 i- *fmt++ = '?'; Err bitreich.org 70 i- col++; Err bitreich.org 70 i- str++; Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i- *fmt = '\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-static void Err bitreich.org 70 i-print_line(char *line, int cur) Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern struct winsize ws; Err bitreich.org 70 i- Err bitreich.org 70 i- if (opt['#'] && line[0] == '#') { Err bitreich.org 70 i- format(line + 1, ws.ws_col - 1); Err bitreich.org 70 i- fprintf(stderr, "\n\x1b[1m %s\x1b[m", formatted); Err bitreich.org 70 i- } else if (cur) { Err bitreich.org 70 i- format(line, ws.ws_col - 1); Err bitreich.org 70 i- fprintf(stderr, "\n\x1b[47;30m\x1b[K %s\x1b[m", formatted); Err bitreich.org 70 i- } else { Err bitreich.org 70 i- format(line, ws.ws_col - 1); Err bitreich.org 70 i- fprintf(stderr, "\n %s", formatted); Err bitreich.org 70 i- } Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-print_screen(void) Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern struct winsize ws; Err bitreich.org 70 i- extern char **matchv; Err bitreich.org 70 i- extern char *prompt; Err bitreich.org 70 i- extern char input[LINE_MAX]; Err bitreich.org 70 i- extern int matchc; Err bitreich.org 70 i- Err bitreich.org 70 i- char **m; Err bitreich.org 70 i- int p; Err bitreich.org 70 i- int i; Err bitreich.org 70 i- int cols; Err bitreich.org 70 i- int rows; Err bitreich.org 70 i- Err bitreich.org 70 i- cols = ws.ws_col - 1; Err bitreich.org 70 i- rows = ws.ws_row - 1; Err bitreich.org 70 i- p = 0; Err bitreich.org 70 i- i = current - current % rows; Err bitreich.org 70 i- m = matchv + i; Err bitreich.org 70 i- fputs("\x1b[2J", stderr); Err bitreich.org 70 i- while (p < rows && i < matchc) { Err bitreich.org 70 i- print_line(*m, i == current); Err bitreich.org 70 i- p++, i++, m++; Err bitreich.org 70 i- } Err bitreich.org 70 i- fputs("\x1b[H", stderr); Err bitreich.org 70 i- if (*prompt) { Err bitreich.org 70 i- format(prompt, cols - 2); Err bitreich.org 70 i- fprintf(stderr, "\x1b[30;47m %s \x1b[m", formatted); Err bitreich.org 70 i- cols -= strlen(formatted) + 2; Err bitreich.org 70 i- } Err bitreich.org 70 i- fputc(' ', stderr); Err bitreich.org 70 i- fputs(format(input, cols), stderr); 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-print_selection(void) Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern char **matchv; Err bitreich.org 70 i- extern char input[LINE_MAX]; Err bitreich.org 70 i- extern int matchc; Err bitreich.org 70 i- Err bitreich.org 70 i- char **match; Err bitreich.org 70 i- Err bitreich.org 70 i- if (opt['#']) { Err bitreich.org 70 i- match = matchv + current; Err bitreich.org 70 i- while (--match >= matchv) { Err bitreich.org 70 i- if ((*match)[0] == '#') { Err bitreich.org 70 i- fputs(*match + 1, stdout); Err bitreich.org 70 i- break; 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- if (matchc == 0 || (opt['#'] && matchv[current][0] == '#')) 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 1diff --git a/display.h b/display.h /scm/iomenu/file/display.h.gph bitreich.org 70 i@@ -1,2 +0,0 @@ Err bitreich.org 70 i-void print_screen(void); Err bitreich.org 70 i-void print_selection(void); Err bitreich.org 70 1diff --git a/iomenu.c b/iomenu.c /scm/iomenu/file/iomenu.c.gph bitreich.org 70 i@@ -0,0 +1,532 @@ Err bitreich.org 70 i+#include 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+#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 "utf8.h" Err bitreich.org 70 i+ Err bitreich.org 70 i+#ifndef SIGWINCH Err bitreich.org 70 i+#define SIGWINCH 28 Err bitreich.org 70 i+#endif Err bitreich.org 70 i+ Err bitreich.org 70 i+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) Err bitreich.org 70 i+#define CTL(char) ((char) ^ 0x40) Err bitreich.org 70 i+#define ALT(char) ((char) + 0x80) Err bitreich.org 70 i+#define CSI(char) ((char) + 0x80 + 0x80) Err bitreich.org 70 i+ Err bitreich.org 70 i+static struct termios termios; Err bitreich.org 70 i+static int ttyfd; Err bitreich.org 70 i+ Err bitreich.org 70 i+struct winsize ws; Err bitreich.org 70 i+int linec = 0, matchc = 0, current = 0; Err bitreich.org 70 i+char **linev = NULL, **matchv = NULL; Err bitreich.org 70 i+char input[LINE_MAX], formatted[LINE_MAX * 8]; Err bitreich.org 70 i+ Err bitreich.org 70 i+char *flag_p = ""; Err bitreich.org 70 i+int flag_hs = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * Keep the line if it match every token (in no particular order, and allowed to Err bitreich.org 70 i+ * be overlapping). 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+{ Err bitreich.org 70 i+ if (flag_hs && line[0] == '#') Err bitreich.org 70 i+ return 2; 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+ return 1; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * As we use a single buffer for the whole stdin, we only need to free it once Err bitreich.org 70 i+ * and it will free all the lines. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static void Err bitreich.org 70 i+free_lines(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern char **linev; Err bitreich.org 70 i+ extern char **matchv; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (linev) { Err bitreich.org 70 i+ free(linev[0]); Err bitreich.org 70 i+ free(linev); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ if (matchv) Err bitreich.org 70 i+ free(matchv); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * Free the structures, reset the terminal state and exit with an error message. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static void Err bitreich.org 70 i+die(const char *s) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ tcsetattr(ttyfd, TCSANOW, &termios); Err bitreich.org 70 i+ close(ttyfd); Err bitreich.org 70 i+ free_lines(); Err bitreich.org 70 i+ perror(s); Err bitreich.org 70 i+ exit(EXIT_FAILURE); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * Split a buffer into an array of lines, without allocating memory for every Err bitreich.org 70 i+ * line, but using the input buffer and replacing characters. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static void Err bitreich.org 70 i+split_lines(char *buf) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern char **linev, **matchv; Err bitreich.org 70 i+ extern int linec; Err bitreich.org 70 i+ Err bitreich.org 70 i+ char *b, **lv, **mv; Err bitreich.org 70 i+ Err bitreich.org 70 i+ linec = 0; Err bitreich.org 70 i+ b = buf; Err bitreich.org 70 i+ while ((b = strchr(b + 1, '\n'))) Err bitreich.org 70 i+ linec++; Err bitreich.org 70 i+ if (!linec) Err bitreich.org 70 i+ linec = 1; Err bitreich.org 70 i+ if (!(lv = linev = calloc(linec + 1, sizeof (char **)))) Err bitreich.org 70 i+ die("calloc"); Err bitreich.org 70 i+ if (!(mv = matchv = calloc(linec + 1, sizeof (char **)))) { Err bitreich.org 70 i+ free(linev); Err bitreich.org 70 i+ die("calloc"); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ *mv = *lv = b = buf; Err bitreich.org 70 i+ while ((b = strchr(b, '\n'))) { Err bitreich.org 70 i+ *b = '\0'; Err bitreich.org 70 i+ mv++, lv++; Err bitreich.org 70 i+ *mv = *lv = ++b; 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+ * Read stdin in a single malloc-ed buffer, realloc-ed to twice its size every Err bitreich.org 70 i+ * time the previous buffer is filled. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static void Err bitreich.org 70 i+read_stdin(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ size_t size, len, off; Err bitreich.org 70 i+ char *buf, *b; Err bitreich.org 70 i+ Err bitreich.org 70 i+ size = BUFSIZ; Err bitreich.org 70 i+ off = 0; Err bitreich.org 70 i+ buf = malloc(size); Err bitreich.org 70 i+ while ((len = read(STDIN_FILENO, buf + off, size - off)) > 0) { Err bitreich.org 70 i+ off += len; Err bitreich.org 70 i+ if (off >= size >> 1) { Err bitreich.org 70 i+ size <<= 1; Err bitreich.org 70 i+ if (!(b = realloc(buf, size + 1))) { Err bitreich.org 70 i+ free(buf); Err bitreich.org 70 i+ die("realloc"); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ buf = b; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ buf[off] = '\0'; Err bitreich.org 70 i+ split_lines(buf); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static void Err bitreich.org 70 i+move(signed int sign) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern char **matchv; Err bitreich.org 70 i+ extern int matchc; Err bitreich.org 70 i+ Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (i = current + sign; 0 <= i && i < matchc; i += sign) { Err bitreich.org 70 i+ if (!flag_hs || matchv[i][0] != '#') { Err bitreich.org 70 i+ current = i; 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+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * First split input into token, then match every token independently against Err bitreich.org 70 i+ * every line. The matching lines fills matchv. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static void Err bitreich.org 70 i+filter(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern char **linev, **matchv; Err bitreich.org 70 i+ extern int linec, matchc, current; Err bitreich.org 70 i+ Err bitreich.org 70 i+ int tokc, n; Err bitreich.org 70 i+ char **tokv, *s, buf[sizeof (input)]; Err bitreich.org 70 i+ Err bitreich.org 70 i+ tokv = NULL; Err bitreich.org 70 i+ current = 0; Err bitreich.org 70 i+ strcpy(buf, input); Err bitreich.org 70 i+ tokc = 0; Err bitreich.org 70 i+ n = 0; Err bitreich.org 70 i+ s = strtok(buf, " "); Err bitreich.org 70 i+ while (s) { Err bitreich.org 70 i+ if (tokc >= n) { Err bitreich.org 70 i+ tokv = realloc(tokv, ++n * sizeof (*tokv)); Err bitreich.org 70 i+ if (tokv == NULL) Err bitreich.org 70 i+ die("realloc"); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ tokv[tokc] = s; Err bitreich.org 70 i+ s = strtok(NULL, " "); Err bitreich.org 70 i+ tokc++; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ matchc = 0; Err bitreich.org 70 i+ for (n = 0; n < linec; n++) Err bitreich.org 70 i+ if (match_line(linev[n], tokv, tokc)) Err bitreich.org 70 i+ matchv[matchc++] = linev[n]; Err bitreich.org 70 i+ free(tokv); Err bitreich.org 70 i+ if (flag_hs && matchv[current][0] == '#') Err bitreich.org 70 i+ move(+1); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static void Err bitreich.org 70 i+move_page(signed int sign) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern struct winsize ws; Err bitreich.org 70 i+ extern int matchc; Err bitreich.org 70 i+ Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ int rows; Err bitreich.org 70 i+ Err bitreich.org 70 i+ rows = ws.ws_row - 1; Err bitreich.org 70 i+ i = current - current % rows + rows * sign; Err bitreich.org 70 i+ if (!(0 <= i && i < matchc)) Err bitreich.org 70 i+ return; Err bitreich.org 70 i+ current = i - 1; Err bitreich.org 70 i+ move(+1); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static void Err bitreich.org 70 i+remove_word() Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern char input[LINE_MAX]; Err bitreich.org 70 i+ Err bitreich.org 70 i+ int len; Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ Err bitreich.org 70 i+ len = strlen(input) - 1; 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+ len = strlen(input) - 1; 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+ filter(); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static void Err bitreich.org 70 i+add_char(char c) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern char input[LINE_MAX]; Err bitreich.org 70 i+ Err bitreich.org 70 i+ int len; Err bitreich.org 70 i+ Err bitreich.org 70 i+ len = strlen(input); Err bitreich.org 70 i+ if (isprint(c)) { Err bitreich.org 70 i+ input[len] = c; Err bitreich.org 70 i+ input[len + 1] = '\0'; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ filter(); Err bitreich.org 70 i+} Err bitreich.org 70 i+ 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+ extern char **matchv; Err bitreich.org 70 i+ extern char input[LINE_MAX]; Err bitreich.org 70 i+ extern int matchc; Err bitreich.org 70 i+ Err bitreich.org 70 i+ char **match; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (flag_hs) { Err bitreich.org 70 i+ match = matchv + current; Err bitreich.org 70 i+ while (--match >= matchv) { Err bitreich.org 70 i+ if ((*match)[0] == '#') { Err bitreich.org 70 i+ fputs(*match + 1, stdout); Err bitreich.org 70 i+ break; 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+ if (matchc == 0 || (flag_hs && matchv[current][0] == '#')) 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+/* Err bitreich.org 70 i+ * Big case table, that calls itself back for with ALT (aka ESC), CSI Err bitreich.org 70 i+ * (aka ESC + [). These last two have values above the range of ASCII. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+int Err bitreich.org 70 i+key(int k) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern char **matchv; Err bitreich.org 70 i+ extern char input[LINE_MAX]; Err bitreich.org 70 i+ extern int linec; Err bitreich.org 70 i+ Err bitreich.org 70 i+top: Err bitreich.org 70 i+ switch (k) { Err bitreich.org 70 i+ case CTL('C'): Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ case CTL('U'): Err bitreich.org 70 i+ input[0] = '\0'; Err bitreich.org 70 i+ filter(); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case CTL('W'): Err bitreich.org 70 i+ remove_word(); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 127: Err bitreich.org 70 i+ case CTL('H'): /* backspace */ Err bitreich.org 70 i+ input[strlen(input) - 1] = '\0'; Err bitreich.org 70 i+ filter(); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case CSI('A'): /* up */ Err bitreich.org 70 i+ case CTL('P'): Err bitreich.org 70 i+ move(-1); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case CSI('B'): /* down */ Err bitreich.org 70 i+ case CTL('N'): Err bitreich.org 70 i+ move(+1); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case CSI('5'): /* page up */ Err bitreich.org 70 i+ if (fgetc(stdin) != '~') Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ /* FALLTHROUGH */ Err bitreich.org 70 i+ case ALT('v'): Err bitreich.org 70 i+ move_page(-1); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case CSI('6'): /* page down */ Err bitreich.org 70 i+ if (fgetc(stdin) != '~') Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ /* FALLTHROUGH */ Err bitreich.org 70 i+ case CTL('V'): Err bitreich.org 70 i+ move_page(+1); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case CTL('I'): /* tab */ Err bitreich.org 70 i+ if (linec > 0) Err bitreich.org 70 i+ strcpy(input, matchv[current]); Err bitreich.org 70 i+ filter(); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case CTL('J'): /* enter */ Err bitreich.org 70 i+ case CTL('M'): Err bitreich.org 70 i+ print_selection(); Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+ case ALT('['): Err bitreich.org 70 i+ k = CSI(fgetc(stdin)); Err bitreich.org 70 i+ goto top; Err bitreich.org 70 i+ case 0x1b: /* escape / alt */ Err bitreich.org 70 i+ k = ALT(fgetc(stdin)); Err bitreich.org 70 i+ goto top; Err bitreich.org 70 i+ default: Err bitreich.org 70 i+ add_char((char) k); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ return 1; 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+{ Err bitreich.org 70 i+ extern struct winsize ws; Err bitreich.org 70 i+ Err bitreich.org 70 i+ int col = 0; Err bitreich.org 70 i+ long rune = 0; Err bitreich.org 70 i+ char *fmt = formatted; Err bitreich.org 70 i+ Err bitreich.org 70 i+ while (*str && col < cols) { Err bitreich.org 70 i+ if (*str == '\t') { Err bitreich.org 70 i+ int t = 8 - col % 8; Err bitreich.org 70 i+ while (t-- && col < cols) { Err bitreich.org 70 i+ *fmt++ = ' '; Err bitreich.org 70 i+ col++; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ str++; Err bitreich.org 70 i+ } else if (utf8_to_rune(&rune, str) && utf8_is_print(rune)) { Err bitreich.org 70 i+ int i = utf8_len(str); Err bitreich.org 70 i+ while (i--) Err bitreich.org 70 i+ *fmt++ = *str++; Err bitreich.org 70 i+ col++; Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ *fmt++ = '?'; Err bitreich.org 70 i+ col++; Err bitreich.org 70 i+ str++; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ *fmt = '\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+static void Err bitreich.org 70 i+print_line(char *line, int cur) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern struct winsize ws; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (flag_hs && line[0] == '#') { Err bitreich.org 70 i+ format(line + 1, ws.ws_col - 1); Err bitreich.org 70 i+ fprintf(stderr, "\n\x1b[1m %s\x1b[m", formatted); Err bitreich.org 70 i+ } else if (cur) { Err bitreich.org 70 i+ format(line, ws.ws_col - 1); Err bitreich.org 70 i+ fprintf(stderr, "\n\x1b[47;30m\x1b[K %s\x1b[m", formatted); Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ format(line, ws.ws_col - 1); Err bitreich.org 70 i+ fprintf(stderr, "\n %s", 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_screen(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern struct winsize ws; Err bitreich.org 70 i+ extern char **matchv; Err bitreich.org 70 i+ extern char *flag_p; Err bitreich.org 70 i+ extern char input[LINE_MAX]; Err bitreich.org 70 i+ extern int matchc; Err bitreich.org 70 i+ Err bitreich.org 70 i+ char **m; Err bitreich.org 70 i+ int p; Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ int cols; Err bitreich.org 70 i+ int rows; Err bitreich.org 70 i+ Err bitreich.org 70 i+ cols = ws.ws_col - 1; Err bitreich.org 70 i+ rows = ws.ws_row - 1; Err bitreich.org 70 i+ p = 0; Err bitreich.org 70 i+ i = current - current % rows; Err bitreich.org 70 i+ m = matchv + i; Err bitreich.org 70 i+ fputs("\x1b[2J", stderr); Err bitreich.org 70 i+ while (p < rows && i < matchc) { Err bitreich.org 70 i+ print_line(*m, i == current); Err bitreich.org 70 i+ p++, i++, m++; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ fputs("\x1b[H", stderr); Err bitreich.org 70 i+ if (*flag_p) { Err bitreich.org 70 i+ format(flag_p, cols - 2); Err bitreich.org 70 i+ fprintf(stderr, "\x1b[30;47m %s \x1b[m", formatted); Err bitreich.org 70 i+ cols -= strlen(formatted) + 2; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ fputc(' ', stderr); Err bitreich.org 70 i+ fputs(format(input, cols), stderr); 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+ * Set terminal in raw mode. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static void Err bitreich.org 70 i+set_terminal(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ struct termios new; Err bitreich.org 70 i+ Err bitreich.org 70 i+ fputs("\x1b[s\x1b[?1049h\x1b[H", stderr); Err bitreich.org 70 i+ if (tcgetattr(ttyfd, &termios) < 0 || tcgetattr(ttyfd, &new) < 0) { Err bitreich.org 70 i+ perror("tcgetattr"); Err bitreich.org 70 i+ exit(EXIT_FAILURE); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ new.c_lflag &= ~(ICANON | ECHO | IGNBRK | IEXTEN | ISIG); Err bitreich.org 70 i+ tcsetattr(ttyfd, TCSANOW, &new); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * Take terminal out of raw mode. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static void Err bitreich.org 70 i+reset_terminal(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ fputs("\x1b[u\033[?1049l", stderr); Err bitreich.org 70 i+ tcsetattr(ttyfd, TCSANOW, &termios); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * Redraw the whole screen on window resize. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static void Err bitreich.org 70 i+sigwinch() Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern struct winsize ws; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (ioctl(ttyfd, TIOCGWINSZ, &ws) < 0) Err bitreich.org 70 i+ die("ioctl"); Err bitreich.org 70 i+ print_screen(); Err bitreich.org 70 i+ signal(SIGWINCH, sigwinch); Err bitreich.org 70 i+} Err bitreich.org 70 i+ 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 [-#] [-p flag_p]\n", stderr); Err bitreich.org 70 i+ exit(EXIT_FAILURE); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * XXX: switch to getopt. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static void Err bitreich.org 70 i+parse_opt(int argc, char *argv[]) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ extern char *flag_p; Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (argv++, argc--; argc > 0; argv++, argc--) { Err bitreich.org 70 i+ if (argv[0][0] != '-') Err bitreich.org 70 i+ usage(); Err bitreich.org 70 i+ switch ((*argv)[1]) { Err bitreich.org 70 i+ case 'p': Err bitreich.org 70 i+ if (!--argc) Err bitreich.org 70 i+ usage(); Err bitreich.org 70 i+ flag_p = *++argv; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case '#': Err bitreich.org 70 i+ flag_hs = 1; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ default: Err bitreich.org 70 i+ usage(); 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+ * Read stdin in a buffer, filling a table of lines, then re-open stdin to Err bitreich.org 70 i+ * /dev/tty for an interactive (raw) session to let the user filter and select Err bitreich.org 70 i+ * one line by searching words within stdin. This was inspired from dmenu. Err bitreich.org 70 i+ */ 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 char input[LINE_MAX]; Err bitreich.org 70 i+ Err bitreich.org 70 i+ int exit_code; Err bitreich.org 70 i+ Err bitreich.org 70 i+ parse_opt(argc, argv); Err bitreich.org 70 i+ read_stdin(); Err bitreich.org 70 i+ filter(); Err bitreich.org 70 i+ if (!freopen("/dev/tty", "r", stdin)) Err bitreich.org 70 i+ die("freopen /dev/tty"); Err bitreich.org 70 i+ if (!freopen("/dev/tty", "w", stderr)) Err bitreich.org 70 i+ die("freopen /dev/tty"); Err bitreich.org 70 i+ ttyfd = open("/dev/tty", O_RDWR); Err bitreich.org 70 i+ set_terminal(); Err bitreich.org 70 i+ sigwinch(); Err bitreich.org 70 i+ input[0] = '\0'; Err bitreich.org 70 i+ while ((exit_code = key(fgetc(stdin))) > 0) Err bitreich.org 70 i+ print_screen(); Err bitreich.org 70 i+ print_screen(); Err bitreich.org 70 i+ reset_terminal(); Err bitreich.org 70 i+ close(ttyfd); Err bitreich.org 70 i+ free_lines(); Err bitreich.org 70 i+ Err bitreich.org 70 i+ return exit_code; Err bitreich.org 70 i+} Err bitreich.org 70 1diff --git a/iomenu.h b/iomenu.h /scm/iomenu/file/iomenu.h.gph bitreich.org 70 i@@ -1,18 +0,0 @@ Err bitreich.org 70 i-#ifndef SIGWINCH Err bitreich.org 70 i-#define SIGWINCH 28 Err bitreich.org 70 i-#endif Err bitreich.org 70 i- Err bitreich.org 70 i-#define MARGIN 30 Err bitreich.org 70 i- Err bitreich.org 70 i-#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) Err bitreich.org 70 i- Err bitreich.org 70 i-extern struct winsize ws; Err bitreich.org 70 i-extern char **linev; Err bitreich.org 70 i-extern int linec; Err bitreich.org 70 i-extern char **matchv; Err bitreich.org 70 i-extern int matchc; Err bitreich.org 70 i-extern char *prompt; Err bitreich.org 70 i-extern char input[LINE_MAX]; Err bitreich.org 70 i-extern char formatted[LINE_MAX * 8]; Err bitreich.org 70 i-extern int current; Err bitreich.org 70 i-extern int opt[128]; Err bitreich.org 70 1diff --git a/main.c b/main.c /scm/iomenu/file/main.c.gph bitreich.org 70 i@@ -1,151 +0,0 @@ Err bitreich.org 70 i-#include 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-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-#include "iomenu.h" Err bitreich.org 70 i-#include "main.h" Err bitreich.org 70 i-#include "buffer.h" Err bitreich.org 70 i-#include "control.h" Err bitreich.org 70 i-#include "display.h" Err bitreich.org 70 i- Err bitreich.org 70 i-static struct termios termios; Err bitreich.org 70 i-static int ttyfd; Err bitreich.org 70 i- Err bitreich.org 70 i-struct winsize ws; Err bitreich.org 70 i-char **linev = NULL; Err bitreich.org 70 i-int linec = 0; Err bitreich.org 70 i-char **matchv = NULL; Err bitreich.org 70 i-int matchc = 0; Err bitreich.org 70 i-char *prompt = ""; Err bitreich.org 70 i-char input[LINE_MAX]; Err bitreich.org 70 i-char formatted[LINE_MAX * 8]; Err bitreich.org 70 i-int current = 0; Err bitreich.org 70 i-int opt[128]; Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Free the structures, reset the terminal state and exit with an error message. Err bitreich.org 70 i- */ Err bitreich.org 70 i-void Err bitreich.org 70 i-die(const char *s) Err bitreich.org 70 i-{ Err bitreich.org 70 i- tcsetattr(ttyfd, TCSANOW, &termios); Err bitreich.org 70 i- close(ttyfd); Err bitreich.org 70 i- free_lines(); Err bitreich.org 70 i- perror(s); Err bitreich.org 70 i- exit(EXIT_FAILURE); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Set terminal in raw mode. Err bitreich.org 70 i- */ Err bitreich.org 70 i-static void Err bitreich.org 70 i-set_terminal(void) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct termios new; Err bitreich.org 70 i- Err bitreich.org 70 i- fputs("\x1b[s\x1b[?1049h\x1b[H", stderr); Err bitreich.org 70 i- if (tcgetattr(ttyfd, &termios) < 0 || tcgetattr(ttyfd, &new) < 0) { Err bitreich.org 70 i- perror("tcgetattr"); Err bitreich.org 70 i- exit(EXIT_FAILURE); Err bitreich.org 70 i- } Err bitreich.org 70 i- new.c_lflag &= ~(ICANON | ECHO | IGNBRK | IEXTEN | ISIG); Err bitreich.org 70 i- tcsetattr(ttyfd, TCSANOW, &new); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Take terminal out of raw mode. Err bitreich.org 70 i- */ Err bitreich.org 70 i-static void Err bitreich.org 70 i-reset_terminal(void) Err bitreich.org 70 i-{ Err bitreich.org 70 i- fputs("\x1b[u\033[?1049l", stderr); Err bitreich.org 70 i- tcsetattr(ttyfd, TCSANOW, &termios); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Redraw the whole screen on window resize. Err bitreich.org 70 i- */ Err bitreich.org 70 i-static void Err bitreich.org 70 i-sigwinch() Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern struct winsize ws; Err bitreich.org 70 i- Err bitreich.org 70 i- if (ioctl(ttyfd, TIOCGWINSZ, &ws) < 0) Err bitreich.org 70 i- die("ioctl"); Err bitreich.org 70 i- print_screen(); Err bitreich.org 70 i- signal(SIGWINCH, sigwinch); Err bitreich.org 70 i-} Err bitreich.org 70 i- 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 [-#] [-p prompt]\n", stderr); Err bitreich.org 70 i- exit(EXIT_FAILURE); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * XXX: switch to getopt. Err bitreich.org 70 i- */ Err bitreich.org 70 i-static void Err bitreich.org 70 i-parse_opt(int argc, char *argv[]) Err bitreich.org 70 i-{ Err bitreich.org 70 i- extern char *prompt; Err bitreich.org 70 i- Err bitreich.org 70 i- memset(opt, 0, 128 * sizeof (int)); Err bitreich.org 70 i- for (argv++, argc--; argc > 0; argv++, argc--) { Err bitreich.org 70 i- if (argv[0][0] != '-') Err bitreich.org 70 i- usage(); Err bitreich.org 70 i- switch ((*argv)[1]) { Err bitreich.org 70 i- case 'p': Err bitreich.org 70 i- if (!--argc) Err bitreich.org 70 i- usage(); Err bitreich.org 70 i- prompt = *++argv; Err bitreich.org 70 i- break; Err bitreich.org 70 i- case '#': Err bitreich.org 70 i- opt['#'] = 1; Err bitreich.org 70 i- break; Err bitreich.org 70 i- default: Err bitreich.org 70 i- usage(); 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- * Read stdin in a buffer, filling a table of lines, then re-open stdin to Err bitreich.org 70 i- * /dev/tty for an interactive (raw) session to let the user filter and select Err bitreich.org 70 i- * one line by searching words within stdin. This was inspired from dmenu. Err bitreich.org 70 i- */ 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 char input[LINE_MAX]; Err bitreich.org 70 i- Err bitreich.org 70 i- int exit_code; Err bitreich.org 70 i- Err bitreich.org 70 i- parse_opt(argc, argv); Err bitreich.org 70 i- read_stdin(); Err bitreich.org 70 i- filter(); Err bitreich.org 70 i- if (!freopen("/dev/tty", "r", stdin)) Err bitreich.org 70 i- die("freopen /dev/tty"); Err bitreich.org 70 i- if (!freopen("/dev/tty", "w", stderr)) Err bitreich.org 70 i- die("freopen /dev/tty"); Err bitreich.org 70 i- ttyfd = open("/dev/tty", O_RDWR); Err bitreich.org 70 i- set_terminal(); Err bitreich.org 70 i- sigwinch(); Err bitreich.org 70 i- input[0] = '\0'; Err bitreich.org 70 i- while ((exit_code = key(fgetc(stdin))) > 0) Err bitreich.org 70 i- print_screen(); Err bitreich.org 70 i- print_screen(); Err bitreich.org 70 i- reset_terminal(); Err bitreich.org 70 i- close(ttyfd); Err bitreich.org 70 i- free_lines(); Err bitreich.org 70 i- Err bitreich.org 70 i- return exit_code; Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/main.h b/main.h /scm/iomenu/file/main.h.gph bitreich.org 70 i@@ -1 +0,0 @@ Err bitreich.org 70 i-void die(const char *); Err bitreich.org 70 .