/* * keyd - A key remapping daemon. * * © 2019 Raheman Vaiya (see also: LICENSE). */ #include #include "string.h" int utf8_read_char(const char *_s, uint32_t *code) { const unsigned char *s = (const unsigned char*)_s; if (!s[0]) return 0; if (s[0] >= 0xF0) { assert(s[1]); assert(s[2]); assert(s[3]); *code = (s[0] & 0x07) << 18 | (s[1] & 0x3F) << 12 | (s[2] & 0x3F) << 6 | (s[3] & 0x3F); return 4; } else if (s[0] >= 0xE0) { assert(s[1]); assert(s[2]); *code = (s[0] & 0x0F) << 12 | (s[1] & 0x3F) << 6 | (s[2] & 0x3F); return 3; } else if (s[0] >= 0xC0) { assert(s[1]); *code = (s[0] & 0x1F) << 6 | (s[1] & 0x3F); return 2; } else { *code = s[0] & 0x7F; return 1; } } int utf8_strlen(const char *s) { uint32_t code; int csz; int n = 0; while ((csz = utf8_read_char(s, &code))) { n++; s+=csz; } return n; } /* * Returns the character size in bytes, or 0 in the case of the empty string. */ size_t str_escape(char *s) { int i = 0; int n = 0; for (i = 0; s[i]; i++) { if (s[i] == '\\') { switch (s[i+1]) { case 'n': s[n++] = '\n'; break; case 't': s[n++] = '\t'; break; case '\\': s[n++] = '\\'; break; case ')': s[n++] = ')'; break; case '(': s[n++] = '('; break; case 0: s[n] = 0; return n; default: s[n++] = '\\'; s[n++] = s[i+1]; break; } i++; } else { s[n++] = s[i]; } } s[n] = 0; return n; }