commit 2137d2f
default
·
2023-08-03 06:42:38 +0000 UTC
parent d455280
Backport from xs.
3 files changed,
+134,
-13
+14,
-0
1@@ -5,6 +5,7 @@
2 #define _XS_JSON_H
3
4 xs_str *xs_json_dumps_pp(const xs_val *data, int indent);
5+int xs_json_dump_pp(const xs_val *data, int indent, FILE *f);
6 #define xs_json_dumps(data) xs_json_dumps_pp(data, 0)
7 xs_val *xs_json_loads(const xs_str *json);
8
9@@ -165,6 +166,19 @@ xs_str *xs_json_dumps_pp(const xs_val *data, int indent)
10 }
11
12
13+int xs_json_dump_pp(const xs_val *data, int indent, FILE *f)
14+/* dumps data into a file as JSON */
15+{
16+ xs *j = xs_json_dumps_pp(data, indent);
17+
18+ if (j == NULL)
19+ return 0;
20+
21+ fwrite(j, strlen(j), 1, f);
22+ return 1;
23+}
24+
25+
26 /** JSON loads **/
27
28 /* this code comes mostly from the Minimum Profit Text Editor (MPDM) */
+119,
-12
1@@ -5,8 +5,15 @@
2 #define _XS_UNICODE_H
3
4 xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint);
5- char *xs_utf8_dec(const char *str, unsigned int *cpoint);
6-
7+ unsigned int xs_utf8_dec(char **str);
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+ #define xs_unicode_is_lower(cpoint) (!!_xs_unicode_lower_search(cpoint))
12+ unsigned int xs_unicode_to_upper(unsigned int cpoint);
13+ unsigned int xs_unicode_to_lower(unsigned int cpoint);
14+ int xs_unicode_nfd(unsigned int cpoint, unsigned int *base, unsigned int *diac);
15+ int xs_unicode_nfc(unsigned int base, unsigned int diac, unsigned int *cpoint);
16
17 #ifdef XS_IMPLEMENTATION
18
19@@ -50,46 +57,146 @@ xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint)
20 }
21
22
23-char *xs_utf8_dec(const char *str, unsigned int *cpoint)
24-/* decodes an utf-8 char inside str into cpoint and returns the next position */
25+unsigned int xs_utf8_dec(char **str)
26+/* decodes an utf-8 char inside str and updates the pointer */
27 {
28- unsigned char *p = (unsigned char *)str;
29+ unsigned char *p = (unsigned char *)*str;
30+ unsigned int cpoint = 0;
31 int c = *p++;
32 int cb = 0;
33
34 if ((c & 0x80) == 0) { /* 1 byte char */
35- *cpoint = c;
36+ cpoint = c;
37 }
38 else
39 if ((c & 0xe0) == 0xc0) { /* 2 byte char */
40- *cpoint = (c & 0x1f) << 6;
41+ cpoint = (c & 0x1f) << 6;
42 cb = 1;
43 }
44 else
45 if ((c & 0xf0) == 0xe0) { /* 3 byte char */
46- *cpoint = (c & 0x0f) << 12;
47+ cpoint = (c & 0x0f) << 12;
48 cb = 2;
49 }
50 else
51 if ((c & 0xf8) == 0xf0) { /* 4 byte char */
52- *cpoint = (c & 0x07) << 18;
53+ cpoint = (c & 0x07) << 18;
54 cb = 3;
55 }
56
57 /* process the continuation bytes */
58 while (cb--) {
59 if ((*p & 0xc0) == 0x80)
60- *cpoint |= (*p++ & 0x3f) << (cb * 6);
61+ cpoint |= (*p++ & 0x3f) << (cb * 6);
62 else {
63- *cpoint = 0xfffd;
64+ cpoint = 0xfffd;
65 break;
66 }
67 }
68
69- return (char *)p;
70+ *str = (char *)p;
71+ return cpoint;
72+}
73+
74+
75+#ifdef _XS_UNICODE_TBL_H
76+
77+/* include xs_unicode_tbl.h before to use these functions */
78+
79+static int int_cmp(const void *p1, const void *p2)
80+{
81+ const unsigned int *a = p1;
82+ const unsigned int *b = p2;
83+
84+ return *a < *b ? -1 : *a > *b ? 1 : 0;
85+}
86+
87+
88+unsigned int *_xs_unicode_upper_search(unsigned int cpoint)
89+/* searches for an uppercase codepoint in the case fold table */
90+{
91+ return bsearch(&cpoint, xs_unicode_case_fold_table,
92+ sizeof(xs_unicode_case_fold_table) / (sizeof(unsigned int) * 2),
93+ sizeof(unsigned int) * 2,
94+ int_cmp);
95+}
96+
97+
98+unsigned int *_xs_unicode_lower_search(unsigned int cpoint)
99+/* searches for a lowercase codepoint in the case fold table */
100+{
101+ unsigned int *p = xs_unicode_case_fold_table + 1;
102+ unsigned int *e = xs_unicode_case_fold_table +
103+ sizeof(xs_unicode_case_fold_table) / sizeof(unsigned int);
104+
105+ while (p < e) {
106+ if (cpoint == *p)
107+ return p;
108+
109+ p += 2;
110+ }
111+
112+ return NULL;
113+}
114+
115+
116+unsigned int xs_unicode_to_upper(unsigned int cpoint)
117+/* returns the cpoint to uppercase */
118+{
119+ unsigned int *p = _xs_unicode_lower_search(cpoint);
120+
121+ return p == NULL ? cpoint : p[-1];
122+}
123+
124+
125+unsigned int xs_unicode_to_lower(unsigned int cpoint)
126+/* returns the cpoint to lowercase */
127+{
128+ unsigned int *p = _xs_unicode_upper_search(cpoint);
129+
130+ return p == NULL ? cpoint : p[1];
131 }
132
133
134+int xs_unicode_nfd(unsigned int cpoint, unsigned int *base, unsigned int *diac)
135+/* applies unicode Normalization Form D */
136+{
137+ unsigned int *r = bsearch(&cpoint, xs_unicode_nfd_table,
138+ sizeof(xs_unicode_nfd_table) / (sizeof(unsigned int) * 3),
139+ sizeof(unsigned int) * 3,
140+ int_cmp);
141+
142+ if (r != NULL) {
143+ *base = r[1];
144+ *diac = r[2];
145+ }
146+
147+ return !!r;
148+}
149+
150+
151+int xs_unicode_nfc(unsigned int base, unsigned int diac, unsigned int *cpoint)
152+/* applies unicode Normalization Form C */
153+{
154+ unsigned int *p = xs_unicode_nfd_table;
155+ unsigned int *e = xs_unicode_nfd_table +
156+ sizeof(xs_unicode_nfd_table) / sizeof(unsigned int);
157+
158+ while (p < e) {
159+ if (p[1] == base && p[2] == diac) {
160+ *cpoint = p[0];
161+ return 1;
162+ }
163+
164+ p += 3;
165+ }
166+
167+ return 0;
168+}
169+
170+
171+#endif /* _XS_UNICODE_TBL_H */
172+
173 #endif /* XS_IMPLEMENTATION */
174
175 #endif /* _XS_UNICODE_H */
+1,
-1
1@@ -1 +1 @@
2-/* 4c151c4cc5b7c6980c1f0dd733a3fab0a30f9695 */
3+/* 5ad148b1c1dbbf7b4550c9fcd13d96ac6def2d21 */