diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2015-07-18 10:35:32 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2015-07-20 12:05:45 +0200 |
| commit | 38f00e3e8a50e1690dcb78cf1eca8b6befb7173b (patch) | |
| tree | f613eec7ee39a312229e97d22557623ef7a2510f /libutf.c | |
| parent | 0fa9885cda0778467ca5737ac888ece5ef371b3d (diff) | |
| download | vis-38f00e3e8a50e1690dcb78cf1eca8b6befb7173b.tar.gz vis-38f00e3e8a50e1690dcb78cf1eca8b6befb7173b.tar.xz | |
vis: improve insertion of verbatim characters via CTRL-V in insert mode
Recognized formats are:
CTRL-V nnn decimal value nnn
CTRL-V onnn or CTRL-V Onnn octal value nnn
CTRL-V xnn or CTRL-V Xnn hex value nn
CTRL-V unnnn Unicode codepoint nnnn
CTRL-V Unnnnnnnn Unicode codepoint nnnnnnnn
Leading zeros can be omitted, any illegal character for the given
format will be ignored and terminates the numerical code.
Diffstat (limited to 'libutf.c')
| -rw-r--r-- | libutf.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/libutf.c b/libutf.c new file mode 100644 index 0000000..5f6ff45 --- /dev/null +++ b/libutf.c @@ -0,0 +1,52 @@ +/* libutf8 © 2012-2015 Connor Lane Smith <cls@lubutu.com> */ +#include "libutf.h" + +int +runelen(Rune r) +{ + if(r <= 0x7F) + return 1; + else if(r <= 0x07FF) + return 2; + else if(r <= 0xD7FF) + return 3; + else if(r <= 0xDFFF) + return 0; /* surrogate character */ + else if(r <= 0xFFFD) + return 3; + else if(r <= 0xFFFF) + return 0; /* illegal character */ + else if(r <= Runemax) + return 4; + else + return 0; /* rune too large */ +} + +int +runetochar(char *s, const Rune *p) +{ + Rune r = *p; + + switch(runelen(r)) { + case 1: /* 0aaaaaaa */ + s[0] = r; + return 1; + case 2: /* 00000aaa aabbbbbb */ + s[0] = 0xC0 | ((r & 0x0007C0) >> 6); /* 110aaaaa */ + s[1] = 0x80 | (r & 0x00003F); /* 10bbbbbb */ + return 2; + case 3: /* aaaabbbb bbcccccc */ + s[0] = 0xE0 | ((r & 0x00F000) >> 12); /* 1110aaaa */ + s[1] = 0x80 | ((r & 0x000FC0) >> 6); /* 10bbbbbb */ + s[2] = 0x80 | (r & 0x00003F); /* 10cccccc */ + return 3; + case 4: /* 000aaabb bbbbcccc ccdddddd */ + s[0] = 0xF0 | ((r & 0x1C0000) >> 18); /* 11110aaa */ + s[1] = 0x80 | ((r & 0x03F000) >> 12); /* 10bbbbbb */ + s[2] = 0x80 | ((r & 0x000FC0) >> 6); /* 10cccccc */ + s[3] = 0x80 | (r & 0x00003F); /* 10dddddd */ + return 4; + default: + return 0; /* error */ + } +} |
