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