iutf8.[ch]: imported utf8len() and utf8check() - 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 c383bef4af98a82331c2c6e56ff7964e3dbf690b /scm/iomenu/commit/c383bef4af98a82331c2c6e56ff7964e3dbf690b.gph bitreich.org 70 1parent 09d7cdbc37907c01400e2193f4eafba74736aa7d /scm/iomenu/commit/09d7cdbc37907c01400e2193f4eafba74736aa7d.gph bitreich.org 70 hAuthor: Josuah Demangeon URL:mailto:josuah.demangeon@gandi.net bitreich.org 70 iDate: Tue, 22 Aug 2017 19:48:53 +0200 Err bitreich.org 70 i Err bitreich.org 70 iutf8.[ch]: imported utf8len() and utf8check() Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M iomenu.c | 37 ++++++++++++++++--------------- Err bitreich.org 70 i D utf.c | 332 ------------------------------- Err bitreich.org 70 i D utf.h | 18 ------------------ Err bitreich.org 70 i A utf8.c | 142 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i A utf8.h | 5 +++++ Err bitreich.org 70 i Err bitreich.org 70 i5 files changed, 166 insertions(+), 368 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/iomenu.c b/iomenu.c /scm/iomenu/file/iomenu.c.gph bitreich.org 70 i@@ -12,9 +12,9 @@ Err bitreich.org 70 i Err bitreich.org 70 i #define CONTINUE 2 /* as opposed to EXIT_SUCCESS and EXIT_FAILURE */ Err bitreich.org 70 i Err bitreich.org 70 i-#define CONTROL(char) (char ^ 0x40) Err bitreich.org 70 i+#define CTL(char) (char ^ 0x40) Err bitreich.org 70 i #define ALT(char) (char + 0x80) Err bitreich.org 70 i-#define ESC(char) (char + 0x80 + 0x80) Err bitreich.org 70 i+#define CSI(char) (char + 0x80 + 0x80) Err bitreich.org 70 i #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) Err bitreich.org 70 i Err bitreich.org 70 i static struct winsize ws; Err bitreich.org 70 i@@ -74,7 +74,7 @@ resetterminal(void) Err bitreich.org 70 i int i; Err bitreich.org 70 i Err bitreich.org 70 i /* clear terminal */ Err bitreich.org 70 i- for (i = 0; i < opt['l'] + 1; i++) Err bitreich.org 70 i+ for (i = 0; i < rows + 1; i++) Err bitreich.org 70 i fputs("\r\033[K\n", stderr); Err bitreich.org 70 i Err bitreich.org 70 i /* reset cursor position */ Err bitreich.org 70 i@@ -322,61 +322,61 @@ key(void) Err bitreich.org 70 i top: Err bitreich.org 70 i switch (key) { Err bitreich.org 70 i Err bitreich.org 70 i- case CONTROL('C'): Err bitreich.org 70 i+ case CTL('C'): Err bitreich.org 70 i return EXIT_FAILURE; Err bitreich.org 70 i Err bitreich.org 70 i- case CONTROL('U'): Err bitreich.org 70 i+ case CTL('U'): Err bitreich.org 70 i input[0] = '\0'; Err bitreich.org 70 i filter(); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i- case CONTROL('W'): Err bitreich.org 70 i+ case CTL('W'): Err bitreich.org 70 i removeword(); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i case 127: Err bitreich.org 70 i- case CONTROL('H'): /* backspace */ 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(); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i- case ESC('A'): /* up */ Err bitreich.org 70 i- case CONTROL('P'): 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 break; Err bitreich.org 70 i Err bitreich.org 70 i- case ESC('B'): /* down */ Err bitreich.org 70 i- case CONTROL('N'): 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 break; Err bitreich.org 70 i Err bitreich.org 70 i- case ESC('5'): Err bitreich.org 70 i+ case CSI('5'): /* page up */ Err bitreich.org 70 i if (fgetc(stdin) != '~') break; Err bitreich.org 70 i /* FALLTHROUGH */ Err bitreich.org 70 i case ALT('v'): Err bitreich.org 70 i movepg(-1); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i- case ESC('6'): Err bitreich.org 70 i+ case CSI('6'): /* page down */ Err bitreich.org 70 i if (fgetc(stdin) != '~') break; Err bitreich.org 70 i /* FALLTHROUGH */ Err bitreich.org 70 i- case CONTROL('V'): Err bitreich.org 70 i+ case CTL('V'): Err bitreich.org 70 i movepg(+1); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i- case CONTROL('I'): /* tab */ Err bitreich.org 70 i+ case CTL('I'): /* tab */ Err bitreich.org 70 i if (linec > 0) Err bitreich.org 70 i strcpy(input, matchv[current]); Err bitreich.org 70 i filter(); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i- case CONTROL('J'): /* enter */ Err bitreich.org 70 i- case CONTROL('M'): Err bitreich.org 70 i+ case CTL('J'): /* enter */ Err bitreich.org 70 i+ case CTL('M'): Err bitreich.org 70 i printselection(); Err bitreich.org 70 i return EXIT_SUCCESS; Err bitreich.org 70 i Err bitreich.org 70 i case ALT('['): Err bitreich.org 70 i- key = ESC(fgetc(stdin)); Err bitreich.org 70 i+ key = CSI(fgetc(stdin)); Err bitreich.org 70 i goto top; Err bitreich.org 70 i Err bitreich.org 70 i case 033: /* escape / alt */ Err bitreich.org 70 i@@ -464,6 +464,7 @@ main(int argc, char *argv[]) Err bitreich.org 70 i input[0] = '\0'; Err bitreich.org 70 i while ((exitcode = key()) == CONTINUE) Err bitreich.org 70 i printscreen(); Err bitreich.org 70 i+ printscreen(); Err bitreich.org 70 i Err bitreich.org 70 i resetterminal(); Err bitreich.org 70 i close(ttyfd); Err bitreich.org 70 1diff --git a/utf.c b/utf.c /scm/iomenu/file/utf.c.gph bitreich.org 70 i@@ -1,332 +0,0 @@ Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Functions handling UTF-8 strings: Err bitreich.org 70 i- * Err bitreich.org 70 i- * stdin -> buffer -> stdout Err bitreich.org 70 i- * UTF-8 -> rune -> UTF-8 Err bitreich.org 70 i- * char[] -> long[] -> char[] 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- Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-#include "utf.h" Err bitreich.org 70 i- Err bitreich.org 70 i- Err bitreich.org 70 i-/* --- lengths -------------------------------------------------------------- */ 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 in rune for the `n` next char in `s`, Err bitreich.org 70 i- * or 0 if ti is misencoded. Err bitreich.org 70 i- */ Err bitreich.org 70 i-int Err bitreich.org 70 i-utflen(char *s, int n) Err bitreich.org 70 i-{ Err bitreich.org 70 i- int len = 1; Err bitreich.org 70 i- int continuation_bytes = Err bitreich.org 70 i- (s[0] & 0x80) == 0x00 ? 0 : /* 0xxxxxxx */ Err bitreich.org 70 i- (s[0] & 0xc0) == 0x80 ? 1 : /* 10xxxxxx */ Err bitreich.org 70 i- (s[0] & 0xe0) == 0xc0 ? 2 : /* 110xxxxx */ Err bitreich.org 70 i- (s[0] & 0xf0) == 0xe0 ? 3 : /* 1110xxxx */ Err bitreich.org 70 i- (s[0] & 0xf8) == 0xf0 ? 4 : /* 11110xxx */ Err bitreich.org 70 i- (s[0] & 0xfc) == 0xf8 ? 5 : /* 111110xx */ Err bitreich.org 70 i- (s[0] & 0xfe) == 0xfc ? 6 : /* 1111110x */ Err bitreich.org 70 i- (s[0] & 0xff) == 0xfe ? 7 : /* 11111110 */ Err bitreich.org 70 i- 8; /* 11111111 */ Err bitreich.org 70 i- Err bitreich.org 70 i- if (continuation_bytes > 6 || continuation_bytes > n) Err bitreich.org 70 i- return 0; Err bitreich.org 70 i- Err bitreich.org 70 i- /* check if continuation bytes are 10xxxxxx and increment `len` */ Err bitreich.org 70 i- switch (continuation_bytes) { /* FALLTHROUGH */ Err bitreich.org 70 i- case 7: if ((s[6] & 0xc0) != 0x80) return 0; else len++; Err bitreich.org 70 i- case 6: if ((s[5] & 0xc0) != 0x80) return 0; else len++; Err bitreich.org 70 i- case 5: if ((s[4] & 0xc0) != 0x80) return 0; else len++; Err bitreich.org 70 i- case 4: if ((s[3] & 0xc0) != 0x80) return 0; else len++; Err bitreich.org 70 i- case 3: if ((s[2] & 0xc0) != 0x80) return 0; else len++; Err bitreich.org 70 i- case 2: if ((s[1] & 0xc0) != 0x80) return 0; else len++; Err bitreich.org 70 i- case 0: return len; Err bitreich.org 70 i- default: 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-/* 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-runelen(long r) Err bitreich.org 70 i-{ Err bitreich.org 70 i- if (r <= 0x0000007f) return 1; Err bitreich.org 70 i- if (r <= 0x000007ff) return 2; Err bitreich.org 70 i- if (r <= 0x0000ffff) return 3; Err bitreich.org 70 i- if (r <= 0x001fffff) return 4; Err bitreich.org 70 i- if (r <= 0x03ffffff) return 5; Err bitreich.org 70 i- if (r <= 0x7fffffff) return 6; 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-/* --- conversions ---------------------------------------------------------- */ Err bitreich.org 70 i- Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Sets `r` to a rune corresponding to the firsts `n` bytes of `s`. Err bitreich.org 70 i- * If `s` is misencoded, the rune is stored as a negative value. Err bitreich.org 70 i- * Err bitreich.org 70 i- * Return the number of bytes read. Err bitreich.org 70 i- */ Err bitreich.org 70 i-int Err bitreich.org 70 i-utftorune(long *r, char *s, int n) Err bitreich.org 70 i-{ Err bitreich.org 70 i- int len = utflen(s, n), i; Err bitreich.org 70 i- Err bitreich.org 70 i- /* first byte */ Err bitreich.org 70 i- switch (len) { Err bitreich.org 70 i- case 1: *r = s[0]; return 1; /* 0xxxxxxx */ Err bitreich.org 70 i- case 2: *r = s[0] & 0x1f; break; /* 110xxxxx */ Err bitreich.org 70 i- case 3: *r = s[0] & 0x0f; break; /* 1110xxxx */ Err bitreich.org 70 i- case 4: *r = s[0] & 0x07; break; /* 11110xxx */ Err bitreich.org 70 i- case 5: *r = s[0] & 0x03; break; /* 111110xx */ Err bitreich.org 70 i- case 6: *r = s[0] & 0x01; break; /* 1111110x */ Err bitreich.org 70 i- default: *r = -(unsigned char) s[0]; return 1; /* misencoded */ Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- /* continuation bytes */ Err bitreich.org 70 i- for (i = 1; i < len; i++) Err bitreich.org 70 i- *r = (*r << 6) | (s[i] & 0x3f); /* 10xxxxxx */ Err bitreich.org 70 i- Err bitreich.org 70 i- /* overlong sequences */ Err bitreich.org 70 i- if (runelen(*r) != len) { Err bitreich.org 70 i- *r = -(unsigned char) s[0]; Err bitreich.org 70 i- return 1; 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- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Convert the utf char sring `src` of size `n` to a long string Err bitreich.org 70 i- * `dest`. Err bitreich.org 70 i- * Err bitreich.org 70 i- * Return the length of `i`. Err bitreich.org 70 i- */ Err bitreich.org 70 i-size_t Err bitreich.org 70 i-utftorunes(long *runes, char *utf, size_t n) Err bitreich.org 70 i-{ Err bitreich.org 70 i- size_t i, j; Err bitreich.org 70 i- Err bitreich.org 70 i- for (i = 0, j = 0; n > 0; i++) Err bitreich.org 70 i- j += utftorune(runes + i, utf + j, n - j); Err bitreich.org 70 i- Err bitreich.org 70 i- runes[i] = '\0'; Err bitreich.org 70 i- return i; 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- * Encode the rune `r` in utf-8 in `s`, null-terminated. Err bitreich.org 70 i- * Err bitreich.org 70 i- * Return the number of bytes written, 0 if `r` is invalid. Err bitreich.org 70 i- */ Err bitreich.org 70 i-int Err bitreich.org 70 i-runetoutf(char *s, long r) Err bitreich.org 70 i-{ Err bitreich.org 70 i- switch (runelen(r)) { Err bitreich.org 70 i- case 1: Err bitreich.org 70 i- s[0] = r; /* 0xxxxxxx */ Err bitreich.org 70 i- s[1] = '\0'; Err bitreich.org 70 i- return 1; Err bitreich.org 70 i- case 2: Err bitreich.org 70 i- s[0] = 0xc0 | (0x1f & (r >> 6)); /* 110xxxxx */ Err bitreich.org 70 i- s[1] = 0x80 | (0x3f & (r)); /* 10xxxxxx */ Err bitreich.org 70 i- s[2] = '\0'; Err bitreich.org 70 i- return 2; Err bitreich.org 70 i- case 3: Err bitreich.org 70 i- s[0] = 0xe0 | (0x0f & (r >> 12)); /* 1110xxxx */ Err bitreich.org 70 i- s[1] = 0x80 | (0x3f & (r >> 6)); /* 10xxxxxx */ Err bitreich.org 70 i- s[2] = 0x80 | (0x3f & (r)); /* 10xxxxxx */ Err bitreich.org 70 i- s[3] = '\0'; Err bitreich.org 70 i- return 3; Err bitreich.org 70 i- case 4: Err bitreich.org 70 i- s[0] = 0xf0 | (0x07 & (r >> 18)); /* 11110xxx */ Err bitreich.org 70 i- s[1] = 0x80 | (0x3f & (r >> 12)); /* 10xxxxxx */ Err bitreich.org 70 i- s[2] = 0x80 | (0x3f & (r >> 6)); /* 10xxxxxx */ Err bitreich.org 70 i- s[3] = 0x80 | (0x3f & (r)); /* 10xxxxxx */ Err bitreich.org 70 i- s[4] = '\0'; Err bitreich.org 70 i- return 4; Err bitreich.org 70 i- case 5: Err bitreich.org 70 i- s[0] = 0xf8 | (0x03 & (r >> 24)); /* 111110xx */ Err bitreich.org 70 i- s[1] = 0x80 | (0x3f & (r >> 18)); /* 10xxxxxx */ Err bitreich.org 70 i- s[2] = 0x80 | (0x3f & (r >> 12)); /* 10xxxxxx */ Err bitreich.org 70 i- s[3] = 0x80 | (0x3f & (r >> 6)); /* 10xxxxxx */ Err bitreich.org 70 i- s[4] = 0x80 | (0x3f & (r)); /* 10xxxxxx */ Err bitreich.org 70 i- s[5] = '\0'; Err bitreich.org 70 i- return 5; Err bitreich.org 70 i- case 6: Err bitreich.org 70 i- s[0] = 0xfc | (0x01 & (r >> 30)); /* 1111110x */ Err bitreich.org 70 i- s[1] = 0x80 | (0x3f & (r >> 24)); /* 10xxxxxx */ Err bitreich.org 70 i- s[2] = 0x80 | (0x3f & (r >> 18)); /* 10xxxxxx */ Err bitreich.org 70 i- s[3] = 0x80 | (0x3f & (r >> 12)); /* 10xxxxxx */ Err bitreich.org 70 i- s[4] = 0x80 | (0x3f & (r >> 6)); /* 10xxxxxx */ Err bitreich.org 70 i- s[5] = 0x80 | (0x3f & (r)); /* 10xxxxxx */ Err bitreich.org 70 i- s[6] = '\0'; Err bitreich.org 70 i- return 6; Err bitreich.org 70 i- default: Err bitreich.org 70 i- s[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-/* Err bitreich.org 70 i- * Fill `s` with a printable representation of `r`. Err bitreich.org 70 i- * Err bitreich.org 70 i- * Return the width of the character. Err bitreich.org 70 i- */ Err bitreich.org 70 i-int Err bitreich.org 70 i-runetoprint(char *s, long r) Err bitreich.org 70 i-{ Err bitreich.org 70 i- if (r < 0) { Err bitreich.org 70 i- return sprintf(s, "[%02x]", (unsigned char) -r); Err bitreich.org 70 i- Err bitreich.org 70 i- } else if (r == 0x7f || r < ' ') { Err bitreich.org 70 i- return sprintf(s, "[%02lx]", r); Err bitreich.org 70 i- Err bitreich.org 70 i- } else if (!runeisprint(r)) { Err bitreich.org 70 i- return sprintf(s, "[%04lx]", r); Err bitreich.org 70 i- Err bitreich.org 70 i- } else { Err bitreich.org 70 i- runetoutf(s, r); Err bitreich.org 70 i- return 1; 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 i- Err bitreich.org 70 i- Err bitreich.org 70 i-/* --- standard library ----------------------------------------------------- */ Err bitreich.org 70 i- Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Returns 1 if the rune is a printable character and 0 if not. Err bitreich.org 70 i- */ Err bitreich.org 70 i-int Err bitreich.org 70 i-runeisprint(long r) Err bitreich.org 70 i-{ Err bitreich.org 70 i- return !( Err bitreich.org 70 i- (r != '\t' && r < ' ') || /* ascii control */ Err bitreich.org 70 i- (r == 0x7f) || Err bitreich.org 70 i- Err bitreich.org 70 i- (0x80 <= r && r < 0xa0) || /* unicode control */ Err bitreich.org 70 i- Err bitreich.org 70 i- (r > 0x10ffff) || /* outside range */ Err bitreich.org 70 i- Err bitreich.org 70 i- ((r & 0x00fffe) == 0x00fffe) || /* noncharacters */ Err bitreich.org 70 i- (0x00fdd0 <= r && r <= 0x00fdef) || Err bitreich.org 70 i- Err bitreich.org 70 i- (0x00e000 <= r && r <= 0x00f8ff) || /* private use */ Err bitreich.org 70 i- (0x0f0000 <= r && r <= 0x0ffffd) || Err bitreich.org 70 i- (0x100000 <= r && r <= 0x10fffd) || Err bitreich.org 70 i- Err bitreich.org 70 i- (0x00d800 <= r && r <= 0x00dfff) /* surrogates */ 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-/* Err bitreich.org 70 i- * Read an utf string from `f` up to the first '\n' character or the Err bitreich.org 70 i- * end of the file. It is stored as a rune array into the newly Err bitreich.org 70 i- * allocated `r`. Err bitreich.org 70 i- * Err bitreich.org 70 i- * Return the length of `r`, or -1 if malloc fails or if the end of Err bitreich.org 70 i- * `f` is reached. Err bitreich.org 70 i- */ Err bitreich.org 70 i-size_t Err bitreich.org 70 i-getrunes(long **r, FILE *f) Err bitreich.org 70 i-{ Err bitreich.org 70 i- size_t slen, rlen = 0, size = BUFSIZ, i; Err bitreich.org 70 i- int c; Err bitreich.org 70 i- char *s; Err bitreich.org 70 i- Err bitreich.org 70 i- if (!(s = malloc(size))) return -1; Err bitreich.org 70 i- for (slen = 0; (c = fgetc(f)) != EOF && (c != '\n'); slen++) { Err bitreich.org 70 i- if (slen > size && !(s = realloc(s, ++size))) return -1; Err bitreich.org 70 i- s[slen] = c; Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- if (!(*r = malloc(size * sizeof (long)))) return -1; Err bitreich.org 70 i- for (i = 0; i < slen; rlen++) Err bitreich.org 70 i- i += utftorune(*r + rlen, s + i, slen - i); Err bitreich.org 70 i- (*r)[rlen] = '\0'; Err bitreich.org 70 i- Err bitreich.org 70 i- free(s); Err bitreich.org 70 i- if (feof(f)) return -1; else return rlen; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i- Err bitreich.org 70 i-long * Err bitreich.org 70 i-runescpy(long *dest, long *src) Err bitreich.org 70 i-{ Err bitreich.org 70 i- size_t i; Err bitreich.org 70 i- Err bitreich.org 70 i- for (i = 0; src[i] != '\0'; i++) Err bitreich.org 70 i- dest[i] = src[i]; Err bitreich.org 70 i- dest[i] = '\0'; Err bitreich.org 70 i- Err bitreich.org 70 i- return dest; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i- Err bitreich.org 70 i-long * Err bitreich.org 70 i-runeschr(long *s, long r) Err bitreich.org 70 i-{ Err bitreich.org 70 i- size_t i; Err bitreich.org 70 i- Err bitreich.org 70 i- for (i = 0; s[i] != '\0'; i++) Err bitreich.org 70 i- if (s[i] == r) return s + i; Err bitreich.org 70 i- Err bitreich.org 70 i- return NULL; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i- Err bitreich.org 70 i-long * Err bitreich.org 70 i-runescat(long *s1, long *s2) Err bitreich.org 70 i-{ Err bitreich.org 70 i- size_t i, j; Err bitreich.org 70 i- Err bitreich.org 70 i- for (i = 0; s1[i] != '\0'; i++); Err bitreich.org 70 i- for (j = 0; s2[j] != '\0'; j++) Err bitreich.org 70 i- s1[i + j] = s2[j]; Err bitreich.org 70 i- s1[i + j] = '\0'; Err bitreich.org 70 i- Err bitreich.org 70 i- return s1; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-main() Err bitreich.org 70 i-{ Err bitreich.org 70 i- char s[BUFSIZ]; Err bitreich.org 70 i- long *r; Err bitreich.org 70 i- int len, i; Err bitreich.org 70 i- Err bitreich.org 70 i- for (len = 0; (len = getrunes(&r, stdin)) >= 0 && !feof(stdin); free(r)) { Err bitreich.org 70 i- for (i = 0; i < len; i++) { Err bitreich.org 70 i- runetoprint(s, r[i]); Err bitreich.org 70 i- fputs(s, stdout); Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- putchar('\n'); Err bitreich.org 70 i- } Err bitreich.org 70 i- free(r); Err bitreich.org 70 i- Err bitreich.org 70 i- return 0; Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/utf.h b/utf.h /scm/iomenu/file/utf.h.gph bitreich.org 70 i@@ -1,18 +0,0 @@ Err bitreich.org 70 i-/* lengths */ Err bitreich.org 70 i-int utflen(char *, int); Err bitreich.org 70 i-int runelen(long); Err bitreich.org 70 i- Err bitreich.org 70 i-/* conversions */ Err bitreich.org 70 i-int utftorune(long *, char *, int); Err bitreich.org 70 i-int utftorune(long *, char *, int); Err bitreich.org 70 i-int runetoutf(char *, long); Err bitreich.org 70 i-int runetoprint(char *, long); Err bitreich.org 70 i- Err bitreich.org 70 i- Err bitreich.org 70 i-/* standard library */ Err bitreich.org 70 i- Err bitreich.org 70 i-int runeisprint(long); Err bitreich.org 70 i-size_t getrunes(long **, FILE *); Err bitreich.org 70 i-long * runescpy(long *, long *); Err bitreich.org 70 i-long * runeschr(long *, long); Err bitreich.org 70 i-long * runescat(long *, long *); Err bitreich.org 70 1diff --git a/utf8.c b/utf8.c /scm/iomenu/file/utf8.c.gph bitreich.org 70 i@@ -0,0 +1,142 @@ 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(7) 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+ * The whole character value is retreived into an 'x' and stored into a Err bitreich.org 70 i+ * (long)[]. 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+ Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i+#include "utf8.h" 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 in rune for the `n` next char in `s`, Err bitreich.org 70 i+ * or 0 if ti is misencoded. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+size_t Err bitreich.org 70 i+utf8len(char *s, int n) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ unsigned char *sp = (unsigned char *) s; Err bitreich.org 70 i+ int i, len = (*sp < 0x80) ? 1 : /* 0xxxxxxx < 10000000 */ Err bitreich.org 70 i+ (*sp < 0xc0) ? 0 : /* 10xxxxxx < 11000000 */ Err bitreich.org 70 i+ (*sp < 0xe0) ? 2 : /* 110xxxxx < 11100000 */ Err bitreich.org 70 i+ (*sp < 0xf0) ? 3 : /* 1110xxxx < 11110000 */ Err bitreich.org 70 i+ (*sp < 0xf8) ? 4 : /* 11110xxx < 11111000 */ Err bitreich.org 70 i+ (*sp < 0xfc) ? 5 : /* 111110xx < 11111100 */ Err bitreich.org 70 i+ (*sp < 0xfe) ? 6 : /* 1111110x < 11111110 */ Err bitreich.org 70 i+ (*sp < 0xff) ? 7 : /* 11111110 < 11111111 */ Err bitreich.org 70 i+ 0; Err bitreich.org 70 i+ if (len > n) return 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* check continuation bytes */ Err bitreich.org 70 i+ for (sp++, i = 1; i < len; i++, sp++) Err bitreich.org 70 i+ if ((*sp & 0xc0) != 0x80) /* 10xxxxxx & 11000000 */ 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+/* 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+size_t Err bitreich.org 70 i+utf8runelen(long r) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return (r <= 0x0000007f) ? 1 : (r <= 0x000007ff) ? 2 : Err bitreich.org 70 i+ (r <= 0x0000ffff) ? 3 : (r <= 0x001fffff) ? 4 : Err bitreich.org 70 i+ (r <= 0x03ffffff) ? 5 : (r <= 0x7fffffff) ? 6 : 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+ * Sets 'r' to a rune corresponding to the firsts 'n' bytes of 's'. Err bitreich.org 70 i+ * Err bitreich.org 70 i+ * Return the number of bytes read or 0 if the string is misencoded. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+size_t Err bitreich.org 70 i+utf8torune(long *r, char *s, size_t n) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ char mask[] = { 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; Err bitreich.org 70 i+ size_t i, len = utf8len(s, n); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (len == 0 || len > 6 || len > n) Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* first byte */ Err bitreich.org 70 i+ *r = *s++ & mask[len - 1]; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* continuation bytes */ Err bitreich.org 70 i+ for (i = 1; i < len; i++) Err bitreich.org 70 i+ *r = (*r << 6) | (*s++ & 0x3f); /* 10xxxxxx */ Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* overlong sequences */ Err bitreich.org 70 i+ if (utf8runelen(*r) != len) 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+/* Err bitreich.org 70 i+ * Returns 1 if the rune is a valid unicode code point and 0 if not. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+int Err bitreich.org 70 i+utf8runeisunicode(long r) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return !( Err bitreich.org 70 i+ (r > 0x10ffff) || /* outside range */ Err bitreich.org 70 i+ Err bitreich.org 70 i+ ((r & 0x00fffe) == 0x00fffe) || /* noncharacters */ Err bitreich.org 70 i+ (0x00fdd0 <= r && r <= 0x00fdef) || Err bitreich.org 70 i+ Err bitreich.org 70 i+ (0x00e000 <= r && r <= 0x00f8ff) || /* private use */ Err bitreich.org 70 i+ (0x0f0000 <= r && r <= 0x0ffffd) || Err bitreich.org 70 i+ (0x100000 <= r && r <= 0x10fffd) || Err bitreich.org 70 i+ Err bitreich.org 70 i+ (0x00d800 <= r && r <= 0x00dfff) /* surrogates */ 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+/* Err bitreich.org 70 i+ * Return 1 if '*s' is correctly encoded in UTF-8 with allowed Unicode Err bitreich.org 70 i+ * code points. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+int Err bitreich.org 70 i+utf8check(char *s, size_t len) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ size_t shift; Err bitreich.org 70 i+ long r = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ while (len > 0) { Err bitreich.org 70 i+ shift = utf8torune(&r, s, len); Err bitreich.org 70 i+ if (!shift || !utf8runeisunicode(r)) Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ s += shift; Err bitreich.org 70 i+ len -= shift; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+} Err bitreich.org 70 1diff --git a/utf8.h b/utf8.h /scm/iomenu/file/utf8.h.gph bitreich.org 70 i@@ -0,0 +1,5 @@ Err bitreich.org 70 i+size_t utf8len(char *, int); Err bitreich.org 70 i+size_t utf8runelen(long); Err bitreich.org 70 i+size_t utf8torune(long *, char *, size_t); Err bitreich.org 70 i+int utf8runeisunicode(long); Err bitreich.org 70 i+int utf8check(char *, size_t); Err bitreich.org 70 .