reading the buffer fast - iomenu - interactive terminal-based selection menu HTML git clone git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu DIR Log DIR Files DIR Refs DIR Tags DIR README DIR LICENSE --- DIR commit 17183e9024bb8a1fa1e2152819ac29a3e82047b4 DIR parent 277ca72956b6deb921cbe96f981214602624c6ac HTML Author: Josuah Demangeon <mail@josuah.net> Date: Wed, 1 Nov 2017 14:42:53 +0100 reading the buffer fast Diffstat: M .gitignore | 1 + M Makefile | 2 +- M buffer.c | 78 +++++++++++++++++-------------- M iomenu.h | 2 -- M main.c | 2 -- 5 files changed, 45 insertions(+), 40 deletions(-) --- DIR diff --git a/.gitignore b/.gitignore @@ -1,2 +1,3 @@ iomenu *.o +*core* DIR diff --git a/Makefile b/Makefile @@ -11,7 +11,7 @@ iomenu: $(OBJ) $(OBJ): $(INC) clean: - rm -f *.o iomenu + rm -f *.o *.core iomenu install: iomenu mkdir -p $(PREFIX)/share/man/man1 DIR diff --git a/buffer.c b/buffer.c @@ -4,31 +4,13 @@ #include <stdlib.h> #include <string.h> #include <limits.h> +#include <unistd.h> #include "iomenu.h" #include "buffer.h" #include "main.h" #include "control.h" -static char * -read_line(FILE *fp) -{ - char *line; - size_t len; - - line = malloc(LINE_MAX + 1); - if (!(fgets(line, LINE_MAX, fp))) { - free(line); - return NULL; - } - - len = strlen(line); - if (len > 0 && line[len - 1] == '\n') - line[len - 1] = '\0'; - - return (line); -} - static int match_line(char *line, char **tokv, int tokc) { @@ -47,8 +29,7 @@ free_lines(void) extern char **linev; if (linev) { - for (; linec > 0; linec--) - free(linev[linec - 1]); + free(linev[0]); free(linev); } if (matchv) @@ -56,24 +37,51 @@ free_lines(void) } void -read_stdin(void) +split_lines(char *buf) { - int size = 0; extern char **linev; + extern int linec; + char *b; + char **lv; + char **mv; - while (1) { - if (linec >= size) { - size += BUFSIZ; - linev = realloc(linev, sizeof (char **) * size); - matchv = realloc(matchv, sizeof (char **) * size); - if (!linev || !matchv) - die("realloc"); - } - if ((linev[linec] = read_line(stdin)) == NULL) - break; + linec = 0; + b = buf; + while ((b = strchr(b + 1, '\n'))) linec++; - matchc++; + if (!(lv = linev = calloc(linec, sizeof (char **)))) + die("calloc"); + if (!(mv = matchv = calloc(linec, sizeof (char **)))) { + free(linev); + die("calloc"); + } + *mv = *lv = b = buf; + while ((b = strchr(b, '\n'))) { + *b++ = '\0'; + mv++, lv++; + *mv = *lv = b; + } +} + +void +read_stdin(void) +{ + size_t size = BUFSIZ; + size_t len; + size_t off; + char *buf; + + off = 0; + buf = malloc(size); + while ((len = read(STDIN_FILENO, buf + off, size - off)) > 0) { + off += len; + if (off > size >> 1) { + size <<= 1; + buf = realloc(buf, size); + } } + buf[off] = '\0'; + split_lines(buf); } void @@ -87,7 +95,7 @@ filter(void) char *s; char buf[sizeof (input)]; - current = offset = next = 0; + current = 0; strcpy(buf, input); tokc = 0; n = 0; DIR diff --git a/iomenu.h b/iomenu.h @@ -15,7 +15,5 @@ extern char *prompt; extern char input[LINE_MAX]; extern char formatted[LINE_MAX * 8]; extern int current; -extern int offset; -extern int next; extern int opt[128]; extern int rows; DIR diff --git a/main.c b/main.c @@ -27,9 +27,7 @@ char *prompt = ""; char input[LINE_MAX]; char formatted[LINE_MAX * 8]; int current = 0; -int offset = 0; int rows = 0; -int next = 0; int opt[128]; void