iAdded embedded UTF-8 handling library - 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 e01fa60f7992641ba6f3f5109dec6783e397a248 /scm/iomenu/commit/e01fa60f7992641ba6f3f5109dec6783e397a248.gph bitreich.org 70 1parent bc428475d5d8e678f99f9006aab8bc1d656c61b6 /scm/iomenu/commit/bc428475d5d8e678f99f9006aab8bc1d656c61b6.gph bitreich.org 70 hAuthor: Josuah Demangeonā  ā µ URL:mailto:mail@josuah.net bitreich.org 70 iDate: Mon, 3 Apr 2017 23:50:45 +0200 Err bitreich.org 70 i Err bitreich.org 70 iAdded embedded UTF-8 handling library Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M iomenu.c | 2 +- Err bitreich.org 70 i M utf.c | 188 +++++++++++++++++++++---------- Err bitreich.org 70 i M utf.h | 22 ++++++++++++---------- Err bitreich.org 70 i Err bitreich.org 70 i3 files changed, 141 insertions(+), 71 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@@ -11,7 +11,7 @@ Err bitreich.org 70 i #include Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-#define OFFSET 30 /* in horizontal mode, amount of space kept for writing */ Err bitreich.org 70 i+#define OFFSET 40 /* in horizontal mode, amount of space kept for writing */ 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 1diff --git a/utf.c b/utf.c /scm/iomenu/file/utf.c.gph bitreich.org 70 i@@ -1,9 +1,12 @@ Err bitreich.org 70 i /* Err bitreich.org 70 i- * Functions handling UTF-8 srings: 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@@ -14,11 +17,12 @@ 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- * 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@@ -53,7 +57,8 @@ utflen(char *s, int n) 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+ * 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@@ -68,15 +73,19 @@ runelen(long r) 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- * 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+ * 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); 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@@ -90,7 +99,7 @@ utftorune(long *r, char *s, int n) 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+ 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@@ -104,8 +113,28 @@ utftorune(long *r, char *s, int n) 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+ * 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 *runev, 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(runev + i, utf[j], n - j); Err bitreich.org 70 i+ Err bitreich.org 70 i+ runev[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@@ -150,12 +179,42 @@ runetoutf(char *s, long r) 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 (!isprintrune(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@@ -163,14 +222,13 @@ 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+ (r < ' ' || r == 0x7f) || /* 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+ ((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@@ -183,63 +241,72 @@ isprintrune(long r) 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+ * 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-int Err bitreich.org 70 i-runetoprint(char *s, long r, int col) 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- if (r < 0) { Err bitreich.org 70 i- return sprintf(s, "[%02x]", (unsigned char) -r); 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- } else if (r == 0x7f || r < ' ') { Err bitreich.org 70 i- return sprintf(s, "[%02lx]", r); 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- } else if (!isprintrune(r)) { Err bitreich.org 70 i- return sprintf(s, "[%04lx]", r); 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- } 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+ free(s); Err bitreich.org 70 i+ return feof(f) ? -1 : rlen; Err bitreich.org 70 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+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-/* 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 file. It is stored as a rune array, and Err bitreich.org 70 i- * `r` is set to point to it. The length of the string is returned, or Err bitreich.org 70 i- * -1 if malloc fails. 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+long * Err bitreich.org 70 i+runeschr(long *s, long r) 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+ size_t i; 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) Err bitreich.org 70 i- if (!(s = realloc(s, ++size))) return -1; Err bitreich.org 70 i- s[slen] = c; 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- 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+ return NULL; Err bitreich.org 70 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+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@@ -248,10 +315,11 @@ 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 (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+ for (len = 0; (len = getutf(&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 1diff --git a/utf.h b/utf.h /scm/iomenu/file/utf.h.gph bitreich.org 70 i@@ -1,14 +1,16 @@ 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+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+/* conversion */ 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-/* rune class */ Err bitreich.org 70 i-int isprintrune(long); Err bitreich.org 70 i+/* input/output */ Err bitreich.org 70 i Err bitreich.org 70 i-/* stdin / stdout */ Err bitreich.org 70 i-int runetoprint(char *, long, int); Err bitreich.org 70 i-int getutf(long **, FILE *); Err bitreich.org 70 i+size_t getutf(long **, FILE *); Err bitreich.org 70 i+ Err bitreich.org 70 i+/* standard library */ Err bitreich.org 70 i+int runeisprint(long); Err bitreich.org 70 i+long *runestrcpy(); Err bitreich.org 70 .