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 */