starting to add utf8 functions to iomenu - iomenu - interactive terminal-based selection menu HTML git clone git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu DIR Log DIR Files DIR Refs DIR Tags DIR README DIR LICENSE --- DIR commit 278c57dbd7ecb5aa22c6136c5d95ff3ff12de141 DIR parent c383bef4af98a82331c2c6e56ff7964e3dbf690b HTML Author: Josuah Demangeon <josuah.demangeon@gandi.net> Date: Tue, 22 Aug 2017 23:21:32 +0200 starting to add utf8 functions to iomenu Diffstat: M Makefile | 2 ++ M iomenu.c | 37 +++++++++++++++++++------------ M utf8.c | 12 ++++++------ M utf8.h | 9 +++++---- 4 files changed, 36 insertions(+), 24 deletions(-) --- DIR diff --git a/Makefile b/Makefile @@ -2,6 +2,8 @@ CFLAGS = -std=c89 -Wpedantic -Wall -Wextra -g # -static all: clean iomenu +iomenu: iomenu.o utf8.o + clean: rm -f *.o iomenu DIR diff --git a/iomenu.c b/iomenu.c @@ -10,6 +10,8 @@ #include <sys/ioctl.h> +#include "utf8.h" + #define CONTINUE 2 /* as opposed to EXIT_SUCCESS and EXIT_FAILURE */ #define CTL(char) (char ^ 0x40) @@ -121,26 +123,33 @@ readlines(void) } static char * -format(char *str, int cols) +format(char *s, int cols) { - int i, j; - - for (i = j = 0; str[i] && j < cols; i++) { - - if (str[i] == '\t') { - int t = 8 - j % 8; - while (t-- > 0 && j < cols) - formatted[j++] = ' '; + int i = 0; + long r = 0; + char *f = formatted; + + while (*s && i < cols) { + if (*s == '\t') { + int t = 8 - i % 8; + while (t-- && i < cols) { + *f++ = ' '; + i++; + } + s++; - } else if (isprint(str[i])) { - formatted[j++] = str[i]; + } else if (utf8torune(&r, s) && utf8isprint(r)) { + int j = utf8len(s); + while (j--) + *f++ = *s++; + i++; } else { - formatted[j++] = '?'; + *f++ = '?'; + i++; } } - - formatted[j] = '\0'; + *f = '\0'; return formatted; } DIR diff --git a/utf8.c b/utf8.c @@ -33,7 +33,7 @@ * or 0 if ti is misencoded. */ size_t -utf8len(char *s, int n) +utf8len(char *s) { unsigned char *sp = (unsigned char *) s; int i, len = (*sp < 0x80) ? 1 : /* 0xxxxxxx < 10000000 */ @@ -45,7 +45,7 @@ utf8len(char *s, int n) (*sp < 0xfe) ? 6 : /* 1111110x < 11111110 */ (*sp < 0xff) ? 7 : /* 11111110 < 11111111 */ 0; - if (len > n) return 0; + if (len > strlen(s)) return 0; /* check continuation bytes */ for (sp++, i = 1; i < len; i++, sp++) @@ -75,12 +75,12 @@ utf8runelen(long r) * Return the number of bytes read or 0 if the string is misencoded. */ size_t -utf8torune(long *r, char *s, size_t n) +utf8torune(long *r, char *s) { char mask[] = { 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; - size_t i, len = utf8len(s, n); + size_t i, len = utf8len(s); - if (len == 0 || len > 6 || len > n) + if (len == 0 || len > 6 || len > strlen(s)) return 0; /* first byte */ @@ -130,7 +130,7 @@ utf8check(char *s, size_t len) long r = 0; while (len > 0) { - shift = utf8torune(&r, s, len); + shift = utf8torune(&r, s); if (!shift || !utf8runeisunicode(r)) return 0; DIR diff --git a/utf8.h b/utf8.h @@ -1,5 +1,6 @@ -size_t utf8len(char *, int); +size_t utf8len(char *); size_t utf8runelen(long); -size_t utf8torune(long *, char *, size_t); -int utf8runeisunicode(long); -int utf8check(char *, size_t); +size_t utf8torune(long *, char *); +int utf8isunicode(long); +int utf8check(char *); +int utf8isprint(long);