iconverted buffer.c from linked list to array - 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 9786d2c290cdd4b3a37979155ced24f86f8358f5 /scm/iomenu/commit/9786d2c290cdd4b3a37979155ced24f86f8358f5.gph bitreich.org 70 1parent 6a1d1b6950adc20996a8bf22441762e08f1dabb8 /scm/iomenu/commit/6a1d1b6950adc20996a8bf22441762e08f1dabb8.gph bitreich.org 70 hAuthor: Josuah Demangeonā  ā µ URL:mailto:mail@josuah.net bitreich.org 70 iDate: Wed, 15 Mar 2017 23:02:10 +0100 Err bitreich.org 70 i Err bitreich.org 70 iconverted buffer.c from linked list to array Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M Makefile | 8 +++----- Err bitreich.org 70 i M buffer.c | 136 ++++++++++--------------------- Err bitreich.org 70 i M iomenu.h | 80 +++++++++++++++---------------- Err bitreich.org 70 i Err bitreich.org 70 i3 files changed, 82 insertions(+), 142 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,8 +1,6 @@ Err bitreich.org 70 i-CFLAGS = -std=c89 -pedantic -Wall -Wextra -g -static Err bitreich.org 70 i+CFLAGS = -std=c99 -pedantic -Wall -Wextra -g -static Err bitreich.org 70 i OBJ = ${SRC:.c=.o} Err bitreich.org 70 i Err bitreich.org 70 i-MANPREFIX = $(PREFIX) Err bitreich.org 70 i- Err bitreich.org 70 i all: clean iomenu Err bitreich.org 70 i Err bitreich.org 70 i iomenu: buffer.c draw.c input.c Err bitreich.org 70 i@@ -11,6 +9,6 @@ clean: Err bitreich.org 70 i rm -f iomenu ${OBJ} Err bitreich.org 70 i Err bitreich.org 70 i install: iomenu Err bitreich.org 70 i- mkdir -p $(PREFIX)/bin $(MANPREFIX)/man/man1 Err bitreich.org 70 i- cp *.1 $(MANPREFIX)/man/man1/ Err bitreich.org 70 i+ mkdir -p $(PREFIX)/bin $(PREFIX)/man/man1 Err bitreich.org 70 i+ cp *.1 $(PREFIX)/man/man1/ Err bitreich.org 70 i cp iomenu $(PREFIX)/bin/ Err bitreich.org 70 1diff --git a/buffer.c b/buffer.c /scm/iomenu/file/buffer.c.gph bitreich.org 70 i@@ -9,129 +9,76 @@ Err bitreich.org 70 i /* Err bitreich.org 70 i * Fill the buffer apropriately with the lines Err bitreich.org 70 i */ Err bitreich.org 70 i-Buffer * Err bitreich.org 70 i+void Err bitreich.org 70 i fill_buffer(void) Err bitreich.org 70 i { Err bitreich.org 70 i- /* fill buffer with string */ Err bitreich.org 70 i- char s[LINE_SIZE]; Err bitreich.org 70 i- Line **buffer = malloc(sizeof(Line)); Err bitreich.org 70 i- FILE *fp = stdin; Err bitreich.org 70 i- int l; Err bitreich.org 70 i+ extern Line **buffer; Err bitreich.org 70 i+ Err bitreich.org 70 i+ char s[LINE_SIZE]; Err bitreich.org 70 i+ size_t size = 1; Err bitreich.org 70 i Err bitreich.org 70 i- if (!fp) Err bitreich.org 70 i- die("Can not open file for reading."); Err bitreich.org 70 i+ buffer = malloc(sizeof(Line) * 2 << 4); Err bitreich.org 70 i Err bitreich.org 70 i input[0] = '\0'; Err bitreich.org 70 i total = matching = 1; Err bitreich.org 70 i Err bitreich.org 70 i- /* empty line in case no line come from stdin */ Err bitreich.org 70 i- first = buffer[current] = malloc(sizeof(Line)); Err bitreich.org 70 i- first->next = first->prev = NULL; Err bitreich.org 70 i- last = NULL; Err bitreich.org 70 i- Err bitreich.org 70 i- /* read the file into a doubly linked list of lines */ Err bitreich.org 70 i- for (l = 1; fgets(s, LINE_SIZE, fp); total++, l++) Err bitreich.org 70 i- last = add_line(l, s, last); Err bitreich.org 70 i- Err bitreich.org 70 i- return buffer; Err bitreich.org 70 i-} 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(s, LINE_SIZE, stdin); total++, matching++) { Err bitreich.org 70 i+ if (total > size) { Err bitreich.org 70 i+ size *= 2; Err bitreich.org 70 i+ if (!realloc(buffer, size * sizeof(Line))) Err bitreich.org 70 i+ die("realloc"); Err bitreich.org 70 i+ } Err bitreich.org 70 i Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Add a line to the end of the buffer[current] buffer. Err bitreich.org 70 i- */ Err bitreich.org 70 i-Line * Err bitreich.org 70 i-add_line( int number, Line *prev) Err bitreich.org 70 i-{ Err bitreich.org 70 i- /* allocate new line */ Err bitreich.org 70 i- last = new_line(s); Err bitreich.org 70 i- last->number = number; Err bitreich.org 70 i- last->matches = 1; /* matches by default */ Err bitreich.org 70 i- matching++; Err bitreich.org 70 i- Err bitreich.org 70 i- /* interlink with previous line if exists */ Err bitreich.org 70 i- if (prev) { Err bitreich.org 70 i- prev->next = last; Err bitreich.org 70 i- last->prev = prev; Err bitreich.org 70 i- } else { Err bitreich.org 70 i- first = last; Err bitreich.org 70 i+ buffer[total]->text[strlen(s) - 1] = '\0'; Err bitreich.org 70 i+ buffer[total]->match = 1; /* empty input match everything */ Err bitreich.org 70 i } Err bitreich.org 70 i- Err bitreich.org 70 i- return last; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-Line * Err bitreich.org 70 i-new_line(char *s) Err bitreich.org 70 i-{ Err bitreich.org 70 i- Line *line = malloc(sizeof(Line)); Err bitreich.org 70 i- Err bitreich.org 70 i- /* strip trailing newline */ Err bitreich.org 70 i- s[strlen(s) - 1] = '\0'; Err bitreich.org 70 i- Err bitreich.org 70 i- /* fill line->content */ Err bitreich.org 70 i- line->content = s; Err bitreich.org 70 i- Err bitreich.org 70 i- return line; 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- * Free the also recursing the doubly linked list. Err bitreich.org 70 i- */ Err bitreich.org 70 i void Err bitreich.org 70 i-free_buffer(Buffer *buffer) Err bitreich.org 70 i+free_buffer(Line **buffer) Err bitreich.org 70 i { Err bitreich.org 70 i Line *next = NULL; Err bitreich.org 70 i Err bitreich.org 70 i- while (first) { Err bitreich.org 70 i- next = first->next; Err bitreich.org 70 i- Err bitreich.org 70 i- free(first); Err bitreich.org 70 i- Err bitreich.org 70 i- first = next; Err bitreich.org 70 i- } Err bitreich.org 70 i+ for (; total > 0; total--) Err bitreich.org 70 i+ free(buffer[total - 1]->text); Err bitreich.org 70 i Err bitreich.org 70 i free(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- * Set the line->matching state according to the return value of match_line, Err bitreich.org 70 i- * and matching to number of matching candidates. Err bitreich.org 70 i- * Err bitreich.org 70 i- * The incremental parameter sets whether check already matching or Err bitreich.org 70 i- * non-matching lines only. This is for performance concerns. Err bitreich.org 70 i+ * If inc is 1, it will only check already matching lines. Err bitreich.org 70 i+ * If inc is 0, it will only check non-matching lines. Err bitreich.org 70 i */ Err bitreich.org 70 i void Err bitreich.org 70 i-filter_lines( int inc) Err bitreich.org 70 i+filter_lines(int inc) Err bitreich.org 70 i { Err bitreich.org 70 i- Line *line = first; Err bitreich.org 70 i char **tokv = NULL; Err bitreich.org 70 i- char *s, buf[sizeof input]; Err bitreich.org 70 i+ char *s, buf[sizeof(input)]; Err bitreich.org 70 i size_t n = 0, tokc = 0; Err bitreich.org 70 i Err bitreich.org 70 i /* tokenize input from space characters, this comes from dmenu */ Err bitreich.org 70 i strcpy(buf, input); Err bitreich.org 70 i for (s = strtok(buf, " "); s; s = strtok(NULL, " ")) { Err bitreich.org 70 i if (++tokc > n && !(tokv = realloc(tokv, ++n * sizeof(*tokv)))) Err bitreich.org 70 i- die("cannot realloc memory for tokv\n"); Err bitreich.org 70 i+ die("realloc"); Err bitreich.org 70 i Err bitreich.org 70 i tokv[tokc - 1] = s; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i /* match lines */ Err bitreich.org 70 i matching = 0; Err bitreich.org 70 i- while (line) { Err bitreich.org 70 i- if (input[0] && !strcmp(input, line->content)) { Err bitreich.org 70 i- line->matches = 1; Err bitreich.org 70 i- buffer[current] = line; Err bitreich.org 70 i- } else if ((inc && line->matches) || (!inc && !line->matches)) { Err bitreich.org 70 i- line->matches = match_line(line, tokv, tokc); Err bitreich.org 70 i- matching += line->matches; Err bitreich.org 70 i- } Err bitreich.org 70 i+ for (int i = 0; i < total; i++) { Err bitreich.org 70 i Err bitreich.org 70 i- line = line->next; Err bitreich.org 70 i+ if (input[0] && strcmp(input, buffer[i]->text) == 0) { Err bitreich.org 70 i+ buffer[i]->match = 1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ } else if ((inc && buffer[i]->match) || (!inc && !buffer[i]->match)) { Err bitreich.org 70 i+ buffer[i]->match = match_line(buffer[i], tokv, tokc); Err bitreich.org 70 i+ matching += buffer[i]->match; 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@@ -142,12 +89,11 @@ filter_lines( int inc) Err bitreich.org 70 i int Err bitreich.org 70 i match_line(Line *line, char **tokv, size_t tokc) Err bitreich.org 70 i { Err bitreich.org 70 i- size_t i, match = 1, offset = 0; Err bitreich.org 70 i- Err bitreich.org 70 i- for (i = 0; i < tokc && match; i++) Err bitreich.org 70 i- match = !!strstr(line->content + offset, tokv[i]); Err bitreich.org 70 i+ for (int i = 0; i < tokc; i++) Err bitreich.org 70 i+ if (!!strstr(buffer[i]->text, tokv[i])) Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i Err bitreich.org 70 i- return match; 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@@ -155,10 +101,10 @@ match_line(Line *line, char **tokv, size_t tokc) Err bitreich.org 70 i * Seek the previous matching line, or NULL if none matches. Err bitreich.org 70 i */ Err bitreich.org 70 i Line * Err bitreich.org 70 i-matching_prev(Line *line) Err bitreich.org 70 i+matching_prev(int pos) Err bitreich.org 70 i { Err bitreich.org 70 i- while ((line = line->prev) && !line->matches); Err bitreich.org 70 i- return line; Err bitreich.org 70 i+ for (; pos > 0 && !buffer[pos]->match; pos--); Err bitreich.org 70 i+ return buffer[pos]; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i@@ -166,8 +112,8 @@ matching_prev(Line *line) Err bitreich.org 70 i * Seek the next matching line, or NULL if none matches. Err bitreich.org 70 i */ Err bitreich.org 70 i Line * Err bitreich.org 70 i-matching_next(Line *line) Err bitreich.org 70 i+matching_next(int pos) Err bitreich.org 70 i { Err bitreich.org 70 i- while ((line = line->next) && !line->matches); Err bitreich.org 70 i- return line; Err bitreich.org 70 i+ for (; pos < total && !buffer[pos]->match; pos++); Err bitreich.org 70 i+ return buffer[pos]; 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,65 +1,61 @@ Err bitreich.org 70 i+/*--- constants --------------------------------------------------------------*/ Err bitreich.org 70 i+ Err bitreich.org 70 i #define LINE_SIZE 1024 Err bitreich.org 70 i #define OFFSET 5 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+ Err bitreich.org 70 i+/*--- macros -----------------------------------------------------------------*/ 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 MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Line coming from stdin Err bitreich.org 70 i- */ Err bitreich.org 70 i+/*--- structures -------------------------------------------------------------*/ Err bitreich.org 70 i+ Err bitreich.org 70 i typedef struct Line { Err bitreich.org 70 i- char *content; /* sent as output and matched by input */ Err bitreich.org 70 i- int matches; /* whether it matches buffer's input */ Err bitreich.org 70 i+ char *text; /* sent as output and matched by input */ Err bitreich.org 70 i+ int match; /* whether it matches buffer's input */ Err bitreich.org 70 i } Line; Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-/* buffer */ Err bitreich.org 70 i-Line *buffer[]; Err bitreich.org 70 i-int current, matching, total; Err bitreich.org 70 i-Line *first, *last; Err bitreich.org 70 i- Err bitreich.org 70 i-/* flags */ Err bitreich.org 70 i-int opt_line_numbers; Err bitreich.org 70 i-int opt_lines; Err bitreich.org 70 i-char *opt_prompt, *input; Err bitreich.org 70 i+/*--- variables --------------------------------------------------------------*/ Err bitreich.org 70 i Err bitreich.org 70 i+Line **buffer; Err bitreich.org 70 i+int current, matching, total; Err bitreich.org 70 i+int opt_lines; Err bitreich.org 70 i+char *opt_prompt, *input; Err bitreich.org 70 i Err bitreich.org 70 i-/* iomenu */ Err bitreich.org 70 i Err bitreich.org 70 i-void die(const char *); Err bitreich.org 70 i-struct termios set_terminal(int); Err bitreich.org 70 i-void usage(void); Err bitreich.org 70 i+/*--- functions --------------------------------------------------------------*/ Err bitreich.org 70 i Err bitreich.org 70 i+/* iomenu */ Err bitreich.org 70 i+void die(const char *); Err bitreich.org 70 i+struct termios set_terminal(int); Err bitreich.org 70 i+void usage(void); Err bitreich.org 70 i Err bitreich.org 70 i /* buffer */ Err bitreich.org 70 i- Err bitreich.org 70 i-Line ** fill_buffer(char *); Err bitreich.org 70 i-void free_buffer(); Err bitreich.org 70 i-Line * add_line(int, char *, char *, Line *); Err bitreich.org 70 i-Line * new_line(char *, char *); Err bitreich.org 70 i-Line * matching_next(Line *); Err bitreich.org 70 i-Line * matching_prev(Line *); Err bitreich.org 70 i-int match_line(Line *, char **, size_t); Err bitreich.org 70 i-void filter_lines(int); Err bitreich.org 70 i- Err bitreich.org 70 i+void fill_buffer(void); Err bitreich.org 70 i+void free_buffer(); Err bitreich.org 70 i+Line * add_line(int, char *, char *, Line *); Err bitreich.org 70 i+Line * new_line(char *, char *); Err bitreich.org 70 i+Line * matching_next(int); Err bitreich.org 70 i+Line * matching_prev(int); Err bitreich.org 70 i+int match_line(Line *, char **, size_t); Err bitreich.org 70 i+void filter_lines(int); Err bitreich.org 70 i Err bitreich.org 70 i /* draw */ Err bitreich.org 70 i- Err bitreich.org 70 i-void draw_screen(int); Err bitreich.org 70 i-void draw_clear(int); Err bitreich.org 70 i-void draw_line(Line *, int); Err bitreich.org 70 i-void draw_lines(int, int); Err bitreich.org 70 i-void draw_prompt(int); Err bitreich.org 70 i- Err bitreich.org 70 i+void draw_screen(int); Err bitreich.org 70 i+void draw_clear(int); Err bitreich.org 70 i+void draw_line(Line *, int); Err bitreich.org 70 i+void draw_lines(int, int); Err bitreich.org 70 i+void draw_prompt(int); Err bitreich.org 70 i Err bitreich.org 70 i /* input */ Err bitreich.org 70 i- Err bitreich.org 70 i-int input_get(int); Err bitreich.org 70 i-int input_key(FILE *); Err bitreich.org 70 i-void action_jump(int); Err bitreich.org 70 i-void action_print_selection(int); Err bitreich.org 70 i-void action_remove_word_input(); Err bitreich.org 70 i-void action_add_character(char); Err bitreich.org 70 i+int input_get(int); Err bitreich.org 70 i+int input_key(FILE *); Err bitreich.org 70 i+void action_jump(int); Err bitreich.org 70 i+void action_print_selection(int); Err bitreich.org 70 i+void action_remove_word_input(); Err bitreich.org 70 i+void action_add_character(char); Err bitreich.org 70 .