1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9/*
10 * N.J. Nes, M.L. Kersten
11 * The String Module
12 * Strings can be created in many ways. Already in the built-in
13 * operations each atom can be cast to a string using the str(atom)
14 * mil command. The string module gives the possibility of
15 * construction string as a substring of the a given string (s). There
16 * are two such construction functions. The first is the substring
17 * from some position (offset) until the end of the string. The second
18 * start again on the given offset position but only copies count
19 * number of bytes. The functions fail when the position and count
20 * fall out of bounds. A negative position indicates that the position
21 * is computed from the end of the source string.
22 *
23 * The strings can be compared using the "=" and "!=" operators.
24 *
25 * The operator "+" concatenates a string and an atom. The atom will
26 * be converted to a string using the atom to string c function. The
27 * string and the result of the conversion are concatenated to form a
28 * new string. This string is returned.
29 *
30 * The length function returns the length of the string. The length is
31 * the number of characters in the string. The maximum string length
32 * handled by the kernel is 32-bits long.
33 *
34 * chrAt() returns the character at position index in the string
35 * s. The function will fail when the index is out of range. The range
36 * is from 0 to length(s)-1.
37 *
38 * The startsWith and endsWith functions test if the string s starts
39 * with or ends with the given prefix or suffix.
40 *
41 * The toLower and toUpper functions cast the string to lower or upper
42 * case characters.
43 *
44 * The search(str,chr) function searches for the first occurrence of a
45 * character from the begining of the string. The search(chr,str)
46 * searches for the last occurrence (or first from the end of the
47 * string). The last search function locates the position of first
48 * occurrence of the string s2 in string s. All search functions
49 * return -1 when the search failed. Otherwise the position is
50 * returned.
51 *
52 * All string functions fail when an incorrect string (NULL pointer)
53 * is given. In the current implementation, a fail is signaled by
54 * returning nil, since this facilitates the use of the string module
55 * in bulk operations.
56 *
57 * All functions in the module have now been converted to
58 * Unicode. Internally, we use UTF-8 to store strings as Unicode in
59 * zero-terminated byte-sequences.
60 */
61#include "monetdb_config.h"
62#include "str.h"
63#include <string.h>
64
65/*
66 * UTF-8 Handling
67 * UTF-8 is a way to store Unicode strings in zero-terminated byte
68 * sequences, which you can e.g. strcmp() with old 8-bit Latin-1
69 * strcmp() functions and which then gives the same results as doing
70 * the strcmp() on equivalent Latin-1 and ASCII character strings
71 * stored in simple one-byte sequences. These characteristics make
72 * UTF-8 an attractive format for upgrading an ASCII-oriented computer
73 * program towards one that supports Unicode. That is why we use UTF-8
74 * in MonetDB.
75 *
76 * For MonetDB, UTF-8 mostly has no consequences, as strings stored in
77 * BATs are regarded as data, and it does not matter for the database
78 * kernel whether the zero-terminated byte sequence it is processing
79 * has UTF-8 or Latin-1 semantics. This module is the only place where
80 * explicit string functionality is located. We {\bf do} have to adapt
81 * the behavior of the length(), search(), substring() and the
82 * like commands to the fact that one (Unicode) character is now
83 * stored in a variable number of bytes (possibly > 1).
84 *
85 * One of the things that become more complex in Unicode are
86 * uppercase/lowercase conversions. The below tables are the simple
87 * one-to-one Unicode case mappings. We do not support the special
88 * casing mappings (e.g. from one to two letters).
89 *
90 * References:
91 * simple casing: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
92 * complex casing: http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt
93 *
94 * The Unicode case conversion implementation in MonetDB fills a
95 * mapping BAT of int,int combinations, in which we perform
96 * high-performance hash-lookup (all code inlined).
97 */
98
99/* These tables were generated from the Unicode 10.0.0 spec. */
100struct UTF8_lower_upper {
101 unsigned int from, to;
102} UTF8_toUpper[] = { /* code points with non-null uppercase conversion */
103 { 0x0061, 0x0041, },
104 { 0x0062, 0x0042, },
105 { 0x0063, 0x0043, },
106 { 0x0064, 0x0044, },
107 { 0x0065, 0x0045, },
108 { 0x0066, 0x0046, },
109 { 0x0067, 0x0047, },
110 { 0x0068, 0x0048, },
111 { 0x0069, 0x0049, },
112 { 0x006A, 0x004A, },
113 { 0x006B, 0x004B, },
114 { 0x006C, 0x004C, },
115 { 0x006D, 0x004D, },
116 { 0x006E, 0x004E, },
117 { 0x006F, 0x004F, },
118 { 0x0070, 0x0050, },
119 { 0x0071, 0x0051, },
120 { 0x0072, 0x0052, },
121 { 0x0073, 0x0053, },
122 { 0x0074, 0x0054, },
123 { 0x0075, 0x0055, },
124 { 0x0076, 0x0056, },
125 { 0x0077, 0x0057, },
126 { 0x0078, 0x0058, },
127 { 0x0079, 0x0059, },
128 { 0x007A, 0x005A, },
129 { 0x00B5, 0x039C, },
130 { 0x00E0, 0x00C0, },
131 { 0x00E1, 0x00C1, },
132 { 0x00E2, 0x00C2, },
133 { 0x00E3, 0x00C3, },
134 { 0x00E4, 0x00C4, },
135 { 0x00E5, 0x00C5, },
136 { 0x00E6, 0x00C6, },
137 { 0x00E7, 0x00C7, },
138 { 0x00E8, 0x00C8, },
139 { 0x00E9, 0x00C9, },
140 { 0x00EA, 0x00CA, },
141 { 0x00EB, 0x00CB, },
142 { 0x00EC, 0x00CC, },
143 { 0x00ED, 0x00CD, },
144 { 0x00EE, 0x00CE, },
145 { 0x00EF, 0x00CF, },
146 { 0x00F0, 0x00D0, },
147 { 0x00F1, 0x00D1, },
148 { 0x00F2, 0x00D2, },
149 { 0x00F3, 0x00D3, },
150 { 0x00F4, 0x00D4, },
151 { 0x00F5, 0x00D5, },
152 { 0x00F6, 0x00D6, },
153 { 0x00F8, 0x00D8, },
154 { 0x00F9, 0x00D9, },
155 { 0x00FA, 0x00DA, },
156 { 0x00FB, 0x00DB, },
157 { 0x00FC, 0x00DC, },
158 { 0x00FD, 0x00DD, },
159 { 0x00FE, 0x00DE, },
160 { 0x00FF, 0x0178, },
161 { 0x0101, 0x0100, },
162 { 0x0103, 0x0102, },
163 { 0x0105, 0x0104, },
164 { 0x0107, 0x0106, },
165 { 0x0109, 0x0108, },
166 { 0x010B, 0x010A, },
167 { 0x010D, 0x010C, },
168 { 0x010F, 0x010E, },
169 { 0x0111, 0x0110, },
170 { 0x0113, 0x0112, },
171 { 0x0115, 0x0114, },
172 { 0x0117, 0x0116, },
173 { 0x0119, 0x0118, },
174 { 0x011B, 0x011A, },
175 { 0x011D, 0x011C, },
176 { 0x011F, 0x011E, },
177 { 0x0121, 0x0120, },
178 { 0x0123, 0x0122, },
179 { 0x0125, 0x0124, },
180 { 0x0127, 0x0126, },
181 { 0x0129, 0x0128, },
182 { 0x012B, 0x012A, },
183 { 0x012D, 0x012C, },
184 { 0x012F, 0x012E, },
185 { 0x0131, 0x0049, },
186 { 0x0133, 0x0132, },
187 { 0x0135, 0x0134, },
188 { 0x0137, 0x0136, },
189 { 0x013A, 0x0139, },
190 { 0x013C, 0x013B, },
191 { 0x013E, 0x013D, },
192 { 0x0140, 0x013F, },
193 { 0x0142, 0x0141, },
194 { 0x0144, 0x0143, },
195 { 0x0146, 0x0145, },
196 { 0x0148, 0x0147, },
197 { 0x014B, 0x014A, },
198 { 0x014D, 0x014C, },
199 { 0x014F, 0x014E, },
200 { 0x0151, 0x0150, },
201 { 0x0153, 0x0152, },
202 { 0x0155, 0x0154, },
203 { 0x0157, 0x0156, },
204 { 0x0159, 0x0158, },
205 { 0x015B, 0x015A, },
206 { 0x015D, 0x015C, },
207 { 0x015F, 0x015E, },
208 { 0x0161, 0x0160, },
209 { 0x0163, 0x0162, },
210 { 0x0165, 0x0164, },
211 { 0x0167, 0x0166, },
212 { 0x0169, 0x0168, },
213 { 0x016B, 0x016A, },
214 { 0x016D, 0x016C, },
215 { 0x016F, 0x016E, },
216 { 0x0171, 0x0170, },
217 { 0x0173, 0x0172, },
218 { 0x0175, 0x0174, },
219 { 0x0177, 0x0176, },
220 { 0x017A, 0x0179, },
221 { 0x017C, 0x017B, },
222 { 0x017E, 0x017D, },
223 { 0x017F, 0x0053, },
224 { 0x0180, 0x0243, },
225 { 0x0183, 0x0182, },
226 { 0x0185, 0x0184, },
227 { 0x0188, 0x0187, },
228 { 0x018C, 0x018B, },
229 { 0x0192, 0x0191, },
230 { 0x0195, 0x01F6, },
231 { 0x0199, 0x0198, },
232 { 0x019A, 0x023D, },
233 { 0x019E, 0x0220, },
234 { 0x01A1, 0x01A0, },
235 { 0x01A3, 0x01A2, },
236 { 0x01A5, 0x01A4, },
237 { 0x01A8, 0x01A7, },
238 { 0x01AD, 0x01AC, },
239 { 0x01B0, 0x01AF, },
240 { 0x01B4, 0x01B3, },
241 { 0x01B6, 0x01B5, },
242 { 0x01B9, 0x01B8, },
243 { 0x01BD, 0x01BC, },
244 { 0x01BF, 0x01F7, },
245 { 0x01C5, 0x01C4, },
246 { 0x01C6, 0x01C4, },
247 { 0x01C8, 0x01C7, },
248 { 0x01C9, 0x01C7, },
249 { 0x01CB, 0x01CA, },
250 { 0x01CC, 0x01CA, },
251 { 0x01CE, 0x01CD, },
252 { 0x01D0, 0x01CF, },
253 { 0x01D2, 0x01D1, },
254 { 0x01D4, 0x01D3, },
255 { 0x01D6, 0x01D5, },
256 { 0x01D8, 0x01D7, },
257 { 0x01DA, 0x01D9, },
258 { 0x01DC, 0x01DB, },
259 { 0x01DD, 0x018E, },
260 { 0x01DF, 0x01DE, },
261 { 0x01E1, 0x01E0, },
262 { 0x01E3, 0x01E2, },
263 { 0x01E5, 0x01E4, },
264 { 0x01E7, 0x01E6, },
265 { 0x01E9, 0x01E8, },
266 { 0x01EB, 0x01EA, },
267 { 0x01ED, 0x01EC, },
268 { 0x01EF, 0x01EE, },
269 { 0x01F2, 0x01F1, },
270 { 0x01F3, 0x01F1, },
271 { 0x01F5, 0x01F4, },
272 { 0x01F9, 0x01F8, },
273 { 0x01FB, 0x01FA, },
274 { 0x01FD, 0x01FC, },
275 { 0x01FF, 0x01FE, },
276 { 0x0201, 0x0200, },
277 { 0x0203, 0x0202, },
278 { 0x0205, 0x0204, },
279 { 0x0207, 0x0206, },
280 { 0x0209, 0x0208, },
281 { 0x020B, 0x020A, },
282 { 0x020D, 0x020C, },
283 { 0x020F, 0x020E, },
284 { 0x0211, 0x0210, },
285 { 0x0213, 0x0212, },
286 { 0x0215, 0x0214, },
287 { 0x0217, 0x0216, },
288 { 0x0219, 0x0218, },
289 { 0x021B, 0x021A, },
290 { 0x021D, 0x021C, },
291 { 0x021F, 0x021E, },
292 { 0x0223, 0x0222, },
293 { 0x0225, 0x0224, },
294 { 0x0227, 0x0226, },
295 { 0x0229, 0x0228, },
296 { 0x022B, 0x022A, },
297 { 0x022D, 0x022C, },
298 { 0x022F, 0x022E, },
299 { 0x0231, 0x0230, },
300 { 0x0233, 0x0232, },
301 { 0x023C, 0x023B, },
302 { 0x023F, 0x2C7E, },
303 { 0x0240, 0x2C7F, },
304 { 0x0242, 0x0241, },
305 { 0x0247, 0x0246, },
306 { 0x0249, 0x0248, },
307 { 0x024B, 0x024A, },
308 { 0x024D, 0x024C, },
309 { 0x024F, 0x024E, },
310 { 0x0250, 0x2C6F, },
311 { 0x0251, 0x2C6D, },
312 { 0x0252, 0x2C70, },
313 { 0x0253, 0x0181, },
314 { 0x0254, 0x0186, },
315 { 0x0256, 0x0189, },
316 { 0x0257, 0x018A, },
317 { 0x0259, 0x018F, },
318 { 0x025B, 0x0190, },
319 { 0x025C, 0xA7AB, },
320 { 0x0260, 0x0193, },
321 { 0x0261, 0xA7AC, },
322 { 0x0263, 0x0194, },
323 { 0x0265, 0xA78D, },
324 { 0x0266, 0xA7AA, },
325 { 0x0268, 0x0197, },
326 { 0x0269, 0x0196, },
327 { 0x026A, 0xA7AE, },
328 { 0x026B, 0x2C62, },
329 { 0x026C, 0xA7AD, },
330 { 0x026F, 0x019C, },
331 { 0x0271, 0x2C6E, },
332 { 0x0272, 0x019D, },
333 { 0x0275, 0x019F, },
334 { 0x027D, 0x2C64, },
335 { 0x0280, 0x01A6, },
336 { 0x0283, 0x01A9, },
337 { 0x0287, 0xA7B1, },
338 { 0x0288, 0x01AE, },
339 { 0x0289, 0x0244, },
340 { 0x028A, 0x01B1, },
341 { 0x028B, 0x01B2, },
342 { 0x028C, 0x0245, },
343 { 0x0292, 0x01B7, },
344 { 0x029D, 0xA7B2, },
345 { 0x029E, 0xA7B0, },
346 { 0x0345, 0x0399, },
347 { 0x0371, 0x0370, },
348 { 0x0373, 0x0372, },
349 { 0x0377, 0x0376, },
350 { 0x037B, 0x03FD, },
351 { 0x037C, 0x03FE, },
352 { 0x037D, 0x03FF, },
353 { 0x03AC, 0x0386, },
354 { 0x03AD, 0x0388, },
355 { 0x03AE, 0x0389, },
356 { 0x03AF, 0x038A, },
357 { 0x03B1, 0x0391, },
358 { 0x03B2, 0x0392, },
359 { 0x03B3, 0x0393, },
360 { 0x03B4, 0x0394, },
361 { 0x03B5, 0x0395, },
362 { 0x03B6, 0x0396, },
363 { 0x03B7, 0x0397, },
364 { 0x03B8, 0x0398, },
365 { 0x03B9, 0x0399, },
366 { 0x03BA, 0x039A, },
367 { 0x03BB, 0x039B, },
368 { 0x03BC, 0x039C, },
369 { 0x03BD, 0x039D, },
370 { 0x03BE, 0x039E, },
371 { 0x03BF, 0x039F, },
372 { 0x03C0, 0x03A0, },
373 { 0x03C1, 0x03A1, },
374 { 0x03C2, 0x03A3, },
375 { 0x03C3, 0x03A3, },
376 { 0x03C4, 0x03A4, },
377 { 0x03C5, 0x03A5, },
378 { 0x03C6, 0x03A6, },
379 { 0x03C7, 0x03A7, },
380 { 0x03C8, 0x03A8, },
381 { 0x03C9, 0x03A9, },
382 { 0x03CA, 0x03AA, },
383 { 0x03CB, 0x03AB, },
384 { 0x03CC, 0x038C, },
385 { 0x03CD, 0x038E, },
386 { 0x03CE, 0x038F, },
387 { 0x03D0, 0x0392, },
388 { 0x03D1, 0x0398, },
389 { 0x03D5, 0x03A6, },
390 { 0x03D6, 0x03A0, },
391 { 0x03D7, 0x03CF, },
392 { 0x03D9, 0x03D8, },
393 { 0x03DB, 0x03DA, },
394 { 0x03DD, 0x03DC, },
395 { 0x03DF, 0x03DE, },
396 { 0x03E1, 0x03E0, },
397 { 0x03E3, 0x03E2, },
398 { 0x03E5, 0x03E4, },
399 { 0x03E7, 0x03E6, },
400 { 0x03E9, 0x03E8, },
401 { 0x03EB, 0x03EA, },
402 { 0x03ED, 0x03EC, },
403 { 0x03EF, 0x03EE, },
404 { 0x03F0, 0x039A, },
405 { 0x03F1, 0x03A1, },
406 { 0x03F2, 0x03F9, },
407 { 0x03F3, 0x037F, },
408 { 0x03F5, 0x0395, },
409 { 0x03F8, 0x03F7, },
410 { 0x03FB, 0x03FA, },
411 { 0x0430, 0x0410, },
412 { 0x0431, 0x0411, },
413 { 0x0432, 0x0412, },
414 { 0x0433, 0x0413, },
415 { 0x0434, 0x0414, },
416 { 0x0435, 0x0415, },
417 { 0x0436, 0x0416, },
418 { 0x0437, 0x0417, },
419 { 0x0438, 0x0418, },
420 { 0x0439, 0x0419, },
421 { 0x043A, 0x041A, },
422 { 0x043B, 0x041B, },
423 { 0x043C, 0x041C, },
424 { 0x043D, 0x041D, },
425 { 0x043E, 0x041E, },
426 { 0x043F, 0x041F, },
427 { 0x0440, 0x0420, },
428 { 0x0441, 0x0421, },
429 { 0x0442, 0x0422, },
430 { 0x0443, 0x0423, },
431 { 0x0444, 0x0424, },
432 { 0x0445, 0x0425, },
433 { 0x0446, 0x0426, },
434 { 0x0447, 0x0427, },
435 { 0x0448, 0x0428, },
436 { 0x0449, 0x0429, },
437 { 0x044A, 0x042A, },
438 { 0x044B, 0x042B, },
439 { 0x044C, 0x042C, },
440 { 0x044D, 0x042D, },
441 { 0x044E, 0x042E, },
442 { 0x044F, 0x042F, },
443 { 0x0450, 0x0400, },
444 { 0x0451, 0x0401, },
445 { 0x0452, 0x0402, },
446 { 0x0453, 0x0403, },
447 { 0x0454, 0x0404, },
448 { 0x0455, 0x0405, },
449 { 0x0456, 0x0406, },
450 { 0x0457, 0x0407, },
451 { 0x0458, 0x0408, },
452 { 0x0459, 0x0409, },
453 { 0x045A, 0x040A, },
454 { 0x045B, 0x040B, },
455 { 0x045C, 0x040C, },
456 { 0x045D, 0x040D, },
457 { 0x045E, 0x040E, },
458 { 0x045F, 0x040F, },
459 { 0x0461, 0x0460, },
460 { 0x0463, 0x0462, },
461 { 0x0465, 0x0464, },
462 { 0x0467, 0x0466, },
463 { 0x0469, 0x0468, },
464 { 0x046B, 0x046A, },
465 { 0x046D, 0x046C, },
466 { 0x046F, 0x046E, },
467 { 0x0471, 0x0470, },
468 { 0x0473, 0x0472, },
469 { 0x0475, 0x0474, },
470 { 0x0477, 0x0476, },
471 { 0x0479, 0x0478, },
472 { 0x047B, 0x047A, },
473 { 0x047D, 0x047C, },
474 { 0x047F, 0x047E, },
475 { 0x0481, 0x0480, },
476 { 0x048B, 0x048A, },
477 { 0x048D, 0x048C, },
478 { 0x048F, 0x048E, },
479 { 0x0491, 0x0490, },
480 { 0x0493, 0x0492, },
481 { 0x0495, 0x0494, },
482 { 0x0497, 0x0496, },
483 { 0x0499, 0x0498, },
484 { 0x049B, 0x049A, },
485 { 0x049D, 0x049C, },
486 { 0x049F, 0x049E, },
487 { 0x04A1, 0x04A0, },
488 { 0x04A3, 0x04A2, },
489 { 0x04A5, 0x04A4, },
490 { 0x04A7, 0x04A6, },
491 { 0x04A9, 0x04A8, },
492 { 0x04AB, 0x04AA, },
493 { 0x04AD, 0x04AC, },
494 { 0x04AF, 0x04AE, },
495 { 0x04B1, 0x04B0, },
496 { 0x04B3, 0x04B2, },
497 { 0x04B5, 0x04B4, },
498 { 0x04B7, 0x04B6, },
499 { 0x04B9, 0x04B8, },
500 { 0x04BB, 0x04BA, },
501 { 0x04BD, 0x04BC, },
502 { 0x04BF, 0x04BE, },
503 { 0x04C2, 0x04C1, },
504 { 0x04C4, 0x04C3, },
505 { 0x04C6, 0x04C5, },
506 { 0x04C8, 0x04C7, },
507 { 0x04CA, 0x04C9, },
508 { 0x04CC, 0x04CB, },
509 { 0x04CE, 0x04CD, },
510 { 0x04CF, 0x04C0, },
511 { 0x04D1, 0x04D0, },
512 { 0x04D3, 0x04D2, },
513 { 0x04D5, 0x04D4, },
514 { 0x04D7, 0x04D6, },
515 { 0x04D9, 0x04D8, },
516 { 0x04DB, 0x04DA, },
517 { 0x04DD, 0x04DC, },
518 { 0x04DF, 0x04DE, },
519 { 0x04E1, 0x04E0, },
520 { 0x04E3, 0x04E2, },
521 { 0x04E5, 0x04E4, },
522 { 0x04E7, 0x04E6, },
523 { 0x04E9, 0x04E8, },
524 { 0x04EB, 0x04EA, },
525 { 0x04ED, 0x04EC, },
526 { 0x04EF, 0x04EE, },
527 { 0x04F1, 0x04F0, },
528 { 0x04F3, 0x04F2, },
529 { 0x04F5, 0x04F4, },
530 { 0x04F7, 0x04F6, },
531 { 0x04F9, 0x04F8, },
532 { 0x04FB, 0x04FA, },
533 { 0x04FD, 0x04FC, },
534 { 0x04FF, 0x04FE, },
535 { 0x0501, 0x0500, },
536 { 0x0503, 0x0502, },
537 { 0x0505, 0x0504, },
538 { 0x0507, 0x0506, },
539 { 0x0509, 0x0508, },
540 { 0x050B, 0x050A, },
541 { 0x050D, 0x050C, },
542 { 0x050F, 0x050E, },
543 { 0x0511, 0x0510, },
544 { 0x0513, 0x0512, },
545 { 0x0515, 0x0514, },
546 { 0x0517, 0x0516, },
547 { 0x0519, 0x0518, },
548 { 0x051B, 0x051A, },
549 { 0x051D, 0x051C, },
550 { 0x051F, 0x051E, },
551 { 0x0521, 0x0520, },
552 { 0x0523, 0x0522, },
553 { 0x0525, 0x0524, },
554 { 0x0527, 0x0526, },
555 { 0x0529, 0x0528, },
556 { 0x052B, 0x052A, },
557 { 0x052D, 0x052C, },
558 { 0x052F, 0x052E, },
559 { 0x0561, 0x0531, },
560 { 0x0562, 0x0532, },
561 { 0x0563, 0x0533, },
562 { 0x0564, 0x0534, },
563 { 0x0565, 0x0535, },
564 { 0x0566, 0x0536, },
565 { 0x0567, 0x0537, },
566 { 0x0568, 0x0538, },
567 { 0x0569, 0x0539, },
568 { 0x056A, 0x053A, },
569 { 0x056B, 0x053B, },
570 { 0x056C, 0x053C, },
571 { 0x056D, 0x053D, },
572 { 0x056E, 0x053E, },
573 { 0x056F, 0x053F, },
574 { 0x0570, 0x0540, },
575 { 0x0571, 0x0541, },
576 { 0x0572, 0x0542, },
577 { 0x0573, 0x0543, },
578 { 0x0574, 0x0544, },
579 { 0x0575, 0x0545, },
580 { 0x0576, 0x0546, },
581 { 0x0577, 0x0547, },
582 { 0x0578, 0x0548, },
583 { 0x0579, 0x0549, },
584 { 0x057A, 0x054A, },
585 { 0x057B, 0x054B, },
586 { 0x057C, 0x054C, },
587 { 0x057D, 0x054D, },
588 { 0x057E, 0x054E, },
589 { 0x057F, 0x054F, },
590 { 0x0580, 0x0550, },
591 { 0x0581, 0x0551, },
592 { 0x0582, 0x0552, },
593 { 0x0583, 0x0553, },
594 { 0x0584, 0x0554, },
595 { 0x0585, 0x0555, },
596 { 0x0586, 0x0556, },
597 { 0x13F8, 0x13F0, },
598 { 0x13F9, 0x13F1, },
599 { 0x13FA, 0x13F2, },
600 { 0x13FB, 0x13F3, },
601 { 0x13FC, 0x13F4, },
602 { 0x13FD, 0x13F5, },
603 { 0x1C80, 0x0412, },
604 { 0x1C81, 0x0414, },
605 { 0x1C82, 0x041E, },
606 { 0x1C83, 0x0421, },
607 { 0x1C84, 0x0422, },
608 { 0x1C85, 0x0422, },
609 { 0x1C86, 0x042A, },
610 { 0x1C87, 0x0462, },
611 { 0x1C88, 0xA64A, },
612 { 0x1D79, 0xA77D, },
613 { 0x1D7D, 0x2C63, },
614 { 0x1E01, 0x1E00, },
615 { 0x1E03, 0x1E02, },
616 { 0x1E05, 0x1E04, },
617 { 0x1E07, 0x1E06, },
618 { 0x1E09, 0x1E08, },
619 { 0x1E0B, 0x1E0A, },
620 { 0x1E0D, 0x1E0C, },
621 { 0x1E0F, 0x1E0E, },
622 { 0x1E11, 0x1E10, },
623 { 0x1E13, 0x1E12, },
624 { 0x1E15, 0x1E14, },
625 { 0x1E17, 0x1E16, },
626 { 0x1E19, 0x1E18, },
627 { 0x1E1B, 0x1E1A, },
628 { 0x1E1D, 0x1E1C, },
629 { 0x1E1F, 0x1E1E, },
630 { 0x1E21, 0x1E20, },
631 { 0x1E23, 0x1E22, },
632 { 0x1E25, 0x1E24, },
633 { 0x1E27, 0x1E26, },
634 { 0x1E29, 0x1E28, },
635 { 0x1E2B, 0x1E2A, },
636 { 0x1E2D, 0x1E2C, },
637 { 0x1E2F, 0x1E2E, },
638 { 0x1E31, 0x1E30, },
639 { 0x1E33, 0x1E32, },
640 { 0x1E35, 0x1E34, },
641 { 0x1E37, 0x1E36, },
642 { 0x1E39, 0x1E38, },
643 { 0x1E3B, 0x1E3A, },
644 { 0x1E3D, 0x1E3C, },
645 { 0x1E3F, 0x1E3E, },
646 { 0x1E41, 0x1E40, },
647 { 0x1E43, 0x1E42, },
648 { 0x1E45, 0x1E44, },
649 { 0x1E47, 0x1E46, },
650 { 0x1E49, 0x1E48, },
651 { 0x1E4B, 0x1E4A, },
652 { 0x1E4D, 0x1E4C, },
653 { 0x1E4F, 0x1E4E, },
654 { 0x1E51, 0x1E50, },
655 { 0x1E53, 0x1E52, },
656 { 0x1E55, 0x1E54, },
657 { 0x1E57, 0x1E56, },
658 { 0x1E59, 0x1E58, },
659 { 0x1E5B, 0x1E5A, },
660 { 0x1E5D, 0x1E5C, },
661 { 0x1E5F, 0x1E5E, },
662 { 0x1E61, 0x1E60, },
663 { 0x1E63, 0x1E62, },
664 { 0x1E65, 0x1E64, },
665 { 0x1E67, 0x1E66, },
666 { 0x1E69, 0x1E68, },
667 { 0x1E6B, 0x1E6A, },
668 { 0x1E6D, 0x1E6C, },
669 { 0x1E6F, 0x1E6E, },
670 { 0x1E71, 0x1E70, },
671 { 0x1E73, 0x1E72, },
672 { 0x1E75, 0x1E74, },
673 { 0x1E77, 0x1E76, },
674 { 0x1E79, 0x1E78, },
675 { 0x1E7B, 0x1E7A, },
676 { 0x1E7D, 0x1E7C, },
677 { 0x1E7F, 0x1E7E, },
678 { 0x1E81, 0x1E80, },
679 { 0x1E83, 0x1E82, },
680 { 0x1E85, 0x1E84, },
681 { 0x1E87, 0x1E86, },
682 { 0x1E89, 0x1E88, },
683 { 0x1E8B, 0x1E8A, },
684 { 0x1E8D, 0x1E8C, },
685 { 0x1E8F, 0x1E8E, },
686 { 0x1E91, 0x1E90, },
687 { 0x1E93, 0x1E92, },
688 { 0x1E95, 0x1E94, },
689 { 0x1E9B, 0x1E60, },
690 { 0x1EA1, 0x1EA0, },
691 { 0x1EA3, 0x1EA2, },
692 { 0x1EA5, 0x1EA4, },
693 { 0x1EA7, 0x1EA6, },
694 { 0x1EA9, 0x1EA8, },
695 { 0x1EAB, 0x1EAA, },
696 { 0x1EAD, 0x1EAC, },
697 { 0x1EAF, 0x1EAE, },
698 { 0x1EB1, 0x1EB0, },
699 { 0x1EB3, 0x1EB2, },
700 { 0x1EB5, 0x1EB4, },
701 { 0x1EB7, 0x1EB6, },
702 { 0x1EB9, 0x1EB8, },
703 { 0x1EBB, 0x1EBA, },
704 { 0x1EBD, 0x1EBC, },
705 { 0x1EBF, 0x1EBE, },
706 { 0x1EC1, 0x1EC0, },
707 { 0x1EC3, 0x1EC2, },
708 { 0x1EC5, 0x1EC4, },
709 { 0x1EC7, 0x1EC6, },
710 { 0x1EC9, 0x1EC8, },
711 { 0x1ECB, 0x1ECA, },
712 { 0x1ECD, 0x1ECC, },
713 { 0x1ECF, 0x1ECE, },
714 { 0x1ED1, 0x1ED0, },
715 { 0x1ED3, 0x1ED2, },
716 { 0x1ED5, 0x1ED4, },
717 { 0x1ED7, 0x1ED6, },
718 { 0x1ED9, 0x1ED8, },
719 { 0x1EDB, 0x1EDA, },
720 { 0x1EDD, 0x1EDC, },
721 { 0x1EDF, 0x1EDE, },
722 { 0x1EE1, 0x1EE0, },
723 { 0x1EE3, 0x1EE2, },
724 { 0x1EE5, 0x1EE4, },
725 { 0x1EE7, 0x1EE6, },
726 { 0x1EE9, 0x1EE8, },
727 { 0x1EEB, 0x1EEA, },
728 { 0x1EED, 0x1EEC, },
729 { 0x1EEF, 0x1EEE, },
730 { 0x1EF1, 0x1EF0, },
731 { 0x1EF3, 0x1EF2, },
732 { 0x1EF5, 0x1EF4, },
733 { 0x1EF7, 0x1EF6, },
734 { 0x1EF9, 0x1EF8, },
735 { 0x1EFB, 0x1EFA, },
736 { 0x1EFD, 0x1EFC, },
737 { 0x1EFF, 0x1EFE, },
738 { 0x1F00, 0x1F08, },
739 { 0x1F01, 0x1F09, },
740 { 0x1F02, 0x1F0A, },
741 { 0x1F03, 0x1F0B, },
742 { 0x1F04, 0x1F0C, },
743 { 0x1F05, 0x1F0D, },
744 { 0x1F06, 0x1F0E, },
745 { 0x1F07, 0x1F0F, },
746 { 0x1F10, 0x1F18, },
747 { 0x1F11, 0x1F19, },
748 { 0x1F12, 0x1F1A, },
749 { 0x1F13, 0x1F1B, },
750 { 0x1F14, 0x1F1C, },
751 { 0x1F15, 0x1F1D, },
752 { 0x1F20, 0x1F28, },
753 { 0x1F21, 0x1F29, },
754 { 0x1F22, 0x1F2A, },
755 { 0x1F23, 0x1F2B, },
756 { 0x1F24, 0x1F2C, },
757 { 0x1F25, 0x1F2D, },
758 { 0x1F26, 0x1F2E, },
759 { 0x1F27, 0x1F2F, },
760 { 0x1F30, 0x1F38, },
761 { 0x1F31, 0x1F39, },
762 { 0x1F32, 0x1F3A, },
763 { 0x1F33, 0x1F3B, },
764 { 0x1F34, 0x1F3C, },
765 { 0x1F35, 0x1F3D, },
766 { 0x1F36, 0x1F3E, },
767 { 0x1F37, 0x1F3F, },
768 { 0x1F40, 0x1F48, },
769 { 0x1F41, 0x1F49, },
770 { 0x1F42, 0x1F4A, },
771 { 0x1F43, 0x1F4B, },
772 { 0x1F44, 0x1F4C, },
773 { 0x1F45, 0x1F4D, },
774 { 0x1F51, 0x1F59, },
775 { 0x1F53, 0x1F5B, },
776 { 0x1F55, 0x1F5D, },
777 { 0x1F57, 0x1F5F, },
778 { 0x1F60, 0x1F68, },
779 { 0x1F61, 0x1F69, },
780 { 0x1F62, 0x1F6A, },
781 { 0x1F63, 0x1F6B, },
782 { 0x1F64, 0x1F6C, },
783 { 0x1F65, 0x1F6D, },
784 { 0x1F66, 0x1F6E, },
785 { 0x1F67, 0x1F6F, },
786 { 0x1F70, 0x1FBA, },
787 { 0x1F71, 0x1FBB, },
788 { 0x1F72, 0x1FC8, },
789 { 0x1F73, 0x1FC9, },
790 { 0x1F74, 0x1FCA, },
791 { 0x1F75, 0x1FCB, },
792 { 0x1F76, 0x1FDA, },
793 { 0x1F77, 0x1FDB, },
794 { 0x1F78, 0x1FF8, },
795 { 0x1F79, 0x1FF9, },
796 { 0x1F7A, 0x1FEA, },
797 { 0x1F7B, 0x1FEB, },
798 { 0x1F7C, 0x1FFA, },
799 { 0x1F7D, 0x1FFB, },
800 { 0x1F80, 0x1F88, },
801 { 0x1F81, 0x1F89, },
802 { 0x1F82, 0x1F8A, },
803 { 0x1F83, 0x1F8B, },
804 { 0x1F84, 0x1F8C, },
805 { 0x1F85, 0x1F8D, },
806 { 0x1F86, 0x1F8E, },
807 { 0x1F87, 0x1F8F, },
808 { 0x1F90, 0x1F98, },
809 { 0x1F91, 0x1F99, },
810 { 0x1F92, 0x1F9A, },
811 { 0x1F93, 0x1F9B, },
812 { 0x1F94, 0x1F9C, },
813 { 0x1F95, 0x1F9D, },
814 { 0x1F96, 0x1F9E, },
815 { 0x1F97, 0x1F9F, },
816 { 0x1FA0, 0x1FA8, },
817 { 0x1FA1, 0x1FA9, },
818 { 0x1FA2, 0x1FAA, },
819 { 0x1FA3, 0x1FAB, },
820 { 0x1FA4, 0x1FAC, },
821 { 0x1FA5, 0x1FAD, },
822 { 0x1FA6, 0x1FAE, },
823 { 0x1FA7, 0x1FAF, },
824 { 0x1FB0, 0x1FB8, },
825 { 0x1FB1, 0x1FB9, },
826 { 0x1FB3, 0x1FBC, },
827 { 0x1FBE, 0x0399, },
828 { 0x1FC3, 0x1FCC, },
829 { 0x1FD0, 0x1FD8, },
830 { 0x1FD1, 0x1FD9, },
831 { 0x1FE0, 0x1FE8, },
832 { 0x1FE1, 0x1FE9, },
833 { 0x1FE5, 0x1FEC, },
834 { 0x1FF3, 0x1FFC, },
835 { 0x214E, 0x2132, },
836 { 0x2170, 0x2160, },
837 { 0x2171, 0x2161, },
838 { 0x2172, 0x2162, },
839 { 0x2173, 0x2163, },
840 { 0x2174, 0x2164, },
841 { 0x2175, 0x2165, },
842 { 0x2176, 0x2166, },
843 { 0x2177, 0x2167, },
844 { 0x2178, 0x2168, },
845 { 0x2179, 0x2169, },
846 { 0x217A, 0x216A, },
847 { 0x217B, 0x216B, },
848 { 0x217C, 0x216C, },
849 { 0x217D, 0x216D, },
850 { 0x217E, 0x216E, },
851 { 0x217F, 0x216F, },
852 { 0x2184, 0x2183, },
853 { 0x24D0, 0x24B6, },
854 { 0x24D1, 0x24B7, },
855 { 0x24D2, 0x24B8, },
856 { 0x24D3, 0x24B9, },
857 { 0x24D4, 0x24BA, },
858 { 0x24D5, 0x24BB, },
859 { 0x24D6, 0x24BC, },
860 { 0x24D7, 0x24BD, },
861 { 0x24D8, 0x24BE, },
862 { 0x24D9, 0x24BF, },
863 { 0x24DA, 0x24C0, },
864 { 0x24DB, 0x24C1, },
865 { 0x24DC, 0x24C2, },
866 { 0x24DD, 0x24C3, },
867 { 0x24DE, 0x24C4, },
868 { 0x24DF, 0x24C5, },
869 { 0x24E0, 0x24C6, },
870 { 0x24E1, 0x24C7, },
871 { 0x24E2, 0x24C8, },
872 { 0x24E3, 0x24C9, },
873 { 0x24E4, 0x24CA, },
874 { 0x24E5, 0x24CB, },
875 { 0x24E6, 0x24CC, },
876 { 0x24E7, 0x24CD, },
877 { 0x24E8, 0x24CE, },
878 { 0x24E9, 0x24CF, },
879 { 0x2C30, 0x2C00, },
880 { 0x2C31, 0x2C01, },
881 { 0x2C32, 0x2C02, },
882 { 0x2C33, 0x2C03, },
883 { 0x2C34, 0x2C04, },
884 { 0x2C35, 0x2C05, },
885 { 0x2C36, 0x2C06, },
886 { 0x2C37, 0x2C07, },
887 { 0x2C38, 0x2C08, },
888 { 0x2C39, 0x2C09, },
889 { 0x2C3A, 0x2C0A, },
890 { 0x2C3B, 0x2C0B, },
891 { 0x2C3C, 0x2C0C, },
892 { 0x2C3D, 0x2C0D, },
893 { 0x2C3E, 0x2C0E, },
894 { 0x2C3F, 0x2C0F, },
895 { 0x2C40, 0x2C10, },
896 { 0x2C41, 0x2C11, },
897 { 0x2C42, 0x2C12, },
898 { 0x2C43, 0x2C13, },
899 { 0x2C44, 0x2C14, },
900 { 0x2C45, 0x2C15, },
901 { 0x2C46, 0x2C16, },
902 { 0x2C47, 0x2C17, },
903 { 0x2C48, 0x2C18, },
904 { 0x2C49, 0x2C19, },
905 { 0x2C4A, 0x2C1A, },
906 { 0x2C4B, 0x2C1B, },
907 { 0x2C4C, 0x2C1C, },
908 { 0x2C4D, 0x2C1D, },
909 { 0x2C4E, 0x2C1E, },
910 { 0x2C4F, 0x2C1F, },
911 { 0x2C50, 0x2C20, },
912 { 0x2C51, 0x2C21, },
913 { 0x2C52, 0x2C22, },
914 { 0x2C53, 0x2C23, },
915 { 0x2C54, 0x2C24, },
916 { 0x2C55, 0x2C25, },
917 { 0x2C56, 0x2C26, },
918 { 0x2C57, 0x2C27, },
919 { 0x2C58, 0x2C28, },
920 { 0x2C59, 0x2C29, },
921 { 0x2C5A, 0x2C2A, },
922 { 0x2C5B, 0x2C2B, },
923 { 0x2C5C, 0x2C2C, },
924 { 0x2C5D, 0x2C2D, },
925 { 0x2C5E, 0x2C2E, },
926 { 0x2C61, 0x2C60, },
927 { 0x2C65, 0x023A, },
928 { 0x2C66, 0x023E, },
929 { 0x2C68, 0x2C67, },
930 { 0x2C6A, 0x2C69, },
931 { 0x2C6C, 0x2C6B, },
932 { 0x2C73, 0x2C72, },
933 { 0x2C76, 0x2C75, },
934 { 0x2C81, 0x2C80, },
935 { 0x2C83, 0x2C82, },
936 { 0x2C85, 0x2C84, },
937 { 0x2C87, 0x2C86, },
938 { 0x2C89, 0x2C88, },
939 { 0x2C8B, 0x2C8A, },
940 { 0x2C8D, 0x2C8C, },
941 { 0x2C8F, 0x2C8E, },
942 { 0x2C91, 0x2C90, },
943 { 0x2C93, 0x2C92, },
944 { 0x2C95, 0x2C94, },
945 { 0x2C97, 0x2C96, },
946 { 0x2C99, 0x2C98, },
947 { 0x2C9B, 0x2C9A, },
948 { 0x2C9D, 0x2C9C, },
949 { 0x2C9F, 0x2C9E, },
950 { 0x2CA1, 0x2CA0, },
951 { 0x2CA3, 0x2CA2, },
952 { 0x2CA5, 0x2CA4, },
953 { 0x2CA7, 0x2CA6, },
954 { 0x2CA9, 0x2CA8, },
955 { 0x2CAB, 0x2CAA, },
956 { 0x2CAD, 0x2CAC, },
957 { 0x2CAF, 0x2CAE, },
958 { 0x2CB1, 0x2CB0, },
959 { 0x2CB3, 0x2CB2, },
960 { 0x2CB5, 0x2CB4, },
961 { 0x2CB7, 0x2CB6, },
962 { 0x2CB9, 0x2CB8, },
963 { 0x2CBB, 0x2CBA, },
964 { 0x2CBD, 0x2CBC, },
965 { 0x2CBF, 0x2CBE, },
966 { 0x2CC1, 0x2CC0, },
967 { 0x2CC3, 0x2CC2, },
968 { 0x2CC5, 0x2CC4, },
969 { 0x2CC7, 0x2CC6, },
970 { 0x2CC9, 0x2CC8, },
971 { 0x2CCB, 0x2CCA, },
972 { 0x2CCD, 0x2CCC, },
973 { 0x2CCF, 0x2CCE, },
974 { 0x2CD1, 0x2CD0, },
975 { 0x2CD3, 0x2CD2, },
976 { 0x2CD5, 0x2CD4, },
977 { 0x2CD7, 0x2CD6, },
978 { 0x2CD9, 0x2CD8, },
979 { 0x2CDB, 0x2CDA, },
980 { 0x2CDD, 0x2CDC, },
981 { 0x2CDF, 0x2CDE, },
982 { 0x2CE1, 0x2CE0, },
983 { 0x2CE3, 0x2CE2, },
984 { 0x2CEC, 0x2CEB, },
985 { 0x2CEE, 0x2CED, },
986 { 0x2CF3, 0x2CF2, },
987 { 0x2D00, 0x10A0, },
988 { 0x2D01, 0x10A1, },
989 { 0x2D02, 0x10A2, },
990 { 0x2D03, 0x10A3, },
991 { 0x2D04, 0x10A4, },
992 { 0x2D05, 0x10A5, },
993 { 0x2D06, 0x10A6, },
994 { 0x2D07, 0x10A7, },
995 { 0x2D08, 0x10A8, },
996 { 0x2D09, 0x10A9, },
997 { 0x2D0A, 0x10AA, },
998 { 0x2D0B, 0x10AB, },
999 { 0x2D0C, 0x10AC, },
1000 { 0x2D0D, 0x10AD, },
1001 { 0x2D0E, 0x10AE, },
1002 { 0x2D0F, 0x10AF, },
1003 { 0x2D10, 0x10B0, },
1004 { 0x2D11, 0x10B1, },
1005 { 0x2D12, 0x10B2, },
1006 { 0x2D13, 0x10B3, },
1007 { 0x2D14, 0x10B4, },
1008 { 0x2D15, 0x10B5, },
1009 { 0x2D16, 0x10B6, },
1010 { 0x2D17, 0x10B7, },
1011 { 0x2D18, 0x10B8, },
1012 { 0x2D19, 0x10B9, },
1013 { 0x2D1A, 0x10BA, },
1014 { 0x2D1B, 0x10BB, },
1015 { 0x2D1C, 0x10BC, },
1016 { 0x2D1D, 0x10BD, },
1017 { 0x2D1E, 0x10BE, },
1018 { 0x2D1F, 0x10BF, },
1019 { 0x2D20, 0x10C0, },
1020 { 0x2D21, 0x10C1, },
1021 { 0x2D22, 0x10C2, },
1022 { 0x2D23, 0x10C3, },
1023 { 0x2D24, 0x10C4, },
1024 { 0x2D25, 0x10C5, },
1025 { 0x2D27, 0x10C7, },
1026 { 0x2D2D, 0x10CD, },
1027 { 0xA641, 0xA640, },
1028 { 0xA643, 0xA642, },
1029 { 0xA645, 0xA644, },
1030 { 0xA647, 0xA646, },
1031 { 0xA649, 0xA648, },
1032 { 0xA64B, 0xA64A, },
1033 { 0xA64D, 0xA64C, },
1034 { 0xA64F, 0xA64E, },
1035 { 0xA651, 0xA650, },
1036 { 0xA653, 0xA652, },
1037 { 0xA655, 0xA654, },
1038 { 0xA657, 0xA656, },
1039 { 0xA659, 0xA658, },
1040 { 0xA65B, 0xA65A, },
1041 { 0xA65D, 0xA65C, },
1042 { 0xA65F, 0xA65E, },
1043 { 0xA661, 0xA660, },
1044 { 0xA663, 0xA662, },
1045 { 0xA665, 0xA664, },
1046 { 0xA667, 0xA666, },
1047 { 0xA669, 0xA668, },
1048 { 0xA66B, 0xA66A, },
1049 { 0xA66D, 0xA66C, },
1050 { 0xA681, 0xA680, },
1051 { 0xA683, 0xA682, },
1052 { 0xA685, 0xA684, },
1053 { 0xA687, 0xA686, },
1054 { 0xA689, 0xA688, },
1055 { 0xA68B, 0xA68A, },
1056 { 0xA68D, 0xA68C, },
1057 { 0xA68F, 0xA68E, },
1058 { 0xA691, 0xA690, },
1059 { 0xA693, 0xA692, },
1060 { 0xA695, 0xA694, },
1061 { 0xA697, 0xA696, },
1062 { 0xA699, 0xA698, },
1063 { 0xA69B, 0xA69A, },
1064 { 0xA723, 0xA722, },
1065 { 0xA725, 0xA724, },
1066 { 0xA727, 0xA726, },
1067 { 0xA729, 0xA728, },
1068 { 0xA72B, 0xA72A, },
1069 { 0xA72D, 0xA72C, },
1070 { 0xA72F, 0xA72E, },
1071 { 0xA733, 0xA732, },
1072 { 0xA735, 0xA734, },
1073 { 0xA737, 0xA736, },
1074 { 0xA739, 0xA738, },
1075 { 0xA73B, 0xA73A, },
1076 { 0xA73D, 0xA73C, },
1077 { 0xA73F, 0xA73E, },
1078 { 0xA741, 0xA740, },
1079 { 0xA743, 0xA742, },
1080 { 0xA745, 0xA744, },
1081 { 0xA747, 0xA746, },
1082 { 0xA749, 0xA748, },
1083 { 0xA74B, 0xA74A, },
1084 { 0xA74D, 0xA74C, },
1085 { 0xA74F, 0xA74E, },
1086 { 0xA751, 0xA750, },
1087 { 0xA753, 0xA752, },
1088 { 0xA755, 0xA754, },
1089 { 0xA757, 0xA756, },
1090 { 0xA759, 0xA758, },
1091 { 0xA75B, 0xA75A, },
1092 { 0xA75D, 0xA75C, },
1093 { 0xA75F, 0xA75E, },
1094 { 0xA761, 0xA760, },
1095 { 0xA763, 0xA762, },
1096 { 0xA765, 0xA764, },
1097 { 0xA767, 0xA766, },
1098 { 0xA769, 0xA768, },
1099 { 0xA76B, 0xA76A, },
1100 { 0xA76D, 0xA76C, },
1101 { 0xA76F, 0xA76E, },
1102 { 0xA77A, 0xA779, },
1103 { 0xA77C, 0xA77B, },
1104 { 0xA77F, 0xA77E, },
1105 { 0xA781, 0xA780, },
1106 { 0xA783, 0xA782, },
1107 { 0xA785, 0xA784, },
1108 { 0xA787, 0xA786, },
1109 { 0xA78C, 0xA78B, },
1110 { 0xA791, 0xA790, },
1111 { 0xA793, 0xA792, },
1112 { 0xA797, 0xA796, },
1113 { 0xA799, 0xA798, },
1114 { 0xA79B, 0xA79A, },
1115 { 0xA79D, 0xA79C, },
1116 { 0xA79F, 0xA79E, },
1117 { 0xA7A1, 0xA7A0, },
1118 { 0xA7A3, 0xA7A2, },
1119 { 0xA7A5, 0xA7A4, },
1120 { 0xA7A7, 0xA7A6, },
1121 { 0xA7A9, 0xA7A8, },
1122 { 0xA7B5, 0xA7B4, },
1123 { 0xA7B7, 0xA7B6, },
1124 { 0xAB53, 0xA7B3, },
1125 { 0xAB70, 0x13A0, },
1126 { 0xAB71, 0x13A1, },
1127 { 0xAB72, 0x13A2, },
1128 { 0xAB73, 0x13A3, },
1129 { 0xAB74, 0x13A4, },
1130 { 0xAB75, 0x13A5, },
1131 { 0xAB76, 0x13A6, },
1132 { 0xAB77, 0x13A7, },
1133 { 0xAB78, 0x13A8, },
1134 { 0xAB79, 0x13A9, },
1135 { 0xAB7A, 0x13AA, },
1136 { 0xAB7B, 0x13AB, },
1137 { 0xAB7C, 0x13AC, },
1138 { 0xAB7D, 0x13AD, },
1139 { 0xAB7E, 0x13AE, },
1140 { 0xAB7F, 0x13AF, },
1141 { 0xAB80, 0x13B0, },
1142 { 0xAB81, 0x13B1, },
1143 { 0xAB82, 0x13B2, },
1144 { 0xAB83, 0x13B3, },
1145 { 0xAB84, 0x13B4, },
1146 { 0xAB85, 0x13B5, },
1147 { 0xAB86, 0x13B6, },
1148 { 0xAB87, 0x13B7, },
1149 { 0xAB88, 0x13B8, },
1150 { 0xAB89, 0x13B9, },
1151 { 0xAB8A, 0x13BA, },
1152 { 0xAB8B, 0x13BB, },
1153 { 0xAB8C, 0x13BC, },
1154 { 0xAB8D, 0x13BD, },
1155 { 0xAB8E, 0x13BE, },
1156 { 0xAB8F, 0x13BF, },
1157 { 0xAB90, 0x13C0, },
1158 { 0xAB91, 0x13C1, },
1159 { 0xAB92, 0x13C2, },
1160 { 0xAB93, 0x13C3, },
1161 { 0xAB94, 0x13C4, },
1162 { 0xAB95, 0x13C5, },
1163 { 0xAB96, 0x13C6, },
1164 { 0xAB97, 0x13C7, },
1165 { 0xAB98, 0x13C8, },
1166 { 0xAB99, 0x13C9, },
1167 { 0xAB9A, 0x13CA, },
1168 { 0xAB9B, 0x13CB, },
1169 { 0xAB9C, 0x13CC, },
1170 { 0xAB9D, 0x13CD, },
1171 { 0xAB9E, 0x13CE, },
1172 { 0xAB9F, 0x13CF, },
1173 { 0xABA0, 0x13D0, },
1174 { 0xABA1, 0x13D1, },
1175 { 0xABA2, 0x13D2, },
1176 { 0xABA3, 0x13D3, },
1177 { 0xABA4, 0x13D4, },
1178 { 0xABA5, 0x13D5, },
1179 { 0xABA6, 0x13D6, },
1180 { 0xABA7, 0x13D7, },
1181 { 0xABA8, 0x13D8, },
1182 { 0xABA9, 0x13D9, },
1183 { 0xABAA, 0x13DA, },
1184 { 0xABAB, 0x13DB, },
1185 { 0xABAC, 0x13DC, },
1186 { 0xABAD, 0x13DD, },
1187 { 0xABAE, 0x13DE, },
1188 { 0xABAF, 0x13DF, },
1189 { 0xABB0, 0x13E0, },
1190 { 0xABB1, 0x13E1, },
1191 { 0xABB2, 0x13E2, },
1192 { 0xABB3, 0x13E3, },
1193 { 0xABB4, 0x13E4, },
1194 { 0xABB5, 0x13E5, },
1195 { 0xABB6, 0x13E6, },
1196 { 0xABB7, 0x13E7, },
1197 { 0xABB8, 0x13E8, },
1198 { 0xABB9, 0x13E9, },
1199 { 0xABBA, 0x13EA, },
1200 { 0xABBB, 0x13EB, },
1201 { 0xABBC, 0x13EC, },
1202 { 0xABBD, 0x13ED, },
1203 { 0xABBE, 0x13EE, },
1204 { 0xABBF, 0x13EF, },
1205 { 0xFF41, 0xFF21, },
1206 { 0xFF42, 0xFF22, },
1207 { 0xFF43, 0xFF23, },
1208 { 0xFF44, 0xFF24, },
1209 { 0xFF45, 0xFF25, },
1210 { 0xFF46, 0xFF26, },
1211 { 0xFF47, 0xFF27, },
1212 { 0xFF48, 0xFF28, },
1213 { 0xFF49, 0xFF29, },
1214 { 0xFF4A, 0xFF2A, },
1215 { 0xFF4B, 0xFF2B, },
1216 { 0xFF4C, 0xFF2C, },
1217 { 0xFF4D, 0xFF2D, },
1218 { 0xFF4E, 0xFF2E, },
1219 { 0xFF4F, 0xFF2F, },
1220 { 0xFF50, 0xFF30, },
1221 { 0xFF51, 0xFF31, },
1222 { 0xFF52, 0xFF32, },
1223 { 0xFF53, 0xFF33, },
1224 { 0xFF54, 0xFF34, },
1225 { 0xFF55, 0xFF35, },
1226 { 0xFF56, 0xFF36, },
1227 { 0xFF57, 0xFF37, },
1228 { 0xFF58, 0xFF38, },
1229 { 0xFF59, 0xFF39, },
1230 { 0xFF5A, 0xFF3A, },
1231 { 0x10428, 0x10400, },
1232 { 0x10429, 0x10401, },
1233 { 0x1042A, 0x10402, },
1234 { 0x1042B, 0x10403, },
1235 { 0x1042C, 0x10404, },
1236 { 0x1042D, 0x10405, },
1237 { 0x1042E, 0x10406, },
1238 { 0x1042F, 0x10407, },
1239 { 0x10430, 0x10408, },
1240 { 0x10431, 0x10409, },
1241 { 0x10432, 0x1040A, },
1242 { 0x10433, 0x1040B, },
1243 { 0x10434, 0x1040C, },
1244 { 0x10435, 0x1040D, },
1245 { 0x10436, 0x1040E, },
1246 { 0x10437, 0x1040F, },
1247 { 0x10438, 0x10410, },
1248 { 0x10439, 0x10411, },
1249 { 0x1043A, 0x10412, },
1250 { 0x1043B, 0x10413, },
1251 { 0x1043C, 0x10414, },
1252 { 0x1043D, 0x10415, },
1253 { 0x1043E, 0x10416, },
1254 { 0x1043F, 0x10417, },
1255 { 0x10440, 0x10418, },
1256 { 0x10441, 0x10419, },
1257 { 0x10442, 0x1041A, },
1258 { 0x10443, 0x1041B, },
1259 { 0x10444, 0x1041C, },
1260 { 0x10445, 0x1041D, },
1261 { 0x10446, 0x1041E, },
1262 { 0x10447, 0x1041F, },
1263 { 0x10448, 0x10420, },
1264 { 0x10449, 0x10421, },
1265 { 0x1044A, 0x10422, },
1266 { 0x1044B, 0x10423, },
1267 { 0x1044C, 0x10424, },
1268 { 0x1044D, 0x10425, },
1269 { 0x1044E, 0x10426, },
1270 { 0x1044F, 0x10427, },
1271 { 0x104D8, 0x104B0, },
1272 { 0x104D9, 0x104B1, },
1273 { 0x104DA, 0x104B2, },
1274 { 0x104DB, 0x104B3, },
1275 { 0x104DC, 0x104B4, },
1276 { 0x104DD, 0x104B5, },
1277 { 0x104DE, 0x104B6, },
1278 { 0x104DF, 0x104B7, },
1279 { 0x104E0, 0x104B8, },
1280 { 0x104E1, 0x104B9, },
1281 { 0x104E2, 0x104BA, },
1282 { 0x104E3, 0x104BB, },
1283 { 0x104E4, 0x104BC, },
1284 { 0x104E5, 0x104BD, },
1285 { 0x104E6, 0x104BE, },
1286 { 0x104E7, 0x104BF, },
1287 { 0x104E8, 0x104C0, },
1288 { 0x104E9, 0x104C1, },
1289 { 0x104EA, 0x104C2, },
1290 { 0x104EB, 0x104C3, },
1291 { 0x104EC, 0x104C4, },
1292 { 0x104ED, 0x104C5, },
1293 { 0x104EE, 0x104C6, },
1294 { 0x104EF, 0x104C7, },
1295 { 0x104F0, 0x104C8, },
1296 { 0x104F1, 0x104C9, },
1297 { 0x104F2, 0x104CA, },
1298 { 0x104F3, 0x104CB, },
1299 { 0x104F4, 0x104CC, },
1300 { 0x104F5, 0x104CD, },
1301 { 0x104F6, 0x104CE, },
1302 { 0x104F7, 0x104CF, },
1303 { 0x104F8, 0x104D0, },
1304 { 0x104F9, 0x104D1, },
1305 { 0x104FA, 0x104D2, },
1306 { 0x104FB, 0x104D3, },
1307 { 0x10CC0, 0x10C80, },
1308 { 0x10CC1, 0x10C81, },
1309 { 0x10CC2, 0x10C82, },
1310 { 0x10CC3, 0x10C83, },
1311 { 0x10CC4, 0x10C84, },
1312 { 0x10CC5, 0x10C85, },
1313 { 0x10CC6, 0x10C86, },
1314 { 0x10CC7, 0x10C87, },
1315 { 0x10CC8, 0x10C88, },
1316 { 0x10CC9, 0x10C89, },
1317 { 0x10CCA, 0x10C8A, },
1318 { 0x10CCB, 0x10C8B, },
1319 { 0x10CCC, 0x10C8C, },
1320 { 0x10CCD, 0x10C8D, },
1321 { 0x10CCE, 0x10C8E, },
1322 { 0x10CCF, 0x10C8F, },
1323 { 0x10CD0, 0x10C90, },
1324 { 0x10CD1, 0x10C91, },
1325 { 0x10CD2, 0x10C92, },
1326 { 0x10CD3, 0x10C93, },
1327 { 0x10CD4, 0x10C94, },
1328 { 0x10CD5, 0x10C95, },
1329 { 0x10CD6, 0x10C96, },
1330 { 0x10CD7, 0x10C97, },
1331 { 0x10CD8, 0x10C98, },
1332 { 0x10CD9, 0x10C99, },
1333 { 0x10CDA, 0x10C9A, },
1334 { 0x10CDB, 0x10C9B, },
1335 { 0x10CDC, 0x10C9C, },
1336 { 0x10CDD, 0x10C9D, },
1337 { 0x10CDE, 0x10C9E, },
1338 { 0x10CDF, 0x10C9F, },
1339 { 0x10CE0, 0x10CA0, },
1340 { 0x10CE1, 0x10CA1, },
1341 { 0x10CE2, 0x10CA2, },
1342 { 0x10CE3, 0x10CA3, },
1343 { 0x10CE4, 0x10CA4, },
1344 { 0x10CE5, 0x10CA5, },
1345 { 0x10CE6, 0x10CA6, },
1346 { 0x10CE7, 0x10CA7, },
1347 { 0x10CE8, 0x10CA8, },
1348 { 0x10CE9, 0x10CA9, },
1349 { 0x10CEA, 0x10CAA, },
1350 { 0x10CEB, 0x10CAB, },
1351 { 0x10CEC, 0x10CAC, },
1352 { 0x10CED, 0x10CAD, },
1353 { 0x10CEE, 0x10CAE, },
1354 { 0x10CEF, 0x10CAF, },
1355 { 0x10CF0, 0x10CB0, },
1356 { 0x10CF1, 0x10CB1, },
1357 { 0x10CF2, 0x10CB2, },
1358 { 0x118C0, 0x118A0, },
1359 { 0x118C1, 0x118A1, },
1360 { 0x118C2, 0x118A2, },
1361 { 0x118C3, 0x118A3, },
1362 { 0x118C4, 0x118A4, },
1363 { 0x118C5, 0x118A5, },
1364 { 0x118C6, 0x118A6, },
1365 { 0x118C7, 0x118A7, },
1366 { 0x118C8, 0x118A8, },
1367 { 0x118C9, 0x118A9, },
1368 { 0x118CA, 0x118AA, },
1369 { 0x118CB, 0x118AB, },
1370 { 0x118CC, 0x118AC, },
1371 { 0x118CD, 0x118AD, },
1372 { 0x118CE, 0x118AE, },
1373 { 0x118CF, 0x118AF, },
1374 { 0x118D0, 0x118B0, },
1375 { 0x118D1, 0x118B1, },
1376 { 0x118D2, 0x118B2, },
1377 { 0x118D3, 0x118B3, },
1378 { 0x118D4, 0x118B4, },
1379 { 0x118D5, 0x118B5, },
1380 { 0x118D6, 0x118B6, },
1381 { 0x118D7, 0x118B7, },
1382 { 0x118D8, 0x118B8, },
1383 { 0x118D9, 0x118B9, },
1384 { 0x118DA, 0x118BA, },
1385 { 0x118DB, 0x118BB, },
1386 { 0x118DC, 0x118BC, },
1387 { 0x118DD, 0x118BD, },
1388 { 0x118DE, 0x118BE, },
1389 { 0x118DF, 0x118BF, },
1390 { 0x1E922, 0x1E900, },
1391 { 0x1E923, 0x1E901, },
1392 { 0x1E924, 0x1E902, },
1393 { 0x1E925, 0x1E903, },
1394 { 0x1E926, 0x1E904, },
1395 { 0x1E927, 0x1E905, },
1396 { 0x1E928, 0x1E906, },
1397 { 0x1E929, 0x1E907, },
1398 { 0x1E92A, 0x1E908, },
1399 { 0x1E92B, 0x1E909, },
1400 { 0x1E92C, 0x1E90A, },
1401 { 0x1E92D, 0x1E90B, },
1402 { 0x1E92E, 0x1E90C, },
1403 { 0x1E92F, 0x1E90D, },
1404 { 0x1E930, 0x1E90E, },
1405 { 0x1E931, 0x1E90F, },
1406 { 0x1E932, 0x1E910, },
1407 { 0x1E933, 0x1E911, },
1408 { 0x1E934, 0x1E912, },
1409 { 0x1E935, 0x1E913, },
1410 { 0x1E936, 0x1E914, },
1411 { 0x1E937, 0x1E915, },
1412 { 0x1E938, 0x1E916, },
1413 { 0x1E939, 0x1E917, },
1414 { 0x1E93A, 0x1E918, },
1415 { 0x1E93B, 0x1E919, },
1416 { 0x1E93C, 0x1E91A, },
1417 { 0x1E93D, 0x1E91B, },
1418 { 0x1E93E, 0x1E91C, },
1419 { 0x1E93F, 0x1E91D, },
1420 { 0x1E940, 0x1E91E, },
1421 { 0x1E941, 0x1E91F, },
1422 { 0x1E942, 0x1E920, },
1423 { 0x1E943, 0x1E921, },
1424}, UTF8_toLower[] = { /* code points with non-null lowercase conversion */
1425 { 0x0041, 0x0061, },
1426 { 0x0042, 0x0062, },
1427 { 0x0043, 0x0063, },
1428 { 0x0044, 0x0064, },
1429 { 0x0045, 0x0065, },
1430 { 0x0046, 0x0066, },
1431 { 0x0047, 0x0067, },
1432 { 0x0048, 0x0068, },
1433 { 0x0049, 0x0069, },
1434 { 0x004A, 0x006A, },
1435 { 0x004B, 0x006B, },
1436 { 0x004C, 0x006C, },
1437 { 0x004D, 0x006D, },
1438 { 0x004E, 0x006E, },
1439 { 0x004F, 0x006F, },
1440 { 0x0050, 0x0070, },
1441 { 0x0051, 0x0071, },
1442 { 0x0052, 0x0072, },
1443 { 0x0053, 0x0073, },
1444 { 0x0054, 0x0074, },
1445 { 0x0055, 0x0075, },
1446 { 0x0056, 0x0076, },
1447 { 0x0057, 0x0077, },
1448 { 0x0058, 0x0078, },
1449 { 0x0059, 0x0079, },
1450 { 0x005A, 0x007A, },
1451 { 0x00C0, 0x00E0, },
1452 { 0x00C1, 0x00E1, },
1453 { 0x00C2, 0x00E2, },
1454 { 0x00C3, 0x00E3, },
1455 { 0x00C4, 0x00E4, },
1456 { 0x00C5, 0x00E5, },
1457 { 0x00C6, 0x00E6, },
1458 { 0x00C7, 0x00E7, },
1459 { 0x00C8, 0x00E8, },
1460 { 0x00C9, 0x00E9, },
1461 { 0x00CA, 0x00EA, },
1462 { 0x00CB, 0x00EB, },
1463 { 0x00CC, 0x00EC, },
1464 { 0x00CD, 0x00ED, },
1465 { 0x00CE, 0x00EE, },
1466 { 0x00CF, 0x00EF, },
1467 { 0x00D0, 0x00F0, },
1468 { 0x00D1, 0x00F1, },
1469 { 0x00D2, 0x00F2, },
1470 { 0x00D3, 0x00F3, },
1471 { 0x00D4, 0x00F4, },
1472 { 0x00D5, 0x00F5, },
1473 { 0x00D6, 0x00F6, },
1474 { 0x00D8, 0x00F8, },
1475 { 0x00D9, 0x00F9, },
1476 { 0x00DA, 0x00FA, },
1477 { 0x00DB, 0x00FB, },
1478 { 0x00DC, 0x00FC, },
1479 { 0x00DD, 0x00FD, },
1480 { 0x00DE, 0x00FE, },
1481 { 0x0100, 0x0101, },
1482 { 0x0102, 0x0103, },
1483 { 0x0104, 0x0105, },
1484 { 0x0106, 0x0107, },
1485 { 0x0108, 0x0109, },
1486 { 0x010A, 0x010B, },
1487 { 0x010C, 0x010D, },
1488 { 0x010E, 0x010F, },
1489 { 0x0110, 0x0111, },
1490 { 0x0112, 0x0113, },
1491 { 0x0114, 0x0115, },
1492 { 0x0116, 0x0117, },
1493 { 0x0118, 0x0119, },
1494 { 0x011A, 0x011B, },
1495 { 0x011C, 0x011D, },
1496 { 0x011E, 0x011F, },
1497 { 0x0120, 0x0121, },
1498 { 0x0122, 0x0123, },
1499 { 0x0124, 0x0125, },
1500 { 0x0126, 0x0127, },
1501 { 0x0128, 0x0129, },
1502 { 0x012A, 0x012B, },
1503 { 0x012C, 0x012D, },
1504 { 0x012E, 0x012F, },
1505 { 0x0130, 0x0069, },
1506 { 0x0132, 0x0133, },
1507 { 0x0134, 0x0135, },
1508 { 0x0136, 0x0137, },
1509 { 0x0139, 0x013A, },
1510 { 0x013B, 0x013C, },
1511 { 0x013D, 0x013E, },
1512 { 0x013F, 0x0140, },
1513 { 0x0141, 0x0142, },
1514 { 0x0143, 0x0144, },
1515 { 0x0145, 0x0146, },
1516 { 0x0147, 0x0148, },
1517 { 0x014A, 0x014B, },
1518 { 0x014C, 0x014D, },
1519 { 0x014E, 0x014F, },
1520 { 0x0150, 0x0151, },
1521 { 0x0152, 0x0153, },
1522 { 0x0154, 0x0155, },
1523 { 0x0156, 0x0157, },
1524 { 0x0158, 0x0159, },
1525 { 0x015A, 0x015B, },
1526 { 0x015C, 0x015D, },
1527 { 0x015E, 0x015F, },
1528 { 0x0160, 0x0161, },
1529 { 0x0162, 0x0163, },
1530 { 0x0164, 0x0165, },
1531 { 0x0166, 0x0167, },
1532 { 0x0168, 0x0169, },
1533 { 0x016A, 0x016B, },
1534 { 0x016C, 0x016D, },
1535 { 0x016E, 0x016F, },
1536 { 0x0170, 0x0171, },
1537 { 0x0172, 0x0173, },
1538 { 0x0174, 0x0175, },
1539 { 0x0176, 0x0177, },
1540 { 0x0178, 0x00FF, },
1541 { 0x0179, 0x017A, },
1542 { 0x017B, 0x017C, },
1543 { 0x017D, 0x017E, },
1544 { 0x0181, 0x0253, },
1545 { 0x0182, 0x0183, },
1546 { 0x0184, 0x0185, },
1547 { 0x0186, 0x0254, },
1548 { 0x0187, 0x0188, },
1549 { 0x0189, 0x0256, },
1550 { 0x018A, 0x0257, },
1551 { 0x018B, 0x018C, },
1552 { 0x018E, 0x01DD, },
1553 { 0x018F, 0x0259, },
1554 { 0x0190, 0x025B, },
1555 { 0x0191, 0x0192, },
1556 { 0x0193, 0x0260, },
1557 { 0x0194, 0x0263, },
1558 { 0x0196, 0x0269, },
1559 { 0x0197, 0x0268, },
1560 { 0x0198, 0x0199, },
1561 { 0x019C, 0x026F, },
1562 { 0x019D, 0x0272, },
1563 { 0x019F, 0x0275, },
1564 { 0x01A0, 0x01A1, },
1565 { 0x01A2, 0x01A3, },
1566 { 0x01A4, 0x01A5, },
1567 { 0x01A6, 0x0280, },
1568 { 0x01A7, 0x01A8, },
1569 { 0x01A9, 0x0283, },
1570 { 0x01AC, 0x01AD, },
1571 { 0x01AE, 0x0288, },
1572 { 0x01AF, 0x01B0, },
1573 { 0x01B1, 0x028A, },
1574 { 0x01B2, 0x028B, },
1575 { 0x01B3, 0x01B4, },
1576 { 0x01B5, 0x01B6, },
1577 { 0x01B7, 0x0292, },
1578 { 0x01B8, 0x01B9, },
1579 { 0x01BC, 0x01BD, },
1580 { 0x01C4, 0x01C6, },
1581 { 0x01C5, 0x01C6, },
1582 { 0x01C7, 0x01C9, },
1583 { 0x01C8, 0x01C9, },
1584 { 0x01CA, 0x01CC, },
1585 { 0x01CB, 0x01CC, },
1586 { 0x01CD, 0x01CE, },
1587 { 0x01CF, 0x01D0, },
1588 { 0x01D1, 0x01D2, },
1589 { 0x01D3, 0x01D4, },
1590 { 0x01D5, 0x01D6, },
1591 { 0x01D7, 0x01D8, },
1592 { 0x01D9, 0x01DA, },
1593 { 0x01DB, 0x01DC, },
1594 { 0x01DE, 0x01DF, },
1595 { 0x01E0, 0x01E1, },
1596 { 0x01E2, 0x01E3, },
1597 { 0x01E4, 0x01E5, },
1598 { 0x01E6, 0x01E7, },
1599 { 0x01E8, 0x01E9, },
1600 { 0x01EA, 0x01EB, },
1601 { 0x01EC, 0x01ED, },
1602 { 0x01EE, 0x01EF, },
1603 { 0x01F1, 0x01F3, },
1604 { 0x01F2, 0x01F3, },
1605 { 0x01F4, 0x01F5, },
1606 { 0x01F6, 0x0195, },
1607 { 0x01F7, 0x01BF, },
1608 { 0x01F8, 0x01F9, },
1609 { 0x01FA, 0x01FB, },
1610 { 0x01FC, 0x01FD, },
1611 { 0x01FE, 0x01FF, },
1612 { 0x0200, 0x0201, },
1613 { 0x0202, 0x0203, },
1614 { 0x0204, 0x0205, },
1615 { 0x0206, 0x0207, },
1616 { 0x0208, 0x0209, },
1617 { 0x020A, 0x020B, },
1618 { 0x020C, 0x020D, },
1619 { 0x020E, 0x020F, },
1620 { 0x0210, 0x0211, },
1621 { 0x0212, 0x0213, },
1622 { 0x0214, 0x0215, },
1623 { 0x0216, 0x0217, },
1624 { 0x0218, 0x0219, },
1625 { 0x021A, 0x021B, },
1626 { 0x021C, 0x021D, },
1627 { 0x021E, 0x021F, },
1628 { 0x0220, 0x019E, },
1629 { 0x0222, 0x0223, },
1630 { 0x0224, 0x0225, },
1631 { 0x0226, 0x0227, },
1632 { 0x0228, 0x0229, },
1633 { 0x022A, 0x022B, },
1634 { 0x022C, 0x022D, },
1635 { 0x022E, 0x022F, },
1636 { 0x0230, 0x0231, },
1637 { 0x0232, 0x0233, },
1638 { 0x023A, 0x2C65, },
1639 { 0x023B, 0x023C, },
1640 { 0x023D, 0x019A, },
1641 { 0x023E, 0x2C66, },
1642 { 0x0241, 0x0242, },
1643 { 0x0243, 0x0180, },
1644 { 0x0244, 0x0289, },
1645 { 0x0245, 0x028C, },
1646 { 0x0246, 0x0247, },
1647 { 0x0248, 0x0249, },
1648 { 0x024A, 0x024B, },
1649 { 0x024C, 0x024D, },
1650 { 0x024E, 0x024F, },
1651 { 0x0370, 0x0371, },
1652 { 0x0372, 0x0373, },
1653 { 0x0376, 0x0377, },
1654 { 0x037F, 0x03F3, },
1655 { 0x0386, 0x03AC, },
1656 { 0x0388, 0x03AD, },
1657 { 0x0389, 0x03AE, },
1658 { 0x038A, 0x03AF, },
1659 { 0x038C, 0x03CC, },
1660 { 0x038E, 0x03CD, },
1661 { 0x038F, 0x03CE, },
1662 { 0x0391, 0x03B1, },
1663 { 0x0392, 0x03B2, },
1664 { 0x0393, 0x03B3, },
1665 { 0x0394, 0x03B4, },
1666 { 0x0395, 0x03B5, },
1667 { 0x0396, 0x03B6, },
1668 { 0x0397, 0x03B7, },
1669 { 0x0398, 0x03B8, },
1670 { 0x0399, 0x03B9, },
1671 { 0x039A, 0x03BA, },
1672 { 0x039B, 0x03BB, },
1673 { 0x039C, 0x03BC, },
1674 { 0x039D, 0x03BD, },
1675 { 0x039E, 0x03BE, },
1676 { 0x039F, 0x03BF, },
1677 { 0x03A0, 0x03C0, },
1678 { 0x03A1, 0x03C1, },
1679 { 0x03A3, 0x03C3, },
1680 { 0x03A4, 0x03C4, },
1681 { 0x03A5, 0x03C5, },
1682 { 0x03A6, 0x03C6, },
1683 { 0x03A7, 0x03C7, },
1684 { 0x03A8, 0x03C8, },
1685 { 0x03A9, 0x03C9, },
1686 { 0x03AA, 0x03CA, },
1687 { 0x03AB, 0x03CB, },
1688 { 0x03CF, 0x03D7, },
1689 { 0x03D8, 0x03D9, },
1690 { 0x03DA, 0x03DB, },
1691 { 0x03DC, 0x03DD, },
1692 { 0x03DE, 0x03DF, },
1693 { 0x03E0, 0x03E1, },
1694 { 0x03E2, 0x03E3, },
1695 { 0x03E4, 0x03E5, },
1696 { 0x03E6, 0x03E7, },
1697 { 0x03E8, 0x03E9, },
1698 { 0x03EA, 0x03EB, },
1699 { 0x03EC, 0x03ED, },
1700 { 0x03EE, 0x03EF, },
1701 { 0x03F4, 0x03B8, },
1702 { 0x03F7, 0x03F8, },
1703 { 0x03F9, 0x03F2, },
1704 { 0x03FA, 0x03FB, },
1705 { 0x03FD, 0x037B, },
1706 { 0x03FE, 0x037C, },
1707 { 0x03FF, 0x037D, },
1708 { 0x0400, 0x0450, },
1709 { 0x0401, 0x0451, },
1710 { 0x0402, 0x0452, },
1711 { 0x0403, 0x0453, },
1712 { 0x0404, 0x0454, },
1713 { 0x0405, 0x0455, },
1714 { 0x0406, 0x0456, },
1715 { 0x0407, 0x0457, },
1716 { 0x0408, 0x0458, },
1717 { 0x0409, 0x0459, },
1718 { 0x040A, 0x045A, },
1719 { 0x040B, 0x045B, },
1720 { 0x040C, 0x045C, },
1721 { 0x040D, 0x045D, },
1722 { 0x040E, 0x045E, },
1723 { 0x040F, 0x045F, },
1724 { 0x0410, 0x0430, },
1725 { 0x0411, 0x0431, },
1726 { 0x0412, 0x0432, },
1727 { 0x0413, 0x0433, },
1728 { 0x0414, 0x0434, },
1729 { 0x0415, 0x0435, },
1730 { 0x0416, 0x0436, },
1731 { 0x0417, 0x0437, },
1732 { 0x0418, 0x0438, },
1733 { 0x0419, 0x0439, },
1734 { 0x041A, 0x043A, },
1735 { 0x041B, 0x043B, },
1736 { 0x041C, 0x043C, },
1737 { 0x041D, 0x043D, },
1738 { 0x041E, 0x043E, },
1739 { 0x041F, 0x043F, },
1740 { 0x0420, 0x0440, },
1741 { 0x0421, 0x0441, },
1742 { 0x0422, 0x0442, },
1743 { 0x0423, 0x0443, },
1744 { 0x0424, 0x0444, },
1745 { 0x0425, 0x0445, },
1746 { 0x0426, 0x0446, },
1747 { 0x0427, 0x0447, },
1748 { 0x0428, 0x0448, },
1749 { 0x0429, 0x0449, },
1750 { 0x042A, 0x044A, },
1751 { 0x042B, 0x044B, },
1752 { 0x042C, 0x044C, },
1753 { 0x042D, 0x044D, },
1754 { 0x042E, 0x044E, },
1755 { 0x042F, 0x044F, },
1756 { 0x0460, 0x0461, },
1757 { 0x0462, 0x0463, },
1758 { 0x0464, 0x0465, },
1759 { 0x0466, 0x0467, },
1760 { 0x0468, 0x0469, },
1761 { 0x046A, 0x046B, },
1762 { 0x046C, 0x046D, },
1763 { 0x046E, 0x046F, },
1764 { 0x0470, 0x0471, },
1765 { 0x0472, 0x0473, },
1766 { 0x0474, 0x0475, },
1767 { 0x0476, 0x0477, },
1768 { 0x0478, 0x0479, },
1769 { 0x047A, 0x047B, },
1770 { 0x047C, 0x047D, },
1771 { 0x047E, 0x047F, },
1772 { 0x0480, 0x0481, },
1773 { 0x048A, 0x048B, },
1774 { 0x048C, 0x048D, },
1775 { 0x048E, 0x048F, },
1776 { 0x0490, 0x0491, },
1777 { 0x0492, 0x0493, },
1778 { 0x0494, 0x0495, },
1779 { 0x0496, 0x0497, },
1780 { 0x0498, 0x0499, },
1781 { 0x049A, 0x049B, },
1782 { 0x049C, 0x049D, },
1783 { 0x049E, 0x049F, },
1784 { 0x04A0, 0x04A1, },
1785 { 0x04A2, 0x04A3, },
1786 { 0x04A4, 0x04A5, },
1787 { 0x04A6, 0x04A7, },
1788 { 0x04A8, 0x04A9, },
1789 { 0x04AA, 0x04AB, },
1790 { 0x04AC, 0x04AD, },
1791 { 0x04AE, 0x04AF, },
1792 { 0x04B0, 0x04B1, },
1793 { 0x04B2, 0x04B3, },
1794 { 0x04B4, 0x04B5, },
1795 { 0x04B6, 0x04B7, },
1796 { 0x04B8, 0x04B9, },
1797 { 0x04BA, 0x04BB, },
1798 { 0x04BC, 0x04BD, },
1799 { 0x04BE, 0x04BF, },
1800 { 0x04C0, 0x04CF, },
1801 { 0x04C1, 0x04C2, },
1802 { 0x04C3, 0x04C4, },
1803 { 0x04C5, 0x04C6, },
1804 { 0x04C7, 0x04C8, },
1805 { 0x04C9, 0x04CA, },
1806 { 0x04CB, 0x04CC, },
1807 { 0x04CD, 0x04CE, },
1808 { 0x04D0, 0x04D1, },
1809 { 0x04D2, 0x04D3, },
1810 { 0x04D4, 0x04D5, },
1811 { 0x04D6, 0x04D7, },
1812 { 0x04D8, 0x04D9, },
1813 { 0x04DA, 0x04DB, },
1814 { 0x04DC, 0x04DD, },
1815 { 0x04DE, 0x04DF, },
1816 { 0x04E0, 0x04E1, },
1817 { 0x04E2, 0x04E3, },
1818 { 0x04E4, 0x04E5, },
1819 { 0x04E6, 0x04E7, },
1820 { 0x04E8, 0x04E9, },
1821 { 0x04EA, 0x04EB, },
1822 { 0x04EC, 0x04ED, },
1823 { 0x04EE, 0x04EF, },
1824 { 0x04F0, 0x04F1, },
1825 { 0x04F2, 0x04F3, },
1826 { 0x04F4, 0x04F5, },
1827 { 0x04F6, 0x04F7, },
1828 { 0x04F8, 0x04F9, },
1829 { 0x04FA, 0x04FB, },
1830 { 0x04FC, 0x04FD, },
1831 { 0x04FE, 0x04FF, },
1832 { 0x0500, 0x0501, },
1833 { 0x0502, 0x0503, },
1834 { 0x0504, 0x0505, },
1835 { 0x0506, 0x0507, },
1836 { 0x0508, 0x0509, },
1837 { 0x050A, 0x050B, },
1838 { 0x050C, 0x050D, },
1839 { 0x050E, 0x050F, },
1840 { 0x0510, 0x0511, },
1841 { 0x0512, 0x0513, },
1842 { 0x0514, 0x0515, },
1843 { 0x0516, 0x0517, },
1844 { 0x0518, 0x0519, },
1845 { 0x051A, 0x051B, },
1846 { 0x051C, 0x051D, },
1847 { 0x051E, 0x051F, },
1848 { 0x0520, 0x0521, },
1849 { 0x0522, 0x0523, },
1850 { 0x0524, 0x0525, },
1851 { 0x0526, 0x0527, },
1852 { 0x0528, 0x0529, },
1853 { 0x052A, 0x052B, },
1854 { 0x052C, 0x052D, },
1855 { 0x052E, 0x052F, },
1856 { 0x0531, 0x0561, },
1857 { 0x0532, 0x0562, },
1858 { 0x0533, 0x0563, },
1859 { 0x0534, 0x0564, },
1860 { 0x0535, 0x0565, },
1861 { 0x0536, 0x0566, },
1862 { 0x0537, 0x0567, },
1863 { 0x0538, 0x0568, },
1864 { 0x0539, 0x0569, },
1865 { 0x053A, 0x056A, },
1866 { 0x053B, 0x056B, },
1867 { 0x053C, 0x056C, },
1868 { 0x053D, 0x056D, },
1869 { 0x053E, 0x056E, },
1870 { 0x053F, 0x056F, },
1871 { 0x0540, 0x0570, },
1872 { 0x0541, 0x0571, },
1873 { 0x0542, 0x0572, },
1874 { 0x0543, 0x0573, },
1875 { 0x0544, 0x0574, },
1876 { 0x0545, 0x0575, },
1877 { 0x0546, 0x0576, },
1878 { 0x0547, 0x0577, },
1879 { 0x0548, 0x0578, },
1880 { 0x0549, 0x0579, },
1881 { 0x054A, 0x057A, },
1882 { 0x054B, 0x057B, },
1883 { 0x054C, 0x057C, },
1884 { 0x054D, 0x057D, },
1885 { 0x054E, 0x057E, },
1886 { 0x054F, 0x057F, },
1887 { 0x0550, 0x0580, },
1888 { 0x0551, 0x0581, },
1889 { 0x0552, 0x0582, },
1890 { 0x0553, 0x0583, },
1891 { 0x0554, 0x0584, },
1892 { 0x0555, 0x0585, },
1893 { 0x0556, 0x0586, },
1894 { 0x10A0, 0x2D00, },
1895 { 0x10A1, 0x2D01, },
1896 { 0x10A2, 0x2D02, },
1897 { 0x10A3, 0x2D03, },
1898 { 0x10A4, 0x2D04, },
1899 { 0x10A5, 0x2D05, },
1900 { 0x10A6, 0x2D06, },
1901 { 0x10A7, 0x2D07, },
1902 { 0x10A8, 0x2D08, },
1903 { 0x10A9, 0x2D09, },
1904 { 0x10AA, 0x2D0A, },
1905 { 0x10AB, 0x2D0B, },
1906 { 0x10AC, 0x2D0C, },
1907 { 0x10AD, 0x2D0D, },
1908 { 0x10AE, 0x2D0E, },
1909 { 0x10AF, 0x2D0F, },
1910 { 0x10B0, 0x2D10, },
1911 { 0x10B1, 0x2D11, },
1912 { 0x10B2, 0x2D12, },
1913 { 0x10B3, 0x2D13, },
1914 { 0x10B4, 0x2D14, },
1915 { 0x10B5, 0x2D15, },
1916 { 0x10B6, 0x2D16, },
1917 { 0x10B7, 0x2D17, },
1918 { 0x10B8, 0x2D18, },
1919 { 0x10B9, 0x2D19, },
1920 { 0x10BA, 0x2D1A, },
1921 { 0x10BB, 0x2D1B, },
1922 { 0x10BC, 0x2D1C, },
1923 { 0x10BD, 0x2D1D, },
1924 { 0x10BE, 0x2D1E, },
1925 { 0x10BF, 0x2D1F, },
1926 { 0x10C0, 0x2D20, },
1927 { 0x10C1, 0x2D21, },
1928 { 0x10C2, 0x2D22, },
1929 { 0x10C3, 0x2D23, },
1930 { 0x10C4, 0x2D24, },
1931 { 0x10C5, 0x2D25, },
1932 { 0x10C7, 0x2D27, },
1933 { 0x10CD, 0x2D2D, },
1934 { 0x13A0, 0xAB70, },
1935 { 0x13A1, 0xAB71, },
1936 { 0x13A2, 0xAB72, },
1937 { 0x13A3, 0xAB73, },
1938 { 0x13A4, 0xAB74, },
1939 { 0x13A5, 0xAB75, },
1940 { 0x13A6, 0xAB76, },
1941 { 0x13A7, 0xAB77, },
1942 { 0x13A8, 0xAB78, },
1943 { 0x13A9, 0xAB79, },
1944 { 0x13AA, 0xAB7A, },
1945 { 0x13AB, 0xAB7B, },
1946 { 0x13AC, 0xAB7C, },
1947 { 0x13AD, 0xAB7D, },
1948 { 0x13AE, 0xAB7E, },
1949 { 0x13AF, 0xAB7F, },
1950 { 0x13B0, 0xAB80, },
1951 { 0x13B1, 0xAB81, },
1952 { 0x13B2, 0xAB82, },
1953 { 0x13B3, 0xAB83, },
1954 { 0x13B4, 0xAB84, },
1955 { 0x13B5, 0xAB85, },
1956 { 0x13B6, 0xAB86, },
1957 { 0x13B7, 0xAB87, },
1958 { 0x13B8, 0xAB88, },
1959 { 0x13B9, 0xAB89, },
1960 { 0x13BA, 0xAB8A, },
1961 { 0x13BB, 0xAB8B, },
1962 { 0x13BC, 0xAB8C, },
1963 { 0x13BD, 0xAB8D, },
1964 { 0x13BE, 0xAB8E, },
1965 { 0x13BF, 0xAB8F, },
1966 { 0x13C0, 0xAB90, },
1967 { 0x13C1, 0xAB91, },
1968 { 0x13C2, 0xAB92, },
1969 { 0x13C3, 0xAB93, },
1970 { 0x13C4, 0xAB94, },
1971 { 0x13C5, 0xAB95, },
1972 { 0x13C6, 0xAB96, },
1973 { 0x13C7, 0xAB97, },
1974 { 0x13C8, 0xAB98, },
1975 { 0x13C9, 0xAB99, },
1976 { 0x13CA, 0xAB9A, },
1977 { 0x13CB, 0xAB9B, },
1978 { 0x13CC, 0xAB9C, },
1979 { 0x13CD, 0xAB9D, },
1980 { 0x13CE, 0xAB9E, },
1981 { 0x13CF, 0xAB9F, },
1982 { 0x13D0, 0xABA0, },
1983 { 0x13D1, 0xABA1, },
1984 { 0x13D2, 0xABA2, },
1985 { 0x13D3, 0xABA3, },
1986 { 0x13D4, 0xABA4, },
1987 { 0x13D5, 0xABA5, },
1988 { 0x13D6, 0xABA6, },
1989 { 0x13D7, 0xABA7, },
1990 { 0x13D8, 0xABA8, },
1991 { 0x13D9, 0xABA9, },
1992 { 0x13DA, 0xABAA, },
1993 { 0x13DB, 0xABAB, },
1994 { 0x13DC, 0xABAC, },
1995 { 0x13DD, 0xABAD, },
1996 { 0x13DE, 0xABAE, },
1997 { 0x13DF, 0xABAF, },
1998 { 0x13E0, 0xABB0, },
1999 { 0x13E1, 0xABB1, },
2000 { 0x13E2, 0xABB2, },
2001 { 0x13E3, 0xABB3, },
2002 { 0x13E4, 0xABB4, },
2003 { 0x13E5, 0xABB5, },
2004 { 0x13E6, 0xABB6, },
2005 { 0x13E7, 0xABB7, },
2006 { 0x13E8, 0xABB8, },
2007 { 0x13E9, 0xABB9, },
2008 { 0x13EA, 0xABBA, },
2009 { 0x13EB, 0xABBB, },
2010 { 0x13EC, 0xABBC, },
2011 { 0x13ED, 0xABBD, },
2012 { 0x13EE, 0xABBE, },
2013 { 0x13EF, 0xABBF, },
2014 { 0x13F0, 0x13F8, },
2015 { 0x13F1, 0x13F9, },
2016 { 0x13F2, 0x13FA, },
2017 { 0x13F3, 0x13FB, },
2018 { 0x13F4, 0x13FC, },
2019 { 0x13F5, 0x13FD, },
2020 { 0x1E00, 0x1E01, },
2021 { 0x1E02, 0x1E03, },
2022 { 0x1E04, 0x1E05, },
2023 { 0x1E06, 0x1E07, },
2024 { 0x1E08, 0x1E09, },
2025 { 0x1E0A, 0x1E0B, },
2026 { 0x1E0C, 0x1E0D, },
2027 { 0x1E0E, 0x1E0F, },
2028 { 0x1E10, 0x1E11, },
2029 { 0x1E12, 0x1E13, },
2030 { 0x1E14, 0x1E15, },
2031 { 0x1E16, 0x1E17, },
2032 { 0x1E18, 0x1E19, },
2033 { 0x1E1A, 0x1E1B, },
2034 { 0x1E1C, 0x1E1D, },
2035 { 0x1E1E, 0x1E1F, },
2036 { 0x1E20, 0x1E21, },
2037 { 0x1E22, 0x1E23, },
2038 { 0x1E24, 0x1E25, },
2039 { 0x1E26, 0x1E27, },
2040 { 0x1E28, 0x1E29, },
2041 { 0x1E2A, 0x1E2B, },
2042 { 0x1E2C, 0x1E2D, },
2043 { 0x1E2E, 0x1E2F, },
2044 { 0x1E30, 0x1E31, },
2045 { 0x1E32, 0x1E33, },
2046 { 0x1E34, 0x1E35, },
2047 { 0x1E36, 0x1E37, },
2048 { 0x1E38, 0x1E39, },
2049 { 0x1E3A, 0x1E3B, },
2050 { 0x1E3C, 0x1E3D, },
2051 { 0x1E3E, 0x1E3F, },
2052 { 0x1E40, 0x1E41, },
2053 { 0x1E42, 0x1E43, },
2054 { 0x1E44, 0x1E45, },
2055 { 0x1E46, 0x1E47, },
2056 { 0x1E48, 0x1E49, },
2057 { 0x1E4A, 0x1E4B, },
2058 { 0x1E4C, 0x1E4D, },
2059 { 0x1E4E, 0x1E4F, },
2060 { 0x1E50, 0x1E51, },
2061 { 0x1E52, 0x1E53, },
2062 { 0x1E54, 0x1E55, },
2063 { 0x1E56, 0x1E57, },
2064 { 0x1E58, 0x1E59, },
2065 { 0x1E5A, 0x1E5B, },
2066 { 0x1E5C, 0x1E5D, },
2067 { 0x1E5E, 0x1E5F, },
2068 { 0x1E60, 0x1E61, },
2069 { 0x1E62, 0x1E63, },
2070 { 0x1E64, 0x1E65, },
2071 { 0x1E66, 0x1E67, },
2072 { 0x1E68, 0x1E69, },
2073 { 0x1E6A, 0x1E6B, },
2074 { 0x1E6C, 0x1E6D, },
2075 { 0x1E6E, 0x1E6F, },
2076 { 0x1E70, 0x1E71, },
2077 { 0x1E72, 0x1E73, },
2078 { 0x1E74, 0x1E75, },
2079 { 0x1E76, 0x1E77, },
2080 { 0x1E78, 0x1E79, },
2081 { 0x1E7A, 0x1E7B, },
2082 { 0x1E7C, 0x1E7D, },
2083 { 0x1E7E, 0x1E7F, },
2084 { 0x1E80, 0x1E81, },
2085 { 0x1E82, 0x1E83, },
2086 { 0x1E84, 0x1E85, },
2087 { 0x1E86, 0x1E87, },
2088 { 0x1E88, 0x1E89, },
2089 { 0x1E8A, 0x1E8B, },
2090 { 0x1E8C, 0x1E8D, },
2091 { 0x1E8E, 0x1E8F, },
2092 { 0x1E90, 0x1E91, },
2093 { 0x1E92, 0x1E93, },
2094 { 0x1E94, 0x1E95, },
2095 { 0x1E9E, 0x00DF, },
2096 { 0x1EA0, 0x1EA1, },
2097 { 0x1EA2, 0x1EA3, },
2098 { 0x1EA4, 0x1EA5, },
2099 { 0x1EA6, 0x1EA7, },
2100 { 0x1EA8, 0x1EA9, },
2101 { 0x1EAA, 0x1EAB, },
2102 { 0x1EAC, 0x1EAD, },
2103 { 0x1EAE, 0x1EAF, },
2104 { 0x1EB0, 0x1EB1, },
2105 { 0x1EB2, 0x1EB3, },
2106 { 0x1EB4, 0x1EB5, },
2107 { 0x1EB6, 0x1EB7, },
2108 { 0x1EB8, 0x1EB9, },
2109 { 0x1EBA, 0x1EBB, },
2110 { 0x1EBC, 0x1EBD, },
2111 { 0x1EBE, 0x1EBF, },
2112 { 0x1EC0, 0x1EC1, },
2113 { 0x1EC2, 0x1EC3, },
2114 { 0x1EC4, 0x1EC5, },
2115 { 0x1EC6, 0x1EC7, },
2116 { 0x1EC8, 0x1EC9, },
2117 { 0x1ECA, 0x1ECB, },
2118 { 0x1ECC, 0x1ECD, },
2119 { 0x1ECE, 0x1ECF, },
2120 { 0x1ED0, 0x1ED1, },
2121 { 0x1ED2, 0x1ED3, },
2122 { 0x1ED4, 0x1ED5, },
2123 { 0x1ED6, 0x1ED7, },
2124 { 0x1ED8, 0x1ED9, },
2125 { 0x1EDA, 0x1EDB, },
2126 { 0x1EDC, 0x1EDD, },
2127 { 0x1EDE, 0x1EDF, },
2128 { 0x1EE0, 0x1EE1, },
2129 { 0x1EE2, 0x1EE3, },
2130 { 0x1EE4, 0x1EE5, },
2131 { 0x1EE6, 0x1EE7, },
2132 { 0x1EE8, 0x1EE9, },
2133 { 0x1EEA, 0x1EEB, },
2134 { 0x1EEC, 0x1EED, },
2135 { 0x1EEE, 0x1EEF, },
2136 { 0x1EF0, 0x1EF1, },
2137 { 0x1EF2, 0x1EF3, },
2138 { 0x1EF4, 0x1EF5, },
2139 { 0x1EF6, 0x1EF7, },
2140 { 0x1EF8, 0x1EF9, },
2141 { 0x1EFA, 0x1EFB, },
2142 { 0x1EFC, 0x1EFD, },
2143 { 0x1EFE, 0x1EFF, },
2144 { 0x1F08, 0x1F00, },
2145 { 0x1F09, 0x1F01, },
2146 { 0x1F0A, 0x1F02, },
2147 { 0x1F0B, 0x1F03, },
2148 { 0x1F0C, 0x1F04, },
2149 { 0x1F0D, 0x1F05, },
2150 { 0x1F0E, 0x1F06, },
2151 { 0x1F0F, 0x1F07, },
2152 { 0x1F18, 0x1F10, },
2153 { 0x1F19, 0x1F11, },
2154 { 0x1F1A, 0x1F12, },
2155 { 0x1F1B, 0x1F13, },
2156 { 0x1F1C, 0x1F14, },
2157 { 0x1F1D, 0x1F15, },
2158 { 0x1F28, 0x1F20, },
2159 { 0x1F29, 0x1F21, },
2160 { 0x1F2A, 0x1F22, },
2161 { 0x1F2B, 0x1F23, },
2162 { 0x1F2C, 0x1F24, },
2163 { 0x1F2D, 0x1F25, },
2164 { 0x1F2E, 0x1F26, },
2165 { 0x1F2F, 0x1F27, },
2166 { 0x1F38, 0x1F30, },
2167 { 0x1F39, 0x1F31, },
2168 { 0x1F3A, 0x1F32, },
2169 { 0x1F3B, 0x1F33, },
2170 { 0x1F3C, 0x1F34, },
2171 { 0x1F3D, 0x1F35, },
2172 { 0x1F3E, 0x1F36, },
2173 { 0x1F3F, 0x1F37, },
2174 { 0x1F48, 0x1F40, },
2175 { 0x1F49, 0x1F41, },
2176 { 0x1F4A, 0x1F42, },
2177 { 0x1F4B, 0x1F43, },
2178 { 0x1F4C, 0x1F44, },
2179 { 0x1F4D, 0x1F45, },
2180 { 0x1F59, 0x1F51, },
2181 { 0x1F5B, 0x1F53, },
2182 { 0x1F5D, 0x1F55, },
2183 { 0x1F5F, 0x1F57, },
2184 { 0x1F68, 0x1F60, },
2185 { 0x1F69, 0x1F61, },
2186 { 0x1F6A, 0x1F62, },
2187 { 0x1F6B, 0x1F63, },
2188 { 0x1F6C, 0x1F64, },
2189 { 0x1F6D, 0x1F65, },
2190 { 0x1F6E, 0x1F66, },
2191 { 0x1F6F, 0x1F67, },
2192 { 0x1F88, 0x1F80, },
2193 { 0x1F89, 0x1F81, },
2194 { 0x1F8A, 0x1F82, },
2195 { 0x1F8B, 0x1F83, },
2196 { 0x1F8C, 0x1F84, },
2197 { 0x1F8D, 0x1F85, },
2198 { 0x1F8E, 0x1F86, },
2199 { 0x1F8F, 0x1F87, },
2200 { 0x1F98, 0x1F90, },
2201 { 0x1F99, 0x1F91, },
2202 { 0x1F9A, 0x1F92, },
2203 { 0x1F9B, 0x1F93, },
2204 { 0x1F9C, 0x1F94, },
2205 { 0x1F9D, 0x1F95, },
2206 { 0x1F9E, 0x1F96, },
2207 { 0x1F9F, 0x1F97, },
2208 { 0x1FA8, 0x1FA0, },
2209 { 0x1FA9, 0x1FA1, },
2210 { 0x1FAA, 0x1FA2, },
2211 { 0x1FAB, 0x1FA3, },
2212 { 0x1FAC, 0x1FA4, },
2213 { 0x1FAD, 0x1FA5, },
2214 { 0x1FAE, 0x1FA6, },
2215 { 0x1FAF, 0x1FA7, },
2216 { 0x1FB8, 0x1FB0, },
2217 { 0x1FB9, 0x1FB1, },
2218 { 0x1FBA, 0x1F70, },
2219 { 0x1FBB, 0x1F71, },
2220 { 0x1FBC, 0x1FB3, },
2221 { 0x1FC8, 0x1F72, },
2222 { 0x1FC9, 0x1F73, },
2223 { 0x1FCA, 0x1F74, },
2224 { 0x1FCB, 0x1F75, },
2225 { 0x1FCC, 0x1FC3, },
2226 { 0x1FD8, 0x1FD0, },
2227 { 0x1FD9, 0x1FD1, },
2228 { 0x1FDA, 0x1F76, },
2229 { 0x1FDB, 0x1F77, },
2230 { 0x1FE8, 0x1FE0, },
2231 { 0x1FE9, 0x1FE1, },
2232 { 0x1FEA, 0x1F7A, },
2233 { 0x1FEB, 0x1F7B, },
2234 { 0x1FEC, 0x1FE5, },
2235 { 0x1FF8, 0x1F78, },
2236 { 0x1FF9, 0x1F79, },
2237 { 0x1FFA, 0x1F7C, },
2238 { 0x1FFB, 0x1F7D, },
2239 { 0x1FFC, 0x1FF3, },
2240 { 0x2126, 0x03C9, },
2241 { 0x212A, 0x006B, },
2242 { 0x212B, 0x00E5, },
2243 { 0x2132, 0x214E, },
2244 { 0x2160, 0x2170, },
2245 { 0x2161, 0x2171, },
2246 { 0x2162, 0x2172, },
2247 { 0x2163, 0x2173, },
2248 { 0x2164, 0x2174, },
2249 { 0x2165, 0x2175, },
2250 { 0x2166, 0x2176, },
2251 { 0x2167, 0x2177, },
2252 { 0x2168, 0x2178, },
2253 { 0x2169, 0x2179, },
2254 { 0x216A, 0x217A, },
2255 { 0x216B, 0x217B, },
2256 { 0x216C, 0x217C, },
2257 { 0x216D, 0x217D, },
2258 { 0x216E, 0x217E, },
2259 { 0x216F, 0x217F, },
2260 { 0x2183, 0x2184, },
2261 { 0x24B6, 0x24D0, },
2262 { 0x24B7, 0x24D1, },
2263 { 0x24B8, 0x24D2, },
2264 { 0x24B9, 0x24D3, },
2265 { 0x24BA, 0x24D4, },
2266 { 0x24BB, 0x24D5, },
2267 { 0x24BC, 0x24D6, },
2268 { 0x24BD, 0x24D7, },
2269 { 0x24BE, 0x24D8, },
2270 { 0x24BF, 0x24D9, },
2271 { 0x24C0, 0x24DA, },
2272 { 0x24C1, 0x24DB, },
2273 { 0x24C2, 0x24DC, },
2274 { 0x24C3, 0x24DD, },
2275 { 0x24C4, 0x24DE, },
2276 { 0x24C5, 0x24DF, },
2277 { 0x24C6, 0x24E0, },
2278 { 0x24C7, 0x24E1, },
2279 { 0x24C8, 0x24E2, },
2280 { 0x24C9, 0x24E3, },
2281 { 0x24CA, 0x24E4, },
2282 { 0x24CB, 0x24E5, },
2283 { 0x24CC, 0x24E6, },
2284 { 0x24CD, 0x24E7, },
2285 { 0x24CE, 0x24E8, },
2286 { 0x24CF, 0x24E9, },
2287 { 0x2C00, 0x2C30, },
2288 { 0x2C01, 0x2C31, },
2289 { 0x2C02, 0x2C32, },
2290 { 0x2C03, 0x2C33, },
2291 { 0x2C04, 0x2C34, },
2292 { 0x2C05, 0x2C35, },
2293 { 0x2C06, 0x2C36, },
2294 { 0x2C07, 0x2C37, },
2295 { 0x2C08, 0x2C38, },
2296 { 0x2C09, 0x2C39, },
2297 { 0x2C0A, 0x2C3A, },
2298 { 0x2C0B, 0x2C3B, },
2299 { 0x2C0C, 0x2C3C, },
2300 { 0x2C0D, 0x2C3D, },
2301 { 0x2C0E, 0x2C3E, },
2302 { 0x2C0F, 0x2C3F, },
2303 { 0x2C10, 0x2C40, },
2304 { 0x2C11, 0x2C41, },
2305 { 0x2C12, 0x2C42, },
2306 { 0x2C13, 0x2C43, },
2307 { 0x2C14, 0x2C44, },
2308 { 0x2C15, 0x2C45, },
2309 { 0x2C16, 0x2C46, },
2310 { 0x2C17, 0x2C47, },
2311 { 0x2C18, 0x2C48, },
2312 { 0x2C19, 0x2C49, },
2313 { 0x2C1A, 0x2C4A, },
2314 { 0x2C1B, 0x2C4B, },
2315 { 0x2C1C, 0x2C4C, },
2316 { 0x2C1D, 0x2C4D, },
2317 { 0x2C1E, 0x2C4E, },
2318 { 0x2C1F, 0x2C4F, },
2319 { 0x2C20, 0x2C50, },
2320 { 0x2C21, 0x2C51, },
2321 { 0x2C22, 0x2C52, },
2322 { 0x2C23, 0x2C53, },
2323 { 0x2C24, 0x2C54, },
2324 { 0x2C25, 0x2C55, },
2325 { 0x2C26, 0x2C56, },
2326 { 0x2C27, 0x2C57, },
2327 { 0x2C28, 0x2C58, },
2328 { 0x2C29, 0x2C59, },
2329 { 0x2C2A, 0x2C5A, },
2330 { 0x2C2B, 0x2C5B, },
2331 { 0x2C2C, 0x2C5C, },
2332 { 0x2C2D, 0x2C5D, },
2333 { 0x2C2E, 0x2C5E, },
2334 { 0x2C60, 0x2C61, },
2335 { 0x2C62, 0x026B, },
2336 { 0x2C63, 0x1D7D, },
2337 { 0x2C64, 0x027D, },
2338 { 0x2C67, 0x2C68, },
2339 { 0x2C69, 0x2C6A, },
2340 { 0x2C6B, 0x2C6C, },
2341 { 0x2C6D, 0x0251, },
2342 { 0x2C6E, 0x0271, },
2343 { 0x2C6F, 0x0250, },
2344 { 0x2C70, 0x0252, },
2345 { 0x2C72, 0x2C73, },
2346 { 0x2C75, 0x2C76, },
2347 { 0x2C7E, 0x023F, },
2348 { 0x2C7F, 0x0240, },
2349 { 0x2C80, 0x2C81, },
2350 { 0x2C82, 0x2C83, },
2351 { 0x2C84, 0x2C85, },
2352 { 0x2C86, 0x2C87, },
2353 { 0x2C88, 0x2C89, },
2354 { 0x2C8A, 0x2C8B, },
2355 { 0x2C8C, 0x2C8D, },
2356 { 0x2C8E, 0x2C8F, },
2357 { 0x2C90, 0x2C91, },
2358 { 0x2C92, 0x2C93, },
2359 { 0x2C94, 0x2C95, },
2360 { 0x2C96, 0x2C97, },
2361 { 0x2C98, 0x2C99, },
2362 { 0x2C9A, 0x2C9B, },
2363 { 0x2C9C, 0x2C9D, },
2364 { 0x2C9E, 0x2C9F, },
2365 { 0x2CA0, 0x2CA1, },
2366 { 0x2CA2, 0x2CA3, },
2367 { 0x2CA4, 0x2CA5, },
2368 { 0x2CA6, 0x2CA7, },
2369 { 0x2CA8, 0x2CA9, },
2370 { 0x2CAA, 0x2CAB, },
2371 { 0x2CAC, 0x2CAD, },
2372 { 0x2CAE, 0x2CAF, },
2373 { 0x2CB0, 0x2CB1, },
2374 { 0x2CB2, 0x2CB3, },
2375 { 0x2CB4, 0x2CB5, },
2376 { 0x2CB6, 0x2CB7, },
2377 { 0x2CB8, 0x2CB9, },
2378 { 0x2CBA, 0x2CBB, },
2379 { 0x2CBC, 0x2CBD, },
2380 { 0x2CBE, 0x2CBF, },
2381 { 0x2CC0, 0x2CC1, },
2382 { 0x2CC2, 0x2CC3, },
2383 { 0x2CC4, 0x2CC5, },
2384 { 0x2CC6, 0x2CC7, },
2385 { 0x2CC8, 0x2CC9, },
2386 { 0x2CCA, 0x2CCB, },
2387 { 0x2CCC, 0x2CCD, },
2388 { 0x2CCE, 0x2CCF, },
2389 { 0x2CD0, 0x2CD1, },
2390 { 0x2CD2, 0x2CD3, },
2391 { 0x2CD4, 0x2CD5, },
2392 { 0x2CD6, 0x2CD7, },
2393 { 0x2CD8, 0x2CD9, },
2394 { 0x2CDA, 0x2CDB, },
2395 { 0x2CDC, 0x2CDD, },
2396 { 0x2CDE, 0x2CDF, },
2397 { 0x2CE0, 0x2CE1, },
2398 { 0x2CE2, 0x2CE3, },
2399 { 0x2CEB, 0x2CEC, },
2400 { 0x2CED, 0x2CEE, },
2401 { 0x2CF2, 0x2CF3, },
2402 { 0xA640, 0xA641, },
2403 { 0xA642, 0xA643, },
2404 { 0xA644, 0xA645, },
2405 { 0xA646, 0xA647, },
2406 { 0xA648, 0xA649, },
2407 { 0xA64A, 0xA64B, },
2408 { 0xA64C, 0xA64D, },
2409 { 0xA64E, 0xA64F, },
2410 { 0xA650, 0xA651, },
2411 { 0xA652, 0xA653, },
2412 { 0xA654, 0xA655, },
2413 { 0xA656, 0xA657, },
2414 { 0xA658, 0xA659, },
2415 { 0xA65A, 0xA65B, },
2416 { 0xA65C, 0xA65D, },
2417 { 0xA65E, 0xA65F, },
2418 { 0xA660, 0xA661, },
2419 { 0xA662, 0xA663, },
2420 { 0xA664, 0xA665, },
2421 { 0xA666, 0xA667, },
2422 { 0xA668, 0xA669, },
2423 { 0xA66A, 0xA66B, },
2424 { 0xA66C, 0xA66D, },
2425 { 0xA680, 0xA681, },
2426 { 0xA682, 0xA683, },
2427 { 0xA684, 0xA685, },
2428 { 0xA686, 0xA687, },
2429 { 0xA688, 0xA689, },
2430 { 0xA68A, 0xA68B, },
2431 { 0xA68C, 0xA68D, },
2432 { 0xA68E, 0xA68F, },
2433 { 0xA690, 0xA691, },
2434 { 0xA692, 0xA693, },
2435 { 0xA694, 0xA695, },
2436 { 0xA696, 0xA697, },
2437 { 0xA698, 0xA699, },
2438 { 0xA69A, 0xA69B, },
2439 { 0xA722, 0xA723, },
2440 { 0xA724, 0xA725, },
2441 { 0xA726, 0xA727, },
2442 { 0xA728, 0xA729, },
2443 { 0xA72A, 0xA72B, },
2444 { 0xA72C, 0xA72D, },
2445 { 0xA72E, 0xA72F, },
2446 { 0xA732, 0xA733, },
2447 { 0xA734, 0xA735, },
2448 { 0xA736, 0xA737, },
2449 { 0xA738, 0xA739, },
2450 { 0xA73A, 0xA73B, },
2451 { 0xA73C, 0xA73D, },
2452 { 0xA73E, 0xA73F, },
2453 { 0xA740, 0xA741, },
2454 { 0xA742, 0xA743, },
2455 { 0xA744, 0xA745, },
2456 { 0xA746, 0xA747, },
2457 { 0xA748, 0xA749, },
2458 { 0xA74A, 0xA74B, },
2459 { 0xA74C, 0xA74D, },
2460 { 0xA74E, 0xA74F, },
2461 { 0xA750, 0xA751, },
2462 { 0xA752, 0xA753, },
2463 { 0xA754, 0xA755, },
2464 { 0xA756, 0xA757, },
2465 { 0xA758, 0xA759, },
2466 { 0xA75A, 0xA75B, },
2467 { 0xA75C, 0xA75D, },
2468 { 0xA75E, 0xA75F, },
2469 { 0xA760, 0xA761, },
2470 { 0xA762, 0xA763, },
2471 { 0xA764, 0xA765, },
2472 { 0xA766, 0xA767, },
2473 { 0xA768, 0xA769, },
2474 { 0xA76A, 0xA76B, },
2475 { 0xA76C, 0xA76D, },
2476 { 0xA76E, 0xA76F, },
2477 { 0xA779, 0xA77A, },
2478 { 0xA77B, 0xA77C, },
2479 { 0xA77D, 0x1D79, },
2480 { 0xA77E, 0xA77F, },
2481 { 0xA780, 0xA781, },
2482 { 0xA782, 0xA783, },
2483 { 0xA784, 0xA785, },
2484 { 0xA786, 0xA787, },
2485 { 0xA78B, 0xA78C, },
2486 { 0xA78D, 0x0265, },
2487 { 0xA790, 0xA791, },
2488 { 0xA792, 0xA793, },
2489 { 0xA796, 0xA797, },
2490 { 0xA798, 0xA799, },
2491 { 0xA79A, 0xA79B, },
2492 { 0xA79C, 0xA79D, },
2493 { 0xA79E, 0xA79F, },
2494 { 0xA7A0, 0xA7A1, },
2495 { 0xA7A2, 0xA7A3, },
2496 { 0xA7A4, 0xA7A5, },
2497 { 0xA7A6, 0xA7A7, },
2498 { 0xA7A8, 0xA7A9, },
2499 { 0xA7AA, 0x0266, },
2500 { 0xA7AB, 0x025C, },
2501 { 0xA7AC, 0x0261, },
2502 { 0xA7AD, 0x026C, },
2503 { 0xA7AE, 0x026A, },
2504 { 0xA7B0, 0x029E, },
2505 { 0xA7B1, 0x0287, },
2506 { 0xA7B2, 0x029D, },
2507 { 0xA7B3, 0xAB53, },
2508 { 0xA7B4, 0xA7B5, },
2509 { 0xA7B6, 0xA7B7, },
2510 { 0xFF21, 0xFF41, },
2511 { 0xFF22, 0xFF42, },
2512 { 0xFF23, 0xFF43, },
2513 { 0xFF24, 0xFF44, },
2514 { 0xFF25, 0xFF45, },
2515 { 0xFF26, 0xFF46, },
2516 { 0xFF27, 0xFF47, },
2517 { 0xFF28, 0xFF48, },
2518 { 0xFF29, 0xFF49, },
2519 { 0xFF2A, 0xFF4A, },
2520 { 0xFF2B, 0xFF4B, },
2521 { 0xFF2C, 0xFF4C, },
2522 { 0xFF2D, 0xFF4D, },
2523 { 0xFF2E, 0xFF4E, },
2524 { 0xFF2F, 0xFF4F, },
2525 { 0xFF30, 0xFF50, },
2526 { 0xFF31, 0xFF51, },
2527 { 0xFF32, 0xFF52, },
2528 { 0xFF33, 0xFF53, },
2529 { 0xFF34, 0xFF54, },
2530 { 0xFF35, 0xFF55, },
2531 { 0xFF36, 0xFF56, },
2532 { 0xFF37, 0xFF57, },
2533 { 0xFF38, 0xFF58, },
2534 { 0xFF39, 0xFF59, },
2535 { 0xFF3A, 0xFF5A, },
2536 { 0x10400, 0x10428, },
2537 { 0x10401, 0x10429, },
2538 { 0x10402, 0x1042A, },
2539 { 0x10403, 0x1042B, },
2540 { 0x10404, 0x1042C, },
2541 { 0x10405, 0x1042D, },
2542 { 0x10406, 0x1042E, },
2543 { 0x10407, 0x1042F, },
2544 { 0x10408, 0x10430, },
2545 { 0x10409, 0x10431, },
2546 { 0x1040A, 0x10432, },
2547 { 0x1040B, 0x10433, },
2548 { 0x1040C, 0x10434, },
2549 { 0x1040D, 0x10435, },
2550 { 0x1040E, 0x10436, },
2551 { 0x1040F, 0x10437, },
2552 { 0x10410, 0x10438, },
2553 { 0x10411, 0x10439, },
2554 { 0x10412, 0x1043A, },
2555 { 0x10413, 0x1043B, },
2556 { 0x10414, 0x1043C, },
2557 { 0x10415, 0x1043D, },
2558 { 0x10416, 0x1043E, },
2559 { 0x10417, 0x1043F, },
2560 { 0x10418, 0x10440, },
2561 { 0x10419, 0x10441, },
2562 { 0x1041A, 0x10442, },
2563 { 0x1041B, 0x10443, },
2564 { 0x1041C, 0x10444, },
2565 { 0x1041D, 0x10445, },
2566 { 0x1041E, 0x10446, },
2567 { 0x1041F, 0x10447, },
2568 { 0x10420, 0x10448, },
2569 { 0x10421, 0x10449, },
2570 { 0x10422, 0x1044A, },
2571 { 0x10423, 0x1044B, },
2572 { 0x10424, 0x1044C, },
2573 { 0x10425, 0x1044D, },
2574 { 0x10426, 0x1044E, },
2575 { 0x10427, 0x1044F, },
2576 { 0x104B0, 0x104D8, },
2577 { 0x104B1, 0x104D9, },
2578 { 0x104B2, 0x104DA, },
2579 { 0x104B3, 0x104DB, },
2580 { 0x104B4, 0x104DC, },
2581 { 0x104B5, 0x104DD, },
2582 { 0x104B6, 0x104DE, },
2583 { 0x104B7, 0x104DF, },
2584 { 0x104B8, 0x104E0, },
2585 { 0x104B9, 0x104E1, },
2586 { 0x104BA, 0x104E2, },
2587 { 0x104BB, 0x104E3, },
2588 { 0x104BC, 0x104E4, },
2589 { 0x104BD, 0x104E5, },
2590 { 0x104BE, 0x104E6, },
2591 { 0x104BF, 0x104E7, },
2592 { 0x104C0, 0x104E8, },
2593 { 0x104C1, 0x104E9, },
2594 { 0x104C2, 0x104EA, },
2595 { 0x104C3, 0x104EB, },
2596 { 0x104C4, 0x104EC, },
2597 { 0x104C5, 0x104ED, },
2598 { 0x104C6, 0x104EE, },
2599 { 0x104C7, 0x104EF, },
2600 { 0x104C8, 0x104F0, },
2601 { 0x104C9, 0x104F1, },
2602 { 0x104CA, 0x104F2, },
2603 { 0x104CB, 0x104F3, },
2604 { 0x104CC, 0x104F4, },
2605 { 0x104CD, 0x104F5, },
2606 { 0x104CE, 0x104F6, },
2607 { 0x104CF, 0x104F7, },
2608 { 0x104D0, 0x104F8, },
2609 { 0x104D1, 0x104F9, },
2610 { 0x104D2, 0x104FA, },
2611 { 0x104D3, 0x104FB, },
2612 { 0x10C80, 0x10CC0, },
2613 { 0x10C81, 0x10CC1, },
2614 { 0x10C82, 0x10CC2, },
2615 { 0x10C83, 0x10CC3, },
2616 { 0x10C84, 0x10CC4, },
2617 { 0x10C85, 0x10CC5, },
2618 { 0x10C86, 0x10CC6, },
2619 { 0x10C87, 0x10CC7, },
2620 { 0x10C88, 0x10CC8, },
2621 { 0x10C89, 0x10CC9, },
2622 { 0x10C8A, 0x10CCA, },
2623 { 0x10C8B, 0x10CCB, },
2624 { 0x10C8C, 0x10CCC, },
2625 { 0x10C8D, 0x10CCD, },
2626 { 0x10C8E, 0x10CCE, },
2627 { 0x10C8F, 0x10CCF, },
2628 { 0x10C90, 0x10CD0, },
2629 { 0x10C91, 0x10CD1, },
2630 { 0x10C92, 0x10CD2, },
2631 { 0x10C93, 0x10CD3, },
2632 { 0x10C94, 0x10CD4, },
2633 { 0x10C95, 0x10CD5, },
2634 { 0x10C96, 0x10CD6, },
2635 { 0x10C97, 0x10CD7, },
2636 { 0x10C98, 0x10CD8, },
2637 { 0x10C99, 0x10CD9, },
2638 { 0x10C9A, 0x10CDA, },
2639 { 0x10C9B, 0x10CDB, },
2640 { 0x10C9C, 0x10CDC, },
2641 { 0x10C9D, 0x10CDD, },
2642 { 0x10C9E, 0x10CDE, },
2643 { 0x10C9F, 0x10CDF, },
2644 { 0x10CA0, 0x10CE0, },
2645 { 0x10CA1, 0x10CE1, },
2646 { 0x10CA2, 0x10CE2, },
2647 { 0x10CA3, 0x10CE3, },
2648 { 0x10CA4, 0x10CE4, },
2649 { 0x10CA5, 0x10CE5, },
2650 { 0x10CA6, 0x10CE6, },
2651 { 0x10CA7, 0x10CE7, },
2652 { 0x10CA8, 0x10CE8, },
2653 { 0x10CA9, 0x10CE9, },
2654 { 0x10CAA, 0x10CEA, },
2655 { 0x10CAB, 0x10CEB, },
2656 { 0x10CAC, 0x10CEC, },
2657 { 0x10CAD, 0x10CED, },
2658 { 0x10CAE, 0x10CEE, },
2659 { 0x10CAF, 0x10CEF, },
2660 { 0x10CB0, 0x10CF0, },
2661 { 0x10CB1, 0x10CF1, },
2662 { 0x10CB2, 0x10CF2, },
2663 { 0x118A0, 0x118C0, },
2664 { 0x118A1, 0x118C1, },
2665 { 0x118A2, 0x118C2, },
2666 { 0x118A3, 0x118C3, },
2667 { 0x118A4, 0x118C4, },
2668 { 0x118A5, 0x118C5, },
2669 { 0x118A6, 0x118C6, },
2670 { 0x118A7, 0x118C7, },
2671 { 0x118A8, 0x118C8, },
2672 { 0x118A9, 0x118C9, },
2673 { 0x118AA, 0x118CA, },
2674 { 0x118AB, 0x118CB, },
2675 { 0x118AC, 0x118CC, },
2676 { 0x118AD, 0x118CD, },
2677 { 0x118AE, 0x118CE, },
2678 { 0x118AF, 0x118CF, },
2679 { 0x118B0, 0x118D0, },
2680 { 0x118B1, 0x118D1, },
2681 { 0x118B2, 0x118D2, },
2682 { 0x118B3, 0x118D3, },
2683 { 0x118B4, 0x118D4, },
2684 { 0x118B5, 0x118D5, },
2685 { 0x118B6, 0x118D6, },
2686 { 0x118B7, 0x118D7, },
2687 { 0x118B8, 0x118D8, },
2688 { 0x118B9, 0x118D9, },
2689 { 0x118BA, 0x118DA, },
2690 { 0x118BB, 0x118DB, },
2691 { 0x118BC, 0x118DC, },
2692 { 0x118BD, 0x118DD, },
2693 { 0x118BE, 0x118DE, },
2694 { 0x118BF, 0x118DF, },
2695 { 0x1E900, 0x1E922, },
2696 { 0x1E901, 0x1E923, },
2697 { 0x1E902, 0x1E924, },
2698 { 0x1E903, 0x1E925, },
2699 { 0x1E904, 0x1E926, },
2700 { 0x1E905, 0x1E927, },
2701 { 0x1E906, 0x1E928, },
2702 { 0x1E907, 0x1E929, },
2703 { 0x1E908, 0x1E92A, },
2704 { 0x1E909, 0x1E92B, },
2705 { 0x1E90A, 0x1E92C, },
2706 { 0x1E90B, 0x1E92D, },
2707 { 0x1E90C, 0x1E92E, },
2708 { 0x1E90D, 0x1E92F, },
2709 { 0x1E90E, 0x1E930, },
2710 { 0x1E90F, 0x1E931, },
2711 { 0x1E910, 0x1E932, },
2712 { 0x1E911, 0x1E933, },
2713 { 0x1E912, 0x1E934, },
2714 { 0x1E913, 0x1E935, },
2715 { 0x1E914, 0x1E936, },
2716 { 0x1E915, 0x1E937, },
2717 { 0x1E916, 0x1E938, },
2718 { 0x1E917, 0x1E939, },
2719 { 0x1E918, 0x1E93A, },
2720 { 0x1E919, 0x1E93B, },
2721 { 0x1E91A, 0x1E93C, },
2722 { 0x1E91B, 0x1E93D, },
2723 { 0x1E91C, 0x1E93E, },
2724 { 0x1E91D, 0x1E93F, },
2725 { 0x1E91E, 0x1E940, },
2726 { 0x1E91F, 0x1E941, },
2727 { 0x1E920, 0x1E942, },
2728 { 0x1E921, 0x1E943, },
2729};
2730
2731static BAT *UTF8_toUpperFrom = NULL, *UTF8_toUpperTo = NULL,
2732 *UTF8_toLowerFrom = NULL, *UTF8_toLowerTo = NULL;
2733
2734#ifndef NDEBUG
2735static void
2736UTF8_assert(const char *s)
2737{
2738 int c;
2739
2740 if (s == NULL)
2741 return;
2742 if (*s == '\200' && s[1] == '\0')
2743 return; /* str_nil */
2744 while ((c = *s++) != '\0') {
2745 if ((c & 0x80) == 0)
2746 continue;
2747 if ((*s++ & 0xC0) != 0x80)
2748 assert(0);
2749 if ((c & 0xE0) == 0xC0)
2750 continue;
2751 if ((*s++ & 0xC0) != 0x80)
2752 assert(0);
2753 if ((c & 0xF0) == 0xE0)
2754 continue;
2755 if ((*s++ & 0xC0) != 0x80)
2756 assert(0);
2757 if ((c & 0xF8) == 0xF0)
2758 continue;
2759 assert(0);
2760 }
2761}
2762#else
2763#define UTF8_assert(s) ((void) 0)
2764#endif
2765
2766str
2767strPrelude(void *ret)
2768{
2769 (void) ret;
2770 if (UTF8_toUpperFrom == NULL) {
2771 size_t i;
2772
2773 UTF8_toUpperFrom = COLnew(0, TYPE_int, 1500, TRANSIENT);
2774 UTF8_toUpperTo = COLnew(0, TYPE_int, 1500, TRANSIENT);
2775 UTF8_toLowerFrom = COLnew(0, TYPE_int, 1500, TRANSIENT);
2776 UTF8_toLowerTo = COLnew(0, TYPE_int, 1500, TRANSIENT);
2777 if (UTF8_toUpperFrom == NULL || UTF8_toUpperTo == NULL ||
2778 UTF8_toLowerFrom == NULL || UTF8_toLowerTo == NULL) {
2779 goto bailout;
2780 }
2781
2782 for (i = 0; i < sizeof(UTF8_toUpper) / sizeof(UTF8_toUpper[0]); i++) {
2783 if (BUNappend(UTF8_toUpperFrom, &UTF8_toUpper[i].from, false) != GDK_SUCCEED ||
2784 BUNappend(UTF8_toUpperTo, &UTF8_toUpper[i].to, false) != GDK_SUCCEED)
2785 goto bailout;
2786 }
2787
2788 for (i = 0; i < sizeof(UTF8_toLower) / sizeof(UTF8_toLower[0]); i++) {
2789 if (BUNappend(UTF8_toLowerFrom, &UTF8_toLower[i].from, false) != GDK_SUCCEED ||
2790 BUNappend(UTF8_toLowerTo, &UTF8_toLower[i].to, false) != GDK_SUCCEED)
2791 goto bailout;
2792 }
2793
2794 if (BBPrename(UTF8_toUpperFrom->batCacheid, "monet_unicode_upper_from") != 0 ||
2795 BBPrename(UTF8_toUpperTo->batCacheid, "monet_unicode_upper_to") != 0 ||
2796 BBPrename(UTF8_toLowerFrom->batCacheid, "monet_unicode_lower_from") != 0 ||
2797 BBPrename(UTF8_toLowerTo->batCacheid, "monet_unicode_lower_to") != 0) {
2798 goto bailout;
2799 }
2800 }
2801 return MAL_SUCCEED;
2802
2803 bailout:
2804 BBPreclaim(UTF8_toUpperFrom);
2805 BBPreclaim(UTF8_toUpperTo);
2806 BBPreclaim(UTF8_toLowerFrom);
2807 BBPreclaim(UTF8_toLowerTo);
2808 UTF8_toUpperFrom = NULL;
2809 UTF8_toUpperTo = NULL;
2810 UTF8_toLowerFrom = NULL;
2811 UTF8_toLowerTo = NULL;
2812 throw(MAL, "str.prelude", GDK_EXCEPTION);
2813}
2814
2815str
2816strEpilogue(void *ret)
2817{
2818 (void) ret;
2819 if (UTF8_toUpperFrom)
2820 BBPunfix(UTF8_toUpperFrom->batCacheid);
2821 if (UTF8_toUpperTo)
2822 BBPunfix(UTF8_toUpperTo->batCacheid);
2823 if (UTF8_toLowerFrom)
2824 BBPunfix(UTF8_toLowerFrom->batCacheid);
2825 if (UTF8_toLowerTo)
2826 BBPunfix(UTF8_toLowerTo->batCacheid);
2827 UTF8_toUpperFrom = NULL;
2828 UTF8_toUpperTo = NULL;
2829 UTF8_toLowerFrom = NULL;
2830 UTF8_toLowerTo = NULL;
2831 return MAL_SUCCEED;
2832}
2833
2834/* Get the last char in (X2), and #bytes it takes, but do not decrease
2835 * the pos in (X2). See gdk_atoms.c for UTF-8 encoding */
2836#define UTF8_LASTCHAR(X1, SZ, X2, SZ2) \
2837 do { \
2838 if (((X2)[SZ2-1] & 0x80) == 0) { \
2839 (X1) = (X2)[SZ2-1]; \
2840 (SZ) = 1; \
2841 } else if (((X2)[SZ2-2] & 0xE0) == 0xC0) { \
2842 (X1) = ((X2)[SZ2-2] & 0x1F) << 6; \
2843 (X1) |= ((X2)[SZ2-1] & 0x3F); \
2844 (SZ) = 2; \
2845 } else if (((X2)[SZ2-3] & 0xF0) == 0xE0) { \
2846 (X1) = ((X2)[SZ2-3] & 0x0F) << 12; \
2847 (X1) |= ((X2)[SZ2-2] & 0x3F) << 6; \
2848 (X1) |= ((X2)[SZ2-1] & 0x3F); \
2849 (SZ) = 3; \
2850 } else if (((X2)[SZ2-4] & 0xF8) == 0xF0) { \
2851 (X1) = ((X2)[SZ2-4] & 0x07) << 18; \
2852 (X1) |= ((X2)[SZ2-3] & 0x3F) << 12; \
2853 (X1) |= ((X2)[SZ2-2] & 0x3F) << 6; \
2854 (X1) |= ((X2)[SZ2-1] & 0x3F); \
2855 (SZ) = 4; \
2856 } else { \
2857 (X1) = int_nil; \
2858 (SZ) = 0; \
2859 } \
2860 } while (0)
2861
2862/* Get the first char in (X2), and #bytes it takes, but do not
2863 * increase the pos in (X2) */
2864#define UTF8_NEXTCHAR(X1, SZ, X2) \
2865 do { \
2866 if (((X2)[0] & 0x80) == 0) { \
2867 (X1) = (X2)[0]; \
2868 (SZ) = 1; \
2869 } else if (((X2)[0] & 0xE0) == 0xC0) { \
2870 (X1) = ((X2)[0] & 0x1F) << 6; \
2871 (X1) |= ((X2)[1] & 0x3F); \
2872 (SZ) = 2; \
2873 } else if (((X2)[0] & 0xF0) == 0xE0) { \
2874 (X1) = ((X2)[0] & 0x0F) << 12; \
2875 (X1) |= ((X2)[1] & 0x3F) << 6; \
2876 (X1) |= ((X2)[2] & 0x3F); \
2877 (SZ) = 3; \
2878 } else if (((X2)[0] & 0xF8) == 0xF0) { \
2879 (X1) = ((X2)[0] & 0x07) << 18; \
2880 (X1) |= ((X2)[1] & 0x3F) << 12; \
2881 (X1) |= ((X2)[2] & 0x3F) << 6; \
2882 (X1) |= ((X2)[3] & 0x3F); \
2883 (SZ) = 4; \
2884 } else { \
2885 (X1) = int_nil; \
2886 (SZ) = 0; \
2887 } \
2888 } while (0)
2889
2890#define UTF8_GETCHAR(X1, X2) \
2891 do { \
2892 if ((*(X2) & 0x80) == 0) { \
2893 (X1) = *(X2)++; \
2894 } else if ((*(X2) & 0xE0) == 0xC0) { \
2895 (X1) = (*(X2)++ & 0x1F) << 6; \
2896 (X1) |= (*(X2)++ & 0x3F); \
2897 } else if ((*(X2) & 0xF0) == 0xE0) { \
2898 (X1) = (*(X2)++ & 0x0F) << 12; \
2899 (X1) |= (*(X2)++ & 0x3F) << 6; \
2900 (X1) |= (*(X2)++ & 0x3F); \
2901 } else if ((*(X2) & 0xF8) == 0xF0) { \
2902 (X1) = (*(X2)++ & 0x07) << 18; \
2903 (X1) |= (*(X2)++ & 0x3F) << 12; \
2904 (X1) |= (*(X2)++ & 0x3F) << 6; \
2905 (X1) |= (*(X2)++ & 0x3F); \
2906 if ((X1) > 0x10FFFF || ((X1) & 0x1FF800) == 0xD800) \
2907 goto illegal; \
2908 } else { \
2909 (X1) = int_nil; \
2910 } \
2911 } while (0)
2912
2913#define UTF8_PUTCHAR(X1, X2) \
2914 do { \
2915 if ((X1) < 0 || (X1) > 0x10FFFF || ((X1) & 0x1FF800) == 0xD800) { \
2916 goto illegal; \
2917 } else if ((X1) <= 0x7F) { \
2918 *(X2)++ = (X1); \
2919 } else if ((X1) <= 0x7FF) { \
2920 *(X2)++ = 0xC0 | ((X1) >> 6); \
2921 *(X2)++ = 0x80 | ((X1) & 0x3F); \
2922 } else if ((X1) <= 0xFFFF) { \
2923 *(X2)++ = 0xE0 | ((X1) >> 12); \
2924 *(X2)++ = 0x80 | (((X1) >> 6) & 0x3F); \
2925 *(X2)++ = 0x80 | ((X1) & 0x3F); \
2926 } else { \
2927 *(X2)++ = 0xF0 | ((X1) >> 18); \
2928 *(X2)++ = 0x80 | (((X1) >> 12) & 0x3F); \
2929 *(X2)++ = 0x80 | (((X1) >> 6) & 0x3F); \
2930 *(X2)++ = 0x80 | ((X1) & 0x3F); \
2931 } \
2932 } while (0)
2933
2934#define UTF8_CHARLEN(UC) \
2935 ((UC) <= 0x7F ? 1 : (UC) <= 0x7FF ? 2 : (UC) <= 0xFFFF ? 3 : 4)
2936// (1 + ((UC) > 0x7F) + ((UC) > 0x7FF) + ((UC) > 0xFFFF))
2937
2938static inline size_t
2939UTF8_strlen(const char *s)
2940{
2941 size_t pos = 0;
2942
2943 UTF8_assert(s);
2944
2945 if (GDK_STRNIL(s))
2946 return 1;
2947
2948 while (*s) {
2949 /* just count leading bytes of encoded code points; only works
2950 * for correctly encoded UTF-8 */
2951 pos += (*s++ & 0xC0) != 0x80;
2952 }
2953 return pos;
2954}
2955
2956static inline int
2957UTF8_strpos(const char *s, const char *end)
2958{
2959 int pos = 0;
2960
2961 UTF8_assert(s);
2962
2963 if (s > end) {
2964 return -1;
2965 }
2966 while (s < end) {
2967 /* just count leading bytes of encoded code points; only works
2968 * for correctly encoded UTF-8 */
2969 pos += (*s++ & 0xC0) != 0x80;
2970 }
2971 return pos;
2972}
2973
2974static inline str
2975UTF8_strtail(const char *s, int pos)
2976{
2977 UTF8_assert(s);
2978 while (*s) {
2979 if ((*s & 0xC0) != 0x80) {
2980 if (pos <= 0)
2981 break;
2982 pos--;
2983 }
2984 s++;
2985 }
2986 return (str) s;
2987}
2988
2989static str
2990convertCase(BAT *from, BAT *to, str *res, const char *src, const char *malfunc)
2991{
2992 BATiter toi = bat_iterator(to);
2993 BATiter fromi = bat_iterator(from);
2994 size_t len = strlen(src);
2995 char *dst;
2996 const char *end = src + len;
2997 BUN UTF8_CONV_r;
2998 bool lower_to_upper = from == UTF8_toUpperFrom;
2999
3000 if (strNil(src)) {
3001 *res = GDKstrdup(str_nil);
3002 } else {
3003 *res = GDKmalloc(len + 1);
3004 if (*res != NULL) {
3005 dst = *res;
3006 while (src < end) {
3007 int c;
3008
3009 UTF8_GETCHAR(c, src);
3010 if ((c & 0x80) == 0) {
3011 /* for ASCII characters we don't need to do a hash
3012 * lookup */
3013 if (lower_to_upper) {
3014 if ('a' <= c && c <= 'z')
3015 c += 'A' - 'a';
3016 } else {
3017 if ('A' <= c && c <= 'Z')
3018 c += 'a' - 'A';
3019 }
3020 } else {
3021 /* use hash, even though BAT is sorted */
3022 HASHfnd_int(UTF8_CONV_r, fromi, &c);
3023 if (UTF8_CONV_r != BUN_NONE)
3024 c = *(int*) BUNtloc(toi, UTF8_CONV_r);
3025 }
3026 if (dst + UTF8_CHARLEN(c) > *res + len) {
3027 /* doesn't fit, so allocate more space;
3028 * also allocate enough for the rest of the
3029 * source */
3030 size_t off = dst - *res;
3031
3032 dst = GDKrealloc(*res, (len += 4 + (end - src)) + 1);
3033 if (dst == NULL) {
3034 /* if realloc fails, original buffer is still
3035 * allocated, so free it */
3036 GDKfree(*res);
3037 goto hashfnd_failed;
3038 }
3039 *res = dst;
3040 dst = *res + off;
3041 }
3042 UTF8_PUTCHAR(c, dst);
3043 }
3044 *dst = 0;
3045 }
3046 }
3047 if (*res != NULL)
3048 return MAL_SUCCEED;
3049 hashfnd_failed:
3050 throw(MAL, malfunc, SQLSTATE(HY001) MAL_MALLOC_FAIL);
3051 illegal:
3052 throw(MAL, malfunc, SQLSTATE(42000) "Illegal Unicode code point");
3053}
3054
3055/*
3056 * Here you find the wrappers around the version 4 library code
3057 * It also contains the direct implementation of the string
3058 * matching support routines.
3059 */
3060#include "mal_exception.h"
3061
3062/*
3063 * The SQL like function return a boolean
3064 */
3065static int
3066STRlike(const char *s, const char *pat, const char *esc)
3067{
3068 const char *t, *p;
3069
3070 t = s;
3071 for (p = pat; *p && *t; p++) {
3072 if (esc && *p == *esc) {
3073 p++;
3074 if (*p != *t)
3075 return FALSE;
3076 t++;
3077 } else if (*p == '_')
3078 t++;
3079 else if (*p == '%') {
3080 p++;
3081 while (*p == '%')
3082 p++;
3083 if (*p == 0)
3084 return TRUE; /* tail is acceptable */
3085 for (; *p && *t; t++)
3086 if (STRlike(t, p, esc))
3087 return TRUE;
3088 if (*p == 0 && *t == 0)
3089 return TRUE;
3090 return FALSE;
3091 } else if (*p == *t)
3092 t++;
3093 else
3094 return FALSE;
3095 }
3096 if (*p == '%' && *(p + 1) == 0)
3097 return TRUE;
3098 return *t == 0 && *p == 0;
3099}
3100
3101str
3102STRlikewrap(bit *ret, const str *s, const str *pat, const str *esc)
3103{
3104 *ret = STRlike(*s, *pat, *esc);
3105 return MAL_SUCCEED;
3106}
3107
3108str
3109STRlikewrap2(bit *ret, const str *s, const str *pat)
3110{
3111 *ret = STRlike(*s, *pat, NULL);
3112 return MAL_SUCCEED;
3113}
3114
3115str
3116STRtostr(str *res, const str *src)
3117{
3118 if( *src == 0)
3119 *res= GDKstrdup(str_nil);
3120 else
3121 *res = GDKstrdup(*src);
3122 if (*res == NULL)
3123 throw(MAL, "str.str", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3124 return MAL_SUCCEED;
3125}
3126
3127str
3128STRConcat(str *res, const str *val1, const str *val2)
3129{
3130 size_t l1, l2;
3131 const char *s1 = *val1;
3132 const char *s2 = *val2;
3133
3134 if (strNil(s1) || strNil(s2)) {
3135 *res = GDKstrdup(str_nil);
3136 } else {
3137 l1 = strlen(s1);
3138 l2 = strlen(s2);
3139 if ((*res = GDKmalloc(l1 + l2 + 1)) != NULL) {
3140 memcpy(*res, s1, l1);
3141 memcpy(*res + l1, s2, l2);
3142 (*res)[l1 + l2] = '\0';
3143 }
3144 }
3145 if (*res == NULL)
3146 throw(MAL, "str.concat", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3147 return MAL_SUCCEED;
3148}
3149
3150str
3151STRLength(int *res, const str *arg1)
3152{
3153 size_t l;
3154 const char *s = *arg1;
3155
3156 if (strNil(s)) {
3157 *res = int_nil;
3158 return MAL_SUCCEED;
3159 }
3160 l = UTF8_strlen(s);
3161 assert(l < INT_MAX);
3162 if (l > INT_MAX)
3163 l = INT_MAX;
3164 *res = (int) l;
3165 return MAL_SUCCEED;
3166}
3167
3168str
3169STRBytes(int *res, const str *arg1)
3170{
3171 size_t l;
3172
3173 l = strlen(*arg1);
3174 assert(l < INT_MAX);
3175 *res = (int) l;
3176 return MAL_SUCCEED;
3177}
3178
3179str
3180STRTail(str *res, const str *arg1, const int *offset)
3181{
3182 int off = *offset;
3183 const char *s = *arg1;
3184
3185 if (strNil(s) || is_int_nil(off)) {
3186 *res = GDKstrdup(str_nil);
3187 } else {
3188 if (off < 0) {
3189 size_t len = UTF8_strlen(s);
3190
3191 assert(len <= INT_MAX);
3192 off += (int) len;
3193 if (off < 0)
3194 off = 0;
3195 }
3196 *res = GDKstrdup(UTF8_strtail(s, off));
3197 }
3198 if (*res == NULL)
3199 throw(MAL, "str.tail", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3200 return MAL_SUCCEED;
3201}
3202
3203str
3204STRSubString(str *res, const str *arg1, const int *offset, const int *length)
3205{
3206 size_t len;
3207 int off = *offset, l = *length;
3208 const char *s = *arg1;
3209
3210 if (strNil(s) || is_int_nil(off) || is_int_nil(l)) {
3211 *res = GDKstrdup(str_nil);
3212 if (*res == NULL)
3213 throw(MAL, "str.substring", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3214 return MAL_SUCCEED;
3215 }
3216 if (off < 0) {
3217 len = UTF8_strlen(s);
3218 assert(len <= INT_MAX);
3219 if (len > INT_MAX)
3220 len = INT_MAX;
3221 off += (int) len;
3222 if (off < 0) {
3223 l += off;
3224 off = 0;
3225 }
3226 }
3227 /* here, off >= 0 */
3228 if (l < 0) {
3229 *res = GDKstrdup("");
3230 if (*res == NULL)
3231 throw(MAL, "str.substring", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3232 return MAL_SUCCEED;
3233 }
3234 s = UTF8_strtail(s, off);
3235 len = (size_t) (UTF8_strtail(s, l) - s);
3236 *res = GDKmalloc(len + 1);
3237 if (*res == NULL)
3238 throw(MAL, "str.substring", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3239 strcpy_len(*res, s, len + 1);
3240 return MAL_SUCCEED;
3241}
3242
3243str
3244STRFromWChr(str *res, const int *c)
3245{
3246 str s;
3247
3248 if (is_int_nil(*c)) {
3249 *res = GDKstrdup(str_nil);
3250 if (*res == NULL)
3251 throw(MAL, "str.unicode", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3252 return MAL_SUCCEED;
3253 }
3254
3255 s = *res = GDKmalloc(5);
3256 if (*res == NULL)
3257 throw(MAL, "str.unicode", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3258 UTF8_PUTCHAR(*c, s);
3259 *s = 0;
3260 return MAL_SUCCEED;
3261 illegal:
3262 GDKfree(*res);
3263 *res = NULL;
3264 throw(MAL, "str.unicode", SQLSTATE(42000) "Illegal Unicode code point");
3265}
3266
3267/* return the Unicode code point of arg1 at position at */
3268str
3269STRWChrAt(int *res, const str *arg1, const int *at)
3270{
3271/* 64bit: should have lng arg */
3272 const char *s = *arg1;
3273
3274 if (strNil(s) || is_int_nil(*at) || *at < 0) {
3275 *res = int_nil;
3276 return MAL_SUCCEED;
3277 }
3278 s = UTF8_strtail(s, *at);
3279 if (s == NULL || *s == 0) {
3280 *res = int_nil;
3281 return MAL_SUCCEED;
3282 }
3283 UTF8_GETCHAR(*res, s);
3284 return MAL_SUCCEED;
3285 illegal:
3286 throw(MAL, "str.unicodeAt", SQLSTATE(42000) "Illegal Unicode code point");
3287}
3288
3289/* returns whether arg1 starts with arg2 */
3290str
3291STRPrefix(bit *res, const str *arg1, const str *arg2)
3292{
3293 const char *s = *arg1;
3294 const char *prefix = *arg2;
3295
3296 if (strNil(s) || strNil(prefix)) {
3297 *res = bit_nil;
3298 return MAL_SUCCEED;
3299 }
3300 *res = strncmp(s, prefix, strlen(prefix)) == 0;
3301 return MAL_SUCCEED;
3302}
3303
3304/* returns whether arg1 ends with arg2 */
3305str
3306STRSuffix(bit *res, const str *arg1, const str *arg2)
3307{
3308 size_t sl, sul;
3309 const char *s = *arg1;
3310 const char *suffix = *arg2;
3311
3312 if (strNil(s) || strNil(suffix)) {
3313 *res = bit_nil;
3314 return MAL_SUCCEED;
3315 }
3316 sl = strlen(s);
3317 sul = strlen(suffix);
3318
3319 if (sl < sul)
3320 *res = 0;
3321 else
3322 *res = strcmp(s + sl - sul, suffix) == 0;
3323 return MAL_SUCCEED;
3324}
3325
3326str
3327STRLower(str *res, const str *arg1)
3328{
3329 return convertCase(UTF8_toLowerFrom, UTF8_toLowerTo, res, *arg1, "str.lower");
3330}
3331
3332str
3333STRUpper(str *res, const str *arg1)
3334{
3335 return convertCase(UTF8_toUpperFrom, UTF8_toUpperTo, res, *arg1, "str.upper");
3336}
3337
3338/* find first occurrence of needle in haystack */
3339str
3340STRstrSearch(int *res, const str *haystack, const str *needle)
3341{
3342/* 64bit: should return lng */
3343 const char *s = *haystack;
3344 const char *s2 = *needle;
3345
3346 if (strNil(s) || strNil(s2)) {
3347 *res = int_nil;
3348 return MAL_SUCCEED;
3349 }
3350 if ((s2 = strstr(s, s2)) != NULL)
3351 *res = UTF8_strpos(s, s2);
3352 else
3353 *res = -1;
3354 return MAL_SUCCEED;
3355}
3356
3357/* find last occurrence of arg2 in arg1 */
3358str
3359STRReverseStrSearch(int *res, const str *arg1, const str *arg2)
3360{
3361/* 64bit: should return lng */
3362 size_t len, slen;
3363 const char *s = *arg1;
3364 const char *s2 = *arg2;
3365
3366 if (strNil(s) || strNil(s2)) {
3367 *res = int_nil;
3368 return MAL_SUCCEED;
3369 }
3370 *res = -1;
3371 len = strlen(s);
3372 slen = strlen(s2);
3373 *res = -1; /* changed if found */
3374 if (len >= slen) {
3375 const char *p = s + len - slen;
3376 do {
3377 if (strncmp(p, s2, slen) == 0) {
3378 *res = UTF8_strpos(s, p);
3379 break;
3380 }
3381 } while (p-- > s);
3382 }
3383 return MAL_SUCCEED;
3384}
3385
3386str
3387STRsplitpart(str *res, str *haystack, str *needle, int *field)
3388{
3389 size_t len;
3390 int f = *field;
3391 char *p;
3392 const char *s = *haystack;
3393 const char *s2 = *needle;
3394
3395 if (strNil(s) || is_int_nil(*field)) {
3396 *res = GDKstrdup(str_nil);
3397 if (*res == NULL)
3398 throw(MAL, "str.splitpart", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3399 return MAL_SUCCEED;
3400 }
3401
3402 if (*field <= 0) {
3403 throw(MAL, "str.splitpart", SQLSTATE(42000) "field position must be greater than zero");
3404 }
3405
3406 len = strlen(s2);
3407
3408 while ((p = strstr(s, s2)) != NULL && f > 1) {
3409 s = p + len;
3410 f--;
3411 }
3412
3413 if (f != 1) {
3414 *res = GDKstrdup("");
3415 if (*res == NULL)
3416 throw(MAL, "str.splitpart", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3417 return MAL_SUCCEED;
3418 }
3419
3420 if (p == NULL) {
3421 len = strlen(s);
3422 } else {
3423 len = (size_t) (p - s);
3424 }
3425
3426 *res = GDKstrndup(s, len);
3427 if (*res == NULL)
3428 throw(MAL, "str.splitpart", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3429 return MAL_SUCCEED;
3430}
3431
3432/* returns number of bytes to remove from left to strip the codepoints in rm */
3433static size_t
3434lstrip(const char *s, size_t len, const int *rm, size_t nrm)
3435{
3436 int c;
3437 size_t i, n, skip = 0;
3438
3439 while (len > 0) {
3440 UTF8_NEXTCHAR(c, n, s);
3441 assert(n > 0 && n <= len);
3442 for (i = 0; i < nrm; i++) {
3443 if (rm[i] == c) {
3444 s += n;
3445 skip += n;
3446 len -= n;
3447 break;
3448 }
3449 }
3450 if (i == nrm)
3451 break;
3452 }
3453 return skip;
3454}
3455
3456/* returns the resulting length of s after stripping codepoints in rm
3457 * from the right */
3458static size_t
3459rstrip(const char *s, size_t len, const int *rm, size_t nrm)
3460{
3461 int c;
3462 size_t i, n;
3463
3464 while (len > 0) {
3465 UTF8_LASTCHAR(c, n, s, len);
3466 assert(n > 0 && n <= len);
3467 for (i = 0; i < nrm; i++) {
3468 if (rm[i] == c) {
3469 len -= n;
3470 break;
3471 }
3472 }
3473 if (i == nrm)
3474 break;
3475 }
3476 return len;
3477}
3478
3479const int whitespace[] = {
3480 ' ', /* space */
3481 '\t', /* tab (character tabulation) */
3482 '\n', /* line feed */
3483 '\r', /* carriage return */
3484 '\f', /* form feed */
3485 '\v', /* vertical tab (line tabulation) */
3486/* below the code points that have the Unicode Zs (space separator) property */
3487 0x00A0, /* no-break space */
3488 0x1680, /* ogham space mark */
3489 0x2000, /* en quad */
3490 0x2001, /* em quad */
3491 0x2002, /* en space */
3492 0x2003, /* em space */
3493 0x2004, /* three-per-em space */
3494 0x2005, /* four-per-em space */
3495 0x2006, /* six-per-em space */
3496 0x2007, /* figure space */
3497 0x2008, /* punctuation space */
3498 0x2009, /* thin space */
3499 0x200A, /* hair space */
3500 0x202F, /* narrow no-break space */
3501 0x205F, /* medium mathematical space */
3502 0x3000, /* ideographic space */
3503};
3504#define NSPACES (sizeof(whitespace) / sizeof(whitespace[0]))
3505
3506/* remove all whitespace from either side of arg1 */
3507str
3508STRStrip(str *res, const str *arg1)
3509{
3510 const char *s = *arg1;
3511 size_t len;
3512 size_t n;
3513
3514 if (GDK_STRNIL(s)) {
3515 *res = GDKstrdup(str_nil);
3516 } else {
3517 len = strlen(s);
3518 n = lstrip(s, len, whitespace, NSPACES);
3519 s += n;
3520 len -= n;
3521 n = rstrip(s, len, whitespace, NSPACES);
3522 *res = GDKstrndup(s, n);
3523 }
3524 if (*res == NULL)
3525 throw(MAL, "str.trim", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3526 return MAL_SUCCEED;
3527}
3528
3529/* remove all whitespace from the start (left) of arg1 */
3530str
3531STRLtrim(str *res, const str *arg1)
3532{
3533 const char *s = *arg1;
3534 size_t len;
3535 size_t n;
3536
3537 if (GDK_STRNIL(s)) {
3538 *res = GDKstrdup(str_nil);
3539 } else {
3540 len = strlen(s);
3541 n = lstrip(s, len, whitespace, NSPACES);
3542 *res = GDKstrndup(s + n, len - n);
3543 }
3544 if (*res == NULL)
3545 throw(MAL, "str.ltrim", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3546 return MAL_SUCCEED;
3547}
3548
3549/* remove all whitespace from the end (right) of arg1 */
3550str
3551STRRtrim(str *res, const str *arg1)
3552{
3553 const char *s = *arg1;
3554 size_t len;
3555 size_t n;
3556
3557 if (GDK_STRNIL(s)) {
3558 *res = GDKstrdup(str_nil);
3559 } else {
3560 len = strlen(s);
3561 n = rstrip(s, len, whitespace, NSPACES);
3562 *res = GDKstrndup(s, n);
3563 }
3564 if (*res == NULL)
3565 throw(MAL, "str.rtrim", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3566 return MAL_SUCCEED;
3567}
3568
3569/* return a list of codepoints in s */
3570static int *
3571trimchars(const char *s, size_t *n)
3572{
3573 size_t len = 0;
3574 int *chars = GDKmalloc(strlen(s) * sizeof(int));
3575 int c;
3576
3577 if (chars == NULL)
3578 return NULL;
3579
3580 while (*s) {
3581 UTF8_GETCHAR(c, s);
3582 assert(!is_int_nil(c));
3583 chars[len++] = c;
3584 }
3585 *n = len;
3586 return chars;
3587 illegal:
3588 GDKfree(chars);
3589 return NULL;
3590}
3591
3592/* remove the longest string containing only characters from arg2 from
3593 * either side of arg1 */
3594str
3595STRStrip2(str *res, const str *arg1, const str *arg2)
3596{
3597 const char *s = *arg1;
3598 size_t len;
3599 size_t n;
3600 size_t nchars;
3601 int *chars;
3602
3603 if (GDK_STRNIL(s)) {
3604 *res = GDKstrdup(str_nil);
3605 } else {
3606 chars = trimchars(*arg2, &nchars);
3607 if (chars == NULL)
3608 throw(MAL, "str.trim", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3609 len = strlen(s);
3610 n = lstrip(s, len, chars, nchars);
3611 s += n;
3612 len -= n;
3613 n = rstrip(s, len, chars, nchars);
3614 GDKfree(chars);
3615 *res = GDKstrndup(s, n);
3616 }
3617 if (*res == NULL)
3618 throw(MAL, "str.trim", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3619 return MAL_SUCCEED;
3620}
3621
3622/* remove the longest string containing only characters from arg2 from
3623 * the start (left) of arg1 */
3624str
3625STRLtrim2(str *res, const str *arg1, const str *arg2)
3626{
3627 const char *s = *arg1;
3628 size_t len;
3629 size_t n;
3630 size_t nchars;
3631 int *chars;
3632
3633 if (GDK_STRNIL(s)) {
3634 *res = GDKstrdup(str_nil);
3635 } else {
3636 chars = trimchars(*arg2, &nchars);
3637 if (chars == NULL)
3638 throw(MAL, "str.trim", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3639 len = strlen(s);
3640 n = lstrip(s, len, chars, nchars);
3641 GDKfree(chars);
3642 *res = GDKstrndup(s + n, len - n);
3643 }
3644 if (*res == NULL)
3645 throw(MAL, "str.ltrim", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3646 return MAL_SUCCEED;
3647}
3648
3649/* remove the longest string containing only characters from arg2 from
3650 * the end (right) of arg1 */
3651str
3652STRRtrim2(str *res, const str *arg1, const str *arg2)
3653{
3654 const char *s = *arg1;
3655 size_t len;
3656 size_t n;
3657 size_t nchars;
3658 int *chars;
3659
3660 if (GDK_STRNIL(s)) {
3661 *res = GDKstrdup(str_nil);
3662 } else {
3663 chars = trimchars(*arg2, &nchars);
3664 if (chars == NULL)
3665 throw(MAL, "str.trim", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3666 len = strlen(s);
3667 n = rstrip(s, len, chars, nchars);
3668 GDKfree(chars);
3669 *res = GDKstrndup(s, n);
3670 }
3671 if (*res == NULL)
3672 throw(MAL, "str.rtrim", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3673 return MAL_SUCCEED;
3674}
3675
3676static char *
3677pad(const char *s, const char *pad, int len, int left)
3678{
3679 size_t slen, padlen, repeats, residual, i;
3680 char *res;
3681
3682 if (GDK_STRNIL(s) || GDK_STRNIL(pad) || is_int_nil(len))
3683 return GDKstrdup(str_nil);
3684
3685 if (len < 0)
3686 len = 0;
3687
3688 slen = UTF8_strlen(s);
3689
3690 if (slen > (size_t) len) {
3691 /* truncate */
3692 pad = UTF8_strtail(s, len);
3693 return GDKstrndup(s, pad - s);
3694 }
3695
3696 padlen = UTF8_strlen(pad);
3697 if (slen == (size_t) len || padlen == 0) {
3698 /* nothing to do (no padding if there is no pad string) */
3699 return GDKstrdup(s);
3700 }
3701
3702 repeats = ((size_t) len - slen) / padlen;
3703 residual = ((size_t) len - slen) % padlen;
3704 if (residual > 0)
3705 residual = (size_t) (UTF8_strtail(pad, (int) residual) - pad);
3706 padlen = strlen(pad);
3707 slen = strlen(s);
3708 res = GDKmalloc(slen + repeats * padlen + residual + 1);
3709 if (res == NULL)
3710 return NULL;
3711 if (left) {
3712 for (i = 0; i < repeats; i++)
3713 memcpy(res + i * padlen, pad, padlen);
3714 if (residual > 0)
3715 memcpy(res + repeats * padlen, pad, residual);
3716 if (slen > 0)
3717 memcpy(res + repeats * padlen + residual, s, slen);
3718 } else {
3719 if (slen > 0)
3720 memcpy(res, s, slen);
3721 for (i = 0; i < repeats; i++)
3722 memcpy(res + slen + i * padlen, pad, padlen);
3723 if (residual > 0)
3724 memcpy(res + slen + repeats * padlen, pad, residual);
3725 }
3726 res[repeats * padlen + residual + slen] = 0;
3727 return res;
3728}
3729
3730/* Fill up 'arg1' to length 'len' by prepending whitespaces.
3731 * If 'arg1' is already longer than 'len', then it's truncated on the right
3732 * (NB: this is the PostgreSQL definition).
3733 *
3734 * Example: lpad('hi', 5)
3735 * Result: ' hi'
3736 */
3737str
3738STRLpad(str *res, const str *arg1, const int *len)
3739{
3740 *res = pad(*arg1, " ", *len, 1);
3741 if (*res == NULL)
3742 throw(MAL, "str.lpad", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3743 return MAL_SUCCEED;
3744}
3745
3746/* Fill up 'arg1' to length 'len' by appending whitespaces.
3747 * If 'arg1' is already longer than 'len', then it's truncated (on the right)
3748 * (NB: this is the PostgreSQL definition).
3749 *
3750 * Example: rpad('hi', 5)
3751 * Result: 'hi '
3752 */
3753str
3754STRRpad(str *res, const str *arg1, const int *len)
3755{
3756 *res = pad(*arg1, " ", *len, 0);
3757 if (*res == NULL)
3758 throw(MAL, "str.rpad", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3759 return MAL_SUCCEED;
3760}
3761
3762/* Fill up 'arg1' to length 'len' by prepending characters from 'arg2'
3763 * If 'arg1' is already longer than 'len', then it's truncated on the right
3764 * (NB: this is the PostgreSQL definition).
3765 *
3766 * Example: lpad('hi', 5, 'xy')
3767 * Result: xyxhi
3768 */
3769str
3770STRLpad2(str *res, const str *arg1, const int *len, const str *arg2)
3771{
3772 if (**arg2 == 0)
3773 throw(MAL, "str.lpad", SQLSTATE(42000) ILLEGAL_ARGUMENT ": pad string is empty");
3774
3775 *res = pad(*arg1, *arg2, *len, 1);
3776 if (*res == NULL)
3777 throw(MAL, "str.lpad", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3778 return MAL_SUCCEED;
3779}
3780
3781/* Fill up 'arg1' to length 'len' by appending characters from 'arg2'
3782 * If 'arg1' is already longer than 'len', then it's truncated (on the right)
3783 * (NB: this is the PostgreSQL definition).
3784 *
3785 * Example: rpad('hi', 5, 'xy')
3786 * Result: hixyx
3787 */
3788str
3789STRRpad2(str *res, const str *arg1, const int *len, const str *arg2)
3790{
3791 if (**arg2 == 0)
3792 throw(MAL, "str.rpad", SQLSTATE(42000) ILLEGAL_ARGUMENT ": pad string is empty");
3793
3794 *res = pad(*arg1, *arg2, *len, 0);
3795 if (*res == NULL)
3796 throw(MAL, "str.rpad", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3797 return MAL_SUCCEED;
3798}
3799
3800str
3801STRSubstitute(str *res, const str *arg1, const str *arg2, const str *arg3, const bit *g)
3802{
3803 const char *s = *arg1;
3804 const char *src = *arg2 ? *arg2 : "";
3805 const char *dst = *arg3 ? *arg3 : "";
3806 int repeat = *g;
3807 size_t lsrc = strlen(src);
3808 size_t ldst = strlen(dst);
3809 size_t l = strLen(s);
3810 size_t n;
3811 char *buf;
3812 const char *pfnd;
3813 char *fnd;
3814
3815 if (s == NULL || strcmp(s, str_nil) == 0) {
3816 if ((*res = GDKstrdup(str_nil)) == NULL)
3817 throw(MAL, "str.substitute", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3818 return MAL_SUCCEED;
3819 }
3820
3821 n = l + ldst;
3822 if (repeat && ldst > lsrc && lsrc) {
3823 n = (ldst * l) / lsrc; /* max length */
3824 }
3825 buf = *res = GDKmalloc(n);
3826 if (*res == NULL)
3827 throw(MAL, "str.substitute", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3828
3829 pfnd = s;
3830 if (lsrc == 0)
3831 lsrc = 1; /* make sure we make progress */
3832 do {
3833 fnd = strstr(pfnd, src);
3834 if (fnd == NULL)
3835 break;
3836 n = fnd - pfnd;
3837 if (n > 0) {
3838 strncpy(buf, pfnd, n);
3839 buf += n;
3840 }
3841 if (ldst > 0) {
3842 strncpy(buf, dst, ldst);
3843 buf += ldst;
3844 }
3845 if (*fnd == 0)
3846 break;
3847 pfnd = fnd + lsrc;
3848 } while (repeat);
3849 strcpy(buf, pfnd);
3850 return MAL_SUCCEED;
3851}
3852
3853str
3854STRascii(int *ret, const str *s){
3855 int offset=0;
3856 return STRWChrAt(ret,s,&offset);
3857}
3858
3859str
3860STRsubstringTail(str *ret, const str *s, const int *start)
3861{
3862 int offset= *start;
3863 if( offset <1) offset =1;
3864 offset--;
3865 return STRTail(ret, s, &offset);
3866}
3867
3868str
3869STRsubstring(str *ret, const str *s, const int *start, const int *l)
3870{
3871 int offset= *start;
3872 if( offset <1) offset =1;
3873 offset--;
3874 return STRSubString(ret, s, &offset, l);
3875}
3876str
3877STRprefix(str *ret, const str *s, const int *l){
3878 int start =0;
3879 return STRSubString(ret,s,&start,l);
3880}
3881str
3882STRsuffix(str *ret, const str *s, const int *l){
3883 int start = (int) (strlen(*s)- *l);
3884 return STRSubString(ret,s,&start,l);
3885}
3886
3887str
3888STRlocate2(int *ret, const str *needle, const str *haystack, const int *start)
3889{
3890 int off = *start <= 0 ? 1 : *start;
3891 char *s = UTF8_strtail(*haystack, off - 1);
3892 int res;
3893
3894 STRstrSearch(&res, &s, needle);
3895 *ret = res >= 0 ? res + off : 0;
3896 return MAL_SUCCEED;
3897}
3898
3899str
3900STRlocate(int *ret, const str *needle, const str *haystack)
3901{
3902 int p = 1;
3903 return STRlocate2(ret, needle, haystack, &p);
3904}
3905
3906str
3907STRinsert(str *ret, const str *s, const int *start, const int *l, const str *s2)
3908{
3909 str v;
3910 int strt = *start;
3911 if (strcmp(*s2, str_nil) == 0 || strcmp(*s, str_nil) == 0) {
3912 if ((*ret = GDKstrdup(str_nil)) == NULL)
3913 throw(MAL, "str.insert", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3914 } else {
3915 size_t l1 = strlen(*s);
3916 size_t l2 = strlen(*s2);
3917
3918 if (l1 + l2 + 1 >= INT_MAX) {
3919 throw(MAL, "str.insert", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3920 }
3921 if (*l < 0)
3922 throw(MAL, "str.insert", SQLSTATE(42000) ILLEGAL_ARGUMENT);
3923 if (strt < 0) {
3924 if ((size_t) -strt <= l1)
3925 strt = (int) (l1 + strt);
3926 else
3927 strt = 0;
3928 }
3929 if ((size_t) strt > l1)
3930 strt = (int) l1;
3931 v = *ret = GDKmalloc(strlen(*s) + strlen(*s2) + 1);
3932 if (v == NULL)
3933 throw(MAL, "str.insert", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3934 if (strt > 0)
3935 strncpy(v, *s, strt);
3936 v[strt] = 0;
3937 strcpy(v + strt, *s2);
3938 if (strt + *l < (int) l1)
3939 strcat(v, *s + strt + *l);
3940 }
3941 return MAL_SUCCEED;
3942}
3943
3944str
3945STRreplace(str *ret, const str *s1, const str *s2, const str *s3){
3946 bit flag= TRUE;
3947 return STRSubstitute(ret,s1,s2,s3,&flag);
3948}
3949
3950str
3951STRrepeat(str *ret, const str *s, const int *c)
3952{
3953 str t;
3954 int i;
3955 size_t l;
3956
3957 if (*c < 0 || strcmp(*s, str_nil) == 0) {
3958 if ((*ret = GDKstrdup(str_nil)) == NULL)
3959 throw(MAL, "str.repeat", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3960 } else {
3961 l = strlen(*s);
3962 if (l >= INT_MAX)
3963 throw(MAL, "str.repeat", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3964 t = *ret = GDKmalloc( *c * l + 1);
3965
3966 if (!t)
3967 throw(MAL, "str.repeat", SQLSTATE(HY001) MAL_MALLOC_FAIL);
3968 *t = 0;
3969 for(i = *c; i>0; i--, t += l)
3970 strcpy(t, *s);
3971 }
3972 return MAL_SUCCEED;
3973}
3974str
3975STRspace(str *ret, const int *l){
3976 char buf[]= " ", *s= buf;
3977 return STRrepeat(ret,&s,l);
3978}
3979