SMOLNET PORTAL home about changes
irefactor to pop general-purpose operations out of the main .c file - 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 c9ce7898a2d7b4f171d39b5b8b8f333fe4070c6f	/scm/iomenu/commit/c9ce7898a2d7b4f171d39b5b8b8f333fe4070c6f.gph	bitreich.org	70
1parent 9e523e73c8f395ee7270ed2826efa3f7ffb5908d	/scm/iomenu/commit/9e523e73c8f395ee7270ed2826efa3f7ffb5908d.gph	bitreich.org	70
hAuthor: Josuah Demangeon <me@josuah.net>	URL:mailto:me@josuah.net	bitreich.org	70
iDate:   Wed, 15 Jul 2020 08:35:35 +0200	Err	bitreich.org	70
i	Err	bitreich.org	70
irefactor to pop general-purpose operations out of the main .c file	Err	bitreich.org	70
i	Err	bitreich.org	70
iThis permits to improve quality slightly by isolating the various aspects of	Err	bitreich.org	70
ithe code: buffer handling, terminal setup, logging, utf-8 handling, character	Err	bitreich.org	70
iclasses.	Err	bitreich.org	70
i	Err	bitreich.org	70
iThis permits to fix bugs in all programs at once and have better quality	Err	bitreich.org	70
icodebase buy checking the common code in many different situations.	Err	bitreich.org	70
i	Err	bitreich.org	70
iIf abused, this can lead to too much cognitive (and performance) overhead	Err	bitreich.org	70
ibecause of all the extra structures introduced. So it is important to keep the	Err	bitreich.org	70
ilibrary code just a thin layer over some aspects of stdlib.	Err	bitreich.org	70
i	Err	bitreich.org	70
iDiffstat:	Err	bitreich.org	70
i  M Makefile                            |       6 +++---	Err	bitreich.org	70
i  D bin/io-mblaze                       |      20 --------------------	Err	bitreich.org	70
i  D bin/io-xdg-open                     |      32 -------------------------------	Err	bitreich.org	70
i  R bin/io-find -> bin/iomenu-find      |       0 	Err	bitreich.org	70
i  R bin/io-fstab -> bin/iomenu-fstab    |       0 	Err	bitreich.org	70
i  R bin/io-man -> bin/iomenu-man        |       0 	Err	bitreich.org	70
i  R bin/io-net -> bin/iomenu-net        |       0 	Err	bitreich.org	70
i  R bin/io-passwd -> bin/iomenu-passwd  |       0 	Err	bitreich.org	70
i  R bin/io-ps -> bin/iomenu-ps          |       0 	Err	bitreich.org	70
i  D config.mk                           |       4 ----	Err	bitreich.org	70
i  M iomenu.c                            |     486 ++++++++++++++-----------------	Err	bitreich.org	70
i  M src/compat.h                        |       9 ++++++++-	Err	bitreich.org	70
i  A src/compat/strlcpy.c                |      15 +++++++++++++++	Err	bitreich.org	70
i  M src/log.c                           |      48 +++++++++++++++++++++----------	Err	bitreich.org	70
i  M src/log.h                           |      11 +++++------	Err	bitreich.org	70
i  M src/mem.c                           |      70 ++++++++++++++++++++++----------	Err	bitreich.org	70
i  M src/mem.h                           |      13 +++++++------	Err	bitreich.org	70
i  D src/str.c                           |     119 -------------------------------	Err	bitreich.org	70
i  D src/str.h                           |      26 --------------------------	Err	bitreich.org	70
i  A src/term.c                          |     107 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i  A src/term.h                          |      39 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i  M src/utf8.c                          |     263 ++++++++-----------------------	Err	bitreich.org	70
i  M src/utf8.h                          |      17 ++++++++++-------	Err	bitreich.org	70
i  D src/util.h                          |      12 ------------	Err	bitreich.org	70
i  D t/test.c                            |      22 ----------------------	Err	bitreich.org	70
i	Err	bitreich.org	70
i25 files changed, 565 insertions(+), 754 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,10 +1,10 @@	Err	bitreich.org	70
i NAME = iomenu	Err	bitreich.org	70
i VERSION = 0.1	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-SRC = src/utf8.c src/str.c src/log.c src/mem.c src/compat/strcasestr.c \	Err	bitreich.org	70
i-  src/compat/strsep.c src/compat/wcwidth.c	Err	bitreich.org	70
i+SRC = src/utf8.c src/log.c src/mem.c src/compat/strcasestr.c \	Err	bitreich.org	70
i+  src/compat/strsep.c src/compat/strlcpy.c src/compat/wcwidth.c src/term.c	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-HDR = src/mem.h src/compat.h src/util.h src/str.h src/log.h src/utf8.h	Err	bitreich.org	70
i+HDR = src/mem.h src/compat.h src/log.h src/term.h src/utf8.h	Err	bitreich.org	70
i 	Err	bitreich.org	70
i BIN = iomenu	Err	bitreich.org	70
i 	Err	bitreich.org	70
1diff --git a/bin/io-mblaze b/bin/io-mblaze	/scm/iomenu/file/bin/io-mblaze.gph	bitreich.org	70
i@@ -1,20 +0,0 @@	Err	bitreich.org	70
i-#!/bin/sh -e	Err	bitreich.org	70
i-# mail client using iomenu, mblaze, to be used with mfilter	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-cd "$HOME/mail"	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-if test "$1" = -a	Err	bitreich.org	70
i-then        IFS='        ' read dir mail <<EOF	Err	bitreich.org	70
i-$(iomenu -'#' <index)	Err	bitreich.org	70
i-EOF	Err	bitreich.org	70
i-        mseq -S <$dir/seq >/dev/null	Err	bitreich.org	70
i-        exec mless "$(echo $mail | sed -r 's, *([0-9]+).*,\1,')"	Err	bitreich.org	70
i-fi	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-wc -l */seq | sed 's, 0, .,; s,/seq$,,' |	Err	bitreich.org	70
i-        iomenu | sed -r 's,^ +[^ ]+ +,,' |	Err	bitreich.org	70
i-        xargs printf %s/%s "$(pwd)" | mlist | msort -r -d | mseq -S	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-mscan -f '%6n %u %D  %20f %t%2i%120S' |	Err	bitreich.org	70
i-        iomenu | sed -r 's,^ *([0-9]*) .*,\1,' |	Err	bitreich.org	70
i-        xargs mless	Err	bitreich.org	70
1diff --git a/bin/io-xdg-open b/bin/io-xdg-open	/scm/iomenu/file/bin/io-xdg-open.gph	bitreich.org	70
i@@ -1,32 +0,0 @@	Err	bitreich.org	70
i-#!/bin/sh -e	Err	bitreich.org	70
i-# pick a file to open with xdg-open with iomenu with caching	Err	bitreich.org	70
i-#	Err	bitreich.org	70
i-# The cache is updated when a directory is selected.	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-LC_COLLATE=C	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-touch "$HOME/.cache/find"	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-if        test -f "$HOME/.cache/find" && test $# = 0	Err	bitreich.org	70
i-then        exec "$0" "$HOME"	Err	bitreich.org	70
i-elif        test $# = 0	Err	bitreich.org	70
i-then        exec xdg-open "$(iomenu <$HOME/.cache/find)"	Err	bitreich.org	70
i-fi	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-mkdir -p "$HOME/.cache"	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        find "$1" '(' -name .git -o -name CVS ')' -prune -o \	Err	bitreich.org	70
i-                -type d -exec printf '%s/\n' '{}' + -o \	Err	bitreich.org	70
i-                -type f -exec printf '%s\n' '{}' + | tee "$HOME/.cache/$$" 	Err	bitreich.org	70
i-        grep -vF "$1" $HOME/.cache/find	Err	bitreich.org	70
i-} | sort -o "$HOME/.cache/find"	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-s=$(iomenu <$HOME/.cache/$$)	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-rm "$HOME/.cache/$$"	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-case $s in	Err	bitreich.org	70
i-('')        exit 1 ;;	Err	bitreich.org	70
i-(*/)        exec "$0" "$(cd "$s" && pwd)" ;;	Err	bitreich.org	70
i-(*)        exec xdg-open "$s" ;;	Err	bitreich.org	70
i-esac	Err	bitreich.org	70
1diff --git a/bin/io-find b/bin/iomenu-find	/scm/iomenu/file/bin/iomenu-find.gph	bitreich.org	70
1diff --git a/bin/io-fstab b/bin/iomenu-fstab	/scm/iomenu/file/bin/iomenu-fstab.gph	bitreich.org	70
1diff --git a/bin/io-man b/bin/iomenu-man	/scm/iomenu/file/bin/iomenu-man.gph	bitreich.org	70
1diff --git a/bin/io-net b/bin/iomenu-net	/scm/iomenu/file/bin/iomenu-net.gph	bitreich.org	70
1diff --git a/bin/io-passwd b/bin/iomenu-passwd	/scm/iomenu/file/bin/iomenu-passwd.gph	bitreich.org	70
1diff --git a/bin/io-ps b/bin/iomenu-ps	/scm/iomenu/file/bin/iomenu-ps.gph	bitreich.org	70
1diff --git a/config.mk b/config.mk	/scm/iomenu/file/config.mk.gph	bitreich.org	70
i@@ -1,4 +0,0 @@	Err	bitreich.org	70
i-PREFIX = /usr/local	Err	bitreich.org	70
i-MANPREFIX = ${PREFIX}/man	Err	bitreich.org	70
i-CFLAGS = -std=c89 -pedantic -Wall -Wextra -g -D_POSIX_C_SOURCE=200809L	Err	bitreich.org	70
i-LFLAGS =	Err	bitreich.org	70
1diff --git a/iomenu.c b/iomenu.c	/scm/iomenu/file/iomenu.c.gph	bitreich.org	70
i@@ -1,5 +1,3 @@	Err	bitreich.org	70
i-#include <sys/ioctl.h>	Err	bitreich.org	70
i-	Err	bitreich.org	70
i #include <ctype.h>	Err	bitreich.org	70
i #include <errno.h>	Err	bitreich.org	70
i #include <fcntl.h>	Err	bitreich.org	70
i@@ -9,25 +7,29 @@	Err	bitreich.org	70
i #include <stdio.h>	Err	bitreich.org	70
i #include <stdlib.h>	Err	bitreich.org	70
i #include <string.h>	Err	bitreich.org	70
i+#include <sys/ioctl.h>	Err	bitreich.org	70
i #include <termios.h>	Err	bitreich.org	70
i #include <unistd.h>	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-#include "utf8.h"	Err	bitreich.org	70
i #include "compat.h"	Err	bitreich.org	70
i-#include "util.h"	Err	bitreich.org	70
i #include "log.h"	Err	bitreich.org	70
i+#include "mem.h"	Err	bitreich.org	70
i+#include "term.h"	Err	bitreich.org	70
i+#include "utf8.h"	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-#ifndef SIGWINCH	Err	bitreich.org	70
i-#define SIGWINCH        28	Err	bitreich.org	70
i-#endif	Err	bitreich.org	70
i+struct {	Err	bitreich.org	70
i+        FILE *tty;	Err	bitreich.org	70
i+        char input[LINE_MAX];	Err	bitreich.org	70
i+        size_t cur;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        char **lines_buf;	Err	bitreich.org	70
i+        size_t lines_len;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        char **match_buf;	Err	bitreich.org	70
i+        size_t match_len;	Err	bitreich.org	70
i+} ctx;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-static struct termios termios;	Err	bitreich.org	70
i-struct winsize ws;	Err	bitreich.org	70
i-static int linec = 0, matchc = 0, cur = 0;	Err	bitreich.org	70
i-static char **linev = NULL, **matchv = NULL;	Err	bitreich.org	70
i-static char input[LINE_MAX];	Err	bitreich.org	70
i-static char *flag['z'];	Err	bitreich.org	70
i-char *argv0;	Err	bitreich.org	70
i+int opt_comment;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i /*	Err	bitreich.org	70
i  * Keep the line if it match every token (in no particular order,	Err	bitreich.org	70
i@@ -36,7 +38,7 @@ char *argv0;	Err	bitreich.org	70
i static int	Err	bitreich.org	70
i match_line(char *line, char **tokv)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        if (flag['#'] && line[0] == '#')	Err	bitreich.org	70
i+        if (opt_comment && line[0] == '#')	Err	bitreich.org	70
i                 return 2;	Err	bitreich.org	70
i         for (; *tokv != NULL; tokv++)	Err	bitreich.org	70
i                 if (strcasestr(line, *tokv) == NULL)	Err	bitreich.org	70
i@@ -49,277 +51,203 @@ match_line(char *line, char **tokv)	Err	bitreich.org	70
i  * error message.	Err	bitreich.org	70
i  */	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-iomenu_die(const char *s)	Err	bitreich.org	70
i+goodbye(const char *s)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i         int e = errno;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        if (tcsetattr(STDERR_FILENO, TCSANOW, &termios) == -1)	Err	bitreich.org	70
i-                warn("tcsetattr while dying");	Err	bitreich.org	70
i+        term_raw_off(2);	Err	bitreich.org	70
i         errno = e;	Err	bitreich.org	70
i         die("%s", s);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * Read one key from stdin and die if it failed to prevent to read	Err	bitreich.org	70
i- * in an endless loop.  This caused the load average to go over 10	Err	bitreich.org	70
i- * at work.  :S	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-getkey(void)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        int c;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        if ((c = fgetc(stdin)) == EOF)	Err	bitreich.org	70
i-                iomenu_die("getting a key");	Err	bitreich.org	70
i-        return c;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * Split a buffer into an array of lines, without allocating memory for every	Err	bitreich.org	70
i- * line, but using the input buffer and replacing '\n' by '\0'.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-static void	Err	bitreich.org	70
i-split_lines(char *buf)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        char        *b, **lv, **mv;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        linec = 1;	Err	bitreich.org	70
i-        for (b = buf; (b = strchr(b, '\n')) != NULL && b[1] != '\0'; b++)	Err	bitreich.org	70
i-                linec++;	Err	bitreich.org	70
i-        if ((lv = linev = calloc(linec + 1, sizeof(char **))) == NULL)	Err	bitreich.org	70
i-                iomenu_die("calloc");	Err	bitreich.org	70
i-        if ((mv = matchv = calloc(linec + 1, sizeof(char **))) == NULL)	Err	bitreich.org	70
i-                iomenu_die("calloc");	Err	bitreich.org	70
i-        *mv = *lv = b = buf;	Err	bitreich.org	70
i-        while ((b = strchr(b, '\n')) != NULL) {	Err	bitreich.org	70
i-                *b = '\0';	Err	bitreich.org	70
i-                *++mv = *++lv = ++b;	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- * Read stdin in a single malloc-ed buffer, realloc-ed to twice its size every	Err	bitreich.org	70
i- * time the previous buffer is filled.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-static void	Err	bitreich.org	70
i-read_stdin(void)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        size_t size, len, off;	Err	bitreich.org	70
i-        char *buf;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        size = BUFSIZ;	Err	bitreich.org	70
i-        off = 0;	Err	bitreich.org	70
i-        if ((buf = malloc(size)) == NULL)	Err	bitreich.org	70
i-                iomenu_die("malloc");	Err	bitreich.org	70
i-        while ((len = read(STDIN_FILENO, buf + off, size - off)) > 0) {	Err	bitreich.org	70
i-                off += len;	Err	bitreich.org	70
i-                if (off == size) {	Err	bitreich.org	70
i-                        size *= 2;	Err	bitreich.org	70
i-                        if ((buf = realloc(buf, size + 1)) == NULL)	Err	bitreich.org	70
i-                                iomenu_die("realloc");	Err	bitreich.org	70
i-                }	Err	bitreich.org	70
i-        }	Err	bitreich.org	70
i-        buf[off] = '\0';	Err	bitreich.org	70
i-        split_lines(buf);	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-move(int sign)	Err	bitreich.org	70
i+do_move(int sign)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        int i;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        for (i = cur + sign; 0 <= i && i < matchc; i += sign) {	Err	bitreich.org	70
i-                if (flag['#'] == 0 || matchv[i][0] != '#') {	Err	bitreich.org	70
i-                        cur = i;	Err	bitreich.org	70
i+        /* integer overflow will do what we need */	Err	bitreich.org	70
i+        for (size_t i = ctx.cur + sign; i < ctx.match_len; i += sign) {	Err	bitreich.org	70
i+                if (opt_comment == 0 || ctx.match_buf[i][0] != '#') {	Err	bitreich.org	70
i+                        ctx.cur = i;	Err	bitreich.org	70
i                         break;	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-static void	Err	bitreich.org	70
i-tokenize(char **tokv, char *str)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        while ((*tokv = strsep(&str, " \t")) != NULL) {	Err	bitreich.org	70
i-                if (**tokv != '\0')	Err	bitreich.org	70
i-                        tokv++;	Err	bitreich.org	70
i-        }	Err	bitreich.org	70
i-        *tokv = NULL;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i /*	Err	bitreich.org	70
i  * First split input into token, then match every token independently against	Err	bitreich.org	70
i- * every line.  The matching lines fills matchv.  Matches are searched inside	Err	bitreich.org	70
i+ * every line.  The matching lines fills matches.  Matches are searched inside	Err	bitreich.org	70
i  * of `searchv' of size `searchc'	Err	bitreich.org	70
i  */	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-filter(int searchc, char **searchv)	Err	bitreich.org	70
i+do_filter(char **search_buf, size_t search_len)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        int n;	Err	bitreich.org	70
i-        char *tokv[sizeof(input) * sizeof(char *) + sizeof(NULL)];	Err	bitreich.org	70
i-        char buf[sizeof(input)];	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        strncpy(buf, input, sizeof(input));	Err	bitreich.org	70
i-        buf[sizeof(input) - 1] = '\0';	Err	bitreich.org	70
i-        tokenize(tokv, buf);	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        cur = matchc = 0;	Err	bitreich.org	70
i-        for (n = 0; n < searchc; n++)	Err	bitreich.org	70
i-                if (match_line(searchv[n], tokv))	Err	bitreich.org	70
i-                        matchv[matchc++] = searchv[n];	Err	bitreich.org	70
i-        if (flag['#'] && matchv[cur][0] == '#')	Err	bitreich.org	70
i-                move(+1);	Err	bitreich.org	70
i+        char **t, *tokv[(sizeof ctx.input + 1) * sizeof(char *)];	Err	bitreich.org	70
i+        char *b, buf[sizeof ctx.input];	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        strlcpy(buf, ctx.input, sizeof buf);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        for (b = buf, t = tokv; (*t = strsep(&b, " \t")) != NULL; t++)	Err	bitreich.org	70
i+                continue;	Err	bitreich.org	70
i+        *t = NULL;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        ctx.cur = ctx.match_len = 0;	Err	bitreich.org	70
i+        for (size_t n = 0; n < search_len; n++)	Err	bitreich.org	70
i+                if (match_line(search_buf[n], tokv))	Err	bitreich.org	70
i+                        ctx.match_buf[ctx.match_len++] = search_buf[n];	Err	bitreich.org	70
i+        if (opt_comment && ctx.match_buf[ctx.cur][0] == '#')	Err	bitreich.org	70
i+                do_move(+1);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-move_page(signed int sign)	Err	bitreich.org	70
i+do_move_page(signed int sign)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        int i, rows;	Err	bitreich.org	70
i+        int rows = term.winsize.ws_row - 1;	Err	bitreich.org	70
i+        size_t i = ctx.cur - ctx.cur % rows + rows * sign;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        rows = ws.ws_row - 1;	Err	bitreich.org	70
i-        i = cur - cur % rows + rows * sign;	Err	bitreich.org	70
i-        if (!(0 <= i && i < matchc))	Err	bitreich.org	70
i+        if (i >= ctx.match_len)	Err	bitreich.org	70
i                 return;	Err	bitreich.org	70
i-        cur = i - 1;	Err	bitreich.org	70
i-        move(+1);	Err	bitreich.org	70
i+        ctx.cur = i - 1;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        do_move(+1);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-move_header(signed int sign)	Err	bitreich.org	70
i+do_move_header(signed int sign)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        move(sign);	Err	bitreich.org	70
i-        if (flag['#'] == 0)	Err	bitreich.org	70
i+        do_move(sign);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        if (opt_comment == 0)	Err	bitreich.org	70
i                 return;	Err	bitreich.org	70
i-        for (cur += sign; 0 <= cur; cur += sign) {	Err	bitreich.org	70
i-                if (cur >= matchc) {	Err	bitreich.org	70
i-                        cur--;	Err	bitreich.org	70
i+        for (ctx.cur += sign;; ctx.cur += sign) {	Err	bitreich.org	70
i+                char *cur = ctx.match_buf[ctx.cur];	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                if (ctx.cur >= ctx.match_len) {	Err	bitreich.org	70
i+                        ctx.cur--;	Err	bitreich.org	70
i                         break;	Err	bitreich.org	70
i                 }	Err	bitreich.org	70
i-                if (matchv[cur][0] == '#')	Err	bitreich.org	70
i+                if (cur[0] == '#')	Err	bitreich.org	70
i                         break;	Err	bitreich.org	70
i         }	Err	bitreich.org	70
i-        move(+1);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        do_move(+1);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-remove_word()	Err	bitreich.org	70
i+do_remove_word(void)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i         int len, i;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        len = strlen(input) - 1;	Err	bitreich.org	70
i-        for (i = len; i >= 0 && isspace(input[i]); i--)	Err	bitreich.org	70
i-                input[i] = '\0';	Err	bitreich.org	70
i-        len = strlen(input) - 1;	Err	bitreich.org	70
i-        for (i = len; i >= 0 && !isspace(input[i]); i--)	Err	bitreich.org	70
i-                input[i] = '\0';	Err	bitreich.org	70
i-        filter(linec, linev);	Err	bitreich.org	70
i+        len = strlen(ctx.input) - 1;	Err	bitreich.org	70
i+        for (i = len; i >= 0 && isspace(ctx.input[i]); i--)	Err	bitreich.org	70
i+                ctx.input[i] = '\0';	Err	bitreich.org	70
i+        len = strlen(ctx.input) - 1;	Err	bitreich.org	70
i+        for (i = len; i >= 0 && !isspace(ctx.input[i]); i--)	Err	bitreich.org	70
i+                ctx.input[i] = '\0';	Err	bitreich.org	70
i+        do_filter(ctx.lines_buf, ctx.lines_len);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-add_char(char c)	Err	bitreich.org	70
i+do_add_char(char c)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i         int len;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        len = strlen(input);	Err	bitreich.org	70
i+        len = strlen(ctx.input);	Err	bitreich.org	70
i+        if (len + 1 == sizeof ctx.input)	Err	bitreich.org	70
i+                return;	Err	bitreich.org	70
i         if (isprint(c)) {	Err	bitreich.org	70
i-                input[len]     = c;	Err	bitreich.org	70
i-                input[len + 1] = '\0';	Err	bitreich.org	70
i+                ctx.input[len] = c;	Err	bitreich.org	70
i+                ctx.input[len + 1] = '\0';	Err	bitreich.org	70
i         }	Err	bitreich.org	70
i-        filter(matchc, matchv);	Err	bitreich.org	70
i+        do_filter(ctx.match_buf, ctx.match_len);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-print_selection(void)	Err	bitreich.org	70
i+do_print_selection(void)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        char **match;	Err	bitreich.org	70
i+        if (opt_comment) {	Err	bitreich.org	70
i+                char **match = ctx.match_buf + ctx.cur;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        if (flag['#']) {	Err	bitreich.org	70
i-                match = matchv + cur;	Err	bitreich.org	70
i-                while (--match >= matchv) {	Err	bitreich.org	70
i+                while (--match >= ctx.match_buf) {	Err	bitreich.org	70
i                         if ((*match)[0] == '#') {	Err	bitreich.org	70
i-                                fputs(*match + 1, stdout);	Err	bitreich.org	70
i+                                fprintf(stdout, "%s", *match + 1);	Err	bitreich.org	70
i                                 break;	Err	bitreich.org	70
i                         }	Err	bitreich.org	70
i                 }	Err	bitreich.org	70
i-                putchar('\t');	Err	bitreich.org	70
i+                fprintf(stdout, "%c", '\t');	Err	bitreich.org	70
i         }	Err	bitreich.org	70
i-        if (matchc == 0 || (flag['#'] && matchv[cur][0] == '#'))	Err	bitreich.org	70
i-                puts(input);	Err	bitreich.org	70
i+        term_raw_off(2);	Err	bitreich.org	70
i+        if (ctx.match_len == 0	Err	bitreich.org	70
i+          || (opt_comment && ctx.match_buf[ctx.cur][0] == '#'))	Err	bitreich.org	70
i+                fprintf(stdout, "%s\n", ctx.input);	Err	bitreich.org	70
i         else	Err	bitreich.org	70
i-                puts(matchv[cur]);	Err	bitreich.org	70
i+                fprintf(stdout, "%s\n", ctx.match_buf[ctx.cur]);	Err	bitreich.org	70
i+        term_raw_on(2);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i /*	Err	bitreich.org	70
i- * Big case table, that calls itself back for with ALT (aka Esc), CSI	Err	bitreich.org	70
i+ * Big case table, that calls itself back for with TERM_KEY_ALT (aka Esc), TERM_KEY_CSI	Err	bitreich.org	70
i  * (aka Esc + [).  These last two have values above the range of ASCII.	Err	bitreich.org	70
i  */	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-key(void)	Err	bitreich.org	70
i+static int	Err	bitreich.org	70
i+key_action(void)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        int k;	Err	bitreich.org	70
i-        k = getkey();	Err	bitreich.org	70
i-top:	Err	bitreich.org	70
i-        switch (k) {	Err	bitreich.org	70
i-        case CTL('C'):	Err	bitreich.org	70
i+        int key;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        key = term_get_key(stderr);	Err	bitreich.org	70
i+        switch (key) {	Err	bitreich.org	70
i+        case TERM_KEY_CTRL('Z'):	Err	bitreich.org	70
i+                term_raw_off(2);	Err	bitreich.org	70
i+                kill(getpid(), SIGSTOP);	Err	bitreich.org	70
i+                term_raw_on(2);	Err	bitreich.org	70
i+                break;	Err	bitreich.org	70
i+        case TERM_KEY_CTRL('C'):	Err	bitreich.org	70
i+        case TERM_KEY_CTRL('D'):	Err	bitreich.org	70
i                 return -1;	Err	bitreich.org	70
i-        case CTL('U'):	Err	bitreich.org	70
i-                input[0] = '\0';	Err	bitreich.org	70
i-                filter(linec, linev);	Err	bitreich.org	70
i+        case TERM_KEY_CTRL('U'):	Err	bitreich.org	70
i+                ctx.input[0] = '\0';	Err	bitreich.org	70
i+                do_filter(ctx.lines_buf, ctx.lines_len);	Err	bitreich.org	70
i                 break;	Err	bitreich.org	70
i-        case CTL('W'):	Err	bitreich.org	70
i-                remove_word();	Err	bitreich.org	70
i+        case TERM_KEY_CTRL('W'):	Err	bitreich.org	70
i+                do_remove_word();	Err	bitreich.org	70
i                 break;	Err	bitreich.org	70
i-        case 127:	Err	bitreich.org	70
i-        case CTL('H'): /* backspace */	Err	bitreich.org	70
i-                input[strlen(input) - 1] = '\0';	Err	bitreich.org	70
i-                filter(linec, linev);	Err	bitreich.org	70
i+        case TERM_KEY_DELETE:	Err	bitreich.org	70
i+        case TERM_KEY_BACKSPACE:	Err	bitreich.org	70
i+                ctx.input[strlen(ctx.input) - 1] = '\0';	Err	bitreich.org	70
i+                do_filter(ctx.lines_buf, ctx.lines_len);	Err	bitreich.org	70
i                 break;	Err	bitreich.org	70
i-        case CSI('A'): /* up */	Err	bitreich.org	70
i-        case CTL('P'):	Err	bitreich.org	70
i-                move(-1);	Err	bitreich.org	70
i+        case TERM_KEY_ARROW_UP:	Err	bitreich.org	70
i+        case TERM_KEY_CTRL('P'):	Err	bitreich.org	70
i+                do_move(-1);	Err	bitreich.org	70
i                 break;	Err	bitreich.org	70
i-        case ALT('p'):	Err	bitreich.org	70
i-                move_header(-1);	Err	bitreich.org	70
i+        case TERM_KEY_ALT('p'):	Err	bitreich.org	70
i+                do_move_header(-1);	Err	bitreich.org	70
i                 break;	Err	bitreich.org	70
i-        case CSI('B'): /* down */	Err	bitreich.org	70
i-        case CTL('N'):	Err	bitreich.org	70
i-                move(+1);	Err	bitreich.org	70
i+        case TERM_KEY_ARROW_DOWN:	Err	bitreich.org	70
i+        case TERM_KEY_CTRL('N'):	Err	bitreich.org	70
i+                do_move(+1);	Err	bitreich.org	70
i                 break;	Err	bitreich.org	70
i-        case ALT('n'):	Err	bitreich.org	70
i-                move_header(+1);	Err	bitreich.org	70
i+        case TERM_KEY_ALT('n'):	Err	bitreich.org	70
i+                do_move_header(+1);	Err	bitreich.org	70
i                 break;	Err	bitreich.org	70
i-        case CSI('5'): /* page up */	Err	bitreich.org	70
i-                if (getkey() != '~')	Err	bitreich.org	70
i-                        break;	Err	bitreich.org	70
i-                /* FALLTHROUGH */	Err	bitreich.org	70
i-        case ALT('v'):	Err	bitreich.org	70
i-                move_page(-1);	Err	bitreich.org	70
i+        case TERM_KEY_PAGE_UP:	Err	bitreich.org	70
i+        case TERM_KEY_ALT('v'):	Err	bitreich.org	70
i+                do_move_page(-1);	Err	bitreich.org	70
i                 break;	Err	bitreich.org	70
i-        case CSI('6'): /* page down */	Err	bitreich.org	70
i-                if (getkey() != '~')	Err	bitreich.org	70
i-                        break;	Err	bitreich.org	70
i-                /* FALLTHROUGH */	Err	bitreich.org	70
i-        case CTL('V'):	Err	bitreich.org	70
i-                move_page(+1);	Err	bitreich.org	70
i+        case TERM_KEY_PAGE_DOWN:	Err	bitreich.org	70
i+        case TERM_KEY_CTRL('V'):	Err	bitreich.org	70
i+                do_move_page(+1);	Err	bitreich.org	70
i                 break;	Err	bitreich.org	70
i-        case CTL('I'): /* tab */	Err	bitreich.org	70
i-                if (linec > 0) {	Err	bitreich.org	70
i-                        strncpy(input, matchv[cur], sizeof(input));	Err	bitreich.org	70
i-                        input[sizeof(input) - 1] = '\0';	Err	bitreich.org	70
i-                }	Err	bitreich.org	70
i-                filter(matchc, matchv);	Err	bitreich.org	70
i+        case TERM_KEY_TAB:	Err	bitreich.org	70
i+                if (ctx.match_len == 0)	Err	bitreich.org	70
i+                        break;	Err	bitreich.org	70
i+                strlcpy(ctx.input, ctx.match_buf[ctx.cur], sizeof(ctx.input));	Err	bitreich.org	70
i+                do_filter(ctx.match_buf, ctx.match_len);	Err	bitreich.org	70
i                 break;	Err	bitreich.org	70
i-        case CTL('J'):/* enter */	Err	bitreich.org	70
i-        case CTL('M'):	Err	bitreich.org	70
i-                print_selection();	Err	bitreich.org	70
i+        case TERM_KEY_ENTER:	Err	bitreich.org	70
i+        case TERM_KEY_CTRL('M'):	Err	bitreich.org	70
i+                do_print_selection();	Err	bitreich.org	70
i                 return 0;	Err	bitreich.org	70
i-        case ALT('['):	Err	bitreich.org	70
i-                k = CSI(getkey());	Err	bitreich.org	70
i-                goto top;	Err	bitreich.org	70
i-        case ESC:	Err	bitreich.org	70
i-                k = ALT(getkey());	Err	bitreich.org	70
i-                goto top;	Err	bitreich.org	70
i         default:	Err	bitreich.org	70
i-                add_char((char) k);	Err	bitreich.org	70
i+                do_add_char(key);	Err	bitreich.org	70
i         }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i         return 1;	Err	bitreich.org	70
i@@ -328,80 +256,93 @@ top:	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i print_line(char *line, int highlight)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        if (flag['#'] && line[0] == '#')	Err	bitreich.org	70
i+        if (opt_comment && line[0] == '#') {	Err	bitreich.org	70
i                 fprintf(stderr, "\n\x1b[1m\r%.*s\x1b[m",	Err	bitreich.org	70
i-                    utf8_col(line + 1, ws.ws_col, 0), line + 1);	Err	bitreich.org	70
i-        else if (highlight)	Err	bitreich.org	70
i+                  term_at_width(line + 1, term.winsize.ws_col, 0), line + 1);	Err	bitreich.org	70
i+        } else if (highlight) {	Err	bitreich.org	70
i                 fprintf(stderr, "\n\x1b[47;30m\x1b[K\r%.*s\x1b[m",	Err	bitreich.org	70
i-                    utf8_col(line, ws.ws_col, 0), line);	Err	bitreich.org	70
i-        else	Err	bitreich.org	70
i+                  term_at_width(line, term.winsize.ws_col, 0), line);	Err	bitreich.org	70
i+        } else {	Err	bitreich.org	70
i                 fprintf(stderr, "\n%.*s",	Err	bitreich.org	70
i-                    utf8_col(line, ws.ws_col, 0), line);	Err	bitreich.org	70
i+                  term_at_width(line, term.winsize.ws_col, 0), line);	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-print_screen(void)	Err	bitreich.org	70
i+do_print_screen(void)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i         char **m;	Err	bitreich.org	70
i-        int p, i, c, cols, rows;	Err	bitreich.org	70
i+        int p, c, cols, rows;	Err	bitreich.org	70
i+        size_t i;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        cols = ws.ws_col;	Err	bitreich.org	70
i-        rows = ws.ws_row - 1; /* -1 to keep one line for user input */	Err	bitreich.org	70
i+        cols = term.winsize.ws_col;	Err	bitreich.org	70
i+        rows = term.winsize.ws_row - 1; /* -1 to keep one line for user input */	Err	bitreich.org	70
i         p = c = 0;	Err	bitreich.org	70
i-        i = cur - cur % rows;	Err	bitreich.org	70
i-        m = matchv + i;	Err	bitreich.org	70
i-        fputs("\x1b[2J", stderr);	Err	bitreich.org	70
i-        while (p < rows && i < matchc) {	Err	bitreich.org	70
i-                print_line(*m, i == cur);	Err	bitreich.org	70
i+        i = ctx.cur - ctx.cur % rows;	Err	bitreich.org	70
i+        m = ctx.match_buf + i;	Err	bitreich.org	70
i+        fprintf(stderr, "\x1b[2J");	Err	bitreich.org	70
i+        while (p < rows && i < ctx.match_len) {	Err	bitreich.org	70
i+                print_line(*m, i == ctx.cur);	Err	bitreich.org	70
i                 p++, i++, m++;	Err	bitreich.org	70
i         }	Err	bitreich.org	70
i-        fputs("\x1b[H", stderr);	Err	bitreich.org	70
i-        fprintf(stderr, "%.*s", utf8_col(input, cols, c), input);	Err	bitreich.org	70
i+        fprintf(stderr, "\x1b[H%.*s",	Err	bitreich.org	70
i+          term_at_width(ctx.input, cols, c), ctx.input);	Err	bitreich.org	70
i         fflush(stderr);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * Set terminal to raw mode.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-term_set(void)	Err	bitreich.org	70
i+sig_winch(int sig)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        struct termios new;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        fputs("\x1b[s\x1b[?1049h\x1b[H", stderr);	Err	bitreich.org	70
i-        if (tcgetattr(STDERR_FILENO, &termios) == -1 ||	Err	bitreich.org	70
i-            tcgetattr(STDERR_FILENO, &new) == -1)	Err	bitreich.org	70
i-                iomenu_die("setting terminal");	Err	bitreich.org	70
i-        new.c_lflag &= ~(ICANON | ECHO | IEXTEN | IGNBRK | ISIG);	Err	bitreich.org	70
i-        if (tcsetattr(STDERR_FILENO, TCSANOW, &new) == -1)	Err	bitreich.org	70
i-                iomenu_die("tcsetattr");	Err	bitreich.org	70
i+        if (ioctl(STDERR_FILENO, TIOCGWINSZ, &term.winsize) == -1)	Err	bitreich.org	70
i+                goodbye("ioctl");	Err	bitreich.org	70
i+        do_print_screen();	Err	bitreich.org	70
i+        signal(sig, sig_winch);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * Take terminal out of raw mode.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-term_reset(void)	Err	bitreich.org	70
i+usage(char const *arg0)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        fputs("\x1b[2J\x1b[u\033[?1049l", stderr);	Err	bitreich.org	70
i-        if (tcsetattr(STDERR_FILENO, TCSANOW, &termios))	Err	bitreich.org	70
i-                iomenu_die("resetting terminal");	Err	bitreich.org	70
i+        fprintf(stderr, "usage: %s [-#] <lines\n", arg0);	Err	bitreich.org	70
i+        exit(1);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-sigwinch(int sig)	Err	bitreich.org	70
i+read_stdin(char **buf, struct mem_pool *pool)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1)	Err	bitreich.org	70
i-                iomenu_die("ioctl");	Err	bitreich.org	70
i-        print_screen();	Err	bitreich.org	70
i-        signal(sig, sigwinch);	Err	bitreich.org	70
i+        if (mem_read((void **)buf, pool) < 0)	Err	bitreich.org	70
i+                goodbye("reading standard input");	Err	bitreich.org	70
i+        if (memchr(*buf, '\0', mem_length(*buf)) != NULL)	Err	bitreich.org	70
i+                goodbye("'\\0' byte in input");	Err	bitreich.org	70
i+        if (mem_append((void **)buf, "", 1) < 0)	Err	bitreich.org	70
i+                goodbye("adding '\\0' terminator");	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i+/*	Err	bitreich.org	70
i+ * Split a buffer into an array of lines, without allocating memory for every	Err	bitreich.org	70
i+ * line, but using the input buffer and replacing '\n' by '\0'.	Err	bitreich.org	70
i+ */	Err	bitreich.org	70
i static void	Err	bitreich.org	70
i-usage(char const *arg0)	Err	bitreich.org	70
i+split_lines(char *s, struct mem_pool *pool)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        fprintf(stderr, "usage: %s [-#]\n", arg0);	Err	bitreich.org	70
i-        exit(1);	Err	bitreich.org	70
i+        ctx.lines_buf = mem_alloc(pool, 0);	Err	bitreich.org	70
i+        if (ctx.lines_buf == NULL)	Err	bitreich.org	70
i+                goodbye("initializing full lines buffer");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        ctx.lines_len = 0;	Err	bitreich.org	70
i+        for (;;) {	Err	bitreich.org	70
i+                if (mem_append((void **)&ctx.lines_buf, &s, sizeof s) < 0)	Err	bitreich.org	70
i+                        goodbye("adding line to array");	Err	bitreich.org	70
i+                ctx.lines_len++;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                s = strchr(s, '\n');	Err	bitreich.org	70
i+                if (s == NULL)	Err	bitreich.org	70
i+                        break;	Err	bitreich.org	70
i+                *s++ = '\0';	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        ctx.match_buf = mem_alloc(pool, mem_length(ctx.lines_buf));	Err	bitreich.org	70
i+        if (ctx.match_buf == NULL)	Err	bitreich.org	70
i+                goodbye("initializing matching lines buffer");	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i /*	Err	bitreich.org	70
i@@ -412,32 +353,49 @@ usage(char const *arg0)	Err	bitreich.org	70
i int	Err	bitreich.org	70
i main(int argc, char *argv[])	Err	bitreich.org	70
i {	Err	bitreich.org	70
i+        struct mem_pool pool = {0};	Err	bitreich.org	70
i+        char *buf;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i         arg0 = *argv;	Err	bitreich.org	70
i-        for (int c; (c = getopt(argc, argv, "#")) > 0; flag[c] = optarg)	Err	bitreich.org	70
i-                if (c == '?')	Err	bitreich.org	70
i+        for (int opt; (opt = getopt(argc, argv, "#v")) > 0;) {	Err	bitreich.org	70
i+                switch (opt) {	Err	bitreich.org	70
i+                case 'v':	Err	bitreich.org	70
i+                        fprintf(stdout, "%s\n", VERSION);	Err	bitreich.org	70
i+                        exit(0);	Err	bitreich.org	70
i+                case '#':	Err	bitreich.org	70
i+                        opt_comment = 1;	Err	bitreich.org	70
i+                        break;	Err	bitreich.org	70
i+                default:	Err	bitreich.org	70
i                         usage(arg0);	Err	bitreich.org	70
i+                }	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i         argc -= optind;	Err	bitreich.org	70
i         argv += optind;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        input[0] = '\0';	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        read_stdin();	Err	bitreich.org	70
i+        read_stdin(&buf, &pool);	Err	bitreich.org	70
i+        split_lines(buf, &pool);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        filter(linec, linev);	Err	bitreich.org	70
i+        do_filter(ctx.lines_buf, ctx.lines_len);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i         if (!isatty(2))	Err	bitreich.org	70
i-                iomenu_die("file descriptor 2 (stderr)");	Err	bitreich.org	70
i+                goodbye("file descriptor 2 (stderr)");	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        term_set();	Err	bitreich.org	70
i-        sigwinch(SIGWINCH);	Err	bitreich.org	70
i+        freopen("/dev/tty", "w+", stderr);	Err	bitreich.org	70
i+        if (stderr == NULL)	Err	bitreich.org	70
i+                goodbye("re-opening standard error read/write");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        term_raw_on(2);	Err	bitreich.org	70
i+        sig_winch(SIGWINCH);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i #ifdef __OpenBSD__	Err	bitreich.org	70
i         pledge("stdio tty", NULL);	Err	bitreich.org	70
i #endif	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        while (key() > 0)	Err	bitreich.org	70
i-                print_screen();	Err	bitreich.org	70
i-        term_reset();	Err	bitreich.org	70
i+        while (key_action() > 0)	Err	bitreich.org	70
i+                do_print_screen();	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        term_raw_off(2);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i+        mem_free(&pool);	Err	bitreich.org	70
i         return 0;	Err	bitreich.org	70
i }	Err	bitreich.org	70
1diff --git a/src/compat.h b/src/compat.h	/scm/iomenu/file/src/compat.h.gph	bitreich.org	70
i@@ -1,11 +1,18 @@	Err	bitreich.org	70
i #ifndef COMPAT_H	Err	bitreich.org	70
i #define COMPAT_H	Err	bitreich.org	70
i 	Err	bitreich.org	70
i+#include <stddef.h>	Err	bitreich.org	70
i+#include <wchar.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i #define wcwidth(c) mk_wcwidth_cjk(c)	Err	bitreich.org	70
i-#define wcswidth(s, n) mk_wcwidth_cjk(s, n)	Err	bitreich.org	70
i 	Err	bitreich.org	70
i /** src/compat/?*.c **/	Err	bitreich.org	70
i char * strcasestr(const char *str1, const char *str2);	Err	bitreich.org	70
i+size_t strlcpy(char *buf, char const *str, size_t sz);	Err	bitreich.org	70
i char * strsep(char **str_p, char const *sep);	Err	bitreich.org	70
i+int mk_wcwidth(wchar_t ucs);	Err	bitreich.org	70
i+int mk_wcswidth(const wchar_t *pwcs, size_t n);	Err	bitreich.org	70
i+int mk_wcwidth_cjk(wchar_t ucs);	Err	bitreich.org	70
i+int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i #endif	Err	bitreich.org	70
1diff --git a/src/compat/strlcpy.c b/src/compat/strlcpy.c	/scm/iomenu/file/src/compat/strlcpy.c.gph	bitreich.org	70
i@@ -0,0 +1,15 @@	Err	bitreich.org	70
i+#include "compat.h"	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <string.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+size_t	Err	bitreich.org	70
i+strlcpy(char *buf, char const *str, size_t sz)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        size_t len, cpy;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        len = strlen(str);	Err	bitreich.org	70
i+        cpy = (len > sz) ? (sz) : (len);	Err	bitreich.org	70
i+        memcpy(buf, str, cpy + 1);	Err	bitreich.org	70
i+        buf[sz - 1] = '\0';	Err	bitreich.org	70
i+        return len;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
1diff --git a/src/log.c b/src/log.c	/scm/iomenu/file/src/log.c.gph	bitreich.org	70
i@@ -1,34 +1,24 @@	Err	bitreich.org	70
i #include "log.h"	Err	bitreich.org	70
i 	Err	bitreich.org	70
i #include <assert.h>	Err	bitreich.org	70
i-#include <string.h>	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * log.c - log to standard error according to the log level	Err	bitreich.org	70
i- *	Err	bitreich.org	70
i- * Instead of logging to syslog, delegate logging to a separate	Err	bitreich.org	70
i- * tool, such as FreeBSD's daemon(8), POSIX's logger(1).	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-	Err	bitreich.org	70
i #include <errno.h>	Err	bitreich.org	70
i #include <stdio.h>	Err	bitreich.org	70
i #include <stdlib.h>	Err	bitreich.org	70
i+#include <string.h>	Err	bitreich.org	70
i 	Err	bitreich.org	70
i+#ifndef LOG_DEFAULT	Err	bitreich.org	70
i #define LOG_DEFAULT 3 /* info */	Err	bitreich.org	70
i+#endif	Err	bitreich.org	70
i 	Err	bitreich.org	70
i char *arg0 = NULL;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i static int log_level = -1;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i void	Err	bitreich.org	70
i-log_print(int level, char const *flag, char const *fmt, ...)	Err	bitreich.org	70
i+log_vprintf(int level, char const *flag, char const *fmt, va_list va)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        va_list va;	Err	bitreich.org	70
i         char *env;	Err	bitreich.org	70
i         int old_errno = errno;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        va_start(va, fmt);	Err	bitreich.org	70
i-	Err	bitreich.org	70
i         if (log_level < 0) {	Err	bitreich.org	70
i                 env = getenv("LOG");	Err	bitreich.org	70
i                 log_level = (env == NULL) ? 0 : atoi(env);	Err	bitreich.org	70
i@@ -50,5 +40,33 @@ log_print(int level, char const *flag, char const *fmt, ...)	Err	bitreich.org	70
i 	Err	bitreich.org	70
i         fprintf(stderr, "\n");	Err	bitreich.org	70
i         fflush(stderr);	Err	bitreich.org	70
i-        va_end(va);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void	Err	bitreich.org	70
i+die(char const *fmt, ...)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        va_list va;	Err	bitreich.org	70
i+        va_start(va, fmt); log_vprintf(1, "error", fmt, va); va_end(va);	Err	bitreich.org	70
i+        exit(1);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void	Err	bitreich.org	70
i+warn(char const *fmt, ...)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        va_list va;	Err	bitreich.org	70
i+        va_start(va, fmt); log_vprintf(2, "warn", fmt, va); va_end(va);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void	Err	bitreich.org	70
i+info(char const *fmt, ...)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        va_list va;	Err	bitreich.org	70
i+        va_start(va, fmt); log_vprintf(3, "info", fmt, va); va_end(va);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void	Err	bitreich.org	70
i+debug(char const *fmt, ...)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        va_list va;	Err	bitreich.org	70
i+        va_start(va, fmt); log_vprintf(4, "debug", fmt, va); va_end(va);	Err	bitreich.org	70
i }	Err	bitreich.org	70
1diff --git a/src/log.h b/src/log.h	/scm/iomenu/file/src/log.h.gph	bitreich.org	70
i@@ -5,11 +5,10 @@	Err	bitreich.org	70
i 	Err	bitreich.org	70
i /** src/log.c **/	Err	bitreich.org	70
i char *arg0;	Err	bitreich.org	70
i-void log_print(int level, char const *flag, char const *fmt, ...);	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-#define die(...) (log_print(1, "error", __VA_ARGS__), exit(1))	Err	bitreich.org	70
i-#define warn(...) log_print(2, "warn", __VA_ARGS__)	Err	bitreich.org	70
i-#define info(...) log_print(3, "info", __VA_ARGS__)	Err	bitreich.org	70
i-#define debug(...) log_print(4, "debug", __VA_ARGS__)	Err	bitreich.org	70
i+void log_vprintf(int level, char const *flag, char const *fmt, va_list va);	Err	bitreich.org	70
i+void die(char const *fmt, ...);	Err	bitreich.org	70
i+void warn(char const *fmt, ...);	Err	bitreich.org	70
i+void info(char const *fmt, ...);	Err	bitreich.org	70
i+void debug(char const *fmt, ...);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i #endif	Err	bitreich.org	70
1diff --git a/src/mem.c b/src/mem.c	/scm/iomenu/file/src/mem.c.gph	bitreich.org	70
i@@ -1,15 +1,16 @@	Err	bitreich.org	70
i #include "mem.h"	Err	bitreich.org	70
i 	Err	bitreich.org	70
i #include <assert.h>	Err	bitreich.org	70
i+#include <errno.h>	Err	bitreich.org	70
i+#include <stdint.h>	Err	bitreich.org	70
i #include <stdlib.h>	Err	bitreich.org	70
i #include <string.h>	Err	bitreich.org	70
i-#include <stdint.h>	Err	bitreich.org	70
i-#include <errno.h>	Err	bitreich.org	70
i+#include <unistd.h>	Err	bitreich.org	70
i 	Err	bitreich.org	70
i static struct mem_block *	Err	bitreich.org	70
i-mem_block(void *v)	Err	bitreich.org	70
i+mem_block(void **memp)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        struct mem_block *block = (void *)((char *)v - sizeof *block);	Err	bitreich.org	70
i+        struct mem_block *block = (void *)((char *)memp - sizeof *block);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i         assert(memcmp(block->magic, MEM_BLOCK_MAGIC, 8) == 0);	Err	bitreich.org	70
i         return block;	Err	bitreich.org	70
i@@ -37,9 +38,9 @@ mem_alloc(struct mem_pool *pool, size_t len)	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i int	Err	bitreich.org	70
i-mem_resize(void **pp, size_t len)	Err	bitreich.org	70
i+mem_resize(void **memp, size_t len)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        struct mem_block *block = mem_block(*pp);	Err	bitreich.org	70
i+        struct mem_block *block = mem_block(*memp);	Err	bitreich.org	70
i         int is_first = (block == block->pool->head);	Err	bitreich.org	70
i         int is_same;	Err	bitreich.org	70
i         void *v;	Err	bitreich.org	70
i@@ -61,53 +62,80 @@ mem_resize(void **pp, size_t len)	Err	bitreich.org	70
i                 block->next->prev = v;	Err	bitreich.org	70
i         if (is_first)	Err	bitreich.org	70
i                 block->pool->head = v;	Err	bitreich.org	70
i-        *pp = block->buf;	Err	bitreich.org	70
i+        *memp = block->buf;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i         assert(memcmp(block->magic, MEM_BLOCK_MAGIC, 8) == 0);	Err	bitreich.org	70
i         return 0;	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i int	Err	bitreich.org	70
i-mem_grow(void **pp, size_t len)	Err	bitreich.org	70
i+mem_grow(void **memp, size_t len)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        assert(SIZE_MAX - len >= mem_block(*pp)->len);	Err	bitreich.org	70
i+        assert(SIZE_MAX - len >= mem_block(*memp)->len);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        return mem_resize(pp, mem_length(*pp) + len);	Err	bitreich.org	70
i+        return mem_resize(memp, mem_length(*memp) + len);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i int	Err	bitreich.org	70
i-mem_shrink(void **pp, size_t len)	Err	bitreich.org	70
i+mem_shrink(void **memp, size_t len)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        assert(mem_block(*pp)->len >= len);	Err	bitreich.org	70
i+        assert(mem_block(*memp)->len >= len);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        return mem_resize(pp, mem_length(*pp) - len);	Err	bitreich.org	70
i+        return mem_resize(memp, mem_length(*memp) - len);	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i size_t	Err	bitreich.org	70
i-mem_length(void *v)	Err	bitreich.org	70
i+mem_length(void *mem)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        return mem_block(v)->len;	Err	bitreich.org	70
i+        return mem_block(mem)->len;	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i int	Err	bitreich.org	70
i-mem_append(void **pp, char const *buf, size_t len)	Err	bitreich.org	70
i+mem_append(void **memp, void const *buf, size_t len)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        size_t old_len = mem_length(*pp);	Err	bitreich.org	70
i+        size_t old_len = mem_length(*memp);	Err	bitreich.org	70
i         struct mem_block *block;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        if (mem_grow(pp, len) < 0)	Err	bitreich.org	70
i+        if (mem_grow(memp, len) < 0)	Err	bitreich.org	70
i                 return -1;	Err	bitreich.org	70
i-        block = mem_block(*pp);	Err	bitreich.org	70
i+        block = mem_block(*memp);	Err	bitreich.org	70
i         memcpy((char *)block->buf + old_len, buf, len);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i         assert(memcmp(block->magic, MEM_BLOCK_MAGIC, 8) == 0);	Err	bitreich.org	70
i         return 0;	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i+int	Err	bitreich.org	70
i+mem_read(void **memp, struct mem_pool *pool)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        struct mem_block *block;	Err	bitreich.org	70
i+        ssize_t sz = 0;	Err	bitreich.org	70
i+        void *mem;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        mem = mem_alloc(pool, 0);	Err	bitreich.org	70
i+        if (mem == NULL)	Err	bitreich.org	70
i+                return -1;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        for (ssize_t r = 1; r > 0; sz += r) {	Err	bitreich.org	70
i+                if (mem_resize(&mem, sz + 2048) < 0)	Err	bitreich.org	70
i+                        return -1;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                r = read(0, (char *)mem + sz, 2048);	Err	bitreich.org	70
i+                if (r < 0)	Err	bitreich.org	70
i+                        return -1;	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+        block = mem_block(mem);	Err	bitreich.org	70
i+        block->len = sz;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        *memp = mem;	Err	bitreich.org	70
i+        assert(memcmp(block->magic, MEM_BLOCK_MAGIC, 8) == 0);	Err	bitreich.org	70
i+        return 0;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i void	Err	bitreich.org	70
i-mem_delete(void *v)	Err	bitreich.org	70
i+mem_delete(void *mem)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        struct mem_block *block = mem_block(v);;	Err	bitreich.org	70
i+        struct mem_block *block = mem_block(mem);;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i         if (block == block->pool->head)	Err	bitreich.org	70
i                 block->pool->head = block->next;	Err	bitreich.org	70
1diff --git a/src/mem.h b/src/mem.h	/scm/iomenu/file/src/mem.h.gph	bitreich.org	70
i@@ -47,12 +47,13 @@ struct mem_block {	Err	bitreich.org	70
i 	Err	bitreich.org	70
i /** src/mem.c **/	Err	bitreich.org	70
i void * mem_alloc(struct mem_pool *pool, size_t len);	Err	bitreich.org	70
i-int mem_resize(void **pp, size_t len);	Err	bitreich.org	70
i-int mem_grow(void **pp, size_t len);	Err	bitreich.org	70
i-int mem_shrink(void **pp, size_t len);	Err	bitreich.org	70
i-size_t mem_length(void *v);	Err	bitreich.org	70
i-int mem_append(void **pp, char const *buf, size_t len);	Err	bitreich.org	70
i-void mem_delete(void *v);	Err	bitreich.org	70
i+int mem_resize(void **memp, size_t len);	Err	bitreich.org	70
i+int mem_grow(void **memp, size_t len);	Err	bitreich.org	70
i+int mem_shrink(void **memp, size_t len);	Err	bitreich.org	70
i+size_t mem_length(void *mem);	Err	bitreich.org	70
i+int mem_append(void **memp, void const *buf, size_t len);	Err	bitreich.org	70
i+int mem_read(void **memp, struct mem_pool *pool);	Err	bitreich.org	70
i+void mem_delete(void *mem);	Err	bitreich.org	70
i void mem_free(struct mem_pool *pool);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i #endif	Err	bitreich.org	70
1diff --git a/src/str.c b/src/str.c	/scm/iomenu/file/src/str.c.gph	bitreich.org	70
i@@ -1,119 +0,0 @@	Err	bitreich.org	70
i-#include "str.h"	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-#include <assert.h>	Err	bitreich.org	70
i-#include <errno.h>	Err	bitreich.org	70
i-#include <stdarg.h>	Err	bitreich.org	70
i-#include <stdint.h>	Err	bitreich.org	70
i-#include <stdio.h>	Err	bitreich.org	70
i-#include <stdlib.h>	Err	bitreich.org	70
i-#include <string.h>	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-#include "mem.h"	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * It is heavy on assert as an inexpensive way to detect memory corruption from	Err	bitreich.org	70
i- * code around: underflows are checked through the magic header, overflow are	Err	bitreich.org	70
i- * checked through the '\0' byte.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-size_t	Err	bitreich.org	70
i-str_length(struct str *str)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        return mem_length(str->mem) - sizeof "";	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-str_init(struct str *str, struct mem_pool *pool)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        str->mem = mem_alloc(pool, 1);	Err	bitreich.org	70
i-        if (str->mem == NULL)	Err	bitreich.org	70
i-                return -1;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        assert(str->mem[0] == '\0');	Err	bitreich.org	70
i-        assert(str_length(str) == 0);	Err	bitreich.org	70
i-        assert(mem_length(str->mem) == 1);	Err	bitreich.org	70
i-        return 0;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-void	Err	bitreich.org	70
i-str_truncate(struct str *str, size_t len)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        assert(str->mem[str_length(str)] == '\0');	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        if (mem_length(str->mem) > len)	Err	bitreich.org	70
i-                str->mem[len] = '\0';	Err	bitreich.org	70
i-        mem_resize((void **)&str->mem, len + 1);	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        assert(str->mem[str_length(str)] == '\0');	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-str_append_mem(struct str *str, char const *buf, size_t len)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        void **pp = (void **)&str->mem;	Err	bitreich.org	70
i-        size_t old_sz;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        assert((old_sz = mem_length(str->mem)) > 0);	Err	bitreich.org	70
i-        assert(memchr(buf, '\0', len) == NULL);	Err	bitreich.org	70
i-        assert(str->mem[str_length(str)] == '\0');	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        if (mem_shrink(pp, 1)) /* strip '\0' */	Err	bitreich.org	70
i-                return -1;	Err	bitreich.org	70
i-        if (mem_append(pp, buf, len) < 0)	Err	bitreich.org	70
i-                return -1;	Err	bitreich.org	70
i-        if (mem_append(pp, "", 1) < 0)	Err	bitreich.org	70
i-                return -1;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        assert(memcmp(str->mem + old_sz-1, buf, len) == 0);	Err	bitreich.org	70
i-        assert(str->mem[old_sz-1 + len] == '\0');	Err	bitreich.org	70
i-        assert(str->mem[str_length(str)] == '\0');	Err	bitreich.org	70
i-        return 0;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-str_append_string(struct str *str, char const *s)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        assert(str->mem[str_length(str)] == '\0');	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        return str_append_mem(str, s, strlen(s));	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-str_append_char(struct str *str, char c)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        assert(str->mem[str_length(str)] == '\0');	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        str_c(str)[str_length(str)] = c;	Err	bitreich.org	70
i-        if (mem_append((void **)str->mem, "", 1) < 0)	Err	bitreich.org	70
i-                return -1;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        assert(str->mem[str_length(str)] == '\0');	Err	bitreich.org	70
i-        return 0;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-str_append_fmt(struct str *str, char const *fmt, ...)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        va_list va;	Err	bitreich.org	70
i-        int n;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        assert(str->mem[str_length(str)] == '\0');	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        va_start(va, fmt);	Err	bitreich.org	70
i-        n = vsnprintf(NULL, 0, fmt, va);	Err	bitreich.org	70
i-        assert(n > 0);	Err	bitreich.org	70
i-        if (mem_grow((void **)&str->mem, n + 1) < 0)	Err	bitreich.org	70
i-                return -1;	Err	bitreich.org	70
i-        vsprintf(str->mem, fmt, va);	Err	bitreich.org	70
i-        va_end(va);	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        assert(str->mem[str_length(str)] == '\0');	Err	bitreich.org	70
i-        return 0;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-char *	Err	bitreich.org	70
i-str_c(struct str *str)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        assert(str->mem[str_length(str)] == '\0');	Err	bitreich.org	70
i-        return str->mem;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
1diff --git a/src/str.h b/src/str.h	/scm/iomenu/file/src/str.h.gph	bitreich.org	70
i@@ -1,26 +0,0 @@	Err	bitreich.org	70
i-#ifndef STR_H	Err	bitreich.org	70
i-#define STR_H	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-#include <stddef.h>	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-#include "mem.h"	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * Length kept by struct mem_block.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-struct str {	Err	bitreich.org	70
i-        char *mem;	Err	bitreich.org	70
i-};	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-/** src/str.c **/	Err	bitreich.org	70
i-size_t str_length(struct str *str);	Err	bitreich.org	70
i-int str_init(struct str *str, struct mem_pool *pool);	Err	bitreich.org	70
i-void str_truncate(struct str *str, size_t len);	Err	bitreich.org	70
i-int str_append_mem(struct str *str, char const *buf, size_t len);	Err	bitreich.org	70
i-int str_append_string(struct str *str, char const *s);	Err	bitreich.org	70
i-int str_append_char(struct str *str, char c);	Err	bitreich.org	70
i-int str_append_fmt(struct str *str, char const *fmt, ...);	Err	bitreich.org	70
i-char * str_c(struct str *str);	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-#endif	Err	bitreich.org	70
1diff --git a/src/term.c b/src/term.c	/scm/iomenu/file/src/term.c.gph	bitreich.org	70
i@@ -0,0 +1,107 @@	Err	bitreich.org	70
i+#include "term.h"	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <ctype.h>	Err	bitreich.org	70
i+#include <stdint.h>	Err	bitreich.org	70
i+#include <stdio.h>	Err	bitreich.org	70
i+#include <string.h>	Err	bitreich.org	70
i+#include <sys/ioctl.h>	Err	bitreich.org	70
i+#include <termios.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include "compat.h"	Err	bitreich.org	70
i+#include "utf8.h"	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+struct term term = {0};	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+static int	Err	bitreich.org	70
i+term_codepoint_width(uint32_t codepoint, int pos)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        if (codepoint == '\t')	Err	bitreich.org	70
i+                return 8 - pos % 8;	Err	bitreich.org	70
i+        return wcwidth(codepoint);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+int	Err	bitreich.org	70
i+term_at_width(char const *s, int width, int pos)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        char const *beg = s;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        for (uint32_t state = 0, codepoint; *s != '\0'; s++) {	Err	bitreich.org	70
i+                if (utf8_decode(&state, &codepoint, *s) == UTF8_ACCEPT) {	Err	bitreich.org	70
i+                        pos += term_codepoint_width(codepoint, pos);	Err	bitreich.org	70
i+                        if (pos > width)	Err	bitreich.org	70
i+                                break;	Err	bitreich.org	70
i+                }	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+        return s - beg;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+int	Err	bitreich.org	70
i+term_raw_on(int fd)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        struct termios new_termios = {0};	Err	bitreich.org	70
i+        char *seq = "\x1b[s\x1b[?1049h\x1b[H";	Err	bitreich.org	70
i+        ssize_t len = strlen(seq);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        if (write(fd, seq, len) < len)	Err	bitreich.org	70
i+                return -1;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        if (tcgetattr(fd, &term.old_termios) < 0)	Err	bitreich.org	70
i+                return -1;	Err	bitreich.org	70
i+        memcpy(&new_termios, &term.old_termios, sizeof new_termios);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        new_termios.c_lflag &= ~(ICANON | ECHO | IEXTEN | IGNBRK | ISIG);	Err	bitreich.org	70
i+        if (tcsetattr(fd, TCSANOW, &new_termios) == -1)	Err	bitreich.org	70
i+                return -1;	Err	bitreich.org	70
i+        return 0;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+int	Err	bitreich.org	70
i+term_raw_off(int fd)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        char *seq = "\x1b[2J\x1b[u\033[?1049l";	Err	bitreich.org	70
i+        ssize_t len = strlen(seq);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        if (tcsetattr(fd, TCSANOW, &term.old_termios) < 0)	Err	bitreich.org	70
i+                return -1;	Err	bitreich.org	70
i+        if (write(fd, seq, len) < len)	Err	bitreich.org	70
i+                return -1;	Err	bitreich.org	70
i+        return 0;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+int	Err	bitreich.org	70
i+term_get_key(FILE *fp)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        int key, num;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        key = fgetc(fp);	Err	bitreich.org	70
i+top:	Err	bitreich.org	70
i+        switch (key) {	Err	bitreich.org	70
i+        case EOF:	Err	bitreich.org	70
i+                return -1;	Err	bitreich.org	70
i+        case TERM_KEY_ALT('['):	Err	bitreich.org	70
i+                key = getc(fp);	Err	bitreich.org	70
i+                if (key == EOF)	Err	bitreich.org	70
i+                        return -1;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                for (num = 0; isdigit(key);) {	Err	bitreich.org	70
i+                        num *= 10;	Err	bitreich.org	70
i+                        num += key - '0';	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                        key = fgetc(fp);	Err	bitreich.org	70
i+                        if (key == EOF)	Err	bitreich.org	70
i+                                return -1;	Err	bitreich.org	70
i+                }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                key = TERM_KEY_CSI(key, num);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                goto top;	Err	bitreich.org	70
i+        case TERM_KEY_ESC:	Err	bitreich.org	70
i+                key = getc(fp);	Err	bitreich.org	70
i+                if (key == EOF)	Err	bitreich.org	70
i+                        return -1;	Err	bitreich.org	70
i+                key = TERM_KEY_ALT(key);	Err	bitreich.org	70
i+                goto top;	Err	bitreich.org	70
i+        default:	Err	bitreich.org	70
i+                return key;	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+}	Err	bitreich.org	70
1diff --git a/src/term.h b/src/term.h	/scm/iomenu/file/src/term.h.gph	bitreich.org	70
i@@ -0,0 +1,39 @@	Err	bitreich.org	70
i+#ifndef TERM_H	Err	bitreich.org	70
i+#define TERM_H	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <stdint.h>	Err	bitreich.org	70
i+#include <stdio.h>	Err	bitreich.org	70
i+#include <sys/ioctl.h>	Err	bitreich.org	70
i+#include <termios.h>	Err	bitreich.org	70
i+#include <unistd.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#define TERM_KEY_CTRL(c)    ((c) & ~0x40)	Err	bitreich.org	70
i+#define TERM_KEY_ALT(c)            (0x100 + (c))	Err	bitreich.org	70
i+#define TERM_KEY_CSI(c, i)  (0x100 + (c) * 0x100 + (i))	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+enum term_key {	Err	bitreich.org	70
i+        TERM_KEY_ESC        = 0x1b,	Err	bitreich.org	70
i+        TERM_KEY_DELETE     = 127,	Err	bitreich.org	70
i+        TERM_KEY_BACKSPACE  = TERM_KEY_CTRL('H'),	Err	bitreich.org	70
i+        TERM_KEY_TAB        = TERM_KEY_CTRL('I'),	Err	bitreich.org	70
i+        TERM_KEY_ENTER      = TERM_KEY_CTRL('J'),	Err	bitreich.org	70
i+        TERM_KEY_ARROW_UP   = TERM_KEY_CSI('A', 0),	Err	bitreich.org	70
i+        TERM_KEY_ARROW_DOWN = TERM_KEY_CSI('B', 0),	Err	bitreich.org	70
i+        TERM_KEY_PAGE_UP    = TERM_KEY_CSI('~', 5),	Err	bitreich.org	70
i+        TERM_KEY_PAGE_DOWN  = TERM_KEY_CSI('~', 6),	Err	bitreich.org	70
i+};	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+struct term {	Err	bitreich.org	70
i+        struct winsize winsize;	Err	bitreich.org	70
i+        struct termios old_termios;	Err	bitreich.org	70
i+};	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+/** src/term.c **/	Err	bitreich.org	70
i+struct term term;	Err	bitreich.org	70
i+int term_width_at_pos(uint32_t codepoint, int pos);	Err	bitreich.org	70
i+int term_at_width(char const *s, int width, int pos);	Err	bitreich.org	70
i+int term_raw_on(int fd);	Err	bitreich.org	70
i+int term_raw_off(int fd);	Err	bitreich.org	70
i+int term_get_key(FILE *fp);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#endif	Err	bitreich.org	70
1diff --git a/src/utf8.c b/src/utf8.c	/scm/iomenu/file/src/utf8.c.gph	bitreich.org	70
i@@ -1,214 +1,85 @@	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * ASCII all have a leading '0' byte:	Err	bitreich.org	70
i- *	Err	bitreich.org	70
i- *   0xxxxxxx	Err	bitreich.org	70
i- *	Err	bitreich.org	70
i- * UTF-8 have one leading '1' and as many following '1' as there are	Err	bitreich.org	70
i- * continuation bytes (with leading '1' and '0').	Err	bitreich.org	70
i- *	Err	bitreich.org	70
i- *   0xxxxxxx	Err	bitreich.org	70
i- *   110xxxxx 10xxxxxx	Err	bitreich.org	70
i- *   1110xxxx 10xxxxxx 10xxxxxx	Err	bitreich.org	70
i- *   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx	Err	bitreich.org	70
i- *   111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx	Err	bitreich.org	70
i- *   1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx	Err	bitreich.org	70
i- *	Err	bitreich.org	70
i- * There is up to 3 continuation bytes -- up to 4 bytes per runes.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-#include <ctype.h>	Err	bitreich.org	70
i-#include <stddef.h>	Err	bitreich.org	70
i-#include <stdlib.h>	Err	bitreich.org	70
i-#include <string.h>	Err	bitreich.org	70
i-#include <stdio.h>	Err	bitreich.org	70
i-	Err	bitreich.org	70
i #include "utf8.h"	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-static int	Err	bitreich.org	70
i-utflen(char const *str)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        int i, len;	Err	bitreich.org	70
i-        unsigned char const *s;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        s = (unsigned char const *)str;	Err	bitreich.org	70
i-        len =        (*s < 0x80) ? 1 : /* 0xxxxxxx < *s < 10000000 */	Err	bitreich.org	70
i-                (*s < 0xc0) ? 0 : /* 10xxxxxx < *s < 11000000 */	Err	bitreich.org	70
i-                (*s < 0xe0) ? 2 : /* 110xxxxx < *s < 11100000 */	Err	bitreich.org	70
i-                (*s < 0xf0) ? 3 : /* 1110xxxx < *s < 11110000 */	Err	bitreich.org	70
i-                (*s < 0xf8) ? 4 : /* 11110xxx < *s < 11111000 */	Err	bitreich.org	70
i-                (*s < 0xfc) ? 5 : /* 111110xx < *s < 11111100 */	Err	bitreich.org	70
i-                (*s < 0xfe) ? 6 : /* 1111110x < *s < 11111110 */	Err	bitreich.org	70
i-                (*s < 0xff) ? 7 : /* 11111110 < *s < 11111111 */	Err	bitreich.org	70
i-                0;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        /* check continuation bytes and '\0' */	Err	bitreich.org	70
i-        for (s++, i = 1; i < len; i++, s++) {	Err	bitreich.org	70
i-                if ((*s & 0xc0) != 0x80) /* 10xxxxxx & 11000000 */	Err	bitreich.org	70
i-                        return 0;	Err	bitreich.org	70
i-        }	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        return len;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-static long	Err	bitreich.org	70
i-torune(char const **str, size_t len)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        long rune;	Err	bitreich.org	70
i-        int n;	Err	bitreich.org	70
i-        char mask[] = { 0x00, 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01 };	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        if (len == 0 || len > 6)	Err	bitreich.org	70
i-                return 0;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        /* first byte */	Err	bitreich.org	70
i-        rune = *(*str)++ & mask[len];	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        /* continuation bytes */	Err	bitreich.org	70
i-        for (n = len - 1; n > 0; n--, (*str)++)	Err	bitreich.org	70
i-                rune = (rune << 6) | (**str & 0x3f);        /* 10xxxxxx */	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        return rune;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * Return the number of bytes required to encode <rune> into UTF-8, or	Err	bitreich.org	70
i- * 0 if rune is too long.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-utf8_runelen(long rune)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        return        (rune <= 0x0000007f) ? 1 :	Err	bitreich.org	70
i-                (rune <= 0x000007ff) ? 2 :	Err	bitreich.org	70
i-                (rune <= 0x0000ffff) ? 3 :	Err	bitreich.org	70
i-                (rune <= 0x001fffff) ? 4 :	Err	bitreich.org	70
i-                (rune <= 0x03ffffff) ? 5 :	Err	bitreich.org	70
i-                (rune <= 0x7fffffff) ? 6 :	Err	bitreich.org	70
i-                0;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i+#include <stddef.h>	Err	bitreich.org	70
i+#include <stdint.h>	Err	bitreich.org	70
i 	Err	bitreich.org	70
i /*	Err	bitreich.org	70
i- * Return the number of bytes in rune for the next char in <s>, or 0 if	Err	bitreich.org	70
i- * is misencoded or if it is '\0'.	Err	bitreich.org	70
i+ * Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>	Err	bitreich.org	70
i+ *	Err	bitreich.org	70
i+ * Permission is hereby granted, free of charge, to any person obtaining a copy	Err	bitreich.org	70
i+ * of this software and associated documentation files (the "Software"), to	Err	bitreich.org	70
i+ * deal in the Software without restriction, including without limitation the	Err	bitreich.org	70
i+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or	Err	bitreich.org	70
i+ * sell copies of the Software, and to permit persons to whom the Software is	Err	bitreich.org	70
i+ * furnished to do so, subject to the following conditions:	Err	bitreich.org	70
i+ *	Err	bitreich.org	70
i+ * The above copyright notice and this permission notice shall be included in	Err	bitreich.org	70
i+ * all copies or substantial portions of the Software.	Err	bitreich.org	70
i+ *	Err	bitreich.org	70
i+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR	Err	bitreich.org	70
i+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,	Err	bitreich.org	70
i+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE	Err	bitreich.org	70
i+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER	Err	bitreich.org	70
i+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING	Err	bitreich.org	70
i+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS	Err	bitreich.org	70
i+ * IN THE SOFTWARE.	Err	bitreich.org	70
i  */	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-utf8_utflen(char const *str)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        long rune;	Err	bitreich.org	70
i-        int len = utflen(str);	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        rune = torune(&str, len);	Err	bitreich.org	70
i-        if (len != utf8_runelen(rune))	Err	bitreich.org	70
i-                return 0;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        return len;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * Return a rune corresponding to the firsts bytes of <str> or -1 if	Err	bitreich.org	70
i- * the rune is invalid, and set <str> to the beginning of the next rune.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-long	Err	bitreich.org	70
i-utf8_torune(char const **str)	Err	bitreich.org	70
i+size_t	Err	bitreich.org	70
i+utf8_encode(char *dest, uint32_t u)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        long rune;	Err	bitreich.org	70
i-        int len;	Err	bitreich.org	70
i+        size_t v, n, n2;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        len = utflen(*str);	Err	bitreich.org	70
i-        rune = torune(str, len);	Err	bitreich.org	70
i-        if (len != utf8_runelen(rune))	Err	bitreich.org	70
i-                return -1;	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        return rune;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * Encode the rune <rune> in UTF-8 in <str>, null-terminated, then return the	Err	bitreich.org	70
i- * number of bytes written, 0 if <rune> is invalid.	Err	bitreich.org	70
i- *	Err	bitreich.org	70
i- * Thanks to Connor Lane Smith for the idea of combining switches and	Err	bitreich.org	70
i- * binary masks.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-utf8_tostr(char *str, long rune)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        switch (utf8_runelen(rune)) {	Err	bitreich.org	70
i-        case 1:	Err	bitreich.org	70
i-                str[0] = rune;                                /* 0xxxxxxx */	Err	bitreich.org	70
i-                str[1] = '\0';	Err	bitreich.org	70
i+        if (u <= 0x7f) {	Err	bitreich.org	70
i+                if (dest != NULL)	Err	bitreich.org	70
i+                        *dest = u;	Err	bitreich.org	70
i                 return 1;	Err	bitreich.org	70
i-        case 2:	Err	bitreich.org	70
i-                str[0] = 0xc0 | (0x1f & (rune >> 6));        /* 110xxxxx */	Err	bitreich.org	70
i-                str[1] = 0x80 | (0x3f & (rune));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[2] = '\0';	Err	bitreich.org	70
i-                return 2;	Err	bitreich.org	70
i-        case 3:	Err	bitreich.org	70
i-                str[0] = 0xe0 | (0x0f & (rune >> 12));        /* 1110xxxx */	Err	bitreich.org	70
i-                str[1] = 0x80 | (0x3f & (rune >> 6));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[2] = 0x80 | (0x3f & (rune));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[3] = '\0';	Err	bitreich.org	70
i-                return 3;	Err	bitreich.org	70
i-        case 4:	Err	bitreich.org	70
i-                str[0] = 0xf0 | (0x07 & (rune >> 18));        /* 11110xxx */	Err	bitreich.org	70
i-                str[1] = 0x80 | (0x3f & (rune >> 12));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[2] = 0x80 | (0x3f & (rune >> 6));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[3] = 0x80 | (0x3f & (rune));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[4] = '\0';	Err	bitreich.org	70
i-                return 4;	Err	bitreich.org	70
i-        case 5:	Err	bitreich.org	70
i-                str[0] = 0xf8 | (0x03 & (rune >> 24));        /* 111110xx */	Err	bitreich.org	70
i-                str[1] = 0x80 | (0x3f & (rune >> 18));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[2] = 0x80 | (0x3f & (rune >> 12));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[3] = 0x80 | (0x3f & (rune >> 6));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[4] = 0x80 | (0x3f & (rune));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[5] = '\0';	Err	bitreich.org	70
i-                return 5;	Err	bitreich.org	70
i-        case 6:	Err	bitreich.org	70
i-                str[0] = 0xfc | (0x01 & (rune >> 30));        /* 1111110x */	Err	bitreich.org	70
i-                str[1] = 0x80 | (0x3f & (rune >> 24));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[2] = 0x80 | (0x3f & (rune >> 18));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[3] = 0x80 | (0x3f & (rune >> 12));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[4] = 0x80 | (0x3f & (rune >> 6));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[5] = 0x80 | (0x3f & (rune));        /* 10xxxxxx */	Err	bitreich.org	70
i-                str[6] = '\0';	Err	bitreich.org	70
i-                return 6;	Err	bitreich.org	70
i-        default:	Err	bitreich.org	70
i-                str[0] = '\0';	Err	bitreich.org	70
i-                return 0;	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- * Return 1 if the rune is a printable character, and 0 otherwise.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-utf8_isprint(long rune)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        return (0x1f < rune && rune != 0x7f && rune < 0x80) || 0x9f < rune;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i+        for (v = 0x3f, n = 0; v >= u; ++n)	Err	bitreich.org	70
i+                v = (v << 5) | 0x1f;	Err	bitreich.org	70
i+        if (v >= 0x7fffffff)	Err	bitreich.org	70
i+                return 0; /* cannot be encoded */	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * Return a pointer to the next rune in <str> or next byte if the rune	Err	bitreich.org	70
i- * is invalid.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-char const *	Err	bitreich.org	70
i-utf8_nextrune(char const *str)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        int len;	Err	bitreich.org	70
i+        if (dest == NULL)	Err	bitreich.org	70
i+                return 1 + n;	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        len = utf8_utflen(str);	Err	bitreich.org	70
i-        return (len == 0) ? str + 1 : str + len;	Err	bitreich.org	70
i+        *dest++ = (0xff << (7 - n)) | (u >> n * 6);	Err	bitreich.org	70
i+        for (n2 = n - 1; n2 ; --n2) {	Err	bitreich.org	70
i+                *dest++ = 0x80 | (u & 0x3f);	Err	bitreich.org	70
i+                u >>= 6;	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+        return 1 + n;	Err	bitreich.org	70
i }	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-/*	Err	bitreich.org	70
i- * Return a pointer to the prev rune in <str> or prev byte if the rune	Err	bitreich.org	70
i- * is invalid.	Err	bitreich.org	70
i- */	Err	bitreich.org	70
i-char const *	Err	bitreich.org	70
i-utf8_prevrune(char const *str)	Err	bitreich.org	70
i+/* Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> *	Err	bitreich.org	70
i+ * See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. */	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+static const uint8_t utf8d[] = {	Err	bitreich.org	70
i+        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 00..1f */	Err	bitreich.org	70
i+        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 20..3f */	Err	bitreich.org	70
i+        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40..5f */	Err	bitreich.org	70
i+        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 60..7f */	Err	bitreich.org	70
i+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, /* 80..9f */	Err	bitreich.org	70
i+        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* a0..bf */	Err	bitreich.org	70
i+        8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* c0..df */	Err	bitreich.org	70
i+        0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, /* e0..ef */	Err	bitreich.org	70
i+        0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, /* f0..ff */	Err	bitreich.org	70
i+        0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, /* s0..s0 */	Err	bitreich.org	70
i+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, /* s1..s2 */	Err	bitreich.org	70
i+        1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, /* s3..s4 */	Err	bitreich.org	70
i+        1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, /* s5..s6 */	Err	bitreich.org	70
i+        1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* s7..s8 */	Err	bitreich.org	70
i+};	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+uint32_t	Err	bitreich.org	70
i+utf8_decode(uint32_t *state, uint32_t *codep, uint32_t byte)	Err	bitreich.org	70
i {	Err	bitreich.org	70
i-        char const *s;	Err	bitreich.org	70
i+        uint32_t type = utf8d[byte];	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-        for (s = str; (*s & 0x80) != 0; s--)	Err	bitreich.org	70
i-                ;	Err	bitreich.org	70
i-        return (utf8_utflen(s) != 0) ? s : str - 1;	Err	bitreich.org	70
i+        *codep = (*state != UTF8_ACCEPT)	Err	bitreich.org	70
i+                ? (byte & 0x3fu) | (*codep << 6)	Err	bitreich.org	70
i+                : (0xff >> type) & (byte);	Err	bitreich.org	70
i+        *state = utf8d[256 + *state*16 + type];	Err	bitreich.org	70
i+        return *state;	Err	bitreich.org	70
i }	Err	bitreich.org	70
1diff --git a/src/utf8.h b/src/utf8.h	/scm/iomenu/file/src/utf8.h.gph	bitreich.org	70
i@@ -1,13 +1,16 @@	Err	bitreich.org	70
i #ifndef UTF8_H	Err	bitreich.org	70
i #define UTF8_H	Err	bitreich.org	70
i 	Err	bitreich.org	70
i+#include <stddef.h>	Err	bitreich.org	70
i+#include <stdint.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+enum {	Err	bitreich.org	70
i+        UTF8_ACCEPT,	Err	bitreich.org	70
i+        UTF8_REJECT,	Err	bitreich.org	70
i+};	Err	bitreich.org	70
i+	Err	bitreich.org	70
i /** src/utf8.c **/	Err	bitreich.org	70
i-int utf8_runelen(long rune);	Err	bitreich.org	70
i-int utf8_utflen(char const *str);	Err	bitreich.org	70
i-long utf8_torune(char const **str);	Err	bitreich.org	70
i-int utf8_tostr(char *str, long rune);	Err	bitreich.org	70
i-int utf8_isprint(long rune);	Err	bitreich.org	70
i-char const * utf8_nextrune(char const *str);	Err	bitreich.org	70
i-char const * utf8_prevrune(char const *str);	Err	bitreich.org	70
i+size_t utf8_encode(char *dest, uint32_t u);	Err	bitreich.org	70
i+uint32_t utf8_decode(uint32_t *state, uint32_t *codep, uint32_t byte);	Err	bitreich.org	70
i 	Err	bitreich.org	70
i #endif	Err	bitreich.org	70
1diff --git a/src/util.h b/src/util.h	/scm/iomenu/file/src/util.h.gph	bitreich.org	70
i@@ -1,12 +0,0 @@	Err	bitreich.org	70
i-#ifndef UTIL_H	Err	bitreich.org	70
i-#define UTIL_H	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-#define ESC                0x1b                        /* Esc key */	Err	bitreich.org	70
i-#define CTL(c)                ((c) & ~0x40)                /* Ctr + (c) key */	Err	bitreich.org	70
i-#define ALT(c)                ((c) + 0x80)                /* Alt + (c) key */	Err	bitreich.org	70
i-#define CSI(c)                ((c) + 0x80 + 0x80)        /* Escape + '[' + (c) code */	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-#define LEN(x)                (sizeof(x) / sizeof(*(x)))	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-#endif	Err	bitreich.org	70
1diff --git a/t/test.c b/t/test.c	/scm/iomenu/file/t/test.c.gph	bitreich.org	70
i@@ -1,22 +0,0 @@	Err	bitreich.org	70
i-#include <stdio.h>	Err	bitreich.org	70
i-#include <wchar.h>	Err	bitreich.org	70
i-#include "utf8.h"	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-int	Err	bitreich.org	70
i-main(void)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        int c, col, o, off;	Err	bitreich.org	70
i-        char s[] = "\t\t浪漫的夢想";	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        for (off = 0; off < 15; off++) {	Err	bitreich.org	70
i-                for (col = off + 1; col < 30; col++) {	Err	bitreich.org	70
i-                        for (c = 0; c < col; c++)	Err	bitreich.org	70
i-                                putchar(c % 8 == 0 ? '>' : '_');	Err	bitreich.org	70
i-                        printf(" %d\n", col);	Err	bitreich.org	70
i-                        for (o = 0; o < off; o++)	Err	bitreich.org	70
i-                                putchar('.');	Err	bitreich.org	70
i-                        printf("%.*s\n\n", utf8_col(s, col, off), s);	Err	bitreich.org	70
i-                }	Err	bitreich.org	70
i-        }	Err	bitreich.org	70
i-        return 0;	Err	bitreich.org	70
i-}	Err	bitreich.org	70
.
Response: text/plain
Original URLgopher://bitreich.org/0/scm/iomenu/commit/c9ce7898a2d7b4f...
Content-Typetext/plain; charset=utf-8