iadded character class function - 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 fa78594463743c4e84f2ad6dbcf599326f170539 /scm/iomenu/commit/fa78594463743c4e84f2ad6dbcf599326f170539.gph bitreich.org 70 1parent 353e9eb3f5f4df50ed5802ee14c593c29eba706e /scm/iomenu/commit/353e9eb3f5f4df50ed5802ee14c593c29eba706e.gph bitreich.org 70 hAuthor: Josuah Demangeonā  ā µ URL:mailto:mail@josuah.net bitreich.org 70 iDate: Sun, 2 Apr 2017 15:51:21 +0200 Err bitreich.org 70 i Err bitreich.org 70 iadded character class function Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i D text.c | 259 ------------------------------- Err bitreich.org 70 i D text.h | 11 ----------- Err bitreich.org 70 i A utf.c | 263 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i A utf.h | 14 ++++++++++++++ Err bitreich.org 70 i Err bitreich.org 70 i4 files changed, 277 insertions(+), 270 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/text.c b/text.c /scm/iomenu/file/text.c.gph bitreich.org 70 i@@ -1,259 +0,0 @@ Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Functions handling UTF-8 srings: 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- 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 "text.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- * Thanks to Connor Lane Smith for the idea of using 0x??. 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 display `rune` 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-/* Err bitreich.org 70 i- * Sets `r` to a rune corresponding to the firsts `n` bytes of `s` Err bitreich.org 70 i- * and return the number of bytes read. 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-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); 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 (int 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- * Encode the rune `r` in utf-8 in `s`, null-terminated, and return Err bitreich.org 70 i- * 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- } 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-/* Err bitreich.org 70 i- * Read a newly allocated string from `f` up to the first '\n' Err bitreich.org 70 i- * character or the end of the fifle. It is stored as a rune array, Err bitreich.org 70 i- * and `r` is set to point to it. Err bitreich.org 70 i- */ Err bitreich.org 70 i-int Err bitreich.org 70 i-getutf(long **r, FILE *f) Err bitreich.org 70 i-{ Err bitreich.org 70 i- int slen, rlen = 0, c, size = BUFSIZ; 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- s[slen] = c; Err bitreich.org 70 i- Err bitreich.org 70 i- if (slen >= size) Err bitreich.org 70 i- if (!(s = realloc(s, ++size))) return -1; 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 (int i = 0; i < slen; rlen++) Err bitreich.org 70 i- i += utftorune(*r + rlen, s + i, slen - i); Err bitreich.org 70 i- Err bitreich.org 70 i- free(s); Err bitreich.org 70 i- return rlen; 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` and return the Err bitreich.org 70 i- * width of the character. The tab characters are converted to Err bitreich.org 70 i- * spaces as if it was at the column `col`. Err bitreich.org 70 i- */ Err bitreich.org 70 i-int Err bitreich.org 70 i-runetoprint(char *s, long r, int col) Err bitreich.org 70 i-{ Err bitreich.org 70 i- /* invalid */ Err bitreich.org 70 i- if (r < 0) { Err bitreich.org 70 i- sprintf(s, "[%02x]", (unsigned char) -r); Err bitreich.org 70 i- Err bitreich.org 70 i- } else if (r == '\t') { Err bitreich.org 70 i- int i; Err bitreich.org 70 i- for (i = 0; i < (col + 1) % 8 - 1; i++) Err bitreich.org 70 i- s[i] = ' '; Err bitreich.org 70 i- s[i] = '\0'; s[0] = '|'; Err bitreich.org 70 i- Err bitreich.org 70 i- /* ascii control */ Err bitreich.org 70 i- } else if (r == 0x7f || r < ' ') { Err bitreich.org 70 i- sprintf(s, "[%02lx]", r); Err bitreich.org 70 i- Err bitreich.org 70 i- /* utf-8 but not printable */ Err bitreich.org 70 i- } else if ( Err bitreich.org 70 i- /* unicode control */ Err bitreich.org 70 i- (0x80 <= r && r < 0xa0) || Err bitreich.org 70 i- Err bitreich.org 70 i- /* outside range */ Err bitreich.org 70 i- (r > 0x10ffff) || Err bitreich.org 70 i- Err bitreich.org 70 i- /* noncharacters */ Err bitreich.org 70 i- (r % 0x010000 == 0x00fffe) || Err bitreich.org 70 i- (r % 0x010000 == 0x00ffff) || Err bitreich.org 70 i- (0x00fdd0 <= r && r <= 0x00fdef) || Err bitreich.org 70 i- Err bitreich.org 70 i- /* private use */ Err bitreich.org 70 i- (0x00e000 <= r && r <= 0x00f8ff) || 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- /* surrogates */ Err bitreich.org 70 i- (0x00d800 <= r && r <= 0x00dfff) Err bitreich.org 70 i- ) { Err bitreich.org 70 i- sprintf(s, "[%04x]", (unsigned int) r); Err bitreich.org 70 i- Err bitreich.org 70 i- /* valid unicode characters */ 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-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- Err bitreich.org 70 i- for (int len; (len = getutf(&r, stdin)) >= 0 && !feof(stdin); free(r)) { Err bitreich.org 70 i- for (int i = 0; i < len; i++) { Err bitreich.org 70 i- runetoprint(s, r[i], 0); 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/text.h b/text.h /scm/iomenu/file/text.h.gph bitreich.org 70 i@@ -1,11 +0,0 @@ Err bitreich.org 70 i-/* rune / utf length */ 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-/* decode / encode */ Err bitreich.org 70 i-int utftorune(long *, char *, int); Err bitreich.org 70 i-int runetoutf(char *, long); Err bitreich.org 70 i- Err bitreich.org 70 i-/* stdin / stdout */ Err bitreich.org 70 i-int getutf(long **, FILE *); Err bitreich.org 70 i-int runetoprint(char *, long, int); Err bitreich.org 70 1diff --git a/utf.c b/utf.c /scm/iomenu/file/utf.c.gph bitreich.org 70 i@@ -0,0 +1,263 @@ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * Functions handling UTF-8 srings: 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+ 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+/* 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+ * Thanks to Connor Lane Smith for the idea of using 0x??. 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 display `rune` 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+/* Err bitreich.org 70 i+ * Sets `r` to a rune corresponding to the firsts `n` bytes of `s` Err bitreich.org 70 i+ * and return the number of bytes read. 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+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); 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 (int 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+ * Encode the rune `r` in utf-8 in `s`, null-terminated, and return Err bitreich.org 70 i+ * 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+ } 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+/* Err bitreich.org 70 i+ * Read a newly allocated string from `f` up to the first '\n' Err bitreich.org 70 i+ * character or the end of the fifle. It is stored as a rune array, Err bitreich.org 70 i+ * and `r` is set to point to it. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+int Err bitreich.org 70 i+getutf(long **r, FILE *f) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ int slen, rlen = 0, c, size = BUFSIZ; 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+ s[slen] = c; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (slen >= size) Err bitreich.org 70 i+ if (!(s = realloc(s, ++size))) return -1; 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 (int i = 0; i < slen; rlen++) Err bitreich.org 70 i+ i += utftorune(*r + rlen, s + i, slen - i); Err bitreich.org 70 i+ Err bitreich.org 70 i+ free(s); Err bitreich.org 70 i+ return rlen; 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 printable character and 0 if not. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+int Err bitreich.org 70 i+isprintrune(long r) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return !( Err bitreich.org 70 i+ (r == 0x7f || r < ' ') || /* ascii control */ 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 % 0x010000 == 0x00fffe) || /* noncharacters */ Err bitreich.org 70 i+ (r % 0x010000 == 0x00ffff) || 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+ * Fill `s` with a printable representation of `r` and return the Err bitreich.org 70 i+ * width of the character. The tab characters are converted to Err bitreich.org 70 i+ * spaces as if it was at the column `col`. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+int Err bitreich.org 70 i+runetoprint(char *s, long r, int col) 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 (!isprintrune(r)) { Err bitreich.org 70 i+ return sprintf(s, "[%04lx]", r); Err bitreich.org 70 i+ Err bitreich.org 70 i+ } else if (r == '\t') { Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ for (i = 1; (col + i) % 8 != 0; i++) Err bitreich.org 70 i+ s[i] = ' '; Err bitreich.org 70 i+ s[0] = ' '; s[i] = '\0'; Err bitreich.org 70 i+ return i; 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+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+ Err bitreich.org 70 i+ for (int len; (len = getutf(&r, stdin)) >= 0 && !feof(stdin); free(r)) { Err bitreich.org 70 i+ for (int i = 0; i < len; i++) { Err bitreich.org 70 i+ runetoprint(s, r[i], 0); 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@@ -0,0 +1,14 @@ Err bitreich.org 70 i+/* rune / utf length */ 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+/* decode / encode */ Err bitreich.org 70 i+int utftorune(long *, char *, int); Err bitreich.org 70 i+int runetoutf(char *, long); Err bitreich.org 70 i+ Err bitreich.org 70 i+/* rune class */ Err bitreich.org 70 i+int isprintrune(long); Err bitreich.org 70 i+ Err bitreich.org 70 i+/* stdin / stdout */ Err bitreich.org 70 i+int getutf(long **, FILE *); Err bitreich.org 70 i+int runetoprint(char *, long, int); Err bitreich.org 70 .