Home
       linux kernel coding style -> BSD - 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 b69d6f5982f4c2b96f8dee1369c48180ed31b035
   DIR parent afbe8d1e4630f1e1ca5f55d8f2a61ef63956494c
  HTML Author: Josuah Demangeon <mail@josuah.net>
       Date:   Thu,  2 Nov 2017 01:09:48 +0100
       
       linux kernel coding style -> BSD
       
       Diffstat:
         M LICENSE                             |      12 +++++-------
         M buffer.c                            |      65 ++++++++++++++++++++++---------
         M buffer.h                            |       6 +++---
         M control.c                           |      35 ++++++++++++++++++++++++-------
         M control.h                           |       8 ++++----
         M display.c                           |      26 +++++++++++++++++++++-----
         M display.h                           |       4 ++--
         M iomenu.h                            |      28 ++++++++++++++--------------
         M main.c                              |      58 ++++++++++++++++++++++---------
         M main.h                              |       2 +-
         M utf8.c                              |       5 +----
         M utf8.h                              |      12 ++++++------
       
       12 files changed, 173 insertions(+), 88 deletions(-)
       ---
   DIR 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.
   DIR 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;
   DIR 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);
   DIR 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;
   DIR 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);
   DIR 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['#']) {
   DIR 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);
   DIR 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];
   DIR 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();
   DIR diff --git a/main.h b/main.h
       @@ -1 +1 @@
       -void die (const char *);
       +void        die(const char *);
   DIR 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>
        
   DIR 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);