isupport in-channel unicode - irc - Unnamed repository; edit this file 'description' to name the repository. Err vernunftzentrum.de 70 hgit clone git://vernunftzentrum.de/irc.git URL:git://vernunftzentrum.de/irc.git vernunftzentrum.de 70 1Log /ckeen/repos/irc/log.gph vernunftzentrum.de 70 1Files /ckeen/repos/irc/files.gph vernunftzentrum.de 70 1Refs /ckeen/repos/irc/refs.gph vernunftzentrum.de 70 1README /ckeen/repos/irc/file/README.gph vernunftzentrum.de 70 i--- Err vernunftzentrum.de 70 1commit 734cc4f0e72259a8be86115c71dce0f112d6ff0b /ckeen/repos/irc/commit/734cc4f0e72259a8be86115c71dce0f112d6ff0b.gph vernunftzentrum.de 70 1parent 1c4a83b81f92884d7add4962151f16b74637a0c5 /ckeen/repos/irc/commit/1c4a83b81f92884d7add4962151f16b74637a0c5.gph vernunftzentrum.de 70 hAuthor: Quentin Carbonneaux URL:mailto:quentin.carbonneaux@yale.edu vernunftzentrum.de 70 iDate: Wed, 4 May 2016 22:17:19 -0400 Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 isupport in-channel unicode Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 iDiffstat: Err vernunftzentrum.de 70 i Makefile | 2 +- Err vernunftzentrum.de 70 i irc.c | 107 +++++++++++++++++++++++++++---- Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i2 files changed, 96 insertions(+), 13 deletions(-) Err vernunftzentrum.de 70 i--- Err vernunftzentrum.de 70 1diff --git a/Makefile b/Makefile /ckeen/repos/irc/file/Makefile.gph vernunftzentrum.de 70 i@@ -1,7 +1,7 @@ Err vernunftzentrum.de 70 i BIN = irc Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i CFLAGS = -std=c99 -Os -D_POSIX_C_SOURCE=201112 -D_GNU_SOURCE Err vernunftzentrum.de 70 i-LDFLAGS = -lncurses Err vernunftzentrum.de 70 i+LDFLAGS = -lncursesw Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i all: ${BIN} Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 1diff --git a/irc.c b/irc.c /ckeen/repos/irc/file/irc.c.gph vernunftzentrum.de 70 i@@ -19,6 +19,7 @@ Err vernunftzentrum.de 70 i #include Err vernunftzentrum.de 70 i #include Err vernunftzentrum.de 70 i #include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i #undef CTRL Err vernunftzentrum.de 70 i #define CTRL(x) (x & 037) Err vernunftzentrum.de 70 i@@ -36,16 +37,20 @@ enum { Err vernunftzentrum.de 70 i LineLen = 512, Err vernunftzentrum.de 70 i MaxChans = 16, Err vernunftzentrum.de 70 i BufSz = 2048, Err vernunftzentrum.de 70 i- LogSz = 4096 Err vernunftzentrum.de 70 i+ LogSz = 4096, Err vernunftzentrum.de 70 i+ UtfSz = 4, Err vernunftzentrum.de 70 i+ RuneInvalid = 0xFFFD, Err vernunftzentrum.de 70 i }; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-struct { Err vernunftzentrum.de 70 i+typedef unsigned int Rune; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+static struct { Err vernunftzentrum.de 70 i int x; Err vernunftzentrum.de 70 i int y; Err vernunftzentrum.de 70 i WINDOW *sw, *mw, *iw; Err vernunftzentrum.de 70 i } scr; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-struct Chan { Err vernunftzentrum.de 70 i+static struct Chan { Err vernunftzentrum.de 70 i char name[ChanLen]; Err vernunftzentrum.de 70 i char *buf, *eol; Err vernunftzentrum.de 70 i int n; /* Scroll offset. */ Err vernunftzentrum.de 70 i@@ -54,13 +59,18 @@ struct Chan { Err vernunftzentrum.de 70 i char new; /* New message. */ Err vernunftzentrum.de 70 i } chl[MaxChans]; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-char nick[64]; Err vernunftzentrum.de 70 i-int quit, winchg; Err vernunftzentrum.de 70 i-int sfd; /* Server file descriptor. */ Err vernunftzentrum.de 70 i-int nch, ch; /* Current number of channels, and current channel. */ Err vernunftzentrum.de 70 i-char outb[BufSz], *outp = outb; /* Output buffer. */ Err vernunftzentrum.de 70 i+static char nick[64]; Err vernunftzentrum.de 70 i+static int quit, winchg; Err vernunftzentrum.de 70 i+static int sfd; /* Server file descriptor. */ Err vernunftzentrum.de 70 i+static int nch, ch; /* Current number of channels, and current channel. */ Err vernunftzentrum.de 70 i+static char outb[BufSz], *outp = outb; /* Output buffer. */ Err vernunftzentrum.de 70 i static FILE *logfp; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i+static unsigned char utfbyte[UtfSz + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; Err vernunftzentrum.de 70 i+static unsigned char utfmask[UtfSz + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; Err vernunftzentrum.de 70 i+static Rune utfmin[UtfSz + 1] = { 0, 0, 0x80, 0x800, 0x10000}; Err vernunftzentrum.de 70 i+static Rune utfmax[UtfSz + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i static void scmd(char *, char *, char *, char *); Err vernunftzentrum.de 70 i static void tdrawbar(void); Err vernunftzentrum.de 70 i static void tredraw(void); Err vernunftzentrum.de 70 i@@ -74,6 +84,71 @@ panic(const char *m) Err vernunftzentrum.de 70 i exit(1); Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i+static size_t Err vernunftzentrum.de 70 i+utf8validate(Rune *u, size_t i) Err vernunftzentrum.de 70 i+{ Err vernunftzentrum.de 70 i+ if (*u < utfmin[i] || *u > utfmax[i] || (0xD800 <= *u && *u <= 0xDFFF)) Err vernunftzentrum.de 70 i+ *u = RuneInvalid; Err vernunftzentrum.de 70 i+ for (i = 1; *u > utfmax[i]; ++i) Err vernunftzentrum.de 70 i+ ; Err vernunftzentrum.de 70 i+ return i; Err vernunftzentrum.de 70 i+} Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+static Rune Err vernunftzentrum.de 70 i+utf8decodebyte(unsigned char c, size_t *i) Err vernunftzentrum.de 70 i+{ Err vernunftzentrum.de 70 i+ for (*i = 0; *i < UtfSz + 1; ++(*i)) Err vernunftzentrum.de 70 i+ if ((c & utfmask[*i]) == utfbyte[*i]) Err vernunftzentrum.de 70 i+ return c & ~utfmask[*i]; Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i+} Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+static size_t Err vernunftzentrum.de 70 i+utf8decode(char *c, Rune *u, size_t clen) Err vernunftzentrum.de 70 i+{ Err vernunftzentrum.de 70 i+ size_t i, j, len, type; Err vernunftzentrum.de 70 i+ Rune udecoded; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ *u = RuneInvalid; Err vernunftzentrum.de 70 i+ if (!clen) Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i+ udecoded = utf8decodebyte(c[0], &len); Err vernunftzentrum.de 70 i+ if (len < 1 || len > UtfSz) Err vernunftzentrum.de 70 i+ return 1; Err vernunftzentrum.de 70 i+ for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { Err vernunftzentrum.de 70 i+ udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); Err vernunftzentrum.de 70 i+ if (type != 0) Err vernunftzentrum.de 70 i+ return j; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ if (j < len) Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i+ *u = udecoded; Err vernunftzentrum.de 70 i+ utf8validate(u, len); Err vernunftzentrum.de 70 i+ return len; Err vernunftzentrum.de 70 i+} Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+static char Err vernunftzentrum.de 70 i+utf8encodebyte(Rune u, size_t i) Err vernunftzentrum.de 70 i+{ Err vernunftzentrum.de 70 i+ return utfbyte[i] | (u & ~utfmask[i]); Err vernunftzentrum.de 70 i+} Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+static size_t Err vernunftzentrum.de 70 i+utf8encode(Rune u, char *c) Err vernunftzentrum.de 70 i+{ Err vernunftzentrum.de 70 i+ size_t len, i; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ len = utf8validate(&u, 0); Err vernunftzentrum.de 70 i+ if (len > UtfSz) Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i+ for (i = len - 1; i != 0; --i) { Err vernunftzentrum.de 70 i+ c[i] = utf8encodebyte(u, 0); Err vernunftzentrum.de 70 i+ u >>= 6; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ c[0] = utf8encodebyte(u, len); Err vernunftzentrum.de 70 i+ return len; Err vernunftzentrum.de 70 i+} Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i static void Err vernunftzentrum.de 70 i sndf(const char *fmt, ...) Err vernunftzentrum.de 70 i { Err vernunftzentrum.de 70 i@@ -206,10 +281,14 @@ pushl(char *p, char *e) Err vernunftzentrum.de 70 i { Err vernunftzentrum.de 70 i int x; Err vernunftzentrum.de 70 i char *w; Err vernunftzentrum.de 70 i+ Rune u; Err vernunftzentrum.de 70 i+ cchar_t cc; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i if ((w = memchr(p, '\n', e - p))) Err vernunftzentrum.de 70 i e = w + 1; Err vernunftzentrum.de 70 i- for (w = p, x = 0;; p++, x++) { Err vernunftzentrum.de 70 i+ w = p; Err vernunftzentrum.de 70 i+ x = 0; Err vernunftzentrum.de 70 i+ for (;;) { Err vernunftzentrum.de 70 i if (x >= scr.x) { Err vernunftzentrum.de 70 i waddch(scr.mw, '\n'); Err vernunftzentrum.de 70 i for (x = 0; x < INDENT; x++) Err vernunftzentrum.de 70 i@@ -219,11 +298,16 @@ pushl(char *p, char *e) Err vernunftzentrum.de 70 i x += p - w; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i if (p >= e || *p == ' ' || p - w + INDENT >= scr.x - 1) { Err vernunftzentrum.de 70 i- for (; w < p; w++) Err vernunftzentrum.de 70 i- waddch(scr.mw, *w); Err vernunftzentrum.de 70 i+ while (w < p) { Err vernunftzentrum.de 70 i+ w += utf8decode(w, &u, UtfSz); Err vernunftzentrum.de 70 i+ setcchar(&cc, &u, 0, 0, 0); Err vernunftzentrum.de 70 i+ wadd_wch(scr.mw, &cc); Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i if (p >= e) Err vernunftzentrum.de 70 i return e; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i+ p += utf8decode(p, &u, UtfSz); Err vernunftzentrum.de 70 i+ x += wcwidth(u); Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i@@ -502,7 +586,6 @@ tdrawbar(void) Err vernunftzentrum.de 70 i werase(scr.sw); Err vernunftzentrum.de 70 i for (l = 0; fst < nch && l < scr.x; fst++) { Err vernunftzentrum.de 70 i char *p = chl[fst].name; Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i if (fst == ch) Err vernunftzentrum.de 70 i wattron(scr.sw, A_BOLD); Err vernunftzentrum.de 70 i waddch(scr.sw, '['), l++; Err vernunftzentrum.de 70 .