(broken) removing further code - iomenu - interactive terminal-based selection menu
(HTM) git clone git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
(DIR) LICENSE
---
(DIR) commit 6a1d1b6950adc20996a8bf22441762e08f1dabb8
(DIR) parent 0a259537342b214215afbeb7625ba86142ba7e8f
(HTM) Author: Josuah Demangeonā ā µ <mail@josuah.net>
Date: Mon, 13 Mar 2017 23:22:53 +0100
(broken) removing further code
Diffstat:
M buffer.c | 66 ++++++++++++++++----------------
M draw.c | 46 ++++++++++++++++----------------
M input.c | 109 +++++++++++++++----------------
M iomenu.c | 43 +++++++++++--------------------
M iomenu.h | 52 +++++++++++++++----------------
5 files changed, 149 insertions(+), 167 deletions(-)
---
(DIR) diff --git a/buffer.c b/buffer.c
@@ -10,7 +10,7 @@
* Fill the buffer apropriately with the lines
*/
Buffer *
-fill_buffer(char *separator)
+fill_buffer(void)
{
/* fill buffer with string */
char s[LINE_SIZE];
@@ -21,48 +21,48 @@ fill_buffer(char *separator)
if (!fp)
die("Can not open file for reading.");
- buffer->input[0] = '\0';
- buffer->total = buffer->matching = 1;
+ input[0] = '\0';
+ total = matching = 1;
/* empty line in case no line come from stdin */
- buffer->first = buffer->current = malloc(sizeof(Line));
- buffer->first->next = buffer->first->prev = NULL;
- buffer->last = NULL;
+ first = buffer[current] = malloc(sizeof(Line));
+ first->next = first->prev = NULL;
+ last = NULL;
/* read the file into a doubly linked list of lines */
- for (l = 1; fgets(s, LINE_SIZE, fp); buffer->total++, l++)
- buffer->last = add_line(buffer, l, s, separator, buffer->last);
+ for (l = 1; fgets(s, LINE_SIZE, fp); total++, l++)
+ last = add_line(l, s, last);
return buffer;
}
/*
- * Add a line to the end of the current buffer.
+ * Add a line to the end of the buffer[current] buffer.
*/
Line *
-add_line(Buffer *buffer, int number, char *s, char *separator, Line *prev)
+add_line( int number, Line *prev)
{
/* allocate new line */
- buffer->last = new_line(s, separator);
- buffer->last->number = number;
- buffer->last->matches = 1; /* matches by default */
- buffer->matching++;
+ last = new_line(s);
+ last->number = number;
+ last->matches = 1; /* matches by default */
+ matching++;
/* interlink with previous line if exists */
if (prev) {
- prev->next = buffer->last;
- buffer->last->prev = prev;
+ prev->next = last;
+ last->prev = prev;
} else {
- buffer->first = buffer->last;
+ first = last;
}
- return buffer->last;
+ return last;
}
Line *
-new_line(char *s, char *separator)
+new_line(char *s)
{
Line *line = malloc(sizeof(Line));
@@ -77,19 +77,19 @@ new_line(char *s, char *separator)
/*
- * Free the buffer, also recursing the doubly linked list.
+ * Free the also recursing the doubly linked list.
*/
void
free_buffer(Buffer *buffer)
{
Line *next = NULL;
- while (buffer->first) {
- next = buffer->first->next;
+ while (first) {
+ next = first->next;
- free(buffer->first);
+ free(first);
- buffer->first = next;
+ first = next;
}
free(buffer);
@@ -98,21 +98,21 @@ free_buffer(Buffer *buffer)
/*
* Set the line->matching state according to the return value of match_line,
- * and buffer->matching to number of matching candidates.
+ * and matching to number of matching candidates.
*
* The incremental parameter sets whether check already matching or
* non-matching lines only. This is for performance concerns.
*/
void
-filter_lines(Buffer *buffer, int inc)
+filter_lines( int inc)
{
- Line *line = buffer->first;
+ Line *line = first;
char **tokv = NULL;
- char *s, buf[sizeof buffer->input];
+ char *s, buf[sizeof input];
size_t n = 0, tokc = 0;
/* tokenize input from space characters, this comes from dmenu */
- strcpy(buf, buffer->input);
+ strcpy(buf, input);
for (s = strtok(buf, " "); s; s = strtok(NULL, " ")) {
if (++tokc > n && !(tokv = realloc(tokv, ++n * sizeof(*tokv))))
die("cannot realloc memory for tokv\n");
@@ -121,14 +121,14 @@ filter_lines(Buffer *buffer, int inc)
}
/* match lines */
- buffer->matching = 0;
+ matching = 0;
while (line) {
- if (buffer->input[0] && !strcmp(buffer->input, line->content)) {
+ if (input[0] && !strcmp(input, line->content)) {
line->matches = 1;
- buffer->current = line;
+ buffer[current] = line;
} else if ((inc && line->matches) || (!inc && !line->matches)) {
line->matches = match_line(line, tokv, tokc);
- buffer->matching += line->matches;
+ matching += line->matches;
}
line = line->next;
(DIR) diff --git a/draw.c b/draw.c
@@ -10,21 +10,21 @@
* Print a line to stderr.
*/
void
-draw_line(Line *line, int current, const int cols, Opt *opt)
+draw_line(Line *line, const int cols)
{
- char output[LINE_SIZE * sizeof(char)] = "\033[K";
+ char output[LINE_SIZE] = "\033[K";
int n = 0;
- if (opt->line_numbers) {
- strcat(output, current ? "\033[1;37m" : "\033[1;30m");
+ if (opt_line_numbers) {
+ strcat(output, buffer[current] ? "\033[1;37m" : "\033[1;30m");
sprintf(output + strlen(output), "%7d\033[m ", line->number);
} else {
- strcat(output, current ? "\033[1;31m > " : " ");
+ strcat(output, buffer[current] ? "\033[1;31m > " : " ");
}
n += 8;
- /* highlight current line */
- if (current)
+ /* highlight buffer[current] line */
+ if (buffer[current])
strcat(output, "\033[1;33m");
/* content */
@@ -48,23 +48,23 @@ draw_line(Line *line, int current, const int cols, Opt *opt)
* The total number oflines printed shall not excess 'count'.
*/
void
-draw_lines(Buffer *buffer, int count, int cols, Opt *opt)
+draw_lines( int count, int cols)
{
- Line *line = buffer->current;
+ Line *line = buffer[current];
int i = 0;
int j = 0;
- /* seek back from current line to the first line to print */
+ /* seek back from buffer[current] line to the first line to print */
while (line && i < count - OFFSET) {
i = line->matches ? i + 1 : i;
line = line->prev;
}
- line = line ? line : buffer->first;
+ line = line ? line : first;
/* print up to count lines that match the input */
while (line && j < count) {
if (line->matches) {
- draw_line(line, line == buffer->current, cols, opt);
+ draw_line(line, line == buffer[current], cols);
j++;
}
@@ -83,7 +83,7 @@ draw_lines(Buffer *buffer, int count, int cols, Opt *opt)
* This also has to clear the previous lines.
*/
void
-draw_screen(Buffer *buffer, int tty_fd, Opt *opt)
+draw_screen( int tty_fd)
{
struct winsize w;
int count;
@@ -91,14 +91,14 @@ draw_screen(Buffer *buffer, int tty_fd, Opt *opt)
if (ioctl(tty_fd, TIOCGWINSZ, &w) < 0)
die("could not get terminal size");
- count = MIN(opt->lines, w.ws_row - 2);
+ count = MIN(opt_lines, w.ws_row - 2);
fputs("\n", stderr);
- draw_lines(buffer, count, w.ws_col, opt);
+ draw_lines(count, w.ws_col);
/* go up to the prompt position and update it */
fprintf(stderr, "\033[%dA", count + 1);
- draw_prompt(buffer, w.ws_col, opt);
+ draw_prompt(w.ws_col);
}
@@ -118,11 +118,11 @@ draw_clear(int lines)
* match.
*/
void
-draw_prompt(Buffer *buffer, int cols, Opt *opt)
+draw_prompt(int cols)
{
size_t i;
- int matching = buffer->matching;
- int total = buffer->total;
+ int matching = matching;
+ int total = total;
/* for the '/' separator between the numbers */
cols--;
@@ -133,12 +133,12 @@ draw_prompt(Buffer *buffer, int cols, Opt *opt)
cols -= !matching ? 1 : 0; /* 0 also has one digit*/
/* actual prompt */
- fprintf(stderr, "\r%-6s\033[K\033[1m>\033[m ", opt->prompt);
- cols -= 2 + MAX(strlen(opt->prompt), 6);
+ fprintf(stderr, "\r%-6s\033[K\033[1m>\033[m ", opt_prompt);
+ cols -= 2 + MAX(strlen(opt_prompt), 6);
/* input without overflowing terminal width */
- for (i = 0; i < strlen(buffer->input) && cols > 0; cols--, i++)
- fputc(buffer->input[i], stderr);
+ for (i = 0; i < strlen(input) && cols > 0; cols--, i++)
+ fputc(input[i], stderr);
/* save the cursor position at the end of the input */
fputs("\033[s", stderr);
(DIR) diff --git a/input.c b/input.c
@@ -11,7 +11,7 @@
* Listen for the user input and call the appropriate functions.
*/
int
-input_get(Buffer *buffer, int tty_fd, Opt *opt)
+input_get(int tty_fd)
{
FILE *tty_fp = fopen("/dev/tty", "r");
int exit_code;
@@ -20,8 +20,8 @@ input_get(Buffer *buffer, int tty_fd, Opt *opt)
struct termios termio_old = set_terminal(tty_fd);
/* get input char by char from the keyboard. */
- while ((exit_code = input_key(tty_fp, buffer, opt)) == CONTINUE)
- draw_screen(buffer, tty_fd, opt);
+ while ((exit_code = input_key(tty_fp)) == CONTINUE)
+ draw_screen(tty_fd);
/* resets the terminal to the previous state. */
tcsetattr(tty_fd, TCSANOW, &termio_old);
@@ -36,61 +36,62 @@ input_get(Buffer *buffer, int tty_fd, Opt *opt)
* Perform action associated with key
*/
int
-input_key(FILE *tty_fp, Buffer *buffer, Opt *opt)
+input_key(FILE *tty_fp)
{
char key = fgetc(tty_fp);
- if (key == opt->validate_key) {
- action_print_selection(buffer, 0, opt);
+ if (key == '\n') {
+ action_print_selection(0);
return EXIT_SUCCESS;
}
switch (key) {
case CONTROL('C'):
- draw_clear(opt->lines);
+ draw_clear(opt_lines);
return EXIT_FAILURE;
case CONTROL('U'):
- buffer->input[0] = '\0';
- buffer->current = buffer->first;
- filter_lines(buffer, 0);
- action_jump(buffer, 1);
- action_jump(buffer, -1);
+ input[0] = '\0';
+ buffer[current] = first;
+ filter_lines(0);
+ action_jump(1);
+ action_jump(-1);
break;
case CONTROL('W'):
action_remove_word_input(buffer);
- filter_lines(buffer, 0);
+ filter_lines(0);
break;
case 127:
case CONTROL('H'): /* backspace */
- buffer->input[strlen(buffer->input) - 1] = '\0';
- filter_lines(buffer, 0);
- action_jump(buffer, 0);
+ input[strlen(input) - 1] = '\0';
+ filter_lines(0);
+ action_jump(0);
break;
case CONTROL('N'):
- action_jump(buffer, 1);
+ action_jump(1);
+ extern char *input;
break;
case CONTROL('P'):
- action_jump(buffer, -1);
+ action_jump(-1);
break;
case CONTROL('I'): /* tab */
- strcpy(buffer->input, buffer->current->content);
- filter_lines(buffer, 1);
+ strcpy(input, buffer[current]->content);
+ filter_lines(1);
break;
case CONTROL('J'):
case CONTROL('M'): /* enter */
- action_print_selection(buffer, 0, opt);
+ action_print_selection(0);
return EXIT_SUCCESS;
case CONTROL('@'): /* ctrl + space */
- action_print_selection(buffer, 1, opt);
+ action_print_selection(1);
return EXIT_SUCCESS;
case CONTROL('['): /* escape */
@@ -100,11 +101,11 @@ input_key(FILE *tty_fp, Buffer *buffer, Opt *opt)
switch (fgetc(tty_fp)) {
case 'A': /* up */
- action_jump(buffer, -1);
+ action_jump(-1);
break;
case 'B': /* Down */
- action_jump(buffer, 1);
+ action_jump(1);
break;
}
break;
@@ -117,11 +118,11 @@ input_key(FILE *tty_fp, Buffer *buffer, Opt *opt)
switch (key) {
case '5': /* page up */
- action_jump(buffer, -10);
+ action_jump(-10);
break;
case '6': /* page down */
- action_jump(buffer, 10);
+ action_jump(10);
break;
}
break;
@@ -131,7 +132,7 @@ input_key(FILE *tty_fp, Buffer *buffer, Opt *opt)
break;
default:
- action_add_character(buffer, key);
+ action_add_character(key);
}
return CONTINUE;
@@ -139,17 +140,17 @@ input_key(FILE *tty_fp, Buffer *buffer, Opt *opt)
/*
- * Set the current line to next/previous/any matching line.
+ * Set the buffer[current] line to next/previous/any matching line.
*/
void
-action_jump(Buffer *buffer, int direction)
+action_jump(int direction)
{
- Line * line = buffer->current;
+ Line * line = buffer[current];
Line * result = line;
- if (direction == 0 && !buffer->current->matches) {
- line = matching_next(buffer->current);
- line = line ? line : matching_prev(buffer->current);
+ if (direction == 0 && !buffer[current]->matches) {
+ line = matching_next(buffer[current]);
+ line = line ? line : matching_prev(buffer[current]);
result = line ? line : result;
}
@@ -163,7 +164,7 @@ action_jump(Buffer *buffer, int direction)
result = line ? line : result;
}
- buffer->current = result;
+ buffer[current] = result;
}
@@ -171,17 +172,17 @@ action_jump(Buffer *buffer, int direction)
* Remove the last word from the buffer's input
*/
void
-action_remove_word_input(Buffer *buffer)
+action_remove_word_input()
{
- size_t length = strlen(buffer->input) - 1;
+ size_t length = strlen(input) - 1;
int i;
- for (i = length; i >= 0 && isspace(buffer->input[i]); i--)
- buffer->input[i] = '\0';
+ for (i = length; i >= 0 && isspace(input[i]); i--)
+ input[i] = '\0';
- length = strlen(buffer->input) - 1;
- for (i = length; i >= 0 && !isspace(buffer->input[i]); i--)
- buffer->input[i] = '\0';
+ length = strlen(input) - 1;
+ for (i = length; i >= 0 && !isspace(input[i]); i--)
+ input[i] = '\0';
}
@@ -189,18 +190,18 @@ action_remove_word_input(Buffer *buffer)
* Add a character to the buffer input and filter lines again.
*/
void
-action_add_character(Buffer *buffer, char key)
+action_add_character(char key)
{
- size_t length = strlen(buffer->input);
+ size_t length = strlen(input);
if (isprint(key)) {
- buffer->input[length] = key;
- buffer->input[length + 1] = '\0';
+ input[length] = key;
+ input[length + 1] = '\0';
}
- filter_lines(buffer, 1);
+ filter_lines(1);
- action_jump(buffer, 0);
+ action_jump(0);
}
@@ -208,20 +209,16 @@ action_add_character(Buffer *buffer, char key)
* Send the selection to stdout.
*/
void
-action_print_selection(Buffer *buffer, int return_input, Opt *opt)
+action_print_selection(int return_input)
{
Line *line = NULL;
fputs("\r\033[K", stderr);
- if (opt->print_number) {
- if (buffer->matching > 0)
- printf("%d\n", buffer->current->number);
+ if (return_input || !matching) {
+ puts(input);
- } else if (return_input || !buffer->matching) {
- puts(buffer->input);
-
- } else if (buffer->matching > 0) {
- puts(buffer->current->content);
+ } else if (matching > 0) {
+ puts(buffer[current]->content);
}
}
(DIR) diff --git a/iomenu.c b/iomenu.c
@@ -1,3 +1,8 @@
+opt_line_numbers = 0;
+opt_print_number = 0;
+opt_lines = 30;
+opt_prompt = "";
+
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
@@ -43,7 +48,7 @@ set_terminal(int tty_fd)
termio_new = termio_old;
termio_new.c_lflag &= ~(ICANON | ECHO | IGNBRK);
- /* apply this state to current terminal now (TCSANOW) */
+ /* apply this state to buffer[current] terminal now (TCSANOW) */
tcsetattr(tty_fd, TCSANOW, &termio_new);
return termio_old;
@@ -53,8 +58,7 @@ set_terminal(int tty_fd)
void
usage(void)
{
- fputs("usage: iomenu [-n] [-N] [-k key] [-s separator] ", stderr);
- fputs("[-p prompt] [-l lines]\n", stderr);
+ fputs("usage: iomenu [-n] [-p prompt] [-l lines]\n", stderr);
exit(EXIT_FAILURE);
}
@@ -67,12 +71,6 @@ main(int argc, char *argv[])
Buffer *buffer = NULL;
Opt *opt = malloc(sizeof(Opt));
- opt->line_numbers = 0;
- opt->print_number = 0;
- opt->validate_key = CONTROL('M');
- opt->separator = NULL;
- opt->lines = 30;
- opt->prompt = "";
/* command line arguments */
for (i = 1; i < argc; i++) {
@@ -81,27 +79,16 @@ main(int argc, char *argv[])
switch (argv[i][1]) {
case 'n':
- opt->line_numbers = 1;
- break;
- case 'N':
- opt->print_number = 1;
- opt->line_numbers = 1;
- break;
- case 'k':
- opt->validate_key = (argv[++i][0] == '^') ?
- CONTROL(toupper(argv[i][1])): argv[i][0];
- break;
- case 's':
- opt->separator = argv[++i];
+ opt_line_numbers = 1;
break;
case 'l':
- if (sscanf(argv[++i], "%d", &opt->lines) <= 0)
+ if (sscanf(argv[++i], "%d", &opt_lines) <= 0)
die("wrong number format after -l");
break;
case 'p':
if (++i >= argc)
- die("wrong string format after -p");
- opt->prompt = argv[i];
+ die("missing string after -p");
+ opt_prompt = argv[i];
break;
default:
usage();
@@ -109,15 +96,15 @@ main(int argc, char *argv[])
}
/* command line arguments */
- buffer = fill_buffer(opt->separator);
+ buffer = fill_buffer();
/* set the interface */
- draw_screen(buffer, tty_fd, opt);
+ draw_screen(tty_fd);
/* listen and interact to input */
- exit_code = input_get(buffer, tty_fd, opt);
+ exit_code = input_get(tty_fd);
- draw_clear(opt->lines);
+ draw_clear(opt_lines);
/* close files descriptors and pointers, and free memory */
close(tty_fd);
(DIR) diff --git a/iomenu.h b/iomenu.h
@@ -8,19 +8,6 @@
/*
- * Options from the command line, to pass to each function that need some
- */
-typedef struct Opt {
- int line_numbers;
- int print_number;
- char validate_key;
- char *separator;
- int lines;
- char *prompt;
-} Opt;
-
-
-/*
* Line coming from stdin
*/
typedef struct Line {
@@ -29,6 +16,17 @@ typedef struct Line {
} Line;
+/* buffer */
+Line *buffer[];
+int current, matching, total;
+Line *first, *last;
+
+/* flags */
+int opt_line_numbers;
+int opt_lines;
+char *opt_prompt, *input;
+
+
/* iomenu */
void die(const char *);
@@ -38,30 +36,30 @@ void usage(void);
/* buffer */
-Buffer * fill_buffer(char *);
-void free_buffer(Buffer *);
-Line * add_line(Buffer *, int, char *, char *, Line *);
+Line ** fill_buffer(char *);
+void free_buffer();
+Line * add_line(int, char *, char *, Line *);
Line * new_line(char *, char *);
Line * matching_next(Line *);
Line * matching_prev(Line *);
int match_line(Line *, char **, size_t);
-void filter_lines(Buffer *, int);
+void filter_lines(int);
/* draw */
-void draw_screen(Buffer *, int, Opt *);
+void draw_screen(int);
void draw_clear(int);
-void draw_line(Line *, int, int, Opt *);
-void draw_lines(Buffer *, int, int, Opt *);
-void draw_prompt(Buffer *, int, Opt *);
+void draw_line(Line *, int);
+void draw_lines(int, int);
+void draw_prompt(int);
/* input */
-int input_get(Buffer *, int, Opt *);
-int input_key(FILE *, Buffer *, Opt *);
-void action_jump(Buffer *, int);
-void action_print_selection(Buffer *,int, Opt *);
-void action_remove_word_input(Buffer *);
-void action_add_character(Buffer *, char);
+int input_get(int);
+int input_key(FILE *);
+void action_jump(int);
+void action_print_selection(int);
+void action_remove_word_input();
+void action_add_character(char);