commit acf3cdc
default
·
2023-11-17 02:51:04 +0000 UTC
parent 57ab8df
Backport from xs.
4 files changed,
+39,
-11
M
xs.h
+5,
-2
1@@ -1180,6 +1180,8 @@ void *xs_memmem(const char *haystack, int h_size, const char *needle, int n_size
2
3 /** hex **/
4
5+static char xs_hex_digits[] = "0123456789abcdef";
6+
7 xs_str *xs_hex_enc(const xs_val *data, int size)
8 /* returns an hexdump of data */
9 {
10@@ -1190,8 +1192,9 @@ xs_str *xs_hex_enc(const xs_val *data, int size)
11 p = s = xs_realloc(NULL, _xs_blk_size(size * 2 + 1));
12
13 for (n = 0; n < size; n++) {
14- snprintf(p, 3, "%02x", (unsigned char)data[n]);
15- p += 2;
16+ *p++ = xs_hex_digits[*data >> 4 & 0xf];
17+ *p++ = xs_hex_digits[*data & 0xf];
18+ data++;
19 }
20
21 *p = '\0';
+4,
-8
1@@ -248,24 +248,20 @@ static xs_val *_xs_json_load_lexer(FILE *f, js_type *t)
2 break;
3 }
4
5- if (cp >= 0xd800 && cp <= 0xdfff) {
6- /* it's a surrogate pair */
7- cp = (cp & 0x3ff) << 10;
8-
9+ if (xs_is_surrogate(cp)) {
10 /* \u must follow */
11 if (fgetc(f) != '\\' || fgetc(f) != 'u') {
12 *t = JS_ERROR;
13 break;
14 }
15
16- unsigned int i;
17- if (fscanf(f, "%04x", &i) != 1) {
18+ unsigned int p2;
19+ if (fscanf(f, "%04x", &p2) != 1) {
20 *t = JS_ERROR;
21 break;
22 }
23
24- cp |= (i & 0x3ff);
25- cp += 0x10000;
26+ cp = xs_surrogate_dec(cp, p2);
27 }
28
29 /* replace dangerous control codes with their visual representations */
+29,
-0
1@@ -8,6 +8,9 @@
2 xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint);
3 unsigned int xs_utf8_dec(char **str);
4 int xs_unicode_width(unsigned int cpoint);
5+ int xs_is_surrogate(unsigned int cpoint);
6+ unsigned int xs_surrogate_dec(unsigned int p1, unsigned int p2);
7+ unsigned int xs_surrogate_enc(unsigned int cpoint);
8 unsigned int *_xs_unicode_upper_search(unsigned int cpoint);
9 unsigned int *_xs_unicode_lower_search(unsigned int cpoint);
10 #define xs_unicode_is_upper(cpoint) (!!_xs_unicode_upper_search(cpoint))
11@@ -138,6 +141,32 @@ int xs_unicode_width(unsigned int cpoint)
12 }
13
14
15+/** surrogate pairs **/
16+
17+int xs_is_surrogate(unsigned int cpoint)
18+/* checks if cpoint is the first element of a Unicode surrogate pair */
19+{
20+ return cpoint >= 0xd800 && cpoint <= 0xdfff;
21+}
22+
23+
24+unsigned int xs_surrogate_dec(unsigned int p1, unsigned int p2)
25+/* "decodes" a surrogate pair into a codepoint */
26+{
27+ return 0x10000 | ((p1 & 0x3ff) << 10) | (p2 & 0x3ff);
28+}
29+
30+
31+unsigned int xs_surrogate_enc(unsigned int cpoint)
32+/* "encodes" a Unicode into a surrogate pair (p1 in the MSB word) */
33+{
34+ unsigned int p1 = 0xd7c0 + (cpoint >> 10);
35+ unsigned int p2 = 0xdc00 + (cpoint & 0x3ff);
36+
37+ return (p1 << 16) | p2;
38+}
39+
40+
41 #ifdef _XS_UNICODE_TBL_H
42
43 /* include xs_unicode_tbl.h before this one to use these functions */
+1,
-1
1@@ -1 +1 @@
2-/* 40d63c59610c642d1c8b2e2b94bbf5cdde69ad6a */
3+/* 0932615dfe85e5d8544c4b2052eb66f3a430eb8c */