26 #ifndef SHEREDOM_UTF8_H_INCLUDED
27 #define SHEREDOM_UTF8_H_INCLUDED
33 #pragma warning(disable : 4820)
44 #define int32_t __int32
45 #define uint32_t __uint32
50 #if defined(__clang__)
51 #pragma clang diagnostic push
52 #pragma clang diagnostic ignored "-Wold-style-cast"
53 #pragma clang diagnostic ignored "-Wcast-qual"
60 #if defined(__clang__) || defined(__GNUC__)
61 #define utf8_nonnull __attribute__((nonnull))
62 #define utf8_pure __attribute__((pure))
63 #define utf8_restrict __restrict__
64 #define utf8_weak __attribute__((weak))
65 #elif defined(_MSC_VER)
68 #define utf8_restrict __restrict
69 #define utf8_weak __inline
71 #error Non clang, non gcc, non MSVC compiler found!
77 utf8_nonnull utf8_pure utf8_weak
int utf8casecmp(
const void *src1,
81 utf8_nonnull utf8_weak
void *
utf8cat(
void *utf8_restrict
dst,
82 const void *utf8_restrict
src);
89 utf8_nonnull utf8_pure utf8_weak
int utf8cmp(
const void *src1,
93 utf8_nonnull utf8_weak
void *
utf8cpy(
void *utf8_restrict
dst,
94 const void *utf8_restrict
src);
98 utf8_nonnull utf8_pure utf8_weak
size_t utf8cspn(
const void *
src,
103 utf8_nonnull utf8_weak
void *
utf8dup(
const void *
src);
107 utf8_nonnull utf8_pure utf8_weak
size_t utf8len(
const void *str);
113 utf8_nonnull utf8_pure utf8_weak
int utf8ncasecmp(
const void *src1,
114 const void *src2,
size_t n);
119 utf8_nonnull utf8_weak
void *
utf8ncat(
void *utf8_restrict
dst,
120 const void *utf8_restrict
src,
size_t n);
125 utf8_nonnull utf8_pure utf8_weak
int utf8ncmp(
const void *src1,
126 const void *src2,
size_t n);
135 utf8_nonnull utf8_weak
void *
utf8ncpy(
void *utf8_restrict
dst,
136 const void *utf8_restrict
src,
size_t n);
140 utf8_nonnull utf8_pure utf8_weak
void *
utf8pbrk(
const void *str,
144 utf8_nonnull utf8_pure utf8_weak
void *
utf8rchr(
const void *
src,
int chr);
148 utf8_nonnull utf8_pure utf8_weak
size_t utf8size(
const void *str);
152 utf8_nonnull utf8_pure utf8_weak
size_t utf8spn(
const void *
src,
156 utf8_nonnull utf8_pure utf8_weak
void *
utf8str(
const void *haystack,
161 utf8_nonnull utf8_pure utf8_weak
void *
utf8casestr(
const void *haystack,
166 utf8_nonnull utf8_pure utf8_weak
void *
utf8valid(
const void *str);
170 utf8_nonnull utf8_weak
void *
utf8codepoint(
const void *utf8_restrict str,
171 int32_t *utf8_restrict out_codepoint);
188 utf8_nonnull utf8_weak
void utf8lwr(
void *utf8_restrict str);
191 utf8_nonnull utf8_weak
void utf8upr(
void *utf8_restrict str);
198 const unsigned char *
s1 = (
const unsigned char *)src1;
199 const unsigned char *s2 = (
const unsigned char *)src2;
201 while ((
'\0' != *s1) || (
'\0' != *s2)) {
202 unsigned char a = *
s1;
203 unsigned char b = *s2;
205 if ((
'A' <= a) && (
'Z' >=
a)) {
209 if ((
'A' <= b) && (
'Z' >=
b)) {
228 char *d = (
char *)dst;
229 const char *
s = (
const char *)src;
248 char c[5] = {
'\0',
'\0',
'\0',
'\0',
'\0'};
253 const char *
s = (
const char *)src;
258 }
else if (0 == ((
int32_t)0xffffff80 & chr)) {
262 }
else if (0 == ((
int32_t)0xfffff800 & chr)) {
265 c[0] = 0xc0 | (char)(chr >> 6);
266 c[1] = 0x80 | (char)(chr & 0x3f);
267 }
else if (0 == ((
int32_t)0xffff0000 & chr)) {
270 c[0] = 0xe0 | (char)(chr >> 12);
271 c[1] = 0x80 | (char)((chr >> 6) & 0x3f);
272 c[2] = 0x80 | (char)(chr & 0x3f);
276 c[0] = 0xf0 | (char)(chr >> 18);
277 c[1] = 0x80 | (char)((chr >> 12) & 0x3f);
278 c[2] = 0x80 | (char)((chr >> 6) & 0x3f);
279 c[3] = 0x80 | (char)(chr & 0x3f);
288 int utf8cmp(
const void *src1,
const void *src2) {
289 const unsigned char *
s1 = (
const unsigned char *)src1;
290 const unsigned char *s2 = (
const unsigned char *)src2;
292 while ((
'\0' != *s1) || (
'\0' != *s2)) {
295 }
else if (*s1 > *s2) {
307 int utf8coll(
const void *src1,
const void *src2);
310 char *d = (
char *)dst;
311 const char *
s = (
const char *)src;
326 const char *
s = (
const char *)src;
330 const char *
r = (
const char *)reject;
337 if ((0x80 != (0xc0 & *r)) && (0 < offset)) {
340 if (*r == s[offset]) {
351 }
while (0x80 == (0xc0 & *r));
364 }
while ((0x80 == (0xc0 & *s)));
374 const char *
s = (
const char *)src;
380 n = (
char *)malloc(bytes);
389 while (
'\0' != s[bytes]) {
400 void *
utf8fry(
const void *str);
403 const unsigned char *
s = (
const unsigned char *)str;
407 if (0xf0 == (0xf8 & *s)) {
410 }
else if (0xe0 == (0xf0 & *s)) {
413 }
else if (0xc0 == (0xe0 & *s)) {
430 const unsigned char *
s1 = (
const unsigned char *)src1;
431 const unsigned char *s2 = (
const unsigned char *)src2;
433 while (((
'\0' != *s1) || (
'\0' != *s2)) && (0 != n--)) {
434 unsigned char a = *
s1;
435 unsigned char b = *s2;
437 if ((
'A' <= a) && (
'Z' >=
a)) {
441 if ((
'A' <= b) && (
'Z' >=
b)) {
461 char *d = (
char *)dst;
462 const char *
s = (
const char *)src;
473 }
while ((
'\0' != *s) && (0 != --
n));
481 int utf8ncmp(
const void *src1,
const void *src2,
size_t n) {
482 const unsigned char *
s1 = (
const unsigned char *)src1;
483 const unsigned char *s2 = (
const unsigned char *)src2;
485 while (((
'\0' != *s1) || (
'\0' != *s2)) && (0 != n--)) {
488 }
else if (*s1 > *s2) {
502 char *d = (
char *)dst;
503 const char *
s = (
const char *)src;
509 }
while ((
'\0' != *s) && (0 != --
n));
521 const char *
s = (
const char *)src;
522 const char *match = 0;
523 char c[5] = {
'\0',
'\0',
'\0',
'\0',
'\0'};
532 }
else if (0 == ((
int)0xffffff80 & chr)) {
536 }
else if (0 == ((
int)0xfffff800 & chr)) {
539 c[0] = 0xc0 | (char)(chr >> 6);
540 c[1] = 0x80 | (char)(chr & 0x3f);
541 }
else if (0 == ((
int)0xffff0000 & chr)) {
544 c[0] = 0xe0 | (char)(chr >> 12);
545 c[1] = 0x80 | (char)((chr >> 6) & 0x3f);
546 c[2] = 0x80 | (char)(chr & 0x3f);
550 c[0] = 0xf0 | (char)(chr >> 18);
551 c[1] = 0x80 | (char)((chr >> 12) & 0x3f);
552 c[2] = 0x80 | (char)((chr >> 6) & 0x3f);
553 c[3] = 0x80 | (char)(chr & 0x3f);
563 while (s[offset] == c[offset]) {
567 if (
'\0' == c[offset]) {
579 }
while (0x80 == (0xc0 & *s));
585 return (
void *)match;
588 void *
utf8pbrk(
const void *str,
const void *accept) {
589 const char *
s = (
const char *)str;
592 const char *
a = (
const char *)accept;
599 if ((0x80 != (0xc0 & *a)) && (0 < offset)) {
602 if (*a == s[offset]) {
613 }
while (0x80 == (0xc0 & *a));
631 }
while ((0x80 == (0xc0 & *s)));
638 const char *
s = (
const char *)str;
640 while (
'\0' != s[size]) {
650 const char *
s = (
const char *)src;
654 const char *
a = (
const char *)accept;
661 if ((0x80 != (0xc0 & *a)) && (0 < offset)) {
669 if (*a == s[offset]) {
677 }
while (0x80 == (0xc0 & *a));
695 void *
utf8str(
const void *haystack,
const void *needle) {
696 const char *
h = (
const char *)haystack;
700 if (
'\0' == *((
const char *)needle)) {
701 return (
void *)haystack;
705 const char *maybeMatch =
h;
706 const char *
n = (
const char *)needle;
708 while (*h == *n && (*h !=
'\0' && *n !=
'\0')) {
716 return (
void *)maybeMatch;
723 }
while (0x80 == (0xc0 & *h));
733 const char *
h = (
const char *)haystack;
737 if (
'\0' == *((
const char *)needle)) {
738 return (
void *)haystack;
742 const char *maybeMatch =
h;
743 const char *
n = (
const char *)needle;
749 if ((
'A' <= a) && (
'Z' >=
a)) {
753 if ((
'A' <= b) && (
'Z' >=
b)) {
769 return (
void *)maybeMatch;
776 }
while (0x80 == (0xc0 & *h));
786 const char *
s = (
const char *)str;
789 if (0xf0 == (0xf8 & *s)) {
792 if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2])) ||
793 (0x80 != (0xc0 & s[3]))) {
798 if (0x80 == (0xc0 & s[4])) {
805 if ((0 == (0x07 & s[0])) && (0 == (0x30 & s[1]))) {
811 }
else if (0xe0 == (0xf0 & *s)) {
814 if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2]))) {
819 if (0x80 == (0xc0 & s[3])) {
826 if ((0 == (0x0f & s[0])) && (0 == (0x20 & s[1]))) {
832 }
else if (0xc0 == (0xe0 & *s)) {
835 if (0x80 != (0xc0 & s[1])) {
840 if (0x80 == (0xc0 & s[2])) {
847 if (0 == (0x1e & s[0])) {
853 }
else if (0x00 == (0x80 & *s)) {
866 int32_t *utf8_restrict out_codepoint) {
867 const char *
s = (
const char *)str;
869 if (0xf0 == (0xf8 & s[0])) {
871 *out_codepoint = ((0x07 & s[0]) << 18) | ((0x3f & s[1]) << 12) |
872 ((0x3f & s[2]) << 6) | (0x3f & s[3]);
874 }
else if (0xe0 == (0xf0 & s[0])) {
877 ((0x0f & s[0]) << 12) | ((0x3f & s[1]) << 6) | (0x3f & s[2]);
879 }
else if (0xc0 == (0xe0 & s[0])) {
881 *out_codepoint = ((0x1f & s[0]) << 6) | (0x3f & s[1]);
885 *out_codepoint = s[0];
893 if (0 == ((
int32_t)0xffffff80 & chr)) {
895 }
else if (0 == ((
int32_t)0xfffff800 & chr)) {
897 }
else if (0 == ((
int32_t)0xffff0000 & chr)) {
905 char *
s = (
char *)str;
907 if (0 == ((
int32_t)0xffffff80 & chr)) {
915 }
else if (0 == ((
int32_t)0xfffff800 & chr)) {
921 s[0] = 0xc0 | (char)(chr >> 6);
922 s[1] = 0x80 | (char)(chr & 0x3f);
924 }
else if (0 == ((
int32_t)0xffff0000 & chr)) {
930 s[0] = 0xe0 | (char)(chr >> 12);
931 s[1] = 0x80 | (char)((chr >> 6) & 0x3f);
932 s[2] = 0x80 | (char)(chr & 0x3f);
940 s[0] = 0xf0 | (char)(chr >> 18);
941 s[1] = 0x80 | (char)((chr >> 12) & 0x3f);
942 s[2] = 0x80 | (char)((chr >> 6) & 0x3f);
943 s[3] = 0x80 | (char)(chr & 0x3f);
952 if ((
'A' <= chr) && (
'Z' >= chr)) {
961 if ((
'A' <= chr) && (
'Z' >= chr)) {
976 if ((
'A' <= cp) && (
'Z' >= cp)) {
994 if ((
'a' <= cp) && (
'z' >= cp)) {
1003 #undef utf8_restrict
1009 #if defined(__clang__)
1010 #pragma clang diagnostic pop
1013 #endif // SHEREDOM_UTF8_H_INCLUDED