not using any struct at all - 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 179c4bde0a49ad89278b73ebbea5d4bfa2559605
(DIR) parent a6d7fac8aad60c7581c11762a3d9a519dfb89d38
(HTM) Author: Josuah Demangeonā ā µ <mail@josuah.net>
Date: Sat, 18 Mar 2017 18:33:05 +0100
not using any struct at all
Diffstat:
M iomenu.c | 114 ++++++++++++-------------------
1 file changed, 43 insertions(+), 71 deletions(-)
---
(DIR) diff --git a/iomenu.c b/iomenu.c
@@ -17,26 +17,20 @@
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
-struct line {
- char text[BUFSIZ];
- int match;
-};
-
-
-char input[BUFSIZ];
-size_t current = 0, matching = 0, linec = 0, offset = 0;
-struct line **linev = NULL;
-int opt_lines = 0;
-char *opt_prompt = "";
+char input[BUFSIZ];
+size_t current = 0, matchc = 0, linec = 0, offset = 0;
+char **linev = NULL, **matchv = NULL;
+char *opt_prompt = "";
+int opt_lines = 0;
void
-free_linev(struct line **linev)
+free_v(char **v, size_t c)
{
- for (; linec > 0; linec--)
- free(linev[linec - 1]);
+ for (; c > 0; c--)
+ free(v[c - 1]);
- free(linev);
+ free(v);
}
@@ -73,12 +67,15 @@ read_lines(void)
char buffer[BUFSIZ];
size_t size = 1 << 6;
- if (!(linev = malloc(sizeof(struct line *) * size)))
+ linev = malloc(sizeof (char **) * size);
+ matchv = malloc(sizeof (char **) * size);
+ if (linev == NULL || matchv == NULL)
die("malloc");
- linev[0] = NULL;
+
+ linev[0] = matchv[0] = NULL;
/* read the file into an array of lines */
- for (; fgets(buffer, sizeof buffer, stdin); linec++, matching++) {
+ for (; fgets(buffer, sizeof buffer, stdin); linec++, matchc++) {
size_t len = strlen(buffer);
if (len > 0 && buffer[len - 1] == '\n')
@@ -86,26 +83,26 @@ read_lines(void)
if (linec >= size) {
size *= 2;
- linev = realloc(linev, sizeof(struct line *) * size);
-
- if (linev == NULL)
+ linev = realloc(linev, sizeof (char **) * size);
+ matchv = realloc(matchv, sizeof (char **) * size);
+ if (linev == NULL || matchv == NULL)
die("realloc");
}
- if (!(linev[linec] = malloc(sizeof(struct line))))
+ linev[linec] = matchv[matchc] = malloc(len);
+ if (linev[linec] == NULL)
die("malloc");
- strcpy(linev[linec]->text, buffer);
- linev[linec]->match = 1;
+ strcpy(linev[linec], buffer);
}
}
int
-match_line(struct line *line, char **tokv, size_t tokc)
+match_line(char *line, char **tokv, size_t tokc)
{
for (size_t i = 0; i < tokc; i++)
- if (strstr(line->text, tokv[i]) == NULL)
+ if (strstr(line, tokv[i]) == NULL)
return 0;
return 1;
@@ -115,16 +112,15 @@ match_line(struct line *line, char **tokv, size_t tokc)
void
filter_lines(void)
{
- char **tokv = NULL;
- char *s, buffer[sizeof(input)];
- size_t n = 0, tokc = 0;
+ char **tokv = NULL, *s, buffer[sizeof (input)];
+ size_t tokc = 0, n = 0;
/* tokenize input from space characters, this comes from dmenu */
strcpy(buffer, input);
for (s = strtok(buffer, " "); s; s = strtok(NULL, " "), tokc++) {
if (tokc >= n) {
- tokv = realloc(tokv, ++n * sizeof(*tokv));
+ tokv = realloc(tokv, ++n * sizeof (*tokv));
if (tokv == NULL)
die("realloc");
@@ -133,35 +129,15 @@ filter_lines(void)
tokv[tokc] = s;
}
- matching = 0;
+ matchc = 0;
for (size_t i = 0; i < linec; i++)
- matching += linev[i]->match = match_line(linev[i], tokv, tokc);
+ if (match_line(linev[i], tokv, tokc))
+ matchv[matchc++] = linev[i];
free(tokv);
}
-int
-matching_prev(int pos)
-{
- for (int i = pos - 1; i >= 0; i--)
- if (linev[i]->match)
- return i;
- return pos;
-}
-
-
-int
-matching_next(size_t pos)
-{
- for (size_t i = pos + 1; i < linec; i++)
- if (linev[i]->match)
- return i;
-
- return pos;
-}
-
-
size_t
print_string(char *str, size_t limit, int current)
{
@@ -194,12 +170,9 @@ print_lines(size_t count, size_t cols)
offset = current / count * count;
- for (size_t i = offset; printed < count && i < linec; i++) {
- if (linev[i]->match) {
- fputc('\n', stderr);
- print_string(linev[i]->text, cols, i == current);
- printed++;
- }
+ for (size_t i = offset; i < count && i < matchc; i++) {
+ fputc('\n', stderr);
+ print_string(matchv[i], cols, i == current);
}
while (printed++ < count)
@@ -212,10 +185,8 @@ print_columns(size_t cols)
{
size_t col = 30;
- for (size_t i = offset; col < cols && i < linec; i++) {
- if (linev[i]->match)
- col += print_string(linev[i]->text, cols - col, i == current);
- }
+ for (size_t i = offset; col < cols && i < matchc; i++)
+ col += print_string(matchv[i], cols - col, i == current);
}
@@ -292,7 +263,7 @@ add_character(char key)
filter_lines();
- current = linec == 0 || linev[0]->match ? 0 : matching_next(0);
+ current = 0;
}
@@ -304,8 +275,8 @@ print_selection(void)
{
fputs("\r\033[K", stderr);
- if (matching > 0) {
- puts(linev[current]->text);
+ if (matchc > 0) {
+ puts(matchv[current]);
} else {
puts(input);
}
@@ -341,20 +312,20 @@ input_key(FILE *tty_fp)
case CONTROL('H'): /* backspace */
input[strlen(input) - 1] = '\0';
filter_lines();
- current = linec == 0 || linev[0]->match ? 0 : matching_next(0);
+ current = 0;
break;
case CONTROL('N'):
- current = matching_next(current);
+ current += current <= matchc - 1 ? 1 : 0;
break;
case CONTROL('P'):
- current = matching_prev(current);
+ current -= current > 0 ? 1 : 0;
break;
case CONTROL('I'): /* tab */
if (linec > 0)
- strcpy(input, linev[current]->text);
+ strcpy(input, matchv[current]);
filter_lines();
break;
@@ -435,7 +406,8 @@ main(int argc, char *argv[])
print_clear(opt_lines);
close(tty_fd);
- free_linev(linev);
+ free_v(linev, linec);
+ free(matchv);
return exit_code;
}