MCPcopy Index your code
hub / github.com/git/git / pick_one_utf8_char

Function pick_one_utf8_char

utf8.c:122–189  ·  view source on GitHub ↗

* Pick one ucs character starting from the location *start points at, * and return it, while updating the *start pointer to point at the * end of that character. When remainder_p is not NULL, the location * holds the number of bytes remaining in the string that we are allowed * to pick from. Otherwise we are allowed to pick up to the NUL that * would eventually appear in the string. *remai

Source from the content-addressed store, hash-verified

120 * and the return value is undefined.
121 */
122static ucs_char_t pick_one_utf8_char(const char **start, size_t *remainder_p)
123{
124 unsigned char *s = (unsigned char *)*start;
125 ucs_char_t ch;
126 size_t remainder, incr;
127
128 /*
129 * A caller that assumes NUL terminated text can choose
130 * not to bother with the remainder length. We will
131 * stop at the first NUL.
132 */
133 remainder = (remainder_p ? *remainder_p : 999);
134
135 if (remainder < 1) {
136 goto invalid;
137 } else if (*s < 0x80) {
138 /* 0xxxxxxx */
139 ch = *s;
140 incr = 1;
141 } else if ((s[0] & 0xe0) == 0xc0) {
142 /* 110XXXXx 10xxxxxx */
143 if (remainder < 2 ||
144 (s[1] & 0xc0) != 0x80 ||
145 (s[0] & 0xfe) == 0xc0)
146 goto invalid;
147 ch = ((s[0] & 0x1f) << 6) | (s[1] & 0x3f);
148 incr = 2;
149 } else if ((s[0] & 0xf0) == 0xe0) {
150 /* 1110XXXX 10Xxxxxx 10xxxxxx */
151 if (remainder < 3 ||
152 (s[1] & 0xc0) != 0x80 ||
153 (s[2] & 0xc0) != 0x80 ||
154 /* overlong? */
155 (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) ||
156 /* surrogate? */
157 (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) ||
158 /* U+FFFE or U+FFFF? */
159 (s[0] == 0xef && s[1] == 0xbf &&
160 (s[2] & 0xfe) == 0xbe))
161 goto invalid;
162 ch = ((s[0] & 0x0f) << 12) |
163 ((s[1] & 0x3f) << 6) | (s[2] & 0x3f);
164 incr = 3;
165 } else if ((s[0] & 0xf8) == 0xf0) {
166 /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */
167 if (remainder < 4 ||
168 (s[1] & 0xc0) != 0x80 ||
169 (s[2] & 0xc0) != 0x80 ||
170 (s[3] & 0xc0) != 0x80 ||
171 /* overlong? */
172 (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) ||
173 /* > U+10FFFF? */
174 (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4)
175 goto invalid;
176 ch = ((s[0] & 0x07) << 18) | ((s[1] & 0x3f) << 12) |
177 ((s[2] & 0x3f) << 6) | (s[3] & 0x3f);
178 incr = 4;
179 } else {

Callers 3

utf8_widthFunction · 0.85
mbs_chrlenFunction · 0.85
next_hfs_charFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected