commit b69d6f5982f4c2b96f8dee1369c48180ed31b035
parent afbe8d1e4630f1e1ca5f55d8f2a61ef63956494c
Author: Josuah Demangeon <mail@josuah.net>
Date: Thu, 2 Nov 2017 01:09:48 +0100
linux kernel coding style -> BSD
Diffstat:
12 files changed, 173 insertions(+), 88 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -1,15 +1,13 @@
-ISC Licence
+Copyright (c) 2017 Josuah Demangeon <mail@josuah.net>
-Copyright (c) 2017 by Josuah Demangeon
-
-Permission to use, copy, modify, and/or distribute this software for any
+Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
-THE SOFTWARE IS PROVIDED “AS IS” AND ISC DISCLAIMS ALL WARRANTIES
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY
-SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/buffer.c b/buffer.c
@@ -11,6 +11,10 @@
#include "main.h"
#include "control.h"
+/*
+ * Keep the line if it match every token (in no particular order, and allowed to
+ * be overlapping).
+ */
static int
match_line(char *line, char **tokv, int tokc)
{
@@ -22,10 +26,15 @@ match_line(char *line, char **tokv, int tokc)
return 1;
}
+/*
+ * As we use a single buffer for the whole stdin, we only need to free it once
+ * and it will free all the lines.
+ */
void
free_lines(void)
{
- extern char **linev;
+ extern char **linev;
+ extern char **matchv;
if (linev) {
free(linev[0]);
@@ -35,14 +44,20 @@ free_lines(void)
free(matchv);
}
+/*
+ * Split a buffer into an array of lines, without allocating memory for every
+ * line, but using the input buffer and replacing characters.
+ */
void
split_lines(char *buf)
{
- extern char **linev;
- extern int linec;
- char *b;
- char **lv;
- char **mv;
+ extern char **linev;
+ extern char **matchv;
+ extern int linec;
+
+ char *b;
+ char **lv;
+ char **mv;
linec = 0;
b = buf;
@@ -64,15 +79,20 @@ split_lines(char *buf)
}
}
+/*
+ * Read stdin in a single malloc-ed buffer, realloc-ed to twice its size every
+ * time the previous buffer is filled.
+ */
void
read_stdin(void)
{
- size_t size = BUFSIZ;
- size_t len;
- size_t off;
- char *buf;
- char *b;
+ size_t size;
+ size_t len;
+ size_t off;
+ char *buf;
+ char *b;
+ size = BUFSIZ;
off = 0;
buf = malloc(size);
while ((len = read(STDIN_FILENO, buf + off, size - off)) > 0) {
@@ -90,17 +110,26 @@ read_stdin(void)
split_lines(buf);
}
+/*
+ * First split input into token, then match every token independently against
+ * every line. The matching lines fills matchv.
+ */
void
filter(void)
{
- extern char **linev;
- extern int current;
- int tokc;
- int n;
- char **tokv = NULL;
- char *s;
- char buf[sizeof (input)];
+ extern char **linev;
+ extern char **matchv;
+ extern int linec;
+ extern int matchc;
+ extern int current;
+
+ int tokc;
+ int n;
+ char **tokv;
+ char *s;
+ char buf[sizeof (input)];
+ tokv = NULL;
current = 0;
strcpy(buf, input);
tokc = 0;
diff --git a/buffer.h b/buffer.h
@@ -1,3 +1,3 @@
-void free_lines (void);
-void read_stdin (void);
-void filter(void);
+void free_lines(void);
+void read_stdin(void);
+void filter(void);
diff --git a/control.c b/control.c
@@ -11,14 +11,17 @@
#include "control.h"
#include "display.h"
-#define CTL(char) ((char) ^ 0x40)
-#define ALT(char) ((char) + 0x80)
-#define CSI(char) ((char) + 0x80 + 0x80)
+#define CTL(char) ((char) ^ 0x40)
+#define ALT(char) ((char) + 0x80)
+#define CSI(char) ((char) + 0x80 + 0x80)
void
move(signed int sign)
{
- int i;
+ extern char **matchv;
+ extern int matchc;
+
+ int i;
for (i = current + sign; 0 <= i && i < matchc; i += sign) {
if (!opt['#'] || matchv[i][0] != '#') {
@@ -31,9 +34,13 @@ move(signed int sign)
static void
move_page(signed int sign)
{
- int i;
- int rows = ws.ws_row - 1;
+ extern struct winsize ws;
+ extern int matchc;
+
+ int i;
+ int rows;
+ rows = ws.ws_row - 1;
i = current - current % rows + rows * sign;
if (!(0 <= i && i < matchc))
return;
@@ -44,6 +51,8 @@ move_page(signed int sign)
static void
remove_word()
{
+ extern char input[LINE_MAX];
+
int len;
int i;
@@ -59,6 +68,8 @@ remove_word()
static void
add_char(char c)
{
+ extern char input[LINE_MAX];
+
int len;
len = strlen(input);
@@ -69,9 +80,17 @@ add_char(char c)
filter();
}
+/*
+ * Big case table, that calls itself back for with ALT (aka ESC), CSI
+ * (aka ESC + [). These last two have values above the range of ASCII.
+ */
int
key(int k)
{
+ extern char **matchv;
+ extern char input[LINE_MAX];
+ extern int linec;
+
top:
switch (k) {
case CTL('C'):
@@ -99,14 +118,14 @@ top:
case CSI('5'): /* page up */
if (fgetc(stdin) != '~')
break;
- /* fallthrough */
+ /* FALLTHROUGH */
case ALT('v'):
move_page(-1);
break;
case CSI('6'): /* page down */
if (fgetc(stdin) != '~')
break;
- /* fallthrough */
+ /* FALLTHROUGH */
case CTL('V'):
move_page(+1);
break;
diff --git a/control.h b/control.h
@@ -1,4 +1,4 @@
-int prev_page (int);
-int next_page (int);
-void move (signed int);
-int key (int);
+int prev_page(int);
+int next_page(int);
+void move(signed int);
+int key(int);
diff --git a/display.c b/display.c
@@ -11,6 +11,8 @@
static char *
format(char *str, int cols)
{
+ extern struct winsize ws;
+
int col = 0;
long rune = 0;
char *fmt = formatted;
@@ -42,6 +44,8 @@ format(char *str, int cols)
static void
print_line(char *line, int cur)
{
+ extern struct winsize ws;
+
if (opt['#'] && line[0] == '#') {
format(line + 1, ws.ws_col - 1);
fprintf(stderr, "\n\x1b[1m %s\x1b[m", formatted);
@@ -57,12 +61,20 @@ print_line(char *line, int cur)
void
print_screen(void)
{
- char **m;
- int p;
- int i;
- int cols = ws.ws_col - 1;
- int rows = ws.ws_row - 1;
+ extern struct winsize ws;
+ extern char **matchv;
+ extern char *prompt;
+ extern char input[LINE_MAX];
+ extern int matchc;
+ char **m;
+ int p;
+ int i;
+ int cols;
+ int rows;
+
+ cols = ws.ws_col - 1;
+ rows = ws.ws_row - 1;
p = 0;
i = current - current % rows;
m = matchv + i;
@@ -85,6 +97,10 @@ print_screen(void)
void
print_selection(void)
{
+ extern char **matchv;
+ extern char input[LINE_MAX];
+ extern int matchc;
+
char **match;
if (opt['#']) {
diff --git a/display.h b/display.h
@@ -1,2 +1,2 @@
-void print_screen (void);
-void print_selection (void);
+void print_screen(void);
+void print_selection(void);
diff --git a/iomenu.h b/iomenu.h
@@ -1,18 +1,18 @@
-#ifndef SIGWINCH
-#define SIGWINCH 28
+#ifndef SIGWINCH
+#define SIGWINCH 28
#endif
-#define MARGIN 30
+#define MARGIN 30
-#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
-extern struct winsize ws;
-extern char **linev;
-extern int linec;
-extern char **matchv;
-extern int matchc;
-extern char *prompt;
-extern char input[LINE_MAX];
-extern char formatted[LINE_MAX * 8];
-extern int current;
-extern int opt[128];
+extern struct winsize ws;
+extern char **linev;
+extern int linec;
+extern char **matchv;
+extern int matchc;
+extern char *prompt;
+extern char input[LINE_MAX];
+extern char formatted[LINE_MAX * 8];
+extern int current;
+extern int opt[128];
diff --git a/main.c b/main.c
@@ -15,20 +15,23 @@
#include "control.h"
#include "display.h"
-static struct termios termios;
-static int ttyfd;
-
-struct winsize ws;
-char **linev = NULL;
-int linec = 0;
-char **matchv = NULL;
-int matchc = 0;
-char *prompt = "";
-char input[LINE_MAX];
-char formatted[LINE_MAX * 8];
-int current = 0;
-int opt[128];
+static struct termios termios;
+static int ttyfd;
+struct winsize ws;
+char **linev = NULL;
+int linec = 0;
+char **matchv = NULL;
+int matchc = 0;
+char *prompt = "";
+char input[LINE_MAX];
+char formatted[LINE_MAX * 8];
+int current = 0;
+int opt[128];
+
+/*
+ * Free the structures, reset the terminal state and exit with an error message.
+ */
void
die(const char *s)
{
@@ -39,10 +42,13 @@ die(const char *s)
exit(EXIT_FAILURE);
}
+/*
+ * Set terminal in raw mode.
+ */
static void
set_terminal(void)
{
- struct termios new;
+ struct termios new;
fputs("\x1b[s\x1b[?1049h\x1b[H", stderr);
if (tcgetattr(ttyfd, &termios) < 0 || tcgetattr(ttyfd, &new) < 0) {
@@ -53,6 +59,9 @@ set_terminal(void)
tcsetattr(ttyfd, TCSANOW, &new);
}
+/*
+ * Take terminal out of raw mode.
+ */
static void
reset_terminal(void)
{
@@ -60,9 +69,14 @@ reset_terminal(void)
tcsetattr(ttyfd, TCSANOW, &termios);
}
+/*
+ * Redraw the whole screen on window resize.
+ */
static void
sigwinch()
{
+ extern struct winsize ws;
+
if (ioctl(ttyfd, TIOCGWINSZ, &ws) < 0)
die("ioctl");
print_screen();
@@ -72,13 +86,18 @@ sigwinch()
static void
usage(void)
{
- fputs("iomenu [-#] [-p prompt]\n", stderr);
+ fputs("usage: iomenu [-#] [-p prompt]\n", stderr);
exit(EXIT_FAILURE);
}
+/*
+ * XXX: switch to getopt.
+ */
static void
parse_opt(int argc, char *argv[])
{
+ extern char *prompt;
+
memset(opt, 0, 128 * sizeof (int));
for (argv++, argc--; argc > 0; argv++, argc--) {
if (argv[0][0] != '-')
@@ -98,10 +117,17 @@ parse_opt(int argc, char *argv[])
}
}
+/*
+ * Read stdin in a buffer, filling a table of lines, then re-open stdin to
+ * /dev/tty for an interactive (raw) session to let the user filter and select
+ * one line by searching words within stdin. This was inspired from dmenu.
+ */
int
main(int argc, char *argv[])
{
- int exit_code;
+ extern char input[LINE_MAX];
+
+ int exit_code;
parse_opt(argc, argv);
read_stdin();
diff --git a/main.h b/main.h
@@ -1 +1 @@
-void die (const char *);
+void die(const char *);
diff --git a/utf8.c b/utf8.c
@@ -1,7 +1,3 @@
-#include <stddef.h>
-
-#include "utf8.h"
-
/*
* ASCII all have a leading '0' byte:
*
@@ -27,6 +23,7 @@
*/
#include <ctype.h>
+#include <stddef.h>
#include <stdlib.h>
#include <string.h>
diff --git a/utf8.h b/utf8.h
@@ -1,6 +1,6 @@
-size_t utf8_len (char *);
-size_t rune_len (long);
-size_t utf8_to_rune (long *, char *);
-int utf8_is_unicode (long);
-int utf8_check (char *);
-int utf8_is_print (long);
+size_t utf8_len(char *);
+size_t rune_len(long);
+size_t utf8_to_rune(long *, char *);
+int utf8_is_unicode(long);
+int utf8_check(char *);
+int utf8_is_print(long);