annotate tools/mkunicode/src/mkunicode.c @ 401:ca5e4360f79a

Js: - Add support of constants map (js::Map<T>) - Add supports for vectors (std::vector<T>) - Add index based getProperty/putProperty
author David Demelier <markand@malikania.fr>
date Sat, 03 Oct 2015 11:27:49 +0200
parents b78d6d8f2872
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
352
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * Tool to create our Unicode.cpp and Unicode.h file.
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Current version: 7.0.0
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Based on mkrunetype from the Go language.
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 *
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * Adapted to generated C++ code.
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
10
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 // Copyright 2009 The Go Authors. All rights reserved.
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 // Use of this source code is governed by a BSD-style
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 // license that can be found in the LICENSE file.
David Demelier <markand@malikania.fr>
parents:
diff changeset
14
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * make is(upper|lower|title|space|alpha)rune and
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 * to(upper|lower|title)rune from a UnicodeData.txt file.
David Demelier <markand@malikania.fr>
parents:
diff changeset
18 * these can be found at unicode.org
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 *
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 * with -c, runs a check of the existing runetype functions vs.
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 * those extracted from UnicodeData.
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 *
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 * with -p, generates tables for pairs of chars, as well as for ranges
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 * and singletons.
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 *
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 * UnicodeData defines 4 fields of interest:
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 * 1) a category
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 * 2) an upper case mapping
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 * 3) a lower case mapping
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 * 4) a title case mapping
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 *
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 * toupper, tolower, and totitle are defined directly from the mapping.
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 *
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 * isalpharune(c) is true iff c is a "letter" category
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 * isupperrune(c) is true iff c is the target of toupperrune,
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 * or is in the uppercase letter category
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 * similarly for islowerrune and istitlerune.
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 * isspacerune is true for space category chars, "C" locale white space chars,
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 * and two additions:
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 * 0085 "next line" control char
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 * feff] "zero-width non-break space"
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 * isdigitrune is true iff c is a numeric-digit category.
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
44
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 #include <stdarg.h>
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 #include <stdio.h>
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 #include <stdlib.h>
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 #include <string.h>
David Demelier <markand@malikania.fr>
parents:
diff changeset
49
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 #include "utf.h"
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 #include "utfdef.h"
David Demelier <markand@malikania.fr>
parents:
diff changeset
52
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 #define nelem(x) (sizeof(x)/sizeof((x)[0]))
David Demelier <markand@malikania.fr>
parents:
diff changeset
54
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 enum {
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 * fields in the unicode data file
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 FIELD_CODE,
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 FIELD_NAME,
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 FIELD_CATEGORY,
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 FIELD_COMBINING,
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 FIELD_BIDIR,
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 FIELD_DECOMP,
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 FIELD_DECIMAL_DIG,
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 FIELD_DIG,
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 FIELD_NUMERIC_VAL,
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 FIELD_MIRRORED,
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 FIELD_UNICODE_1_NAME,
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 FIELD_COMMENT,
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 FIELD_UPPER,
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 FIELD_LOWER,
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 FIELD_TITLE,
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 NFIELDS,
David Demelier <markand@malikania.fr>
parents:
diff changeset
75
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 MAX_LINE = 1024,
David Demelier <markand@malikania.fr>
parents:
diff changeset
77
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 TO_OFFSET = 1 << 20,
David Demelier <markand@malikania.fr>
parents:
diff changeset
79
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 NRUNES = 1 << 21,
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 };
David Demelier <markand@malikania.fr>
parents:
diff changeset
82
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 #define TO_DELTA(xmapped,x) (TO_OFFSET + (xmapped) - (x))
David Demelier <markand@malikania.fr>
parents:
diff changeset
84
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 static char myisspace[NRUNES];
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 static char myisalpha[NRUNES];
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 static char myisdigit[NRUNES];
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 static char myisupper[NRUNES];
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 static char myislower[NRUNES];
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 static char myistitle[NRUNES];
David Demelier <markand@malikania.fr>
parents:
diff changeset
91
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 static int mytoupper[NRUNES];
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 static int mytolower[NRUNES];
David Demelier <markand@malikania.fr>
parents:
diff changeset
94 static int mytotitle[NRUNES];
David Demelier <markand@malikania.fr>
parents:
diff changeset
95
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 static void check(void);
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 static void mktables(char *src, int usepairs);
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 static void fatal(const char *fmt, ...);
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 static int mygetfields(char **fields, int nfields, char *str, const char *delim);
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 static int getunicodeline(FILE *in, char **fields, char *buf);
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 static int getcode(char *s);
David Demelier <markand@malikania.fr>
parents:
diff changeset
102
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 static void
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 usage(void)
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 fprintf(stderr, "usage: mktables [-cp] <UnicodeData.txt>\n");
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 exit(1);
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
109
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 int
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 main(int argc, char *argv[])
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 FILE *in;
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 char buf[MAX_LINE], buf2[MAX_LINE];
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 char *fields[NFIELDS + 1], *fields2[NFIELDS + 1];
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 char *p;
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 int i, code, last, usepairs;
David Demelier <markand@malikania.fr>
parents:
diff changeset
118
David Demelier <markand@malikania.fr>
parents:
diff changeset
119 usepairs = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
120
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 --argc;
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 ++argv;
David Demelier <markand@malikania.fr>
parents:
diff changeset
123
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 if (argc != 1){
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 usage();
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
127
David Demelier <markand@malikania.fr>
parents:
diff changeset
128 in = fopen(argv[0], "r");
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 if (in == NULL){
David Demelier <markand@malikania.fr>
parents:
diff changeset
130 fatal("can't open %s", argv[0]);
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
132
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 for(i = 0; i < NRUNES; i++){
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 mytoupper[i] = i;
David Demelier <markand@malikania.fr>
parents:
diff changeset
135 mytolower[i] = i;
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 mytotitle[i] = i;
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
138
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 * make sure isspace has all of the "C" locale whitespace chars
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 myisspace['\t'] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 myisspace['\n'] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 myisspace['\r'] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 myisspace['\f'] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 myisspace['\v'] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
147
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 * a couple of other exceptions
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 myisspace[0x85] = 1; /* control char, "next line" */
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 myisspace[0xfeff] = 1; /* zero-width non-break space */
David Demelier <markand@malikania.fr>
parents:
diff changeset
153
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 last = -1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 while(getunicodeline(in, fields, buf)){
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 code = getcode(fields[FIELD_CODE]);
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 if (code >= NRUNES)
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 fatal("code-point value too big: %x", code);
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 if(code <= last)
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 fatal("bad code sequence: %x then %x", last, code);
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 last = code;
David Demelier <markand@malikania.fr>
parents:
diff changeset
162
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 * check for ranges
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 p = fields[FIELD_CATEGORY];
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 if(strstr(fields[FIELD_NAME], ", First>") != NULL){
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 if(!getunicodeline(in, fields2, buf2))
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 fatal("range start at eof");
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 if (strstr(fields2[FIELD_NAME], ", Last>") == NULL)
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 fatal("range start not followed by range end");
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 last = getcode(fields2[FIELD_CODE]);
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 if(last <= code)
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 fatal("range out of sequence: %x then %x", code, last);
David Demelier <markand@malikania.fr>
parents:
diff changeset
175 if(strcmp(p, fields2[FIELD_CATEGORY]) != 0)
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 fatal("range with mismatched category");
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
178
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 * set properties and conversions
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 for (; code <= last; code++){
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 if(p[0] == 'L')
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 myisalpha[code] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 if(p[0] == 'Z')
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 myisspace[code] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
187
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 if(strcmp(p, "Lu") == 0)
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 myisupper[code] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 if(strcmp(p, "Ll") == 0)
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 myislower[code] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
192
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 if(strcmp(p, "Lt") == 0)
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 myistitle[code] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
195
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 if(strcmp(p, "Nd") == 0)
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 myisdigit[code] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
198
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 * when finding conversions, also need to mark
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 * upper/lower case, since some chars, like
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 * "III" (0x2162), aren't defined as letters but have a
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 * lower case mapping ("iii" (0x2172)).
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 if(fields[FIELD_UPPER][0] != '\0'){
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 mytoupper[code] = getcode(fields[FIELD_UPPER]);
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 if(fields[FIELD_LOWER][0] != '\0'){
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 mytolower[code] = getcode(fields[FIELD_LOWER]);
David Demelier <markand@malikania.fr>
parents:
diff changeset
210 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 if(fields[FIELD_TITLE][0] != '\0'){
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 mytotitle[code] = getcode(fields[FIELD_TITLE]);
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
216
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 fclose(in);
David Demelier <markand@malikania.fr>
parents:
diff changeset
218
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
220 * check for codes with no totitle mapping but a toupper mapping.
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 * these appear in UnicodeData-2.0.14.txt, but are almost certainly
David Demelier <markand@malikania.fr>
parents:
diff changeset
222 * erroneous.
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
224 for(i = 0; i < NRUNES; i++){
David Demelier <markand@malikania.fr>
parents:
diff changeset
225 if(mytotitle[i] == i
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 && mytoupper[i] != i
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 && !myistitle[i])
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 fprintf(stderr, "warning: code=%.4x not istitle, totitle is same, toupper=%.4x\n", i, mytoupper[i]);
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
230
David Demelier <markand@malikania.fr>
parents:
diff changeset
231 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
232 * make sure isupper[c] is true if for some x toupper[x] == c
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 * ditto for islower and istitle
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
235 for(i = 0; i < NRUNES; i++) {
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 if(mytoupper[i] != i)
David Demelier <markand@malikania.fr>
parents:
diff changeset
237 myisupper[mytoupper[i]] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
238 if(mytolower[i] != i)
David Demelier <markand@malikania.fr>
parents:
diff changeset
239 myislower[mytolower[i]] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 if(mytotitle[i] != i)
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 myistitle[mytotitle[i]] = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
242 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
243
David Demelier <markand@malikania.fr>
parents:
diff changeset
244 mktables(argv[0], usepairs);
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 exit(0);
David Demelier <markand@malikania.fr>
parents:
diff changeset
246 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
247
David Demelier <markand@malikania.fr>
parents:
diff changeset
248 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 * generate a properties array for ranges, clearing those cases covered.
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 * if force, generate one-entry ranges for singletons.
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
252 static int
David Demelier <markand@malikania.fr>
parents:
diff changeset
253 mkisrange(const char* label, char* prop, int force)
David Demelier <markand@malikania.fr>
parents:
diff changeset
254 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
255 int start, stop, some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
256
David Demelier <markand@malikania.fr>
parents:
diff changeset
257 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 * first, the ranges
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
260 some = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 for(start = 0; start < NRUNES; ) {
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 if(!prop[start]){
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 start++;
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 continue;
David Demelier <markand@malikania.fr>
parents:
diff changeset
265 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
266
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 for(stop = start + 1; stop < NRUNES; stop++){
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 if(!prop[stop]){
David Demelier <markand@malikania.fr>
parents:
diff changeset
269 break;
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 prop[stop] = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
272 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 if(force || stop != start + 1){
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 if(!some){
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 printf("static char32_t is%sr[] = {\n", label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
276 some = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
278 prop[start] = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
279 printf("\t0x%.4x, 0x%.4x,\n", start, stop - 1);
David Demelier <markand@malikania.fr>
parents:
diff changeset
280 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
281
David Demelier <markand@malikania.fr>
parents:
diff changeset
282 start = stop;
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
284 if(some)
David Demelier <markand@malikania.fr>
parents:
diff changeset
285 printf("};\n\n");
David Demelier <markand@malikania.fr>
parents:
diff changeset
286 return some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
287 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
288
David Demelier <markand@malikania.fr>
parents:
diff changeset
289 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
290 * generate a mapping array for pairs with a skip between,
David Demelier <markand@malikania.fr>
parents:
diff changeset
291 * clearing those entries covered.
David Demelier <markand@malikania.fr>
parents:
diff changeset
292 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
293 static int
David Demelier <markand@malikania.fr>
parents:
diff changeset
294 mkispair(const char *label, char *prop)
David Demelier <markand@malikania.fr>
parents:
diff changeset
295 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
296 int start, stop, some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
297
David Demelier <markand@malikania.fr>
parents:
diff changeset
298 some = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
299 for(start = 0; start + 2 < NRUNES; ) {
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 if(!prop[start]){
David Demelier <markand@malikania.fr>
parents:
diff changeset
301 start++;
David Demelier <markand@malikania.fr>
parents:
diff changeset
302 continue;
David Demelier <markand@malikania.fr>
parents:
diff changeset
303 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
304
David Demelier <markand@malikania.fr>
parents:
diff changeset
305 for(stop = start + 2; stop < NRUNES; stop += 2){
David Demelier <markand@malikania.fr>
parents:
diff changeset
306 if(!prop[stop]){
David Demelier <markand@malikania.fr>
parents:
diff changeset
307 break;
David Demelier <markand@malikania.fr>
parents:
diff changeset
308 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
309 prop[stop] = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
310 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
311 if(stop != start + 2){
David Demelier <markand@malikania.fr>
parents:
diff changeset
312 if(!some){
David Demelier <markand@malikania.fr>
parents:
diff changeset
313 printf("static char32_t is%sp[] = {\n", label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
314 some = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
315 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
316 prop[start] = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
317 printf("\t0x%.4x, 0x%.4x,\n", start, stop - 2);
David Demelier <markand@malikania.fr>
parents:
diff changeset
318 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
319
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 start = stop;
David Demelier <markand@malikania.fr>
parents:
diff changeset
321 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
322 if(some)
David Demelier <markand@malikania.fr>
parents:
diff changeset
323 printf("};\n\n");
David Demelier <markand@malikania.fr>
parents:
diff changeset
324 return some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
325 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
326
David Demelier <markand@malikania.fr>
parents:
diff changeset
327 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
328 * generate a properties array for singletons, clearing those cases covered.
David Demelier <markand@malikania.fr>
parents:
diff changeset
329 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
330 static int
David Demelier <markand@malikania.fr>
parents:
diff changeset
331 mkissingle(const char *label, char *prop)
David Demelier <markand@malikania.fr>
parents:
diff changeset
332 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
333 int start, some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
334
David Demelier <markand@malikania.fr>
parents:
diff changeset
335 some = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
336 for(start = 0; start < NRUNES; start++) {
David Demelier <markand@malikania.fr>
parents:
diff changeset
337 if(!prop[start]){
David Demelier <markand@malikania.fr>
parents:
diff changeset
338 continue;
David Demelier <markand@malikania.fr>
parents:
diff changeset
339 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
340
David Demelier <markand@malikania.fr>
parents:
diff changeset
341 if(!some){
David Demelier <markand@malikania.fr>
parents:
diff changeset
342 printf("static char32_t is%ss[] = {\n", label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
343 some = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
344 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
345 prop[start] = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
346 printf("\t0x%.4x,\n", start);
David Demelier <markand@malikania.fr>
parents:
diff changeset
347 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
348 if(some)
David Demelier <markand@malikania.fr>
parents:
diff changeset
349 printf("};\n\n");
David Demelier <markand@malikania.fr>
parents:
diff changeset
350 return some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
351 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
352
David Demelier <markand@malikania.fr>
parents:
diff changeset
353 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
354 * generate tables and a function for is<label>rune
David Demelier <markand@malikania.fr>
parents:
diff changeset
355 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
356 static void
David Demelier <markand@malikania.fr>
parents:
diff changeset
357 mkis(const char* label, char* prop, int usepairs)
David Demelier <markand@malikania.fr>
parents:
diff changeset
358 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
359 int isr, isp, iss;
David Demelier <markand@malikania.fr>
parents:
diff changeset
360
David Demelier <markand@malikania.fr>
parents:
diff changeset
361 isr = mkisrange(label, prop, 0);
David Demelier <markand@malikania.fr>
parents:
diff changeset
362 isp = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
363 if(usepairs)
David Demelier <markand@malikania.fr>
parents:
diff changeset
364 isp = mkispair(label, prop);
David Demelier <markand@malikania.fr>
parents:
diff changeset
365 iss = mkissingle(label, prop);
David Demelier <markand@malikania.fr>
parents:
diff changeset
366
David Demelier <markand@malikania.fr>
parents:
diff changeset
367 printf(
395
b78d6d8f2872 Unicode: remove class, use namespace
David Demelier <markand@malikania.fr>
parents: 352
diff changeset
368 "bool is%s(char32_t c) noexcept\n"
352
David Demelier <markand@malikania.fr>
parents:
diff changeset
369 "{\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
370 " char32_t *p;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
371 "\n",
David Demelier <markand@malikania.fr>
parents:
diff changeset
372 label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
373
David Demelier <markand@malikania.fr>
parents:
diff changeset
374 if(isr)
David Demelier <markand@malikania.fr>
parents:
diff changeset
375 printf(
David Demelier <markand@malikania.fr>
parents:
diff changeset
376 " p = rbsearch(c, is%sr, nelem (is%sr)/2, 2);\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
377 " if (p && c >= p[0] && c <= p[1])\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
378 " return true;\n",
David Demelier <markand@malikania.fr>
parents:
diff changeset
379 label, label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
380
David Demelier <markand@malikania.fr>
parents:
diff changeset
381 if(isp)
David Demelier <markand@malikania.fr>
parents:
diff changeset
382 printf(
David Demelier <markand@malikania.fr>
parents:
diff changeset
383 "\n p = rbsearch(c, is%sp, nelem (is%sp)/2, 2);\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
384 " if (p && c >= p[0] && c <= p[1] && !((c - p[0]) & 1))\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
385 " return true;\n",
David Demelier <markand@malikania.fr>
parents:
diff changeset
386 label, label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
387
David Demelier <markand@malikania.fr>
parents:
diff changeset
388 if(iss)
David Demelier <markand@malikania.fr>
parents:
diff changeset
389 printf(
David Demelier <markand@malikania.fr>
parents:
diff changeset
390 "\n p = rbsearch(c, is%ss, nelem (is%ss), 1);\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
391 " if (p && c == p[0])\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
392 " return true;\n",
David Demelier <markand@malikania.fr>
parents:
diff changeset
393 label, label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
394
David Demelier <markand@malikania.fr>
parents:
diff changeset
395
David Demelier <markand@malikania.fr>
parents:
diff changeset
396 printf(
David Demelier <markand@malikania.fr>
parents:
diff changeset
397 "\n return false;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
398 "}\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
399 "\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
400 );
David Demelier <markand@malikania.fr>
parents:
diff changeset
401 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
402
David Demelier <markand@malikania.fr>
parents:
diff changeset
403 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
404 * generate a mapping array for ranges, clearing those entries covered.
David Demelier <markand@malikania.fr>
parents:
diff changeset
405 * if force, generate one-entry ranges for singletons.
David Demelier <markand@malikania.fr>
parents:
diff changeset
406 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
407 static int
David Demelier <markand@malikania.fr>
parents:
diff changeset
408 mktorange(const char* label, int* map, int force)
David Demelier <markand@malikania.fr>
parents:
diff changeset
409 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
410 int start, stop, delta, some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
411
David Demelier <markand@malikania.fr>
parents:
diff changeset
412 some = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
413 for(start = 0; start < NRUNES; ) {
David Demelier <markand@malikania.fr>
parents:
diff changeset
414 if(map[start] == start){
David Demelier <markand@malikania.fr>
parents:
diff changeset
415 start++;
David Demelier <markand@malikania.fr>
parents:
diff changeset
416 continue;
David Demelier <markand@malikania.fr>
parents:
diff changeset
417 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
418
David Demelier <markand@malikania.fr>
parents:
diff changeset
419 delta = TO_DELTA(map[start], start);
David Demelier <markand@malikania.fr>
parents:
diff changeset
420 if(delta != (Rune)delta)
David Demelier <markand@malikania.fr>
parents:
diff changeset
421 fatal("bad map delta %d", delta);
David Demelier <markand@malikania.fr>
parents:
diff changeset
422 for(stop = start + 1; stop < NRUNES; stop++){
David Demelier <markand@malikania.fr>
parents:
diff changeset
423 if(TO_DELTA(map[stop], stop) != delta){
David Demelier <markand@malikania.fr>
parents:
diff changeset
424 break;
David Demelier <markand@malikania.fr>
parents:
diff changeset
425 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
426 map[stop] = stop;
David Demelier <markand@malikania.fr>
parents:
diff changeset
427 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
428 if(stop != start + 1){
David Demelier <markand@malikania.fr>
parents:
diff changeset
429 if(!some){
David Demelier <markand@malikania.fr>
parents:
diff changeset
430 printf("char32_t to%sr[] = {\n", label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
431 some = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
432 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
433 map[start] = start;
David Demelier <markand@malikania.fr>
parents:
diff changeset
434 printf("\t0x%.4x, 0x%.4x, %d,\n", start, stop - 1, delta);
David Demelier <markand@malikania.fr>
parents:
diff changeset
435 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
436
David Demelier <markand@malikania.fr>
parents:
diff changeset
437 start = stop;
David Demelier <markand@malikania.fr>
parents:
diff changeset
438 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
439 if(some)
David Demelier <markand@malikania.fr>
parents:
diff changeset
440 printf("};\n\n");
David Demelier <markand@malikania.fr>
parents:
diff changeset
441 return some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
442 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
443
David Demelier <markand@malikania.fr>
parents:
diff changeset
444 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
445 * generate a mapping array for pairs with a skip between,
David Demelier <markand@malikania.fr>
parents:
diff changeset
446 * clearing those entries covered.
David Demelier <markand@malikania.fr>
parents:
diff changeset
447 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
448 static int
David Demelier <markand@malikania.fr>
parents:
diff changeset
449 mktopair(const char* label, int* map)
David Demelier <markand@malikania.fr>
parents:
diff changeset
450 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
451 int start, stop, delta, some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
452
David Demelier <markand@malikania.fr>
parents:
diff changeset
453 some = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
454 for(start = 0; start + 2 < NRUNES; ) {
David Demelier <markand@malikania.fr>
parents:
diff changeset
455 if(map[start] == start){
David Demelier <markand@malikania.fr>
parents:
diff changeset
456 start++;
David Demelier <markand@malikania.fr>
parents:
diff changeset
457 continue;
David Demelier <markand@malikania.fr>
parents:
diff changeset
458 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
459
David Demelier <markand@malikania.fr>
parents:
diff changeset
460 delta = TO_DELTA(map[start], start);
David Demelier <markand@malikania.fr>
parents:
diff changeset
461 if(delta != (Rune)delta)
David Demelier <markand@malikania.fr>
parents:
diff changeset
462 fatal("bad map delta %d", delta);
David Demelier <markand@malikania.fr>
parents:
diff changeset
463 for(stop = start + 2; stop < NRUNES; stop += 2){
David Demelier <markand@malikania.fr>
parents:
diff changeset
464 if(TO_DELTA(map[stop], stop) != delta){
David Demelier <markand@malikania.fr>
parents:
diff changeset
465 break;
David Demelier <markand@malikania.fr>
parents:
diff changeset
466 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
467 map[stop] = stop;
David Demelier <markand@malikania.fr>
parents:
diff changeset
468 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
469 if(stop != start + 2){
David Demelier <markand@malikania.fr>
parents:
diff changeset
470 if(!some){
David Demelier <markand@malikania.fr>
parents:
diff changeset
471 printf("static char32_t to%sp[] = {\n", label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
472 some = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
473 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
474 map[start] = start;
David Demelier <markand@malikania.fr>
parents:
diff changeset
475 printf("\t0x%.4x, 0x%.4x, %d,\n", start, stop - 2, delta);
David Demelier <markand@malikania.fr>
parents:
diff changeset
476 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
477
David Demelier <markand@malikania.fr>
parents:
diff changeset
478 start = stop;
David Demelier <markand@malikania.fr>
parents:
diff changeset
479 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
480 if(some)
David Demelier <markand@malikania.fr>
parents:
diff changeset
481 printf("};\n\n");
David Demelier <markand@malikania.fr>
parents:
diff changeset
482 return some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
483 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
484
David Demelier <markand@malikania.fr>
parents:
diff changeset
485 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
486 * generate a mapping array for singletons, clearing those entries covered.
David Demelier <markand@malikania.fr>
parents:
diff changeset
487 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
488 static int
David Demelier <markand@malikania.fr>
parents:
diff changeset
489 mktosingle(const char* label, int* map)
David Demelier <markand@malikania.fr>
parents:
diff changeset
490 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
491 int start, delta, some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
492
David Demelier <markand@malikania.fr>
parents:
diff changeset
493 some = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
494 for(start = 0; start < NRUNES; start++) {
David Demelier <markand@malikania.fr>
parents:
diff changeset
495 if(map[start] == start){
David Demelier <markand@malikania.fr>
parents:
diff changeset
496 continue;
David Demelier <markand@malikania.fr>
parents:
diff changeset
497 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
498
David Demelier <markand@malikania.fr>
parents:
diff changeset
499 delta = TO_DELTA(map[start], start);
David Demelier <markand@malikania.fr>
parents:
diff changeset
500 if(delta != (Rune)delta)
David Demelier <markand@malikania.fr>
parents:
diff changeset
501 fatal("bad map delta %d", delta);
David Demelier <markand@malikania.fr>
parents:
diff changeset
502 if(!some){
David Demelier <markand@malikania.fr>
parents:
diff changeset
503 printf("static char32_t to%ss[] = {\n", label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
504 some = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
505 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
506 map[start] = start;
David Demelier <markand@malikania.fr>
parents:
diff changeset
507 printf("\t0x%.4x, %d,\n", start, delta);
David Demelier <markand@malikania.fr>
parents:
diff changeset
508 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
509 if(some)
David Demelier <markand@malikania.fr>
parents:
diff changeset
510 printf("};\n\n");
David Demelier <markand@malikania.fr>
parents:
diff changeset
511 return some;
David Demelier <markand@malikania.fr>
parents:
diff changeset
512 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
513
David Demelier <markand@malikania.fr>
parents:
diff changeset
514 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
515 * generate tables and a function for to<label>rune
David Demelier <markand@malikania.fr>
parents:
diff changeset
516 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
517 static void
David Demelier <markand@malikania.fr>
parents:
diff changeset
518 mkto(const char* label, int* map, int usepairs)
David Demelier <markand@malikania.fr>
parents:
diff changeset
519 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
520 int tor, top, tos;
David Demelier <markand@malikania.fr>
parents:
diff changeset
521
David Demelier <markand@malikania.fr>
parents:
diff changeset
522 tor = mktorange(label, map, 0);
David Demelier <markand@malikania.fr>
parents:
diff changeset
523 top = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
524 if(usepairs)
David Demelier <markand@malikania.fr>
parents:
diff changeset
525 top = mktopair(label, map);
David Demelier <markand@malikania.fr>
parents:
diff changeset
526 tos = mktosingle(label, map);
David Demelier <markand@malikania.fr>
parents:
diff changeset
527
David Demelier <markand@malikania.fr>
parents:
diff changeset
528 printf(
395
b78d6d8f2872 Unicode: remove class, use namespace
David Demelier <markand@malikania.fr>
parents: 352
diff changeset
529 "char32_t to%s(char32_t c) noexcept\n"
352
David Demelier <markand@malikania.fr>
parents:
diff changeset
530 "{\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
531 " char32_t *p;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
532 "\n",
David Demelier <markand@malikania.fr>
parents:
diff changeset
533 label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
534
David Demelier <markand@malikania.fr>
parents:
diff changeset
535 if(tor)
David Demelier <markand@malikania.fr>
parents:
diff changeset
536 printf(
David Demelier <markand@malikania.fr>
parents:
diff changeset
537 " p = rbsearch(c, to%sr, nelem (to%sr)/3, 3);\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
538 " if (p && c >= p[0] && c <= p[1])\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
539 " return c + p[2] - %d;\n",
David Demelier <markand@malikania.fr>
parents:
diff changeset
540 label, label, TO_OFFSET);
David Demelier <markand@malikania.fr>
parents:
diff changeset
541
David Demelier <markand@malikania.fr>
parents:
diff changeset
542 if(top)
David Demelier <markand@malikania.fr>
parents:
diff changeset
543 printf(
David Demelier <markand@malikania.fr>
parents:
diff changeset
544 "\n p = rbsearch(c, to%sp, nelem (to%sp)/3, 3);\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
545 " if (p && c >= p[0] && c <= p[1] && !((c - p[0]) & 1))\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
546 " return c + p[2] - %d;\n",
David Demelier <markand@malikania.fr>
parents:
diff changeset
547 label, label, TO_OFFSET);
David Demelier <markand@malikania.fr>
parents:
diff changeset
548
David Demelier <markand@malikania.fr>
parents:
diff changeset
549 if(tos)
David Demelier <markand@malikania.fr>
parents:
diff changeset
550 printf(
David Demelier <markand@malikania.fr>
parents:
diff changeset
551 "\n p = rbsearch(c, to%ss, nelem (to%ss)/2, 2);\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
552 " if (p && c == p[0])\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
553 " return c + p[1] - %d;\n",
David Demelier <markand@malikania.fr>
parents:
diff changeset
554 label, label, TO_OFFSET);
David Demelier <markand@malikania.fr>
parents:
diff changeset
555
David Demelier <markand@malikania.fr>
parents:
diff changeset
556 printf(
David Demelier <markand@malikania.fr>
parents:
diff changeset
557 "\n return c;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
558 "}\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
559 "\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
560 );
David Demelier <markand@malikania.fr>
parents:
diff changeset
561 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
562
David Demelier <markand@malikania.fr>
parents:
diff changeset
563 // Make only range tables and a function for is<label>rune.
David Demelier <markand@malikania.fr>
parents:
diff changeset
564 static void
David Demelier <markand@malikania.fr>
parents:
diff changeset
565 mkisronly(const char* label, char* prop)
David Demelier <markand@malikania.fr>
parents:
diff changeset
566 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
567 mkisrange(label, prop, 1);
David Demelier <markand@malikania.fr>
parents:
diff changeset
568 printf(
395
b78d6d8f2872 Unicode: remove class, use namespace
David Demelier <markand@malikania.fr>
parents: 352
diff changeset
569 "bool is%s(char32_t c) noexcept\n"
352
David Demelier <markand@malikania.fr>
parents:
diff changeset
570 "{\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
571 " char32_t *p;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
572 "\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
573 " p = rbsearch(c, is%sr, nelem (is%sr)/2, 2);\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
574 " if (p && c >= p[0] && c <= p[1])\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
575 " return true;\n\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
576 " return false;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
577 "}\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
578 "\n",
David Demelier <markand@malikania.fr>
parents:
diff changeset
579 label, label, label);
David Demelier <markand@malikania.fr>
parents:
diff changeset
580 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
581
David Demelier <markand@malikania.fr>
parents:
diff changeset
582 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
583 * generate the body of runetype.
David Demelier <markand@malikania.fr>
parents:
diff changeset
584 * assumes there is a function Rune* rbsearch(Rune c, Rune *t, int n, int ne);
David Demelier <markand@malikania.fr>
parents:
diff changeset
585 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
586 static void
David Demelier <markand@malikania.fr>
parents:
diff changeset
587 mktables(char *src, int usepairs)
David Demelier <markand@malikania.fr>
parents:
diff changeset
588 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
589 /* Add nelem macro */
David Demelier <markand@malikania.fr>
parents:
diff changeset
590 printf(
David Demelier <markand@malikania.fr>
parents:
diff changeset
591 "#define nelem(x) (sizeof (x) / sizeof ((x)[0]))\n\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
592 );
David Demelier <markand@malikania.fr>
parents:
diff changeset
593
David Demelier <markand@malikania.fr>
parents:
diff changeset
594 /* Add the rbsearch function */
David Demelier <markand@malikania.fr>
parents:
diff changeset
595 printf(
David Demelier <markand@malikania.fr>
parents:
diff changeset
596 "char32_t *rbsearch(char32_t c, char32_t *t, int n, int ne) noexcept\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
597 "{\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
598 " char32_t *p;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
599 " int m;\n\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
600 " while (n > 1) {\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
601 " m = n >> 1;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
602 " p = t + m * ne;\n\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
603 " if (c >= p[0]) {\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
604 " t = p;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
605 " n = n - m;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
606 " } else {\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
607 " n = m;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
608 " }\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
609 " }\n\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
610 " if (n && c >= t[0])\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
611 " return t;\n\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
612 " return nullptr;\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
613 "}\n\n"
David Demelier <markand@malikania.fr>
parents:
diff changeset
614 );
David Demelier <markand@malikania.fr>
parents:
diff changeset
615
David Demelier <markand@malikania.fr>
parents:
diff changeset
616 /*
David Demelier <markand@malikania.fr>
parents:
diff changeset
617 * we special case the space and digit tables, since they are assumed
David Demelier <markand@malikania.fr>
parents:
diff changeset
618 * to be small with several ranges.
David Demelier <markand@malikania.fr>
parents:
diff changeset
619 */
David Demelier <markand@malikania.fr>
parents:
diff changeset
620 mkisronly("space", myisspace);
David Demelier <markand@malikania.fr>
parents:
diff changeset
621 mkisronly("digit", myisdigit);
David Demelier <markand@malikania.fr>
parents:
diff changeset
622
David Demelier <markand@malikania.fr>
parents:
diff changeset
623 mkis("alpha", myisalpha, 0);
David Demelier <markand@malikania.fr>
parents:
diff changeset
624 mkis("upper", myisupper, usepairs);
David Demelier <markand@malikania.fr>
parents:
diff changeset
625 mkis("lower", myislower, usepairs);
David Demelier <markand@malikania.fr>
parents:
diff changeset
626 mkis("title", myistitle, usepairs);
David Demelier <markand@malikania.fr>
parents:
diff changeset
627
David Demelier <markand@malikania.fr>
parents:
diff changeset
628 mkto("upper", mytoupper, usepairs);
David Demelier <markand@malikania.fr>
parents:
diff changeset
629 mkto("lower", mytolower, usepairs);
David Demelier <markand@malikania.fr>
parents:
diff changeset
630 mkto("title", mytotitle, usepairs);
David Demelier <markand@malikania.fr>
parents:
diff changeset
631 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
632
David Demelier <markand@malikania.fr>
parents:
diff changeset
633 static int
David Demelier <markand@malikania.fr>
parents:
diff changeset
634 mygetfields(char **fields, int nfields, char *str, const char *delim)
David Demelier <markand@malikania.fr>
parents:
diff changeset
635 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
636 int nf;
David Demelier <markand@malikania.fr>
parents:
diff changeset
637
David Demelier <markand@malikania.fr>
parents:
diff changeset
638 fields[0] = str;
David Demelier <markand@malikania.fr>
parents:
diff changeset
639 nf = 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
640 if(nf >= nfields)
David Demelier <markand@malikania.fr>
parents:
diff changeset
641 return nf;
David Demelier <markand@malikania.fr>
parents:
diff changeset
642
David Demelier <markand@malikania.fr>
parents:
diff changeset
643 for(; *str; str++){
David Demelier <markand@malikania.fr>
parents:
diff changeset
644 if(strchr(delim, *str) != NULL){
David Demelier <markand@malikania.fr>
parents:
diff changeset
645 *str = '\0';
David Demelier <markand@malikania.fr>
parents:
diff changeset
646 fields[nf++] = str + 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
647 if(nf >= nfields)
David Demelier <markand@malikania.fr>
parents:
diff changeset
648 break;
David Demelier <markand@malikania.fr>
parents:
diff changeset
649 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
650 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
651 return nf;
David Demelier <markand@malikania.fr>
parents:
diff changeset
652 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
653
David Demelier <markand@malikania.fr>
parents:
diff changeset
654 static int
David Demelier <markand@malikania.fr>
parents:
diff changeset
655 getunicodeline(FILE *in, char **fields, char *buf)
David Demelier <markand@malikania.fr>
parents:
diff changeset
656 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
657 char *p;
David Demelier <markand@malikania.fr>
parents:
diff changeset
658
David Demelier <markand@malikania.fr>
parents:
diff changeset
659 if(fgets(buf, MAX_LINE, in) == NULL)
David Demelier <markand@malikania.fr>
parents:
diff changeset
660 return 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
661
David Demelier <markand@malikania.fr>
parents:
diff changeset
662 p = strchr(buf, '\n');
David Demelier <markand@malikania.fr>
parents:
diff changeset
663 if (p == NULL)
David Demelier <markand@malikania.fr>
parents:
diff changeset
664 fatal("line too long");
David Demelier <markand@malikania.fr>
parents:
diff changeset
665 *p = '\0';
David Demelier <markand@malikania.fr>
parents:
diff changeset
666
David Demelier <markand@malikania.fr>
parents:
diff changeset
667 if (mygetfields(fields, NFIELDS + 1, buf, ";") != NFIELDS)
David Demelier <markand@malikania.fr>
parents:
diff changeset
668 fatal("bad number of fields");
David Demelier <markand@malikania.fr>
parents:
diff changeset
669
David Demelier <markand@malikania.fr>
parents:
diff changeset
670 return 1;
David Demelier <markand@malikania.fr>
parents:
diff changeset
671 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
672
David Demelier <markand@malikania.fr>
parents:
diff changeset
673 static int
David Demelier <markand@malikania.fr>
parents:
diff changeset
674 getcode(char *s)
David Demelier <markand@malikania.fr>
parents:
diff changeset
675 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
676 int i, code;
David Demelier <markand@malikania.fr>
parents:
diff changeset
677
David Demelier <markand@malikania.fr>
parents:
diff changeset
678 code = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
679 i = 0;
David Demelier <markand@malikania.fr>
parents:
diff changeset
680 /* Parse a hex number */
David Demelier <markand@malikania.fr>
parents:
diff changeset
681 while(s[i]) {
David Demelier <markand@malikania.fr>
parents:
diff changeset
682 code <<= 4;
David Demelier <markand@malikania.fr>
parents:
diff changeset
683 if(s[i] >= '0' && s[i] <= '9')
David Demelier <markand@malikania.fr>
parents:
diff changeset
684 code += s[i] - '0';
David Demelier <markand@malikania.fr>
parents:
diff changeset
685 else if(s[i] >= 'A' && s[i] <= 'F')
David Demelier <markand@malikania.fr>
parents:
diff changeset
686 code += s[i] - 'A' + 10;
David Demelier <markand@malikania.fr>
parents:
diff changeset
687 else
David Demelier <markand@malikania.fr>
parents:
diff changeset
688 fatal("bad code char '%c'", s[i]);
David Demelier <markand@malikania.fr>
parents:
diff changeset
689 i++;
David Demelier <markand@malikania.fr>
parents:
diff changeset
690 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
691 return code;
David Demelier <markand@malikania.fr>
parents:
diff changeset
692 }
David Demelier <markand@malikania.fr>
parents:
diff changeset
693
David Demelier <markand@malikania.fr>
parents:
diff changeset
694 static void
David Demelier <markand@malikania.fr>
parents:
diff changeset
695 fatal(const char *fmt, ...)
David Demelier <markand@malikania.fr>
parents:
diff changeset
696 {
David Demelier <markand@malikania.fr>
parents:
diff changeset
697 va_list arg;
David Demelier <markand@malikania.fr>
parents:
diff changeset
698
David Demelier <markand@malikania.fr>
parents:
diff changeset
699 fprintf(stderr, "mkunicode: fatal error: ");
David Demelier <markand@malikania.fr>
parents:
diff changeset
700 va_start(arg, fmt);
David Demelier <markand@malikania.fr>
parents:
diff changeset
701 vfprintf(stderr, fmt, arg);
David Demelier <markand@malikania.fr>
parents:
diff changeset
702 va_end(arg);
David Demelier <markand@malikania.fr>
parents:
diff changeset
703 fprintf(stderr, "\n");
David Demelier <markand@malikania.fr>
parents:
diff changeset
704
David Demelier <markand@malikania.fr>
parents:
diff changeset
705 exit(1);
395
b78d6d8f2872 Unicode: remove class, use namespace
David Demelier <markand@malikania.fr>
parents: 352
diff changeset
706 }