]> git.lizzy.rs Git - linenoise.git/blob - utf8.c
linenosePrompt() -> linenoiseEdit().
[linenoise.git] / utf8.c
1 /**
2  * UTF-8 utility functions
3  *
4  * (c) 2010 Steve Bennett <steveb@workware.net.au>
5  *
6  * See LICENCE for licence details.
7  */
8
9 #include <ctype.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include "utf8.h"
14
15 #ifdef USE_UTF8
16 int utf8_fromunicode(char *p, unsigned short uc)
17 {
18     if (uc <= 0x7f) {
19         *p = uc;
20         return 1;
21     }
22     else if (uc <= 0x7ff) {
23         *p++ = 0xc0 | ((uc & 0x7c0) >> 6);
24         *p = 0x80 | (uc & 0x3f);
25         return 2;
26     }
27     else {
28         *p++ = 0xe0 | ((uc & 0xf000) >> 12);
29         *p++ = 0x80 | ((uc & 0xfc0) >> 6);
30         *p = 0x80 | (uc & 0x3f);
31         return 3;
32     }
33 }
34
35 int utf8_charlen(int c)
36 {
37     if ((c & 0x80) == 0) {
38         return 1;
39     }
40     if ((c & 0xe0) == 0xc0) {
41         return 2;
42     }
43     if ((c & 0xf0) == 0xe0) {
44         return 3;
45     }
46     if ((c & 0xf8) == 0xf0) {
47         return 4;
48     }
49     /* Invalid sequence */
50     return -1;
51 }
52
53 int utf8_strlen(const char *str, int bytelen)
54 {
55     int charlen = 0;
56     if (bytelen < 0) {
57         bytelen = strlen(str);
58     }
59     while (bytelen) {
60         int c;
61         int l = utf8_tounicode(str, &c);
62         charlen++;
63         str += l;
64         bytelen -= l;
65     }
66     return charlen;
67 }
68
69 int utf8_index(const char *str, int index)
70 {
71     const char *s = str;
72     while (index--) {
73         int c;
74         s += utf8_tounicode(s, &c);
75     }
76     return s - str;
77 }
78
79 int utf8_charequal(const char *s1, const char *s2)
80 {
81     int c1, c2;
82
83     utf8_tounicode(s1, &c1);
84     utf8_tounicode(s2, &c2);
85
86     return c1 == c2;
87 }
88
89 int utf8_tounicode(const char *str, int *uc)
90 {
91     unsigned const char *s = (unsigned const char *)str;
92
93     if (s[0] < 0xc0) {
94         *uc = s[0];
95         return 1;
96     }
97     if (s[0] < 0xe0) {
98         if ((s[1] & 0xc0) == 0x80) {
99             *uc = ((s[0] & ~0xc0) << 6) | (s[1] & ~0x80);
100             return 2;
101         }
102     }
103     else if (s[0] < 0xf0) {
104         if (((str[1] & 0xc0) == 0x80) && ((str[2] & 0xc0) == 0x80)) {
105             *uc = ((s[0] & ~0xe0) << 12) | ((s[1] & ~0x80) << 6) | (s[2] & ~0x80);
106             return 3;
107         }
108     }
109
110     /* Invalid sequence, so just return the byte */
111     *uc = *s;
112     return 1;
113 }
114
115 #endif