You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
1.4 KiB
97 lines
1.4 KiB
/* |
|
* keyd - A key remapping daemon. |
|
* |
|
* © 2019 Raheman Vaiya (see also: LICENSE). |
|
*/ |
|
#include <assert.h> |
|
|
|
#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; |
|
} |
|
|
|
|