msdosfs_conv.c revision 1.11 1 1.11 mlelstv /* $NetBSD: msdosfs_conv.c,v 1.11 2016/01/30 09:59:27 mlelstv Exp $ */
2 1.1 jdolecek
3 1.1 jdolecek /*-
4 1.1 jdolecek * Copyright (C) 1995, 1997 Wolfgang Solfrank.
5 1.1 jdolecek * Copyright (C) 1995, 1997 TooLs GmbH.
6 1.1 jdolecek * All rights reserved.
7 1.1 jdolecek * Original code by Paul Popelka (paulp (at) uts.amdahl.com) (see below).
8 1.1 jdolecek *
9 1.1 jdolecek * Redistribution and use in source and binary forms, with or without
10 1.1 jdolecek * modification, are permitted provided that the following conditions
11 1.1 jdolecek * are met:
12 1.1 jdolecek * 1. Redistributions of source code must retain the above copyright
13 1.1 jdolecek * notice, this list of conditions and the following disclaimer.
14 1.1 jdolecek * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 jdolecek * notice, this list of conditions and the following disclaimer in the
16 1.1 jdolecek * documentation and/or other materials provided with the distribution.
17 1.1 jdolecek * 3. All advertising materials mentioning features or use of this software
18 1.1 jdolecek * must display the following acknowledgement:
19 1.1 jdolecek * This product includes software developed by TooLs GmbH.
20 1.1 jdolecek * 4. The name of TooLs GmbH may not be used to endorse or promote products
21 1.1 jdolecek * derived from this software without specific prior written permission.
22 1.1 jdolecek *
23 1.1 jdolecek * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
24 1.1 jdolecek * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 1.1 jdolecek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 1.1 jdolecek * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 1.1 jdolecek * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 1.1 jdolecek * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29 1.1 jdolecek * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 1.1 jdolecek * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31 1.1 jdolecek * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32 1.1 jdolecek * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 1.1 jdolecek */
34 1.1 jdolecek /*
35 1.1 jdolecek * Written by Paul Popelka (paulp (at) uts.amdahl.com)
36 1.1 jdolecek *
37 1.1 jdolecek * You can do anything you want with this software, just don't say you wrote
38 1.1 jdolecek * it, and don't remove this notice.
39 1.1 jdolecek *
40 1.1 jdolecek * This software is provided "as is".
41 1.1 jdolecek *
42 1.1 jdolecek * The author supplies this software to be publicly redistributed on the
43 1.1 jdolecek * understanding that the author is not responsible for the correct
44 1.1 jdolecek * functioning of this software in any circumstances and is not liable for
45 1.1 jdolecek * any damages caused by this software.
46 1.1 jdolecek *
47 1.1 jdolecek * October 1992
48 1.11 mlelstv *
49 1.11 mlelstv *
50 1.11 mlelstv * Unicode 5.0 case folding taken from
51 1.11 mlelstv *
52 1.11 mlelstv * http://www.unicode.org/Public/5.0.0/ucd/CaseFolding.txt
53 1.11 mlelstv *
54 1.11 mlelstv * Unicode Character Database
55 1.11 mlelstv * Copyright (c) 1991-2006 Unicode, Inc.
56 1.11 mlelstv * For terms of use, see http://www.unicode.org/terms_of_use.html
57 1.11 mlelstv * For documentation, see UCD.html
58 1.1 jdolecek */
59 1.1 jdolecek
60 1.8 christos #if HAVE_NBTOOL_CONFIG_H
61 1.8 christos #include "nbtool_config.h"
62 1.8 christos #endif
63 1.8 christos
64 1.1 jdolecek #include <sys/cdefs.h>
65 1.11 mlelstv __KERNEL_RCSID(0, "$NetBSD: msdosfs_conv.c,v 1.11 2016/01/30 09:59:27 mlelstv Exp $");
66 1.1 jdolecek
67 1.1 jdolecek /*
68 1.1 jdolecek * System include files.
69 1.1 jdolecek */
70 1.1 jdolecek #include <sys/param.h>
71 1.9 christos #include <sys/time.h>
72 1.11 mlelstv #include <sys/endian.h>
73 1.9 christos #ifdef _KERNEL
74 1.9 christos #include <sys/dirent.h>
75 1.1 jdolecek #include <sys/systm.h>
76 1.1 jdolecek #include <sys/kernel.h>
77 1.1 jdolecek #include <sys/vnode.h>
78 1.9 christos #else
79 1.8 christos #include <stdio.h>
80 1.10 martin #include <string.h>
81 1.9 christos #include <dirent.h>
82 1.9 christos #include <sys/queue.h>
83 1.8 christos #endif
84 1.10 martin #include <dev/clock_subr.h>
85 1.1 jdolecek
86 1.1 jdolecek /*
87 1.1 jdolecek * MSDOSFS include files.
88 1.1 jdolecek */
89 1.1 jdolecek #include <fs/msdosfs/direntry.h>
90 1.1 jdolecek #include <fs/msdosfs/denode.h>
91 1.1 jdolecek
92 1.11 mlelstv static int invalidname(const u_int16_t *, int);
93 1.11 mlelstv
94 1.11 mlelstv static int ucs2utf8(const u_int16_t *, u_int8_t *, int);
95 1.11 mlelstv static int utf8ucs2(const u_int8_t *, int, u_int16_t *);
96 1.11 mlelstv
97 1.11 mlelstv static int ucs2utf8str(const u_int16_t *, int, u_int8_t *, int);
98 1.11 mlelstv static int utf8ucs2str(const u_int8_t *, int, u_int16_t *, int);
99 1.11 mlelstv static int ucs2char8str(const u_int16_t *, int, u_int8_t *, int);
100 1.11 mlelstv static int char8ucs2str(const u_int8_t *, int, u_int16_t *, int);
101 1.11 mlelstv
102 1.11 mlelstv static void ucs2pad(u_int16_t *, int, int);
103 1.11 mlelstv
104 1.11 mlelstv static u_int16_t ucs2fold(u_int16_t);
105 1.11 mlelstv static int ucs2match(u_int16_t *, u_int16_t *, int n);
106 1.11 mlelstv static int char8match(u_int16_t *, u_int16_t *, int n);
107 1.11 mlelstv
108 1.1 jdolecek /*
109 1.10 martin * The number of seconds between Jan 1, 1970 and Jan 1, 1980. In that
110 1.10 martin * interval there were 8 regular years and 2 leap years.
111 1.1 jdolecek */
112 1.10 martin #define DOSBIASYEAR 1980
113 1.10 martin #define SECONDSTO1980 (((8 * 365) + (2 * 366)) * (24 * 60 * 60))
114 1.1 jdolecek /*
115 1.10 martin * msdos fs can not store dates beyound the year 2234
116 1.1 jdolecek */
117 1.10 martin #define DOSMAXYEAR ((DD_YEAR_MASK >> DD_YEAR_SHIFT) + DOSBIASYEAR)
118 1.1 jdolecek
119 1.1 jdolecek /*
120 1.1 jdolecek * Convert the unix version of time to dos's idea of time to be used in
121 1.1 jdolecek * file timestamps. The passed in unix time is assumed to be in GMT.
122 1.1 jdolecek */
123 1.1 jdolecek void
124 1.6 dsl unix2dostime(const struct timespec *tsp, int gmtoff, u_int16_t *ddp, u_int16_t *dtp, u_int8_t *dhp)
125 1.1 jdolecek {
126 1.1 jdolecek u_long t;
127 1.10 martin struct clock_ymdhms ymd;
128 1.10 martin
129 1.10 martin t = tsp->tv_sec + gmtoff; /* time zone correction */
130 1.1 jdolecek
131 1.1 jdolecek /*
132 1.10 martin * DOS timestamps can not represent dates before 1980.
133 1.10 martin */
134 1.10 martin if (t < SECONDSTO1980)
135 1.10 martin goto invalid_dos_date;
136 1.10 martin
137 1.10 martin /*
138 1.10 martin * DOS granularity is 2 seconds
139 1.1 jdolecek */
140 1.1 jdolecek t &= ~1;
141 1.10 martin
142 1.10 martin /*
143 1.10 martin * Convert to year/month/day/.. format
144 1.10 martin */
145 1.10 martin clock_secs_to_ymdhms(t, &ymd);
146 1.10 martin if (ymd.dt_year > DOSMAXYEAR)
147 1.10 martin goto invalid_dos_date;
148 1.10 martin
149 1.10 martin /*
150 1.10 martin * Now transform to DOS format
151 1.10 martin */
152 1.10 martin *ddp = (ymd.dt_day << DD_DAY_SHIFT)
153 1.10 martin + (ymd.dt_mon << DD_MONTH_SHIFT)
154 1.10 martin + ((ymd.dt_year - DOSBIASYEAR) << DD_YEAR_SHIFT);
155 1.10 martin if (dhp)
156 1.10 martin *dhp = (tsp->tv_sec & 1) * 100 + tsp->tv_nsec / 10000000;
157 1.10 martin if (dtp)
158 1.10 martin *dtp = (((t / 2) % 30) << DT_2SECONDS_SHIFT)
159 1.1 jdolecek + (((t / 60) % 60) << DT_MINUTES_SHIFT)
160 1.1 jdolecek + (((t / 3600) % 24) << DT_HOURS_SHIFT);
161 1.10 martin return;
162 1.1 jdolecek
163 1.10 martin invalid_dos_date:
164 1.10 martin *ddp = 0;
165 1.1 jdolecek if (dtp)
166 1.10 martin *dtp = 0;
167 1.1 jdolecek if (dhp)
168 1.10 martin *dhp = 0;
169 1.1 jdolecek }
170 1.1 jdolecek
171 1.1 jdolecek /*
172 1.1 jdolecek * Convert from dos' idea of time to unix'. This will probably only be
173 1.1 jdolecek * called from the stat(), and fstat() system calls and so probably need
174 1.1 jdolecek * not be too efficient.
175 1.1 jdolecek */
176 1.1 jdolecek void
177 1.6 dsl dos2unixtime(u_int dd, u_int dt, u_int dh, int gmtoff, struct timespec *tsp)
178 1.1 jdolecek {
179 1.10 martin time_t seconds;
180 1.10 martin struct clock_ymdhms ymd;
181 1.1 jdolecek
182 1.1 jdolecek if (dd == 0) {
183 1.1 jdolecek /*
184 1.1 jdolecek * Uninitialized field, return the epoch.
185 1.1 jdolecek */
186 1.1 jdolecek tsp->tv_sec = 0;
187 1.1 jdolecek tsp->tv_nsec = 0;
188 1.1 jdolecek return;
189 1.1 jdolecek }
190 1.10 martin
191 1.10 martin memset(&ymd, 0, sizeof(ymd));
192 1.10 martin ymd.dt_year = ((dd & DD_YEAR_MASK) >> DD_YEAR_SHIFT) + 1980 ;
193 1.10 martin ymd.dt_mon = ((dd & DD_MONTH_MASK) >> DD_MONTH_SHIFT);
194 1.10 martin ymd.dt_day = ((dd & DD_DAY_MASK) >> DD_DAY_SHIFT);
195 1.10 martin ymd.dt_hour = (dt & DT_HOURS_MASK) >> DT_HOURS_SHIFT;
196 1.10 martin ymd.dt_min = (dt & DT_MINUTES_MASK) >> DT_MINUTES_SHIFT;
197 1.10 martin ymd.dt_sec = ((dt & DT_2SECONDS_MASK) >> DT_2SECONDS_SHIFT) * 2;
198 1.10 martin
199 1.10 martin seconds = clock_ymdhms_to_secs(&ymd);
200 1.10 martin
201 1.10 martin tsp->tv_sec = seconds;
202 1.2 itojun tsp->tv_sec -= gmtoff; /* time zone correction */
203 1.1 jdolecek tsp->tv_nsec = (dh % 100) * 10000000;
204 1.1 jdolecek }
205 1.1 jdolecek
206 1.1 jdolecek static const u_char
207 1.1 jdolecek unix2dos[256] = {
208 1.1 jdolecek 0, 0, 0, 0, 0, 0, 0, 0, /* 00-07 */
209 1.1 jdolecek 0, 0, 0, 0, 0, 0, 0, 0, /* 08-0f */
210 1.1 jdolecek 0, 0, 0, 0, 0, 0, 0, 0, /* 10-17 */
211 1.1 jdolecek 0, 0, 0, 0, 0, 0, 0, 0, /* 18-1f */
212 1.1 jdolecek 0, '!', 0, '#', '$', '%', '&', '\'', /* 20-27 */
213 1.1 jdolecek '(', ')', 0, '+', 0, '-', 0, 0, /* 28-2f */
214 1.1 jdolecek '0', '1', '2', '3', '4', '5', '6', '7', /* 30-37 */
215 1.1 jdolecek '8', '9', 0, 0, 0, 0, 0, 0, /* 38-3f */
216 1.1 jdolecek '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 40-47 */
217 1.1 jdolecek 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 48-4f */
218 1.1 jdolecek 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 50-57 */
219 1.1 jdolecek 'X', 'Y', 'Z', 0, 0, 0, '^', '_', /* 58-5f */
220 1.1 jdolecek '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 60-67 */
221 1.1 jdolecek 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 68-6f */
222 1.1 jdolecek 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 70-77 */
223 1.1 jdolecek 'X', 'Y', 'Z', '{', 0, '}', '~', 0, /* 78-7f */
224 1.1 jdolecek 0, 0, 0, 0, 0, 0, 0, 0, /* 80-87 */
225 1.1 jdolecek 0, 0, 0, 0, 0, 0, 0, 0, /* 88-8f */
226 1.1 jdolecek 0, 0, 0, 0, 0, 0, 0, 0, /* 90-97 */
227 1.1 jdolecek 0, 0, 0, 0, 0, 0, 0, 0, /* 98-9f */
228 1.1 jdolecek 0, 0xad, 0xbd, 0x9c, 0xcf, 0xbe, 0xdd, 0xf5, /* a0-a7 */
229 1.1 jdolecek 0xf9, 0xb8, 0xa6, 0xae, 0xaa, 0xf0, 0xa9, 0xee, /* a8-af */
230 1.1 jdolecek 0xf8, 0xf1, 0xfd, 0xfc, 0xef, 0xe6, 0xf4, 0xfa, /* b0-b7 */
231 1.1 jdolecek 0xf7, 0xfb, 0xa7, 0xaf, 0xac, 0xab, 0xf3, 0xa8, /* b8-bf */
232 1.1 jdolecek 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* c0-c7 */
233 1.1 jdolecek 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* c8-cf */
234 1.1 jdolecek 0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0x9e, /* d0-d7 */
235 1.1 jdolecek 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0xe1, /* d8-df */
236 1.1 jdolecek 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* e0-e7 */
237 1.1 jdolecek 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* e8-ef */
238 1.1 jdolecek 0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0xf6, /* f0-f7 */
239 1.1 jdolecek 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0x98, /* f8-ff */
240 1.1 jdolecek };
241 1.1 jdolecek
242 1.1 jdolecek static const u_char
243 1.1 jdolecek dos2unix[256] = {
244 1.1 jdolecek '?', '?', '?', '?', '?', '?', '?', '?', /* 00-07 */
245 1.1 jdolecek '?', '?', '?', '?', '?', '?', '?', '?', /* 08-0f */
246 1.1 jdolecek '?', '?', '?', '?', '?', '?', '?', '?', /* 10-17 */
247 1.1 jdolecek '?', '?', '?', '?', '?', '?', '?', '?', /* 18-1f */
248 1.1 jdolecek ' ', '!', '"', '#', '$', '%', '&', '\'', /* 20-27 */
249 1.1 jdolecek '(', ')', '*', '+', ',', '-', '.', '/', /* 28-2f */
250 1.1 jdolecek '0', '1', '2', '3', '4', '5', '6', '7', /* 30-37 */
251 1.1 jdolecek '8', '9', ':', ';', '<', '=', '>', '?', /* 38-3f */
252 1.1 jdolecek '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 40-47 */
253 1.1 jdolecek 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 48-4f */
254 1.1 jdolecek 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 50-57 */
255 1.1 jdolecek 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', /* 58-5f */
256 1.1 jdolecek '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* 60-67 */
257 1.1 jdolecek 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* 68-6f */
258 1.1 jdolecek 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 70-77 */
259 1.1 jdolecek 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, /* 78-7f */
260 1.1 jdolecek 0xc7, 0xfc, 0xe9, 0xe2, 0xe4, 0xe0, 0xe5, 0xe7, /* 80-87 */
261 1.1 jdolecek 0xea, 0xeb, 0xe8, 0xef, 0xee, 0xec, 0xc4, 0xc5, /* 88-8f */
262 1.1 jdolecek 0xc9, 0xe6, 0xc6, 0xf4, 0xf6, 0xf2, 0xfb, 0xf9, /* 90-97 */
263 1.1 jdolecek 0xff, 0xd6, 0xdc, 0xf8, 0xa3, 0xd8, 0xd7, '?', /* 98-9f */
264 1.1 jdolecek 0xe1, 0xed, 0xf3, 0xfa, 0xf1, 0xd1, 0xaa, 0xba, /* a0-a7 */
265 1.1 jdolecek 0xbf, 0xae, 0xac, 0xbd, 0xbc, 0xa1, 0xab, 0xbb, /* a8-af */
266 1.1 jdolecek '?', '?', '?', '?', '?', 0xc1, 0xc2, 0xc0, /* b0-b7 */
267 1.1 jdolecek 0xa9, '?', '?', '?', '?', 0xa2, 0xa5, '?', /* b8-bf */
268 1.1 jdolecek '?', '?', '?', '?', '?', '?', 0xe3, 0xc3, /* c0-c7 */
269 1.1 jdolecek '?', '?', '?', '?', '?', '?', '?', 0xa4, /* c8-cf */
270 1.1 jdolecek 0xf0, 0xd0, 0xca, 0xcb, 0xc8, '?', 0xcd, 0xce, /* d0-d7 */
271 1.1 jdolecek 0xcf, '?', '?', '?', '?', 0xa6, 0xcc, '?', /* d8-df */
272 1.1 jdolecek 0xd3, 0xdf, 0xd4, 0xd2, 0xf5, 0xd5, 0xb5, 0xfe, /* e0-e7 */
273 1.1 jdolecek 0xde, 0xda, 0xdb, 0xd9, 0xfd, 0xdd, 0xaf, 0x3f, /* e8-ef */
274 1.1 jdolecek 0xad, 0xb1, '?', 0xbe, 0xb6, 0xa7, 0xf7, 0xb8, /* f0-f7 */
275 1.1 jdolecek 0xb0, 0xa8, 0xb7, 0xb9, 0xb3, 0xb2, '?', '?', /* f8-ff */
276 1.1 jdolecek };
277 1.1 jdolecek
278 1.1 jdolecek static const u_char
279 1.1 jdolecek u2l[256] = {
280 1.1 jdolecek 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 00-07 */
281 1.1 jdolecek 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 08-0f */
282 1.1 jdolecek 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 10-17 */
283 1.1 jdolecek 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 18-1f */
284 1.1 jdolecek ' ', '!', '"', '#', '$', '%', '&', '\'', /* 20-27 */
285 1.1 jdolecek '(', ')', '*', '+', ',', '-', '.', '/', /* 28-2f */
286 1.1 jdolecek '0', '1', '2', '3', '4', '5', '6', '7', /* 30-37 */
287 1.1 jdolecek '8', '9', ':', ';', '<', '=', '>', '?', /* 38-3f */
288 1.1 jdolecek '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* 40-47 */
289 1.1 jdolecek 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* 48-4f */
290 1.1 jdolecek 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 50-57 */
291 1.1 jdolecek 'x', 'y', 'z', '[', '\\', ']', '^', '_', /* 58-5f */
292 1.1 jdolecek '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* 60-67 */
293 1.1 jdolecek 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* 68-6f */
294 1.1 jdolecek 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 70-77 */
295 1.1 jdolecek 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, /* 78-7f */
296 1.1 jdolecek 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 80-87 */
297 1.1 jdolecek 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 88-8f */
298 1.1 jdolecek 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 90-97 */
299 1.1 jdolecek 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 98-9f */
300 1.1 jdolecek 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* a0-a7 */
301 1.1 jdolecek 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* a8-af */
302 1.1 jdolecek 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* b0-b7 */
303 1.1 jdolecek 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* b8-bf */
304 1.1 jdolecek 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* c0-c7 */
305 1.1 jdolecek 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* c8-cf */
306 1.1 jdolecek 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7, /* d0-d7 */
307 1.1 jdolecek 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* d8-df */
308 1.1 jdolecek 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* e0-e7 */
309 1.1 jdolecek 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* e8-ef */
310 1.1 jdolecek 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* f0-f7 */
311 1.1 jdolecek 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* f8-ff */
312 1.1 jdolecek };
313 1.1 jdolecek
314 1.11 mlelstv /* Unicode case folding for codes 0x0000..0xffff */
315 1.11 mlelstv static const u_int16_t
316 1.11 mlelstv foldmap[] = {
317 1.11 mlelstv 0x0041, 0x0061, /* LATIN CAPITAL LETTER A */
318 1.11 mlelstv 0x0042, 0x0062, /* LATIN CAPITAL LETTER B */
319 1.11 mlelstv 0x0043, 0x0063, /* LATIN CAPITAL LETTER C */
320 1.11 mlelstv 0x0044, 0x0064, /* LATIN CAPITAL LETTER D */
321 1.11 mlelstv 0x0045, 0x0065, /* LATIN CAPITAL LETTER E */
322 1.11 mlelstv 0x0046, 0x0066, /* LATIN CAPITAL LETTER F */
323 1.11 mlelstv 0x0047, 0x0067, /* LATIN CAPITAL LETTER G */
324 1.11 mlelstv 0x0048, 0x0068, /* LATIN CAPITAL LETTER H */
325 1.11 mlelstv 0x0049, 0x0069, /* LATIN CAPITAL LETTER I */
326 1.11 mlelstv 0x004A, 0x006A, /* LATIN CAPITAL LETTER J */
327 1.11 mlelstv 0x004B, 0x006B, /* LATIN CAPITAL LETTER K */
328 1.11 mlelstv 0x004C, 0x006C, /* LATIN CAPITAL LETTER L */
329 1.11 mlelstv 0x004D, 0x006D, /* LATIN CAPITAL LETTER M */
330 1.11 mlelstv 0x004E, 0x006E, /* LATIN CAPITAL LETTER N */
331 1.11 mlelstv 0x004F, 0x006F, /* LATIN CAPITAL LETTER O */
332 1.11 mlelstv 0x0050, 0x0070, /* LATIN CAPITAL LETTER P */
333 1.11 mlelstv 0x0051, 0x0071, /* LATIN CAPITAL LETTER Q */
334 1.11 mlelstv 0x0052, 0x0072, /* LATIN CAPITAL LETTER R */
335 1.11 mlelstv 0x0053, 0x0073, /* LATIN CAPITAL LETTER S */
336 1.11 mlelstv 0x0054, 0x0074, /* LATIN CAPITAL LETTER T */
337 1.11 mlelstv 0x0055, 0x0075, /* LATIN CAPITAL LETTER U */
338 1.11 mlelstv 0x0056, 0x0076, /* LATIN CAPITAL LETTER V */
339 1.11 mlelstv 0x0057, 0x0077, /* LATIN CAPITAL LETTER W */
340 1.11 mlelstv 0x0058, 0x0078, /* LATIN CAPITAL LETTER X */
341 1.11 mlelstv 0x0059, 0x0079, /* LATIN CAPITAL LETTER Y */
342 1.11 mlelstv 0x005A, 0x007A, /* LATIN CAPITAL LETTER Z */
343 1.11 mlelstv 0x00B5, 0x03BC, /* MICRO SIGN */
344 1.11 mlelstv 0x00C0, 0x00E0, /* LATIN CAPITAL LETTER A WITH GRAVE */
345 1.11 mlelstv 0x00C1, 0x00E1, /* LATIN CAPITAL LETTER A WITH ACUTE */
346 1.11 mlelstv 0x00C2, 0x00E2, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
347 1.11 mlelstv 0x00C3, 0x00E3, /* LATIN CAPITAL LETTER A WITH TILDE */
348 1.11 mlelstv 0x00C4, 0x00E4, /* LATIN CAPITAL LETTER A WITH DIAERESIS */
349 1.11 mlelstv 0x00C5, 0x00E5, /* LATIN CAPITAL LETTER A WITH RING ABOVE */
350 1.11 mlelstv 0x00C6, 0x00E6, /* LATIN CAPITAL LETTER AE */
351 1.11 mlelstv 0x00C7, 0x00E7, /* LATIN CAPITAL LETTER C WITH CEDILLA */
352 1.11 mlelstv 0x00C8, 0x00E8, /* LATIN CAPITAL LETTER E WITH GRAVE */
353 1.11 mlelstv 0x00C9, 0x00E9, /* LATIN CAPITAL LETTER E WITH ACUTE */
354 1.11 mlelstv 0x00CA, 0x00EA, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
355 1.11 mlelstv 0x00CB, 0x00EB, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
356 1.11 mlelstv 0x00CC, 0x00EC, /* LATIN CAPITAL LETTER I WITH GRAVE */
357 1.11 mlelstv 0x00CD, 0x00ED, /* LATIN CAPITAL LETTER I WITH ACUTE */
358 1.11 mlelstv 0x00CE, 0x00EE, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
359 1.11 mlelstv 0x00CF, 0x00EF, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
360 1.11 mlelstv 0x00D0, 0x00F0, /* LATIN CAPITAL LETTER ETH */
361 1.11 mlelstv 0x00D1, 0x00F1, /* LATIN CAPITAL LETTER N WITH TILDE */
362 1.11 mlelstv 0x00D2, 0x00F2, /* LATIN CAPITAL LETTER O WITH GRAVE */
363 1.11 mlelstv 0x00D3, 0x00F3, /* LATIN CAPITAL LETTER O WITH ACUTE */
364 1.11 mlelstv 0x00D4, 0x00F4, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
365 1.11 mlelstv 0x00D5, 0x00F5, /* LATIN CAPITAL LETTER O WITH TILDE */
366 1.11 mlelstv 0x00D6, 0x00F6, /* LATIN CAPITAL LETTER O WITH DIAERESIS */
367 1.11 mlelstv 0x00D8, 0x00F8, /* LATIN CAPITAL LETTER O WITH STROKE */
368 1.11 mlelstv 0x00D9, 0x00F9, /* LATIN CAPITAL LETTER U WITH GRAVE */
369 1.11 mlelstv 0x00DA, 0x00FA, /* LATIN CAPITAL LETTER U WITH ACUTE */
370 1.11 mlelstv 0x00DB, 0x00FB, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
371 1.11 mlelstv 0x00DC, 0x00FC, /* LATIN CAPITAL LETTER U WITH DIAERESIS */
372 1.11 mlelstv 0x00DD, 0x00FD, /* LATIN CAPITAL LETTER Y WITH ACUTE */
373 1.11 mlelstv 0x00DE, 0x00FE, /* LATIN CAPITAL LETTER THORN */
374 1.11 mlelstv 0x0100, 0x0101, /* LATIN CAPITAL LETTER A WITH MACRON */
375 1.11 mlelstv 0x0102, 0x0103, /* LATIN CAPITAL LETTER A WITH BREVE */
376 1.11 mlelstv 0x0104, 0x0105, /* LATIN CAPITAL LETTER A WITH OGONEK */
377 1.11 mlelstv 0x0106, 0x0107, /* LATIN CAPITAL LETTER C WITH ACUTE */
378 1.11 mlelstv 0x0108, 0x0109, /* LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
379 1.11 mlelstv 0x010A, 0x010B, /* LATIN CAPITAL LETTER C WITH DOT ABOVE */
380 1.11 mlelstv 0x010C, 0x010D, /* LATIN CAPITAL LETTER C WITH CARON */
381 1.11 mlelstv 0x010E, 0x010F, /* LATIN CAPITAL LETTER D WITH CARON */
382 1.11 mlelstv 0x0110, 0x0111, /* LATIN CAPITAL LETTER D WITH STROKE */
383 1.11 mlelstv 0x0112, 0x0113, /* LATIN CAPITAL LETTER E WITH MACRON */
384 1.11 mlelstv 0x0114, 0x0115, /* LATIN CAPITAL LETTER E WITH BREVE */
385 1.11 mlelstv 0x0116, 0x0117, /* LATIN CAPITAL LETTER E WITH DOT ABOVE */
386 1.11 mlelstv 0x0118, 0x0119, /* LATIN CAPITAL LETTER E WITH OGONEK */
387 1.11 mlelstv 0x011A, 0x011B, /* LATIN CAPITAL LETTER E WITH CARON */
388 1.11 mlelstv 0x011C, 0x011D, /* LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
389 1.11 mlelstv 0x011E, 0x011F, /* LATIN CAPITAL LETTER G WITH BREVE */
390 1.11 mlelstv 0x0120, 0x0121, /* LATIN CAPITAL LETTER G WITH DOT ABOVE */
391 1.11 mlelstv 0x0122, 0x0123, /* LATIN CAPITAL LETTER G WITH CEDILLA */
392 1.11 mlelstv 0x0124, 0x0125, /* LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
393 1.11 mlelstv 0x0126, 0x0127, /* LATIN CAPITAL LETTER H WITH STROKE */
394 1.11 mlelstv 0x0128, 0x0129, /* LATIN CAPITAL LETTER I WITH TILDE */
395 1.11 mlelstv 0x012A, 0x012B, /* LATIN CAPITAL LETTER I WITH MACRON */
396 1.11 mlelstv 0x012C, 0x012D, /* LATIN CAPITAL LETTER I WITH BREVE */
397 1.11 mlelstv 0x012E, 0x012F, /* LATIN CAPITAL LETTER I WITH OGONEK */
398 1.11 mlelstv 0x0132, 0x0133, /* LATIN CAPITAL LIGATURE IJ */
399 1.11 mlelstv 0x0134, 0x0135, /* LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
400 1.11 mlelstv 0x0136, 0x0137, /* LATIN CAPITAL LETTER K WITH CEDILLA */
401 1.11 mlelstv 0x0139, 0x013A, /* LATIN CAPITAL LETTER L WITH ACUTE */
402 1.11 mlelstv 0x013B, 0x013C, /* LATIN CAPITAL LETTER L WITH CEDILLA */
403 1.11 mlelstv 0x013D, 0x013E, /* LATIN CAPITAL LETTER L WITH CARON */
404 1.11 mlelstv 0x013F, 0x0140, /* LATIN CAPITAL LETTER L WITH MIDDLE DOT */
405 1.11 mlelstv 0x0141, 0x0142, /* LATIN CAPITAL LETTER L WITH STROKE */
406 1.11 mlelstv 0x0143, 0x0144, /* LATIN CAPITAL LETTER N WITH ACUTE */
407 1.11 mlelstv 0x0145, 0x0146, /* LATIN CAPITAL LETTER N WITH CEDILLA */
408 1.11 mlelstv 0x0147, 0x0148, /* LATIN CAPITAL LETTER N WITH CARON */
409 1.11 mlelstv 0x014A, 0x014B, /* LATIN CAPITAL LETTER ENG */
410 1.11 mlelstv 0x014C, 0x014D, /* LATIN CAPITAL LETTER O WITH MACRON */
411 1.11 mlelstv 0x014E, 0x014F, /* LATIN CAPITAL LETTER O WITH BREVE */
412 1.11 mlelstv 0x0150, 0x0151, /* LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
413 1.11 mlelstv 0x0152, 0x0153, /* LATIN CAPITAL LIGATURE OE */
414 1.11 mlelstv 0x0154, 0x0155, /* LATIN CAPITAL LETTER R WITH ACUTE */
415 1.11 mlelstv 0x0156, 0x0157, /* LATIN CAPITAL LETTER R WITH CEDILLA */
416 1.11 mlelstv 0x0158, 0x0159, /* LATIN CAPITAL LETTER R WITH CARON */
417 1.11 mlelstv 0x015A, 0x015B, /* LATIN CAPITAL LETTER S WITH ACUTE */
418 1.11 mlelstv 0x015C, 0x015D, /* LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
419 1.11 mlelstv 0x015E, 0x015F, /* LATIN CAPITAL LETTER S WITH CEDILLA */
420 1.11 mlelstv 0x0160, 0x0161, /* LATIN CAPITAL LETTER S WITH CARON */
421 1.11 mlelstv 0x0162, 0x0163, /* LATIN CAPITAL LETTER T WITH CEDILLA */
422 1.11 mlelstv 0x0164, 0x0165, /* LATIN CAPITAL LETTER T WITH CARON */
423 1.11 mlelstv 0x0166, 0x0167, /* LATIN CAPITAL LETTER T WITH STROKE */
424 1.11 mlelstv 0x0168, 0x0169, /* LATIN CAPITAL LETTER U WITH TILDE */
425 1.11 mlelstv 0x016A, 0x016B, /* LATIN CAPITAL LETTER U WITH MACRON */
426 1.11 mlelstv 0x016C, 0x016D, /* LATIN CAPITAL LETTER U WITH BREVE */
427 1.11 mlelstv 0x016E, 0x016F, /* LATIN CAPITAL LETTER U WITH RING ABOVE */
428 1.11 mlelstv 0x0170, 0x0171, /* LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
429 1.11 mlelstv 0x0172, 0x0173, /* LATIN CAPITAL LETTER U WITH OGONEK */
430 1.11 mlelstv 0x0174, 0x0175, /* LATIN CAPITAL LETTER W WITH CIRCUMFLEX */
431 1.11 mlelstv 0x0176, 0x0177, /* LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */
432 1.11 mlelstv 0x0178, 0x00FF, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
433 1.11 mlelstv 0x0179, 0x017A, /* LATIN CAPITAL LETTER Z WITH ACUTE */
434 1.11 mlelstv 0x017B, 0x017C, /* LATIN CAPITAL LETTER Z WITH DOT ABOVE */
435 1.11 mlelstv 0x017D, 0x017E, /* LATIN CAPITAL LETTER Z WITH CARON */
436 1.11 mlelstv 0x017F, 0x0073, /* LATIN SMALL LETTER LONG S */
437 1.11 mlelstv 0x0181, 0x0253, /* LATIN CAPITAL LETTER B WITH HOOK */
438 1.11 mlelstv 0x0182, 0x0183, /* LATIN CAPITAL LETTER B WITH TOPBAR */
439 1.11 mlelstv 0x0184, 0x0185, /* LATIN CAPITAL LETTER TONE SIX */
440 1.11 mlelstv 0x0186, 0x0254, /* LATIN CAPITAL LETTER OPEN O */
441 1.11 mlelstv 0x0187, 0x0188, /* LATIN CAPITAL LETTER C WITH HOOK */
442 1.11 mlelstv 0x0189, 0x0256, /* LATIN CAPITAL LETTER AFRICAN D */
443 1.11 mlelstv 0x018A, 0x0257, /* LATIN CAPITAL LETTER D WITH HOOK */
444 1.11 mlelstv 0x018B, 0x018C, /* LATIN CAPITAL LETTER D WITH TOPBAR */
445 1.11 mlelstv 0x018E, 0x01DD, /* LATIN CAPITAL LETTER REVERSED E */
446 1.11 mlelstv 0x018F, 0x0259, /* LATIN CAPITAL LETTER SCHWA */
447 1.11 mlelstv 0x0190, 0x025B, /* LATIN CAPITAL LETTER OPEN E */
448 1.11 mlelstv 0x0191, 0x0192, /* LATIN CAPITAL LETTER F WITH HOOK */
449 1.11 mlelstv 0x0193, 0x0260, /* LATIN CAPITAL LETTER G WITH HOOK */
450 1.11 mlelstv 0x0194, 0x0263, /* LATIN CAPITAL LETTER GAMMA */
451 1.11 mlelstv 0x0196, 0x0269, /* LATIN CAPITAL LETTER IOTA */
452 1.11 mlelstv 0x0197, 0x0268, /* LATIN CAPITAL LETTER I WITH STROKE */
453 1.11 mlelstv 0x0198, 0x0199, /* LATIN CAPITAL LETTER K WITH HOOK */
454 1.11 mlelstv 0x019C, 0x026F, /* LATIN CAPITAL LETTER TURNED M */
455 1.11 mlelstv 0x019D, 0x0272, /* LATIN CAPITAL LETTER N WITH LEFT HOOK */
456 1.11 mlelstv 0x019F, 0x0275, /* LATIN CAPITAL LETTER O WITH MIDDLE TILDE */
457 1.11 mlelstv 0x01A0, 0x01A1, /* LATIN CAPITAL LETTER O WITH HORN */
458 1.11 mlelstv 0x01A2, 0x01A3, /* LATIN CAPITAL LETTER OI */
459 1.11 mlelstv 0x01A4, 0x01A5, /* LATIN CAPITAL LETTER P WITH HOOK */
460 1.11 mlelstv 0x01A6, 0x0280, /* LATIN LETTER YR */
461 1.11 mlelstv 0x01A7, 0x01A8, /* LATIN CAPITAL LETTER TONE TWO */
462 1.11 mlelstv 0x01A9, 0x0283, /* LATIN CAPITAL LETTER ESH */
463 1.11 mlelstv 0x01AC, 0x01AD, /* LATIN CAPITAL LETTER T WITH HOOK */
464 1.11 mlelstv 0x01AE, 0x0288, /* LATIN CAPITAL LETTER T WITH RETROFLEX HOOK */
465 1.11 mlelstv 0x01AF, 0x01B0, /* LATIN CAPITAL LETTER U WITH HORN */
466 1.11 mlelstv 0x01B1, 0x028A, /* LATIN CAPITAL LETTER UPSILON */
467 1.11 mlelstv 0x01B2, 0x028B, /* LATIN CAPITAL LETTER V WITH HOOK */
468 1.11 mlelstv 0x01B3, 0x01B4, /* LATIN CAPITAL LETTER Y WITH HOOK */
469 1.11 mlelstv 0x01B5, 0x01B6, /* LATIN CAPITAL LETTER Z WITH STROKE */
470 1.11 mlelstv 0x01B7, 0x0292, /* LATIN CAPITAL LETTER EZH */
471 1.11 mlelstv 0x01B8, 0x01B9, /* LATIN CAPITAL LETTER EZH REVERSED */
472 1.11 mlelstv 0x01BC, 0x01BD, /* LATIN CAPITAL LETTER TONE FIVE */
473 1.11 mlelstv 0x01C4, 0x01C6, /* LATIN CAPITAL LETTER DZ WITH CARON */
474 1.11 mlelstv 0x01C5, 0x01C6, /* LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON */
475 1.11 mlelstv 0x01C7, 0x01C9, /* LATIN CAPITAL LETTER LJ */
476 1.11 mlelstv 0x01C8, 0x01C9, /* LATIN CAPITAL LETTER L WITH SMALL LETTER J */
477 1.11 mlelstv 0x01CA, 0x01CC, /* LATIN CAPITAL LETTER NJ */
478 1.11 mlelstv 0x01CB, 0x01CC, /* LATIN CAPITAL LETTER N WITH SMALL LETTER J */
479 1.11 mlelstv 0x01CD, 0x01CE, /* LATIN CAPITAL LETTER A WITH CARON */
480 1.11 mlelstv 0x01CF, 0x01D0, /* LATIN CAPITAL LETTER I WITH CARON */
481 1.11 mlelstv 0x01D1, 0x01D2, /* LATIN CAPITAL LETTER O WITH CARON */
482 1.11 mlelstv 0x01D3, 0x01D4, /* LATIN CAPITAL LETTER U WITH CARON */
483 1.11 mlelstv 0x01D5, 0x01D6, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON */
484 1.11 mlelstv 0x01D7, 0x01D8, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE */
485 1.11 mlelstv 0x01D9, 0x01DA, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON */
486 1.11 mlelstv 0x01DB, 0x01DC, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE */
487 1.11 mlelstv 0x01DE, 0x01DF, /* LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON */
488 1.11 mlelstv 0x01E0, 0x01E1, /* LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON */
489 1.11 mlelstv 0x01E2, 0x01E3, /* LATIN CAPITAL LETTER AE WITH MACRON */
490 1.11 mlelstv 0x01E4, 0x01E5, /* LATIN CAPITAL LETTER G WITH STROKE */
491 1.11 mlelstv 0x01E6, 0x01E7, /* LATIN CAPITAL LETTER G WITH CARON */
492 1.11 mlelstv 0x01E8, 0x01E9, /* LATIN CAPITAL LETTER K WITH CARON */
493 1.11 mlelstv 0x01EA, 0x01EB, /* LATIN CAPITAL LETTER O WITH OGONEK */
494 1.11 mlelstv 0x01EC, 0x01ED, /* LATIN CAPITAL LETTER O WITH OGONEK AND MACRON */
495 1.11 mlelstv 0x01EE, 0x01EF, /* LATIN CAPITAL LETTER EZH WITH CARON */
496 1.11 mlelstv 0x01F1, 0x01F3, /* LATIN CAPITAL LETTER DZ */
497 1.11 mlelstv 0x01F2, 0x01F3, /* LATIN CAPITAL LETTER D WITH SMALL LETTER Z */
498 1.11 mlelstv 0x01F4, 0x01F5, /* LATIN CAPITAL LETTER G WITH ACUTE */
499 1.11 mlelstv 0x01F6, 0x0195, /* LATIN CAPITAL LETTER HWAIR */
500 1.11 mlelstv 0x01F7, 0x01BF, /* LATIN CAPITAL LETTER WYNN */
501 1.11 mlelstv 0x01F8, 0x01F9, /* LATIN CAPITAL LETTER N WITH GRAVE */
502 1.11 mlelstv 0x01FA, 0x01FB, /* LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE */
503 1.11 mlelstv 0x01FC, 0x01FD, /* LATIN CAPITAL LETTER AE WITH ACUTE */
504 1.11 mlelstv 0x01FE, 0x01FF, /* LATIN CAPITAL LETTER O WITH STROKE AND ACUTE */
505 1.11 mlelstv 0x0200, 0x0201, /* LATIN CAPITAL LETTER A WITH DOUBLE GRAVE */
506 1.11 mlelstv 0x0202, 0x0203, /* LATIN CAPITAL LETTER A WITH INVERTED BREVE */
507 1.11 mlelstv 0x0204, 0x0205, /* LATIN CAPITAL LETTER E WITH DOUBLE GRAVE */
508 1.11 mlelstv 0x0206, 0x0207, /* LATIN CAPITAL LETTER E WITH INVERTED BREVE */
509 1.11 mlelstv 0x0208, 0x0209, /* LATIN CAPITAL LETTER I WITH DOUBLE GRAVE */
510 1.11 mlelstv 0x020A, 0x020B, /* LATIN CAPITAL LETTER I WITH INVERTED BREVE */
511 1.11 mlelstv 0x020C, 0x020D, /* LATIN CAPITAL LETTER O WITH DOUBLE GRAVE */
512 1.11 mlelstv 0x020E, 0x020F, /* LATIN CAPITAL LETTER O WITH INVERTED BREVE */
513 1.11 mlelstv 0x0210, 0x0211, /* LATIN CAPITAL LETTER R WITH DOUBLE GRAVE */
514 1.11 mlelstv 0x0212, 0x0213, /* LATIN CAPITAL LETTER R WITH INVERTED BREVE */
515 1.11 mlelstv 0x0214, 0x0215, /* LATIN CAPITAL LETTER U WITH DOUBLE GRAVE */
516 1.11 mlelstv 0x0216, 0x0217, /* LATIN CAPITAL LETTER U WITH INVERTED BREVE */
517 1.11 mlelstv 0x0218, 0x0219, /* LATIN CAPITAL LETTER S WITH COMMA BELOW */
518 1.11 mlelstv 0x021A, 0x021B, /* LATIN CAPITAL LETTER T WITH COMMA BELOW */
519 1.11 mlelstv 0x021C, 0x021D, /* LATIN CAPITAL LETTER YOGH */
520 1.11 mlelstv 0x021E, 0x021F, /* LATIN CAPITAL LETTER H WITH CARON */
521 1.11 mlelstv 0x0220, 0x019E, /* LATIN CAPITAL LETTER N WITH LONG RIGHT LEG */
522 1.11 mlelstv 0x0222, 0x0223, /* LATIN CAPITAL LETTER OU */
523 1.11 mlelstv 0x0224, 0x0225, /* LATIN CAPITAL LETTER Z WITH HOOK */
524 1.11 mlelstv 0x0226, 0x0227, /* LATIN CAPITAL LETTER A WITH DOT ABOVE */
525 1.11 mlelstv 0x0228, 0x0229, /* LATIN CAPITAL LETTER E WITH CEDILLA */
526 1.11 mlelstv 0x022A, 0x022B, /* LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON */
527 1.11 mlelstv 0x022C, 0x022D, /* LATIN CAPITAL LETTER O WITH TILDE AND MACRON */
528 1.11 mlelstv 0x022E, 0x022F, /* LATIN CAPITAL LETTER O WITH DOT ABOVE */
529 1.11 mlelstv 0x0230, 0x0231, /* LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON */
530 1.11 mlelstv 0x0232, 0x0233, /* LATIN CAPITAL LETTER Y WITH MACRON */
531 1.11 mlelstv 0x023A, 0x2C65, /* LATIN CAPITAL LETTER A WITH STROKE */
532 1.11 mlelstv 0x023B, 0x023C, /* LATIN CAPITAL LETTER C WITH STROKE */
533 1.11 mlelstv 0x023D, 0x019A, /* LATIN CAPITAL LETTER L WITH BAR */
534 1.11 mlelstv 0x023E, 0x2C66, /* LATIN CAPITAL LETTER T WITH DIAGONAL STROKE */
535 1.11 mlelstv 0x0241, 0x0242, /* LATIN CAPITAL LETTER GLOTTAL STOP */
536 1.11 mlelstv 0x0243, 0x0180, /* LATIN CAPITAL LETTER B WITH STROKE */
537 1.11 mlelstv 0x0244, 0x0289, /* LATIN CAPITAL LETTER U BAR */
538 1.11 mlelstv 0x0245, 0x028C, /* LATIN CAPITAL LETTER TURNED V */
539 1.11 mlelstv 0x0246, 0x0247, /* LATIN CAPITAL LETTER E WITH STROKE */
540 1.11 mlelstv 0x0248, 0x0249, /* LATIN CAPITAL LETTER J WITH STROKE */
541 1.11 mlelstv 0x024A, 0x024B, /* LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL */
542 1.11 mlelstv 0x024C, 0x024D, /* LATIN CAPITAL LETTER R WITH STROKE */
543 1.11 mlelstv 0x024E, 0x024F, /* LATIN CAPITAL LETTER Y WITH STROKE */
544 1.11 mlelstv 0x0345, 0x03B9, /* COMBINING GREEK YPOGEGRAMMENI */
545 1.11 mlelstv 0x0386, 0x03AC, /* GREEK CAPITAL LETTER ALPHA WITH TONOS */
546 1.11 mlelstv 0x0388, 0x03AD, /* GREEK CAPITAL LETTER EPSILON WITH TONOS */
547 1.11 mlelstv 0x0389, 0x03AE, /* GREEK CAPITAL LETTER ETA WITH TONOS */
548 1.11 mlelstv 0x038A, 0x03AF, /* GREEK CAPITAL LETTER IOTA WITH TONOS */
549 1.11 mlelstv 0x038C, 0x03CC, /* GREEK CAPITAL LETTER OMICRON WITH TONOS */
550 1.11 mlelstv 0x038E, 0x03CD, /* GREEK CAPITAL LETTER UPSILON WITH TONOS */
551 1.11 mlelstv 0x038F, 0x03CE, /* GREEK CAPITAL LETTER OMEGA WITH TONOS */
552 1.11 mlelstv 0x0391, 0x03B1, /* GREEK CAPITAL LETTER ALPHA */
553 1.11 mlelstv 0x0392, 0x03B2, /* GREEK CAPITAL LETTER BETA */
554 1.11 mlelstv 0x0393, 0x03B3, /* GREEK CAPITAL LETTER GAMMA */
555 1.11 mlelstv 0x0394, 0x03B4, /* GREEK CAPITAL LETTER DELTA */
556 1.11 mlelstv 0x0395, 0x03B5, /* GREEK CAPITAL LETTER EPSILON */
557 1.11 mlelstv 0x0396, 0x03B6, /* GREEK CAPITAL LETTER ZETA */
558 1.11 mlelstv 0x0397, 0x03B7, /* GREEK CAPITAL LETTER ETA */
559 1.11 mlelstv 0x0398, 0x03B8, /* GREEK CAPITAL LETTER THETA */
560 1.11 mlelstv 0x0399, 0x03B9, /* GREEK CAPITAL LETTER IOTA */
561 1.11 mlelstv 0x039A, 0x03BA, /* GREEK CAPITAL LETTER KAPPA */
562 1.11 mlelstv 0x039B, 0x03BB, /* GREEK CAPITAL LETTER LAMDA */
563 1.11 mlelstv 0x039C, 0x03BC, /* GREEK CAPITAL LETTER MU */
564 1.11 mlelstv 0x039D, 0x03BD, /* GREEK CAPITAL LETTER NU */
565 1.11 mlelstv 0x039E, 0x03BE, /* GREEK CAPITAL LETTER XI */
566 1.11 mlelstv 0x039F, 0x03BF, /* GREEK CAPITAL LETTER OMICRON */
567 1.11 mlelstv 0x03A0, 0x03C0, /* GREEK CAPITAL LETTER PI */
568 1.11 mlelstv 0x03A1, 0x03C1, /* GREEK CAPITAL LETTER RHO */
569 1.11 mlelstv 0x03A3, 0x03C3, /* GREEK CAPITAL LETTER SIGMA */
570 1.11 mlelstv 0x03A4, 0x03C4, /* GREEK CAPITAL LETTER TAU */
571 1.11 mlelstv 0x03A5, 0x03C5, /* GREEK CAPITAL LETTER UPSILON */
572 1.11 mlelstv 0x03A6, 0x03C6, /* GREEK CAPITAL LETTER PHI */
573 1.11 mlelstv 0x03A7, 0x03C7, /* GREEK CAPITAL LETTER CHI */
574 1.11 mlelstv 0x03A8, 0x03C8, /* GREEK CAPITAL LETTER PSI */
575 1.11 mlelstv 0x03A9, 0x03C9, /* GREEK CAPITAL LETTER OMEGA */
576 1.11 mlelstv 0x03AA, 0x03CA, /* GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
577 1.11 mlelstv 0x03AB, 0x03CB, /* GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
578 1.11 mlelstv 0x03C2, 0x03C3, /* GREEK SMALL LETTER FINAL SIGMA */
579 1.11 mlelstv 0x03D0, 0x03B2, /* GREEK BETA SYMBOL */
580 1.11 mlelstv 0x03D1, 0x03B8, /* GREEK THETA SYMBOL */
581 1.11 mlelstv 0x03D5, 0x03C6, /* GREEK PHI SYMBOL */
582 1.11 mlelstv 0x03D6, 0x03C0, /* GREEK PI SYMBOL */
583 1.11 mlelstv 0x03D8, 0x03D9, /* GREEK LETTER ARCHAIC KOPPA */
584 1.11 mlelstv 0x03DA, 0x03DB, /* GREEK LETTER STIGMA */
585 1.11 mlelstv 0x03DC, 0x03DD, /* GREEK LETTER DIGAMMA */
586 1.11 mlelstv 0x03DE, 0x03DF, /* GREEK LETTER KOPPA */
587 1.11 mlelstv 0x03E0, 0x03E1, /* GREEK LETTER SAMPI */
588 1.11 mlelstv 0x03E2, 0x03E3, /* COPTIC CAPITAL LETTER SHEI */
589 1.11 mlelstv 0x03E4, 0x03E5, /* COPTIC CAPITAL LETTER FEI */
590 1.11 mlelstv 0x03E6, 0x03E7, /* COPTIC CAPITAL LETTER KHEI */
591 1.11 mlelstv 0x03E8, 0x03E9, /* COPTIC CAPITAL LETTER HORI */
592 1.11 mlelstv 0x03EA, 0x03EB, /* COPTIC CAPITAL LETTER GANGIA */
593 1.11 mlelstv 0x03EC, 0x03ED, /* COPTIC CAPITAL LETTER SHIMA */
594 1.11 mlelstv 0x03EE, 0x03EF, /* COPTIC CAPITAL LETTER DEI */
595 1.11 mlelstv 0x03F0, 0x03BA, /* GREEK KAPPA SYMBOL */
596 1.11 mlelstv 0x03F1, 0x03C1, /* GREEK RHO SYMBOL */
597 1.11 mlelstv 0x03F4, 0x03B8, /* GREEK CAPITAL THETA SYMBOL */
598 1.11 mlelstv 0x03F5, 0x03B5, /* GREEK LUNATE EPSILON SYMBOL */
599 1.11 mlelstv 0x03F7, 0x03F8, /* GREEK CAPITAL LETTER SHO */
600 1.11 mlelstv 0x03F9, 0x03F2, /* GREEK CAPITAL LUNATE SIGMA SYMBOL */
601 1.11 mlelstv 0x03FA, 0x03FB, /* GREEK CAPITAL LETTER SAN */
602 1.11 mlelstv 0x03FD, 0x037B, /* GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL */
603 1.11 mlelstv 0x03FE, 0x037C, /* GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL */
604 1.11 mlelstv 0x03FF, 0x037D, /* GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL */
605 1.11 mlelstv 0x0400, 0x0450, /* CYRILLIC CAPITAL LETTER IE WITH GRAVE */
606 1.11 mlelstv 0x0401, 0x0451, /* CYRILLIC CAPITAL LETTER IO */
607 1.11 mlelstv 0x0402, 0x0452, /* CYRILLIC CAPITAL LETTER DJE */
608 1.11 mlelstv 0x0403, 0x0453, /* CYRILLIC CAPITAL LETTER GJE */
609 1.11 mlelstv 0x0404, 0x0454, /* CYRILLIC CAPITAL LETTER UKRAINIAN IE */
610 1.11 mlelstv 0x0405, 0x0455, /* CYRILLIC CAPITAL LETTER DZE */
611 1.11 mlelstv 0x0406, 0x0456, /* CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
612 1.11 mlelstv 0x0407, 0x0457, /* CYRILLIC CAPITAL LETTER YI */
613 1.11 mlelstv 0x0408, 0x0458, /* CYRILLIC CAPITAL LETTER JE */
614 1.11 mlelstv 0x0409, 0x0459, /* CYRILLIC CAPITAL LETTER LJE */
615 1.11 mlelstv 0x040A, 0x045A, /* CYRILLIC CAPITAL LETTER NJE */
616 1.11 mlelstv 0x040B, 0x045B, /* CYRILLIC CAPITAL LETTER TSHE */
617 1.11 mlelstv 0x040C, 0x045C, /* CYRILLIC CAPITAL LETTER KJE */
618 1.11 mlelstv 0x040D, 0x045D, /* CYRILLIC CAPITAL LETTER I WITH GRAVE */
619 1.11 mlelstv 0x040E, 0x045E, /* CYRILLIC CAPITAL LETTER SHORT U */
620 1.11 mlelstv 0x040F, 0x045F, /* CYRILLIC CAPITAL LETTER DZHE */
621 1.11 mlelstv 0x0410, 0x0430, /* CYRILLIC CAPITAL LETTER A */
622 1.11 mlelstv 0x0411, 0x0431, /* CYRILLIC CAPITAL LETTER BE */
623 1.11 mlelstv 0x0412, 0x0432, /* CYRILLIC CAPITAL LETTER VE */
624 1.11 mlelstv 0x0413, 0x0433, /* CYRILLIC CAPITAL LETTER GHE */
625 1.11 mlelstv 0x0414, 0x0434, /* CYRILLIC CAPITAL LETTER DE */
626 1.11 mlelstv 0x0415, 0x0435, /* CYRILLIC CAPITAL LETTER IE */
627 1.11 mlelstv 0x0416, 0x0436, /* CYRILLIC CAPITAL LETTER ZHE */
628 1.11 mlelstv 0x0417, 0x0437, /* CYRILLIC CAPITAL LETTER ZE */
629 1.11 mlelstv 0x0418, 0x0438, /* CYRILLIC CAPITAL LETTER I */
630 1.11 mlelstv 0x0419, 0x0439, /* CYRILLIC CAPITAL LETTER SHORT I */
631 1.11 mlelstv 0x041A, 0x043A, /* CYRILLIC CAPITAL LETTER KA */
632 1.11 mlelstv 0x041B, 0x043B, /* CYRILLIC CAPITAL LETTER EL */
633 1.11 mlelstv 0x041C, 0x043C, /* CYRILLIC CAPITAL LETTER EM */
634 1.11 mlelstv 0x041D, 0x043D, /* CYRILLIC CAPITAL LETTER EN */
635 1.11 mlelstv 0x041E, 0x043E, /* CYRILLIC CAPITAL LETTER O */
636 1.11 mlelstv 0x041F, 0x043F, /* CYRILLIC CAPITAL LETTER PE */
637 1.11 mlelstv 0x0420, 0x0440, /* CYRILLIC CAPITAL LETTER ER */
638 1.11 mlelstv 0x0421, 0x0441, /* CYRILLIC CAPITAL LETTER ES */
639 1.11 mlelstv 0x0422, 0x0442, /* CYRILLIC CAPITAL LETTER TE */
640 1.11 mlelstv 0x0423, 0x0443, /* CYRILLIC CAPITAL LETTER U */
641 1.11 mlelstv 0x0424, 0x0444, /* CYRILLIC CAPITAL LETTER EF */
642 1.11 mlelstv 0x0425, 0x0445, /* CYRILLIC CAPITAL LETTER HA */
643 1.11 mlelstv 0x0426, 0x0446, /* CYRILLIC CAPITAL LETTER TSE */
644 1.11 mlelstv 0x0427, 0x0447, /* CYRILLIC CAPITAL LETTER CHE */
645 1.11 mlelstv 0x0428, 0x0448, /* CYRILLIC CAPITAL LETTER SHA */
646 1.11 mlelstv 0x0429, 0x0449, /* CYRILLIC CAPITAL LETTER SHCHA */
647 1.11 mlelstv 0x042A, 0x044A, /* CYRILLIC CAPITAL LETTER HARD SIGN */
648 1.11 mlelstv 0x042B, 0x044B, /* CYRILLIC CAPITAL LETTER YERU */
649 1.11 mlelstv 0x042C, 0x044C, /* CYRILLIC CAPITAL LETTER SOFT SIGN */
650 1.11 mlelstv 0x042D, 0x044D, /* CYRILLIC CAPITAL LETTER E */
651 1.11 mlelstv 0x042E, 0x044E, /* CYRILLIC CAPITAL LETTER YU */
652 1.11 mlelstv 0x042F, 0x044F, /* CYRILLIC CAPITAL LETTER YA */
653 1.11 mlelstv 0x0460, 0x0461, /* CYRILLIC CAPITAL LETTER OMEGA */
654 1.11 mlelstv 0x0462, 0x0463, /* CYRILLIC CAPITAL LETTER YAT */
655 1.11 mlelstv 0x0464, 0x0465, /* CYRILLIC CAPITAL LETTER IOTIFIED E */
656 1.11 mlelstv 0x0466, 0x0467, /* CYRILLIC CAPITAL LETTER LITTLE YUS */
657 1.11 mlelstv 0x0468, 0x0469, /* CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS */
658 1.11 mlelstv 0x046A, 0x046B, /* CYRILLIC CAPITAL LETTER BIG YUS */
659 1.11 mlelstv 0x046C, 0x046D, /* CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS */
660 1.11 mlelstv 0x046E, 0x046F, /* CYRILLIC CAPITAL LETTER KSI */
661 1.11 mlelstv 0x0470, 0x0471, /* CYRILLIC CAPITAL LETTER PSI */
662 1.11 mlelstv 0x0472, 0x0473, /* CYRILLIC CAPITAL LETTER FITA */
663 1.11 mlelstv 0x0474, 0x0475, /* CYRILLIC CAPITAL LETTER IZHITSA */
664 1.11 mlelstv 0x0476, 0x0477, /* CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT */
665 1.11 mlelstv 0x0478, 0x0479, /* CYRILLIC CAPITAL LETTER UK */
666 1.11 mlelstv 0x047A, 0x047B, /* CYRILLIC CAPITAL LETTER ROUND OMEGA */
667 1.11 mlelstv 0x047C, 0x047D, /* CYRILLIC CAPITAL LETTER OMEGA WITH TITLO */
668 1.11 mlelstv 0x047E, 0x047F, /* CYRILLIC CAPITAL LETTER OT */
669 1.11 mlelstv 0x0480, 0x0481, /* CYRILLIC CAPITAL LETTER KOPPA */
670 1.11 mlelstv 0x048A, 0x048B, /* CYRILLIC CAPITAL LETTER SHORT I WITH TAIL */
671 1.11 mlelstv 0x048C, 0x048D, /* CYRILLIC CAPITAL LETTER SEMISOFT SIGN */
672 1.11 mlelstv 0x048E, 0x048F, /* CYRILLIC CAPITAL LETTER ER WITH TICK */
673 1.11 mlelstv 0x0490, 0x0491, /* CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
674 1.11 mlelstv 0x0492, 0x0493, /* CYRILLIC CAPITAL LETTER GHE WITH STROKE */
675 1.11 mlelstv 0x0494, 0x0495, /* CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK */
676 1.11 mlelstv 0x0496, 0x0497, /* CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */
677 1.11 mlelstv 0x0498, 0x0499, /* CYRILLIC CAPITAL LETTER ZE WITH DESCENDER */
678 1.11 mlelstv 0x049A, 0x049B, /* CYRILLIC CAPITAL LETTER KA WITH DESCENDER */
679 1.11 mlelstv 0x049C, 0x049D, /* CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */
680 1.11 mlelstv 0x049E, 0x049F, /* CYRILLIC CAPITAL LETTER KA WITH STROKE */
681 1.11 mlelstv 0x04A0, 0x04A1, /* CYRILLIC CAPITAL LETTER BASHKIR KA */
682 1.11 mlelstv 0x04A2, 0x04A3, /* CYRILLIC CAPITAL LETTER EN WITH DESCENDER */
683 1.11 mlelstv 0x04A4, 0x04A5, /* CYRILLIC CAPITAL LIGATURE EN GHE */
684 1.11 mlelstv 0x04A6, 0x04A7, /* CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK */
685 1.11 mlelstv 0x04A8, 0x04A9, /* CYRILLIC CAPITAL LETTER ABKHASIAN HA */
686 1.11 mlelstv 0x04AA, 0x04AB, /* CYRILLIC CAPITAL LETTER ES WITH DESCENDER */
687 1.11 mlelstv 0x04AC, 0x04AD, /* CYRILLIC CAPITAL LETTER TE WITH DESCENDER */
688 1.11 mlelstv 0x04AE, 0x04AF, /* CYRILLIC CAPITAL LETTER STRAIGHT U */
689 1.11 mlelstv 0x04B0, 0x04B1, /* CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */
690 1.11 mlelstv 0x04B2, 0x04B3, /* CYRILLIC CAPITAL LETTER HA WITH DESCENDER */
691 1.11 mlelstv 0x04B4, 0x04B5, /* CYRILLIC CAPITAL LIGATURE TE TSE */
692 1.11 mlelstv 0x04B6, 0x04B7, /* CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */
693 1.11 mlelstv 0x04B8, 0x04B9, /* CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */
694 1.11 mlelstv 0x04BA, 0x04BB, /* CYRILLIC CAPITAL LETTER SHHA */
695 1.11 mlelstv 0x04BC, 0x04BD, /* CYRILLIC CAPITAL LETTER ABKHASIAN CHE */
696 1.11 mlelstv 0x04BE, 0x04BF, /* CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER */
697 1.11 mlelstv 0x04C0, 0x04CF, /* CYRILLIC LETTER PALOCHKA */
698 1.11 mlelstv 0x04C1, 0x04C2, /* CYRILLIC CAPITAL LETTER ZHE WITH BREVE */
699 1.11 mlelstv 0x04C3, 0x04C4, /* CYRILLIC CAPITAL LETTER KA WITH HOOK */
700 1.11 mlelstv 0x04C5, 0x04C6, /* CYRILLIC CAPITAL LETTER EL WITH TAIL */
701 1.11 mlelstv 0x04C7, 0x04C8, /* CYRILLIC CAPITAL LETTER EN WITH HOOK */
702 1.11 mlelstv 0x04C9, 0x04CA, /* CYRILLIC CAPITAL LETTER EN WITH TAIL */
703 1.11 mlelstv 0x04CB, 0x04CC, /* CYRILLIC CAPITAL LETTER KHAKASSIAN CHE */
704 1.11 mlelstv 0x04CD, 0x04CE, /* CYRILLIC CAPITAL LETTER EM WITH TAIL */
705 1.11 mlelstv 0x04D0, 0x04D1, /* CYRILLIC CAPITAL LETTER A WITH BREVE */
706 1.11 mlelstv 0x04D2, 0x04D3, /* CYRILLIC CAPITAL LETTER A WITH DIAERESIS */
707 1.11 mlelstv 0x04D4, 0x04D5, /* CYRILLIC CAPITAL LIGATURE A IE */
708 1.11 mlelstv 0x04D6, 0x04D7, /* CYRILLIC CAPITAL LETTER IE WITH BREVE */
709 1.11 mlelstv 0x04D8, 0x04D9, /* CYRILLIC CAPITAL LETTER SCHWA */
710 1.11 mlelstv 0x04DA, 0x04DB, /* CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS */
711 1.11 mlelstv 0x04DC, 0x04DD, /* CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS */
712 1.11 mlelstv 0x04DE, 0x04DF, /* CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS */
713 1.11 mlelstv 0x04E0, 0x04E1, /* CYRILLIC CAPITAL LETTER ABKHASIAN DZE */
714 1.11 mlelstv 0x04E2, 0x04E3, /* CYRILLIC CAPITAL LETTER I WITH MACRON */
715 1.11 mlelstv 0x04E4, 0x04E5, /* CYRILLIC CAPITAL LETTER I WITH DIAERESIS */
716 1.11 mlelstv 0x04E6, 0x04E7, /* CYRILLIC CAPITAL LETTER O WITH DIAERESIS */
717 1.11 mlelstv 0x04E8, 0x04E9, /* CYRILLIC CAPITAL LETTER BARRED O */
718 1.11 mlelstv 0x04EA, 0x04EB, /* CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS */
719 1.11 mlelstv 0x04EC, 0x04ED, /* CYRILLIC CAPITAL LETTER E WITH DIAERESIS */
720 1.11 mlelstv 0x04EE, 0x04EF, /* CYRILLIC CAPITAL LETTER U WITH MACRON */
721 1.11 mlelstv 0x04F0, 0x04F1, /* CYRILLIC CAPITAL LETTER U WITH DIAERESIS */
722 1.11 mlelstv 0x04F2, 0x04F3, /* CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE */
723 1.11 mlelstv 0x04F4, 0x04F5, /* CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS */
724 1.11 mlelstv 0x04F6, 0x04F7, /* CYRILLIC CAPITAL LETTER GHE WITH DESCENDER */
725 1.11 mlelstv 0x04F8, 0x04F9, /* CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS */
726 1.11 mlelstv 0x04FA, 0x04FB, /* CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK */
727 1.11 mlelstv 0x04FC, 0x04FD, /* CYRILLIC CAPITAL LETTER HA WITH HOOK */
728 1.11 mlelstv 0x04FE, 0x04FF, /* CYRILLIC CAPITAL LETTER HA WITH STROKE */
729 1.11 mlelstv 0x0500, 0x0501, /* CYRILLIC CAPITAL LETTER KOMI DE */
730 1.11 mlelstv 0x0502, 0x0503, /* CYRILLIC CAPITAL LETTER KOMI DJE */
731 1.11 mlelstv 0x0504, 0x0505, /* CYRILLIC CAPITAL LETTER KOMI ZJE */
732 1.11 mlelstv 0x0506, 0x0507, /* CYRILLIC CAPITAL LETTER KOMI DZJE */
733 1.11 mlelstv 0x0508, 0x0509, /* CYRILLIC CAPITAL LETTER KOMI LJE */
734 1.11 mlelstv 0x050A, 0x050B, /* CYRILLIC CAPITAL LETTER KOMI NJE */
735 1.11 mlelstv 0x050C, 0x050D, /* CYRILLIC CAPITAL LETTER KOMI SJE */
736 1.11 mlelstv 0x050E, 0x050F, /* CYRILLIC CAPITAL LETTER KOMI TJE */
737 1.11 mlelstv 0x0510, 0x0511, /* CYRILLIC CAPITAL LETTER REVERSED ZE */
738 1.11 mlelstv 0x0512, 0x0513, /* CYRILLIC CAPITAL LETTER EL WITH HOOK */
739 1.11 mlelstv 0x0531, 0x0561, /* ARMENIAN CAPITAL LETTER AYB */
740 1.11 mlelstv 0x0532, 0x0562, /* ARMENIAN CAPITAL LETTER BEN */
741 1.11 mlelstv 0x0533, 0x0563, /* ARMENIAN CAPITAL LETTER GIM */
742 1.11 mlelstv 0x0534, 0x0564, /* ARMENIAN CAPITAL LETTER DA */
743 1.11 mlelstv 0x0535, 0x0565, /* ARMENIAN CAPITAL LETTER ECH */
744 1.11 mlelstv 0x0536, 0x0566, /* ARMENIAN CAPITAL LETTER ZA */
745 1.11 mlelstv 0x0537, 0x0567, /* ARMENIAN CAPITAL LETTER EH */
746 1.11 mlelstv 0x0538, 0x0568, /* ARMENIAN CAPITAL LETTER ET */
747 1.11 mlelstv 0x0539, 0x0569, /* ARMENIAN CAPITAL LETTER TO */
748 1.11 mlelstv 0x053A, 0x056A, /* ARMENIAN CAPITAL LETTER ZHE */
749 1.11 mlelstv 0x053B, 0x056B, /* ARMENIAN CAPITAL LETTER INI */
750 1.11 mlelstv 0x053C, 0x056C, /* ARMENIAN CAPITAL LETTER LIWN */
751 1.11 mlelstv 0x053D, 0x056D, /* ARMENIAN CAPITAL LETTER XEH */
752 1.11 mlelstv 0x053E, 0x056E, /* ARMENIAN CAPITAL LETTER CA */
753 1.11 mlelstv 0x053F, 0x056F, /* ARMENIAN CAPITAL LETTER KEN */
754 1.11 mlelstv 0x0540, 0x0570, /* ARMENIAN CAPITAL LETTER HO */
755 1.11 mlelstv 0x0541, 0x0571, /* ARMENIAN CAPITAL LETTER JA */
756 1.11 mlelstv 0x0542, 0x0572, /* ARMENIAN CAPITAL LETTER GHAD */
757 1.11 mlelstv 0x0543, 0x0573, /* ARMENIAN CAPITAL LETTER CHEH */
758 1.11 mlelstv 0x0544, 0x0574, /* ARMENIAN CAPITAL LETTER MEN */
759 1.11 mlelstv 0x0545, 0x0575, /* ARMENIAN CAPITAL LETTER YI */
760 1.11 mlelstv 0x0546, 0x0576, /* ARMENIAN CAPITAL LETTER NOW */
761 1.11 mlelstv 0x0547, 0x0577, /* ARMENIAN CAPITAL LETTER SHA */
762 1.11 mlelstv 0x0548, 0x0578, /* ARMENIAN CAPITAL LETTER VO */
763 1.11 mlelstv 0x0549, 0x0579, /* ARMENIAN CAPITAL LETTER CHA */
764 1.11 mlelstv 0x054A, 0x057A, /* ARMENIAN CAPITAL LETTER PEH */
765 1.11 mlelstv 0x054B, 0x057B, /* ARMENIAN CAPITAL LETTER JHEH */
766 1.11 mlelstv 0x054C, 0x057C, /* ARMENIAN CAPITAL LETTER RA */
767 1.11 mlelstv 0x054D, 0x057D, /* ARMENIAN CAPITAL LETTER SEH */
768 1.11 mlelstv 0x054E, 0x057E, /* ARMENIAN CAPITAL LETTER VEW */
769 1.11 mlelstv 0x054F, 0x057F, /* ARMENIAN CAPITAL LETTER TIWN */
770 1.11 mlelstv 0x0550, 0x0580, /* ARMENIAN CAPITAL LETTER REH */
771 1.11 mlelstv 0x0551, 0x0581, /* ARMENIAN CAPITAL LETTER CO */
772 1.11 mlelstv 0x0552, 0x0582, /* ARMENIAN CAPITAL LETTER YIWN */
773 1.11 mlelstv 0x0553, 0x0583, /* ARMENIAN CAPITAL LETTER PIWR */
774 1.11 mlelstv 0x0554, 0x0584, /* ARMENIAN CAPITAL LETTER KEH */
775 1.11 mlelstv 0x0555, 0x0585, /* ARMENIAN CAPITAL LETTER OH */
776 1.11 mlelstv 0x0556, 0x0586, /* ARMENIAN CAPITAL LETTER FEH */
777 1.11 mlelstv 0x10A0, 0x2D00, /* GEORGIAN CAPITAL LETTER AN */
778 1.11 mlelstv 0x10A1, 0x2D01, /* GEORGIAN CAPITAL LETTER BAN */
779 1.11 mlelstv 0x10A2, 0x2D02, /* GEORGIAN CAPITAL LETTER GAN */
780 1.11 mlelstv 0x10A3, 0x2D03, /* GEORGIAN CAPITAL LETTER DON */
781 1.11 mlelstv 0x10A4, 0x2D04, /* GEORGIAN CAPITAL LETTER EN */
782 1.11 mlelstv 0x10A5, 0x2D05, /* GEORGIAN CAPITAL LETTER VIN */
783 1.11 mlelstv 0x10A6, 0x2D06, /* GEORGIAN CAPITAL LETTER ZEN */
784 1.11 mlelstv 0x10A7, 0x2D07, /* GEORGIAN CAPITAL LETTER TAN */
785 1.11 mlelstv 0x10A8, 0x2D08, /* GEORGIAN CAPITAL LETTER IN */
786 1.11 mlelstv 0x10A9, 0x2D09, /* GEORGIAN CAPITAL LETTER KAN */
787 1.11 mlelstv 0x10AA, 0x2D0A, /* GEORGIAN CAPITAL LETTER LAS */
788 1.11 mlelstv 0x10AB, 0x2D0B, /* GEORGIAN CAPITAL LETTER MAN */
789 1.11 mlelstv 0x10AC, 0x2D0C, /* GEORGIAN CAPITAL LETTER NAR */
790 1.11 mlelstv 0x10AD, 0x2D0D, /* GEORGIAN CAPITAL LETTER ON */
791 1.11 mlelstv 0x10AE, 0x2D0E, /* GEORGIAN CAPITAL LETTER PAR */
792 1.11 mlelstv 0x10AF, 0x2D0F, /* GEORGIAN CAPITAL LETTER ZHAR */
793 1.11 mlelstv 0x10B0, 0x2D10, /* GEORGIAN CAPITAL LETTER RAE */
794 1.11 mlelstv 0x10B1, 0x2D11, /* GEORGIAN CAPITAL LETTER SAN */
795 1.11 mlelstv 0x10B2, 0x2D12, /* GEORGIAN CAPITAL LETTER TAR */
796 1.11 mlelstv 0x10B3, 0x2D13, /* GEORGIAN CAPITAL LETTER UN */
797 1.11 mlelstv 0x10B4, 0x2D14, /* GEORGIAN CAPITAL LETTER PHAR */
798 1.11 mlelstv 0x10B5, 0x2D15, /* GEORGIAN CAPITAL LETTER KHAR */
799 1.11 mlelstv 0x10B6, 0x2D16, /* GEORGIAN CAPITAL LETTER GHAN */
800 1.11 mlelstv 0x10B7, 0x2D17, /* GEORGIAN CAPITAL LETTER QAR */
801 1.11 mlelstv 0x10B8, 0x2D18, /* GEORGIAN CAPITAL LETTER SHIN */
802 1.11 mlelstv 0x10B9, 0x2D19, /* GEORGIAN CAPITAL LETTER CHIN */
803 1.11 mlelstv 0x10BA, 0x2D1A, /* GEORGIAN CAPITAL LETTER CAN */
804 1.11 mlelstv 0x10BB, 0x2D1B, /* GEORGIAN CAPITAL LETTER JIL */
805 1.11 mlelstv 0x10BC, 0x2D1C, /* GEORGIAN CAPITAL LETTER CIL */
806 1.11 mlelstv 0x10BD, 0x2D1D, /* GEORGIAN CAPITAL LETTER CHAR */
807 1.11 mlelstv 0x10BE, 0x2D1E, /* GEORGIAN CAPITAL LETTER XAN */
808 1.11 mlelstv 0x10BF, 0x2D1F, /* GEORGIAN CAPITAL LETTER JHAN */
809 1.11 mlelstv 0x10C0, 0x2D20, /* GEORGIAN CAPITAL LETTER HAE */
810 1.11 mlelstv 0x10C1, 0x2D21, /* GEORGIAN CAPITAL LETTER HE */
811 1.11 mlelstv 0x10C2, 0x2D22, /* GEORGIAN CAPITAL LETTER HIE */
812 1.11 mlelstv 0x10C3, 0x2D23, /* GEORGIAN CAPITAL LETTER WE */
813 1.11 mlelstv 0x10C4, 0x2D24, /* GEORGIAN CAPITAL LETTER HAR */
814 1.11 mlelstv 0x10C5, 0x2D25, /* GEORGIAN CAPITAL LETTER HOE */
815 1.11 mlelstv 0x1E00, 0x1E01, /* LATIN CAPITAL LETTER A WITH RING BELOW */
816 1.11 mlelstv 0x1E02, 0x1E03, /* LATIN CAPITAL LETTER B WITH DOT ABOVE */
817 1.11 mlelstv 0x1E04, 0x1E05, /* LATIN CAPITAL LETTER B WITH DOT BELOW */
818 1.11 mlelstv 0x1E06, 0x1E07, /* LATIN CAPITAL LETTER B WITH LINE BELOW */
819 1.11 mlelstv 0x1E08, 0x1E09, /* LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE */
820 1.11 mlelstv 0x1E0A, 0x1E0B, /* LATIN CAPITAL LETTER D WITH DOT ABOVE */
821 1.11 mlelstv 0x1E0C, 0x1E0D, /* LATIN CAPITAL LETTER D WITH DOT BELOW */
822 1.11 mlelstv 0x1E0E, 0x1E0F, /* LATIN CAPITAL LETTER D WITH LINE BELOW */
823 1.11 mlelstv 0x1E10, 0x1E11, /* LATIN CAPITAL LETTER D WITH CEDILLA */
824 1.11 mlelstv 0x1E12, 0x1E13, /* LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW */
825 1.11 mlelstv 0x1E14, 0x1E15, /* LATIN CAPITAL LETTER E WITH MACRON AND GRAVE */
826 1.11 mlelstv 0x1E16, 0x1E17, /* LATIN CAPITAL LETTER E WITH MACRON AND ACUTE */
827 1.11 mlelstv 0x1E18, 0x1E19, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW */
828 1.11 mlelstv 0x1E1A, 0x1E1B, /* LATIN CAPITAL LETTER E WITH TILDE BELOW */
829 1.11 mlelstv 0x1E1C, 0x1E1D, /* LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE */
830 1.11 mlelstv 0x1E1E, 0x1E1F, /* LATIN CAPITAL LETTER F WITH DOT ABOVE */
831 1.11 mlelstv 0x1E20, 0x1E21, /* LATIN CAPITAL LETTER G WITH MACRON */
832 1.11 mlelstv 0x1E22, 0x1E23, /* LATIN CAPITAL LETTER H WITH DOT ABOVE */
833 1.11 mlelstv 0x1E24, 0x1E25, /* LATIN CAPITAL LETTER H WITH DOT BELOW */
834 1.11 mlelstv 0x1E26, 0x1E27, /* LATIN CAPITAL LETTER H WITH DIAERESIS */
835 1.11 mlelstv 0x1E28, 0x1E29, /* LATIN CAPITAL LETTER H WITH CEDILLA */
836 1.11 mlelstv 0x1E2A, 0x1E2B, /* LATIN CAPITAL LETTER H WITH BREVE BELOW */
837 1.11 mlelstv 0x1E2C, 0x1E2D, /* LATIN CAPITAL LETTER I WITH TILDE BELOW */
838 1.11 mlelstv 0x1E2E, 0x1E2F, /* LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE */
839 1.11 mlelstv 0x1E30, 0x1E31, /* LATIN CAPITAL LETTER K WITH ACUTE */
840 1.11 mlelstv 0x1E32, 0x1E33, /* LATIN CAPITAL LETTER K WITH DOT BELOW */
841 1.11 mlelstv 0x1E34, 0x1E35, /* LATIN CAPITAL LETTER K WITH LINE BELOW */
842 1.11 mlelstv 0x1E36, 0x1E37, /* LATIN CAPITAL LETTER L WITH DOT BELOW */
843 1.11 mlelstv 0x1E38, 0x1E39, /* LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON */
844 1.11 mlelstv 0x1E3A, 0x1E3B, /* LATIN CAPITAL LETTER L WITH LINE BELOW */
845 1.11 mlelstv 0x1E3C, 0x1E3D, /* LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW */
846 1.11 mlelstv 0x1E3E, 0x1E3F, /* LATIN CAPITAL LETTER M WITH ACUTE */
847 1.11 mlelstv 0x1E40, 0x1E41, /* LATIN CAPITAL LETTER M WITH DOT ABOVE */
848 1.11 mlelstv 0x1E42, 0x1E43, /* LATIN CAPITAL LETTER M WITH DOT BELOW */
849 1.11 mlelstv 0x1E44, 0x1E45, /* LATIN CAPITAL LETTER N WITH DOT ABOVE */
850 1.11 mlelstv 0x1E46, 0x1E47, /* LATIN CAPITAL LETTER N WITH DOT BELOW */
851 1.11 mlelstv 0x1E48, 0x1E49, /* LATIN CAPITAL LETTER N WITH LINE BELOW */
852 1.11 mlelstv 0x1E4A, 0x1E4B, /* LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW */
853 1.11 mlelstv 0x1E4C, 0x1E4D, /* LATIN CAPITAL LETTER O WITH TILDE AND ACUTE */
854 1.11 mlelstv 0x1E4E, 0x1E4F, /* LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS */
855 1.11 mlelstv 0x1E50, 0x1E51, /* LATIN CAPITAL LETTER O WITH MACRON AND GRAVE */
856 1.11 mlelstv 0x1E52, 0x1E53, /* LATIN CAPITAL LETTER O WITH MACRON AND ACUTE */
857 1.11 mlelstv 0x1E54, 0x1E55, /* LATIN CAPITAL LETTER P WITH ACUTE */
858 1.11 mlelstv 0x1E56, 0x1E57, /* LATIN CAPITAL LETTER P WITH DOT ABOVE */
859 1.11 mlelstv 0x1E58, 0x1E59, /* LATIN CAPITAL LETTER R WITH DOT ABOVE */
860 1.11 mlelstv 0x1E5A, 0x1E5B, /* LATIN CAPITAL LETTER R WITH DOT BELOW */
861 1.11 mlelstv 0x1E5C, 0x1E5D, /* LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON */
862 1.11 mlelstv 0x1E5E, 0x1E5F, /* LATIN CAPITAL LETTER R WITH LINE BELOW */
863 1.11 mlelstv 0x1E60, 0x1E61, /* LATIN CAPITAL LETTER S WITH DOT ABOVE */
864 1.11 mlelstv 0x1E62, 0x1E63, /* LATIN CAPITAL LETTER S WITH DOT BELOW */
865 1.11 mlelstv 0x1E64, 0x1E65, /* LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE */
866 1.11 mlelstv 0x1E66, 0x1E67, /* LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE */
867 1.11 mlelstv 0x1E68, 0x1E69, /* LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE */
868 1.11 mlelstv 0x1E6A, 0x1E6B, /* LATIN CAPITAL LETTER T WITH DOT ABOVE */
869 1.11 mlelstv 0x1E6C, 0x1E6D, /* LATIN CAPITAL LETTER T WITH DOT BELOW */
870 1.11 mlelstv 0x1E6E, 0x1E6F, /* LATIN CAPITAL LETTER T WITH LINE BELOW */
871 1.11 mlelstv 0x1E70, 0x1E71, /* LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW */
872 1.11 mlelstv 0x1E72, 0x1E73, /* LATIN CAPITAL LETTER U WITH DIAERESIS BELOW */
873 1.11 mlelstv 0x1E74, 0x1E75, /* LATIN CAPITAL LETTER U WITH TILDE BELOW */
874 1.11 mlelstv 0x1E76, 0x1E77, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW */
875 1.11 mlelstv 0x1E78, 0x1E79, /* LATIN CAPITAL LETTER U WITH TILDE AND ACUTE */
876 1.11 mlelstv 0x1E7A, 0x1E7B, /* LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS */
877 1.11 mlelstv 0x1E7C, 0x1E7D, /* LATIN CAPITAL LETTER V WITH TILDE */
878 1.11 mlelstv 0x1E7E, 0x1E7F, /* LATIN CAPITAL LETTER V WITH DOT BELOW */
879 1.11 mlelstv 0x1E80, 0x1E81, /* LATIN CAPITAL LETTER W WITH GRAVE */
880 1.11 mlelstv 0x1E82, 0x1E83, /* LATIN CAPITAL LETTER W WITH ACUTE */
881 1.11 mlelstv 0x1E84, 0x1E85, /* LATIN CAPITAL LETTER W WITH DIAERESIS */
882 1.11 mlelstv 0x1E86, 0x1E87, /* LATIN CAPITAL LETTER W WITH DOT ABOVE */
883 1.11 mlelstv 0x1E88, 0x1E89, /* LATIN CAPITAL LETTER W WITH DOT BELOW */
884 1.11 mlelstv 0x1E8A, 0x1E8B, /* LATIN CAPITAL LETTER X WITH DOT ABOVE */
885 1.11 mlelstv 0x1E8C, 0x1E8D, /* LATIN CAPITAL LETTER X WITH DIAERESIS */
886 1.11 mlelstv 0x1E8E, 0x1E8F, /* LATIN CAPITAL LETTER Y WITH DOT ABOVE */
887 1.11 mlelstv 0x1E90, 0x1E91, /* LATIN CAPITAL LETTER Z WITH CIRCUMFLEX */
888 1.11 mlelstv 0x1E92, 0x1E93, /* LATIN CAPITAL LETTER Z WITH DOT BELOW */
889 1.11 mlelstv 0x1E94, 0x1E95, /* LATIN CAPITAL LETTER Z WITH LINE BELOW */
890 1.11 mlelstv 0x1E9B, 0x1E61, /* LATIN SMALL LETTER LONG S WITH DOT ABOVE */
891 1.11 mlelstv 0x1EA0, 0x1EA1, /* LATIN CAPITAL LETTER A WITH DOT BELOW */
892 1.11 mlelstv 0x1EA2, 0x1EA3, /* LATIN CAPITAL LETTER A WITH HOOK ABOVE */
893 1.11 mlelstv 0x1EA4, 0x1EA5, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */
894 1.11 mlelstv 0x1EA6, 0x1EA7, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */
895 1.11 mlelstv 0x1EA8, 0x1EA9, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
896 1.11 mlelstv 0x1EAA, 0x1EAB, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */
897 1.11 mlelstv 0x1EAC, 0x1EAD, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
898 1.11 mlelstv 0x1EAE, 0x1EAF, /* LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */
899 1.11 mlelstv 0x1EB0, 0x1EB1, /* LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */
900 1.11 mlelstv 0x1EB2, 0x1EB3, /* LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */
901 1.11 mlelstv 0x1EB4, 0x1EB5, /* LATIN CAPITAL LETTER A WITH BREVE AND TILDE */
902 1.11 mlelstv 0x1EB6, 0x1EB7, /* LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */
903 1.11 mlelstv 0x1EB8, 0x1EB9, /* LATIN CAPITAL LETTER E WITH DOT BELOW */
904 1.11 mlelstv 0x1EBA, 0x1EBB, /* LATIN CAPITAL LETTER E WITH HOOK ABOVE */
905 1.11 mlelstv 0x1EBC, 0x1EBD, /* LATIN CAPITAL LETTER E WITH TILDE */
906 1.11 mlelstv 0x1EBE, 0x1EBF, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */
907 1.11 mlelstv 0x1EC0, 0x1EC1, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */
908 1.11 mlelstv 0x1EC2, 0x1EC3, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
909 1.11 mlelstv 0x1EC4, 0x1EC5, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */
910 1.11 mlelstv 0x1EC6, 0x1EC7, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
911 1.11 mlelstv 0x1EC8, 0x1EC9, /* LATIN CAPITAL LETTER I WITH HOOK ABOVE */
912 1.11 mlelstv 0x1ECA, 0x1ECB, /* LATIN CAPITAL LETTER I WITH DOT BELOW */
913 1.11 mlelstv 0x1ECC, 0x1ECD, /* LATIN CAPITAL LETTER O WITH DOT BELOW */
914 1.11 mlelstv 0x1ECE, 0x1ECF, /* LATIN CAPITAL LETTER O WITH HOOK ABOVE */
915 1.11 mlelstv 0x1ED0, 0x1ED1, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
916 1.11 mlelstv 0x1ED2, 0x1ED3, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */
917 1.11 mlelstv 0x1ED4, 0x1ED5, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
918 1.11 mlelstv 0x1ED6, 0x1ED7, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */
919 1.11 mlelstv 0x1ED8, 0x1ED9, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
920 1.11 mlelstv 0x1EDA, 0x1EDB, /* LATIN CAPITAL LETTER O WITH HORN AND ACUTE */
921 1.11 mlelstv 0x1EDC, 0x1EDD, /* LATIN CAPITAL LETTER O WITH HORN AND GRAVE */
922 1.11 mlelstv 0x1EDE, 0x1EDF, /* LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */
923 1.11 mlelstv 0x1EE0, 0x1EE1, /* LATIN CAPITAL LETTER O WITH HORN AND TILDE */
924 1.11 mlelstv 0x1EE2, 0x1EE3, /* LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */
925 1.11 mlelstv 0x1EE4, 0x1EE5, /* LATIN CAPITAL LETTER U WITH DOT BELOW */
926 1.11 mlelstv 0x1EE6, 0x1EE7, /* LATIN CAPITAL LETTER U WITH HOOK ABOVE */
927 1.11 mlelstv 0x1EE8, 0x1EE9, /* LATIN CAPITAL LETTER U WITH HORN AND ACUTE */
928 1.11 mlelstv 0x1EEA, 0x1EEB, /* LATIN CAPITAL LETTER U WITH HORN AND GRAVE */
929 1.11 mlelstv 0x1EEC, 0x1EED, /* LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */
930 1.11 mlelstv 0x1EEE, 0x1EEF, /* LATIN CAPITAL LETTER U WITH HORN AND TILDE */
931 1.11 mlelstv 0x1EF0, 0x1EF1, /* LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */
932 1.11 mlelstv 0x1EF2, 0x1EF3, /* LATIN CAPITAL LETTER Y WITH GRAVE */
933 1.11 mlelstv 0x1EF4, 0x1EF5, /* LATIN CAPITAL LETTER Y WITH DOT BELOW */
934 1.11 mlelstv 0x1EF6, 0x1EF7, /* LATIN CAPITAL LETTER Y WITH HOOK ABOVE */
935 1.11 mlelstv 0x1EF8, 0x1EF9, /* LATIN CAPITAL LETTER Y WITH TILDE */
936 1.11 mlelstv 0x1F08, 0x1F00, /* GREEK CAPITAL LETTER ALPHA WITH PSILI */
937 1.11 mlelstv 0x1F09, 0x1F01, /* GREEK CAPITAL LETTER ALPHA WITH DASIA */
938 1.11 mlelstv 0x1F0A, 0x1F02, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA */
939 1.11 mlelstv 0x1F0B, 0x1F03, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA */
940 1.11 mlelstv 0x1F0C, 0x1F04, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA */
941 1.11 mlelstv 0x1F0D, 0x1F05, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA */
942 1.11 mlelstv 0x1F0E, 0x1F06, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI */
943 1.11 mlelstv 0x1F0F, 0x1F07, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI */
944 1.11 mlelstv 0x1F18, 0x1F10, /* GREEK CAPITAL LETTER EPSILON WITH PSILI */
945 1.11 mlelstv 0x1F19, 0x1F11, /* GREEK CAPITAL LETTER EPSILON WITH DASIA */
946 1.11 mlelstv 0x1F1A, 0x1F12, /* GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA */
947 1.11 mlelstv 0x1F1B, 0x1F13, /* GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA */
948 1.11 mlelstv 0x1F1C, 0x1F14, /* GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA */
949 1.11 mlelstv 0x1F1D, 0x1F15, /* GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA */
950 1.11 mlelstv 0x1F28, 0x1F20, /* GREEK CAPITAL LETTER ETA WITH PSILI */
951 1.11 mlelstv 0x1F29, 0x1F21, /* GREEK CAPITAL LETTER ETA WITH DASIA */
952 1.11 mlelstv 0x1F2A, 0x1F22, /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA */
953 1.11 mlelstv 0x1F2B, 0x1F23, /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA */
954 1.11 mlelstv 0x1F2C, 0x1F24, /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA */
955 1.11 mlelstv 0x1F2D, 0x1F25, /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA */
956 1.11 mlelstv 0x1F2E, 0x1F26, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI */
957 1.11 mlelstv 0x1F2F, 0x1F27, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI */
958 1.11 mlelstv 0x1F38, 0x1F30, /* GREEK CAPITAL LETTER IOTA WITH PSILI */
959 1.11 mlelstv 0x1F39, 0x1F31, /* GREEK CAPITAL LETTER IOTA WITH DASIA */
960 1.11 mlelstv 0x1F3A, 0x1F32, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA */
961 1.11 mlelstv 0x1F3B, 0x1F33, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA */
962 1.11 mlelstv 0x1F3C, 0x1F34, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA */
963 1.11 mlelstv 0x1F3D, 0x1F35, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA */
964 1.11 mlelstv 0x1F3E, 0x1F36, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI */
965 1.11 mlelstv 0x1F3F, 0x1F37, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI */
966 1.11 mlelstv 0x1F48, 0x1F40, /* GREEK CAPITAL LETTER OMICRON WITH PSILI */
967 1.11 mlelstv 0x1F49, 0x1F41, /* GREEK CAPITAL LETTER OMICRON WITH DASIA */
968 1.11 mlelstv 0x1F4A, 0x1F42, /* GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA */
969 1.11 mlelstv 0x1F4B, 0x1F43, /* GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA */
970 1.11 mlelstv 0x1F4C, 0x1F44, /* GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA */
971 1.11 mlelstv 0x1F4D, 0x1F45, /* GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA */
972 1.11 mlelstv 0x1F59, 0x1F51, /* GREEK CAPITAL LETTER UPSILON WITH DASIA */
973 1.11 mlelstv 0x1F5B, 0x1F53, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA */
974 1.11 mlelstv 0x1F5D, 0x1F55, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA */
975 1.11 mlelstv 0x1F5F, 0x1F57, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI */
976 1.11 mlelstv 0x1F68, 0x1F60, /* GREEK CAPITAL LETTER OMEGA WITH PSILI */
977 1.11 mlelstv 0x1F69, 0x1F61, /* GREEK CAPITAL LETTER OMEGA WITH DASIA */
978 1.11 mlelstv 0x1F6A, 0x1F62, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA */
979 1.11 mlelstv 0x1F6B, 0x1F63, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA */
980 1.11 mlelstv 0x1F6C, 0x1F64, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA */
981 1.11 mlelstv 0x1F6D, 0x1F65, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA */
982 1.11 mlelstv 0x1F6E, 0x1F66, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI */
983 1.11 mlelstv 0x1F6F, 0x1F67, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI */
984 1.11 mlelstv 0x1F88, 0x1F80, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI */
985 1.11 mlelstv 0x1F89, 0x1F81, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI */
986 1.11 mlelstv 0x1F8A, 0x1F82, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
987 1.11 mlelstv 0x1F8B, 0x1F83, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
988 1.11 mlelstv 0x1F8C, 0x1F84, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
989 1.11 mlelstv 0x1F8D, 0x1F85, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
990 1.11 mlelstv 0x1F8E, 0x1F86, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
991 1.11 mlelstv 0x1F8F, 0x1F87, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
992 1.11 mlelstv 0x1F98, 0x1F90, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI */
993 1.11 mlelstv 0x1F99, 0x1F91, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI */
994 1.11 mlelstv 0x1F9A, 0x1F92, /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
995 1.11 mlelstv 0x1F9B, 0x1F93, /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
996 1.11 mlelstv 0x1F9C, 0x1F94, /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
997 1.11 mlelstv 0x1F9D, 0x1F95, /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
998 1.11 mlelstv 0x1F9E, 0x1F96, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
999 1.11 mlelstv 0x1F9F, 0x1F97, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
1000 1.11 mlelstv 0x1FA8, 0x1FA0, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI */
1001 1.11 mlelstv 0x1FA9, 0x1FA1, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI */
1002 1.11 mlelstv 0x1FAA, 0x1FA2, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
1003 1.11 mlelstv 0x1FAB, 0x1FA3, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
1004 1.11 mlelstv 0x1FAC, 0x1FA4, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
1005 1.11 mlelstv 0x1FAD, 0x1FA5, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
1006 1.11 mlelstv 0x1FAE, 0x1FA6, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
1007 1.11 mlelstv 0x1FAF, 0x1FA7, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
1008 1.11 mlelstv 0x1FB8, 0x1FB0, /* GREEK CAPITAL LETTER ALPHA WITH VRACHY */
1009 1.11 mlelstv 0x1FB9, 0x1FB1, /* GREEK CAPITAL LETTER ALPHA WITH MACRON */
1010 1.11 mlelstv 0x1FBA, 0x1F70, /* GREEK CAPITAL LETTER ALPHA WITH VARIA */
1011 1.11 mlelstv 0x1FBB, 0x1F71, /* GREEK CAPITAL LETTER ALPHA WITH OXIA */
1012 1.11 mlelstv 0x1FBC, 0x1FB3, /* GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI */
1013 1.11 mlelstv 0x1FBE, 0x03B9, /* GREEK PROSGEGRAMMENI */
1014 1.11 mlelstv 0x1FC8, 0x1F72, /* GREEK CAPITAL LETTER EPSILON WITH VARIA */
1015 1.11 mlelstv 0x1FC9, 0x1F73, /* GREEK CAPITAL LETTER EPSILON WITH OXIA */
1016 1.11 mlelstv 0x1FCA, 0x1F74, /* GREEK CAPITAL LETTER ETA WITH VARIA */
1017 1.11 mlelstv 0x1FCB, 0x1F75, /* GREEK CAPITAL LETTER ETA WITH OXIA */
1018 1.11 mlelstv 0x1FCC, 0x1FC3, /* GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI */
1019 1.11 mlelstv 0x1FD8, 0x1FD0, /* GREEK CAPITAL LETTER IOTA WITH VRACHY */
1020 1.11 mlelstv 0x1FD9, 0x1FD1, /* GREEK CAPITAL LETTER IOTA WITH MACRON */
1021 1.11 mlelstv 0x1FDA, 0x1F76, /* GREEK CAPITAL LETTER IOTA WITH VARIA */
1022 1.11 mlelstv 0x1FDB, 0x1F77, /* GREEK CAPITAL LETTER IOTA WITH OXIA */
1023 1.11 mlelstv 0x1FE8, 0x1FE0, /* GREEK CAPITAL LETTER UPSILON WITH VRACHY */
1024 1.11 mlelstv 0x1FE9, 0x1FE1, /* GREEK CAPITAL LETTER UPSILON WITH MACRON */
1025 1.11 mlelstv 0x1FEA, 0x1F7A, /* GREEK CAPITAL LETTER UPSILON WITH VARIA */
1026 1.11 mlelstv 0x1FEB, 0x1F7B, /* GREEK CAPITAL LETTER UPSILON WITH OXIA */
1027 1.11 mlelstv 0x1FEC, 0x1FE5, /* GREEK CAPITAL LETTER RHO WITH DASIA */
1028 1.11 mlelstv 0x1FF8, 0x1F78, /* GREEK CAPITAL LETTER OMICRON WITH VARIA */
1029 1.11 mlelstv 0x1FF9, 0x1F79, /* GREEK CAPITAL LETTER OMICRON WITH OXIA */
1030 1.11 mlelstv 0x1FFA, 0x1F7C, /* GREEK CAPITAL LETTER OMEGA WITH VARIA */
1031 1.11 mlelstv 0x1FFB, 0x1F7D, /* GREEK CAPITAL LETTER OMEGA WITH OXIA */
1032 1.11 mlelstv 0x1FFC, 0x1FF3, /* GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI */
1033 1.11 mlelstv 0x2126, 0x03C9, /* OHM SIGN */
1034 1.11 mlelstv 0x212A, 0x006B, /* KELVIN SIGN */
1035 1.11 mlelstv 0x212B, 0x00E5, /* ANGSTROM SIGN */
1036 1.11 mlelstv 0x2132, 0x214E, /* TURNED CAPITAL F */
1037 1.11 mlelstv 0x2160, 0x2170, /* ROMAN NUMERAL ONE */
1038 1.11 mlelstv 0x2161, 0x2171, /* ROMAN NUMERAL TWO */
1039 1.11 mlelstv 0x2162, 0x2172, /* ROMAN NUMERAL THREE */
1040 1.11 mlelstv 0x2163, 0x2173, /* ROMAN NUMERAL FOUR */
1041 1.11 mlelstv 0x2164, 0x2174, /* ROMAN NUMERAL FIVE */
1042 1.11 mlelstv 0x2165, 0x2175, /* ROMAN NUMERAL SIX */
1043 1.11 mlelstv 0x2166, 0x2176, /* ROMAN NUMERAL SEVEN */
1044 1.11 mlelstv 0x2167, 0x2177, /* ROMAN NUMERAL EIGHT */
1045 1.11 mlelstv 0x2168, 0x2178, /* ROMAN NUMERAL NINE */
1046 1.11 mlelstv 0x2169, 0x2179, /* ROMAN NUMERAL TEN */
1047 1.11 mlelstv 0x216A, 0x217A, /* ROMAN NUMERAL ELEVEN */
1048 1.11 mlelstv 0x216B, 0x217B, /* ROMAN NUMERAL TWELVE */
1049 1.11 mlelstv 0x216C, 0x217C, /* ROMAN NUMERAL FIFTY */
1050 1.11 mlelstv 0x216D, 0x217D, /* ROMAN NUMERAL ONE HUNDRED */
1051 1.11 mlelstv 0x216E, 0x217E, /* ROMAN NUMERAL FIVE HUNDRED */
1052 1.11 mlelstv 0x216F, 0x217F, /* ROMAN NUMERAL ONE THOUSAND */
1053 1.11 mlelstv 0x2183, 0x2184, /* ROMAN NUMERAL REVERSED ONE HUNDRED */
1054 1.11 mlelstv 0x24B6, 0x24D0, /* CIRCLED LATIN CAPITAL LETTER A */
1055 1.11 mlelstv 0x24B7, 0x24D1, /* CIRCLED LATIN CAPITAL LETTER B */
1056 1.11 mlelstv 0x24B8, 0x24D2, /* CIRCLED LATIN CAPITAL LETTER C */
1057 1.11 mlelstv 0x24B9, 0x24D3, /* CIRCLED LATIN CAPITAL LETTER D */
1058 1.11 mlelstv 0x24BA, 0x24D4, /* CIRCLED LATIN CAPITAL LETTER E */
1059 1.11 mlelstv 0x24BB, 0x24D5, /* CIRCLED LATIN CAPITAL LETTER F */
1060 1.11 mlelstv 0x24BC, 0x24D6, /* CIRCLED LATIN CAPITAL LETTER G */
1061 1.11 mlelstv 0x24BD, 0x24D7, /* CIRCLED LATIN CAPITAL LETTER H */
1062 1.11 mlelstv 0x24BE, 0x24D8, /* CIRCLED LATIN CAPITAL LETTER I */
1063 1.11 mlelstv 0x24BF, 0x24D9, /* CIRCLED LATIN CAPITAL LETTER J */
1064 1.11 mlelstv 0x24C0, 0x24DA, /* CIRCLED LATIN CAPITAL LETTER K */
1065 1.11 mlelstv 0x24C1, 0x24DB, /* CIRCLED LATIN CAPITAL LETTER L */
1066 1.11 mlelstv 0x24C2, 0x24DC, /* CIRCLED LATIN CAPITAL LETTER M */
1067 1.11 mlelstv 0x24C3, 0x24DD, /* CIRCLED LATIN CAPITAL LETTER N */
1068 1.11 mlelstv 0x24C4, 0x24DE, /* CIRCLED LATIN CAPITAL LETTER O */
1069 1.11 mlelstv 0x24C5, 0x24DF, /* CIRCLED LATIN CAPITAL LETTER P */
1070 1.11 mlelstv 0x24C6, 0x24E0, /* CIRCLED LATIN CAPITAL LETTER Q */
1071 1.11 mlelstv 0x24C7, 0x24E1, /* CIRCLED LATIN CAPITAL LETTER R */
1072 1.11 mlelstv 0x24C8, 0x24E2, /* CIRCLED LATIN CAPITAL LETTER S */
1073 1.11 mlelstv 0x24C9, 0x24E3, /* CIRCLED LATIN CAPITAL LETTER T */
1074 1.11 mlelstv 0x24CA, 0x24E4, /* CIRCLED LATIN CAPITAL LETTER U */
1075 1.11 mlelstv 0x24CB, 0x24E5, /* CIRCLED LATIN CAPITAL LETTER V */
1076 1.11 mlelstv 0x24CC, 0x24E6, /* CIRCLED LATIN CAPITAL LETTER W */
1077 1.11 mlelstv 0x24CD, 0x24E7, /* CIRCLED LATIN CAPITAL LETTER X */
1078 1.11 mlelstv 0x24CE, 0x24E8, /* CIRCLED LATIN CAPITAL LETTER Y */
1079 1.11 mlelstv 0x24CF, 0x24E9, /* CIRCLED LATIN CAPITAL LETTER Z */
1080 1.11 mlelstv 0x2C00, 0x2C30, /* GLAGOLITIC CAPITAL LETTER AZU */
1081 1.11 mlelstv 0x2C01, 0x2C31, /* GLAGOLITIC CAPITAL LETTER BUKY */
1082 1.11 mlelstv 0x2C02, 0x2C32, /* GLAGOLITIC CAPITAL LETTER VEDE */
1083 1.11 mlelstv 0x2C03, 0x2C33, /* GLAGOLITIC CAPITAL LETTER GLAGOLI */
1084 1.11 mlelstv 0x2C04, 0x2C34, /* GLAGOLITIC CAPITAL LETTER DOBRO */
1085 1.11 mlelstv 0x2C05, 0x2C35, /* GLAGOLITIC CAPITAL LETTER YESTU */
1086 1.11 mlelstv 0x2C06, 0x2C36, /* GLAGOLITIC CAPITAL LETTER ZHIVETE */
1087 1.11 mlelstv 0x2C07, 0x2C37, /* GLAGOLITIC CAPITAL LETTER DZELO */
1088 1.11 mlelstv 0x2C08, 0x2C38, /* GLAGOLITIC CAPITAL LETTER ZEMLJA */
1089 1.11 mlelstv 0x2C09, 0x2C39, /* GLAGOLITIC CAPITAL LETTER IZHE */
1090 1.11 mlelstv 0x2C0A, 0x2C3A, /* GLAGOLITIC CAPITAL LETTER INITIAL IZHE */
1091 1.11 mlelstv 0x2C0B, 0x2C3B, /* GLAGOLITIC CAPITAL LETTER I */
1092 1.11 mlelstv 0x2C0C, 0x2C3C, /* GLAGOLITIC CAPITAL LETTER DJERVI */
1093 1.11 mlelstv 0x2C0D, 0x2C3D, /* GLAGOLITIC CAPITAL LETTER KAKO */
1094 1.11 mlelstv 0x2C0E, 0x2C3E, /* GLAGOLITIC CAPITAL LETTER LJUDIJE */
1095 1.11 mlelstv 0x2C0F, 0x2C3F, /* GLAGOLITIC CAPITAL LETTER MYSLITE */
1096 1.11 mlelstv 0x2C10, 0x2C40, /* GLAGOLITIC CAPITAL LETTER NASHI */
1097 1.11 mlelstv 0x2C11, 0x2C41, /* GLAGOLITIC CAPITAL LETTER ONU */
1098 1.11 mlelstv 0x2C12, 0x2C42, /* GLAGOLITIC CAPITAL LETTER POKOJI */
1099 1.11 mlelstv 0x2C13, 0x2C43, /* GLAGOLITIC CAPITAL LETTER RITSI */
1100 1.11 mlelstv 0x2C14, 0x2C44, /* GLAGOLITIC CAPITAL LETTER SLOVO */
1101 1.11 mlelstv 0x2C15, 0x2C45, /* GLAGOLITIC CAPITAL LETTER TVRIDO */
1102 1.11 mlelstv 0x2C16, 0x2C46, /* GLAGOLITIC CAPITAL LETTER UKU */
1103 1.11 mlelstv 0x2C17, 0x2C47, /* GLAGOLITIC CAPITAL LETTER FRITU */
1104 1.11 mlelstv 0x2C18, 0x2C48, /* GLAGOLITIC CAPITAL LETTER HERU */
1105 1.11 mlelstv 0x2C19, 0x2C49, /* GLAGOLITIC CAPITAL LETTER OTU */
1106 1.11 mlelstv 0x2C1A, 0x2C4A, /* GLAGOLITIC CAPITAL LETTER PE */
1107 1.11 mlelstv 0x2C1B, 0x2C4B, /* GLAGOLITIC CAPITAL LETTER SHTA */
1108 1.11 mlelstv 0x2C1C, 0x2C4C, /* GLAGOLITIC CAPITAL LETTER TSI */
1109 1.11 mlelstv 0x2C1D, 0x2C4D, /* GLAGOLITIC CAPITAL LETTER CHRIVI */
1110 1.11 mlelstv 0x2C1E, 0x2C4E, /* GLAGOLITIC CAPITAL LETTER SHA */
1111 1.11 mlelstv 0x2C1F, 0x2C4F, /* GLAGOLITIC CAPITAL LETTER YERU */
1112 1.11 mlelstv 0x2C20, 0x2C50, /* GLAGOLITIC CAPITAL LETTER YERI */
1113 1.11 mlelstv 0x2C21, 0x2C51, /* GLAGOLITIC CAPITAL LETTER YATI */
1114 1.11 mlelstv 0x2C22, 0x2C52, /* GLAGOLITIC CAPITAL LETTER SPIDERY HA */
1115 1.11 mlelstv 0x2C23, 0x2C53, /* GLAGOLITIC CAPITAL LETTER YU */
1116 1.11 mlelstv 0x2C24, 0x2C54, /* GLAGOLITIC CAPITAL LETTER SMALL YUS */
1117 1.11 mlelstv 0x2C25, 0x2C55, /* GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL */
1118 1.11 mlelstv 0x2C26, 0x2C56, /* GLAGOLITIC CAPITAL LETTER YO */
1119 1.11 mlelstv 0x2C27, 0x2C57, /* GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS */
1120 1.11 mlelstv 0x2C28, 0x2C58, /* GLAGOLITIC CAPITAL LETTER BIG YUS */
1121 1.11 mlelstv 0x2C29, 0x2C59, /* GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS */
1122 1.11 mlelstv 0x2C2A, 0x2C5A, /* GLAGOLITIC CAPITAL LETTER FITA */
1123 1.11 mlelstv 0x2C2B, 0x2C5B, /* GLAGOLITIC CAPITAL LETTER IZHITSA */
1124 1.11 mlelstv 0x2C2C, 0x2C5C, /* GLAGOLITIC CAPITAL LETTER SHTAPIC */
1125 1.11 mlelstv 0x2C2D, 0x2C5D, /* GLAGOLITIC CAPITAL LETTER TROKUTASTI A */
1126 1.11 mlelstv 0x2C2E, 0x2C5E, /* GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE */
1127 1.11 mlelstv 0x2C60, 0x2C61, /* LATIN CAPITAL LETTER L WITH DOUBLE BAR */
1128 1.11 mlelstv 0x2C62, 0x026B, /* LATIN CAPITAL LETTER L WITH MIDDLE TILDE */
1129 1.11 mlelstv 0x2C63, 0x1D7D, /* LATIN CAPITAL LETTER P WITH STROKE */
1130 1.11 mlelstv 0x2C64, 0x027D, /* LATIN CAPITAL LETTER R WITH TAIL */
1131 1.11 mlelstv 0x2C67, 0x2C68, /* LATIN CAPITAL LETTER H WITH DESCENDER */
1132 1.11 mlelstv 0x2C69, 0x2C6A, /* LATIN CAPITAL LETTER K WITH DESCENDER */
1133 1.11 mlelstv 0x2C6B, 0x2C6C, /* LATIN CAPITAL LETTER Z WITH DESCENDER */
1134 1.11 mlelstv 0x2C75, 0x2C76, /* LATIN CAPITAL LETTER HALF H */
1135 1.11 mlelstv 0x2C80, 0x2C81, /* COPTIC CAPITAL LETTER ALFA */
1136 1.11 mlelstv 0x2C82, 0x2C83, /* COPTIC CAPITAL LETTER VIDA */
1137 1.11 mlelstv 0x2C84, 0x2C85, /* COPTIC CAPITAL LETTER GAMMA */
1138 1.11 mlelstv 0x2C86, 0x2C87, /* COPTIC CAPITAL LETTER DALDA */
1139 1.11 mlelstv 0x2C88, 0x2C89, /* COPTIC CAPITAL LETTER EIE */
1140 1.11 mlelstv 0x2C8A, 0x2C8B, /* COPTIC CAPITAL LETTER SOU */
1141 1.11 mlelstv 0x2C8C, 0x2C8D, /* COPTIC CAPITAL LETTER ZATA */
1142 1.11 mlelstv 0x2C8E, 0x2C8F, /* COPTIC CAPITAL LETTER HATE */
1143 1.11 mlelstv 0x2C90, 0x2C91, /* COPTIC CAPITAL LETTER THETHE */
1144 1.11 mlelstv 0x2C92, 0x2C93, /* COPTIC CAPITAL LETTER IAUDA */
1145 1.11 mlelstv 0x2C94, 0x2C95, /* COPTIC CAPITAL LETTER KAPA */
1146 1.11 mlelstv 0x2C96, 0x2C97, /* COPTIC CAPITAL LETTER LAULA */
1147 1.11 mlelstv 0x2C98, 0x2C99, /* COPTIC CAPITAL LETTER MI */
1148 1.11 mlelstv 0x2C9A, 0x2C9B, /* COPTIC CAPITAL LETTER NI */
1149 1.11 mlelstv 0x2C9C, 0x2C9D, /* COPTIC CAPITAL LETTER KSI */
1150 1.11 mlelstv 0x2C9E, 0x2C9F, /* COPTIC CAPITAL LETTER O */
1151 1.11 mlelstv 0x2CA0, 0x2CA1, /* COPTIC CAPITAL LETTER PI */
1152 1.11 mlelstv 0x2CA2, 0x2CA3, /* COPTIC CAPITAL LETTER RO */
1153 1.11 mlelstv 0x2CA4, 0x2CA5, /* COPTIC CAPITAL LETTER SIMA */
1154 1.11 mlelstv 0x2CA6, 0x2CA7, /* COPTIC CAPITAL LETTER TAU */
1155 1.11 mlelstv 0x2CA8, 0x2CA9, /* COPTIC CAPITAL LETTER UA */
1156 1.11 mlelstv 0x2CAA, 0x2CAB, /* COPTIC CAPITAL LETTER FI */
1157 1.11 mlelstv 0x2CAC, 0x2CAD, /* COPTIC CAPITAL LETTER KHI */
1158 1.11 mlelstv 0x2CAE, 0x2CAF, /* COPTIC CAPITAL LETTER PSI */
1159 1.11 mlelstv 0x2CB0, 0x2CB1, /* COPTIC CAPITAL LETTER OOU */
1160 1.11 mlelstv 0x2CB2, 0x2CB3, /* COPTIC CAPITAL LETTER DIALECT-P ALEF */
1161 1.11 mlelstv 0x2CB4, 0x2CB5, /* COPTIC CAPITAL LETTER OLD COPTIC AIN */
1162 1.11 mlelstv 0x2CB6, 0x2CB7, /* COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE */
1163 1.11 mlelstv 0x2CB8, 0x2CB9, /* COPTIC CAPITAL LETTER DIALECT-P KAPA */
1164 1.11 mlelstv 0x2CBA, 0x2CBB, /* COPTIC CAPITAL LETTER DIALECT-P NI */
1165 1.11 mlelstv 0x2CBC, 0x2CBD, /* COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI */
1166 1.11 mlelstv 0x2CBE, 0x2CBF, /* COPTIC CAPITAL LETTER OLD COPTIC OOU */
1167 1.11 mlelstv 0x2CC0, 0x2CC1, /* COPTIC CAPITAL LETTER SAMPI */
1168 1.11 mlelstv 0x2CC2, 0x2CC3, /* COPTIC CAPITAL LETTER CROSSED SHEI */
1169 1.11 mlelstv 0x2CC4, 0x2CC5, /* COPTIC CAPITAL LETTER OLD COPTIC SHEI */
1170 1.11 mlelstv 0x2CC6, 0x2CC7, /* COPTIC CAPITAL LETTER OLD COPTIC ESH */
1171 1.11 mlelstv 0x2CC8, 0x2CC9, /* COPTIC CAPITAL LETTER AKHMIMIC KHEI */
1172 1.11 mlelstv 0x2CCA, 0x2CCB, /* COPTIC CAPITAL LETTER DIALECT-P HORI */
1173 1.11 mlelstv 0x2CCC, 0x2CCD, /* COPTIC CAPITAL LETTER OLD COPTIC HORI */
1174 1.11 mlelstv 0x2CCE, 0x2CCF, /* COPTIC CAPITAL LETTER OLD COPTIC HA */
1175 1.11 mlelstv 0x2CD0, 0x2CD1, /* COPTIC CAPITAL LETTER L-SHAPED HA */
1176 1.11 mlelstv 0x2CD2, 0x2CD3, /* COPTIC CAPITAL LETTER OLD COPTIC HEI */
1177 1.11 mlelstv 0x2CD4, 0x2CD5, /* COPTIC CAPITAL LETTER OLD COPTIC HAT */
1178 1.11 mlelstv 0x2CD6, 0x2CD7, /* COPTIC CAPITAL LETTER OLD COPTIC GANGIA */
1179 1.11 mlelstv 0x2CD8, 0x2CD9, /* COPTIC CAPITAL LETTER OLD COPTIC DJA */
1180 1.11 mlelstv 0x2CDA, 0x2CDB, /* COPTIC CAPITAL LETTER OLD COPTIC SHIMA */
1181 1.11 mlelstv 0x2CDC, 0x2CDD, /* COPTIC CAPITAL LETTER OLD NUBIAN SHIMA */
1182 1.11 mlelstv 0x2CDE, 0x2CDF, /* COPTIC CAPITAL LETTER OLD NUBIAN NGI */
1183 1.11 mlelstv 0x2CE0, 0x2CE1, /* COPTIC CAPITAL LETTER OLD NUBIAN NYI */
1184 1.11 mlelstv 0x2CE2, 0x2CE3, /* COPTIC CAPITAL LETTER OLD NUBIAN WAU */
1185 1.11 mlelstv 0xFF21, 0xFF41, /* FULLWIDTH LATIN CAPITAL LETTER A */
1186 1.11 mlelstv 0xFF22, 0xFF42, /* FULLWIDTH LATIN CAPITAL LETTER B */
1187 1.11 mlelstv 0xFF23, 0xFF43, /* FULLWIDTH LATIN CAPITAL LETTER C */
1188 1.11 mlelstv 0xFF24, 0xFF44, /* FULLWIDTH LATIN CAPITAL LETTER D */
1189 1.11 mlelstv 0xFF25, 0xFF45, /* FULLWIDTH LATIN CAPITAL LETTER E */
1190 1.11 mlelstv 0xFF26, 0xFF46, /* FULLWIDTH LATIN CAPITAL LETTER F */
1191 1.11 mlelstv 0xFF27, 0xFF47, /* FULLWIDTH LATIN CAPITAL LETTER G */
1192 1.11 mlelstv 0xFF28, 0xFF48, /* FULLWIDTH LATIN CAPITAL LETTER H */
1193 1.11 mlelstv 0xFF29, 0xFF49, /* FULLWIDTH LATIN CAPITAL LETTER I */
1194 1.11 mlelstv 0xFF2A, 0xFF4A, /* FULLWIDTH LATIN CAPITAL LETTER J */
1195 1.11 mlelstv 0xFF2B, 0xFF4B, /* FULLWIDTH LATIN CAPITAL LETTER K */
1196 1.11 mlelstv 0xFF2C, 0xFF4C, /* FULLWIDTH LATIN CAPITAL LETTER L */
1197 1.11 mlelstv 0xFF2D, 0xFF4D, /* FULLWIDTH LATIN CAPITAL LETTER M */
1198 1.11 mlelstv 0xFF2E, 0xFF4E, /* FULLWIDTH LATIN CAPITAL LETTER N */
1199 1.11 mlelstv 0xFF2F, 0xFF4F, /* FULLWIDTH LATIN CAPITAL LETTER O */
1200 1.11 mlelstv 0xFF30, 0xFF50, /* FULLWIDTH LATIN CAPITAL LETTER P */
1201 1.11 mlelstv 0xFF31, 0xFF51, /* FULLWIDTH LATIN CAPITAL LETTER Q */
1202 1.11 mlelstv 0xFF32, 0xFF52, /* FULLWIDTH LATIN CAPITAL LETTER R */
1203 1.11 mlelstv 0xFF33, 0xFF53, /* FULLWIDTH LATIN CAPITAL LETTER S */
1204 1.11 mlelstv 0xFF34, 0xFF54, /* FULLWIDTH LATIN CAPITAL LETTER T */
1205 1.11 mlelstv 0xFF35, 0xFF55, /* FULLWIDTH LATIN CAPITAL LETTER U */
1206 1.11 mlelstv 0xFF36, 0xFF56, /* FULLWIDTH LATIN CAPITAL LETTER V */
1207 1.11 mlelstv 0xFF37, 0xFF57, /* FULLWIDTH LATIN CAPITAL LETTER W */
1208 1.11 mlelstv 0xFF38, 0xFF58, /* FULLWIDTH LATIN CAPITAL LETTER X */
1209 1.11 mlelstv 0xFF39, 0xFF59, /* FULLWIDTH LATIN CAPITAL LETTER Y */
1210 1.11 mlelstv 0xFF3A, 0xFF5A, /* FULLWIDTH LATIN CAPITAL LETTER Z */
1211 1.11 mlelstv };
1212 1.11 mlelstv
1213 1.1 jdolecek /*
1214 1.1 jdolecek * DOS filenames are made of 2 parts, the name part and the extension part.
1215 1.1 jdolecek * The name part is 8 characters long and the extension part is 3
1216 1.1 jdolecek * characters long. They may contain trailing blanks if the name or
1217 1.1 jdolecek * extension are not long enough to fill their respective fields.
1218 1.1 jdolecek */
1219 1.1 jdolecek
1220 1.1 jdolecek /*
1221 1.1 jdolecek * Convert a DOS filename to a unix filename. And, return the number of
1222 1.1 jdolecek * characters in the resulting unix filename excluding the terminating
1223 1.1 jdolecek * null.
1224 1.1 jdolecek */
1225 1.1 jdolecek int
1226 1.7 cegger dos2unixfn(u_char dn[11], u_char *un, int lower)
1227 1.1 jdolecek {
1228 1.1 jdolecek int i, j;
1229 1.1 jdolecek int thislong = 1;
1230 1.1 jdolecek u_char c;
1231 1.1 jdolecek
1232 1.1 jdolecek /*
1233 1.1 jdolecek * If first char of the filename is SLOT_E5 (0x05), then the real
1234 1.1 jdolecek * first char of the filename should be 0xe5. But, they couldn't
1235 1.1 jdolecek * just have a 0xe5 mean 0xe5 because that is used to mean a freed
1236 1.1 jdolecek * directory slot. Another dos quirk.
1237 1.1 jdolecek */
1238 1.1 jdolecek if (*dn == SLOT_E5)
1239 1.1 jdolecek c = dos2unix[0xe5];
1240 1.1 jdolecek else
1241 1.1 jdolecek c = dos2unix[*dn];
1242 1.1 jdolecek *un++ = lower ? u2l[c] : c;
1243 1.1 jdolecek
1244 1.1 jdolecek /*
1245 1.1 jdolecek * Copy the rest into the unix filename string, ignoring
1246 1.1 jdolecek * trailing blanks.
1247 1.1 jdolecek */
1248 1.1 jdolecek
1249 1.1 jdolecek for (j=7; (j >= 0) && (dn[j] == ' '); j--)
1250 1.1 jdolecek ;
1251 1.1 jdolecek
1252 1.1 jdolecek for (i = 1; i <= j; i++) {
1253 1.1 jdolecek c = dos2unix[dn[i]];
1254 1.1 jdolecek *un++ = lower ? u2l[c] : c;
1255 1.1 jdolecek thislong++;
1256 1.1 jdolecek }
1257 1.1 jdolecek dn += 8;
1258 1.3 perry
1259 1.1 jdolecek /*
1260 1.1 jdolecek * Now, if there is an extension then put in a period and copy in
1261 1.1 jdolecek * the extension.
1262 1.1 jdolecek */
1263 1.1 jdolecek if (*dn != ' ') {
1264 1.1 jdolecek *un++ = '.';
1265 1.1 jdolecek thislong++;
1266 1.1 jdolecek for (i = 0; i < 3 && *dn != ' '; i++) {
1267 1.1 jdolecek c = dos2unix[*dn++];
1268 1.1 jdolecek *un++ = lower ? u2l[c] : c;
1269 1.1 jdolecek thislong++;
1270 1.1 jdolecek }
1271 1.1 jdolecek }
1272 1.1 jdolecek *un++ = 0;
1273 1.1 jdolecek
1274 1.1 jdolecek return (thislong);
1275 1.1 jdolecek }
1276 1.1 jdolecek
1277 1.1 jdolecek /*
1278 1.1 jdolecek * Convert a unix filename to a DOS filename according to Win95 rules.
1279 1.1 jdolecek * If applicable and gen is not 0, it is inserted into the converted
1280 1.1 jdolecek * filename as a generation number.
1281 1.1 jdolecek * Returns
1282 1.1 jdolecek * 0 if name couldn't be converted
1283 1.1 jdolecek * 1 if the converted name is the same as the original
1284 1.1 jdolecek * (no long filename entry necessary for Win95)
1285 1.1 jdolecek * 2 if conversion was successful
1286 1.1 jdolecek * 3 if conversion was successful and generation number was inserted
1287 1.1 jdolecek */
1288 1.1 jdolecek int
1289 1.7 cegger unix2dosfn(const u_char *un, u_char dn[12], int unlen, u_int gen)
1290 1.1 jdolecek {
1291 1.1 jdolecek int i, j, l;
1292 1.1 jdolecek int conv = 1;
1293 1.1 jdolecek const u_char *cp, *dp, *dp1;
1294 1.1 jdolecek u_char gentext[6], *wcp;
1295 1.1 jdolecek int shortlen;
1296 1.1 jdolecek
1297 1.1 jdolecek /*
1298 1.1 jdolecek * Fill the dos filename string with blanks. These are DOS's pad
1299 1.1 jdolecek * characters.
1300 1.1 jdolecek */
1301 1.1 jdolecek for (i = 0; i < 11; i++)
1302 1.1 jdolecek dn[i] = ' ';
1303 1.1 jdolecek dn[11] = 0;
1304 1.1 jdolecek
1305 1.1 jdolecek /*
1306 1.1 jdolecek * The filenames "." and ".." are handled specially, since they
1307 1.1 jdolecek * don't follow dos filename rules.
1308 1.1 jdolecek */
1309 1.1 jdolecek if (un[0] == '.' && unlen == 1) {
1310 1.1 jdolecek dn[0] = '.';
1311 1.1 jdolecek return gen <= 1;
1312 1.1 jdolecek }
1313 1.1 jdolecek if (un[0] == '.' && un[1] == '.' && unlen == 2) {
1314 1.1 jdolecek dn[0] = '.';
1315 1.1 jdolecek dn[1] = '.';
1316 1.1 jdolecek return gen <= 1;
1317 1.1 jdolecek }
1318 1.1 jdolecek
1319 1.1 jdolecek /*
1320 1.1 jdolecek * Filenames with only blanks and dots are not allowed!
1321 1.1 jdolecek */
1322 1.1 jdolecek for (cp = un, i = unlen; --i >= 0; cp++)
1323 1.1 jdolecek if (*cp != ' ' && *cp != '.')
1324 1.1 jdolecek break;
1325 1.1 jdolecek if (i < 0)
1326 1.1 jdolecek return 0;
1327 1.1 jdolecek
1328 1.1 jdolecek /*
1329 1.1 jdolecek * Now find the extension
1330 1.1 jdolecek * Note: dot as first char doesn't start extension
1331 1.1 jdolecek * and trailing dots and blanks are ignored
1332 1.1 jdolecek */
1333 1.1 jdolecek dp = dp1 = 0;
1334 1.1 jdolecek for (cp = un + 1, i = unlen - 1; --i >= 0;) {
1335 1.1 jdolecek switch (*cp++) {
1336 1.1 jdolecek case '.':
1337 1.1 jdolecek if (!dp1)
1338 1.1 jdolecek dp1 = cp;
1339 1.1 jdolecek break;
1340 1.1 jdolecek case ' ':
1341 1.1 jdolecek break;
1342 1.1 jdolecek default:
1343 1.1 jdolecek if (dp1)
1344 1.1 jdolecek dp = dp1;
1345 1.1 jdolecek dp1 = 0;
1346 1.1 jdolecek break;
1347 1.1 jdolecek }
1348 1.1 jdolecek }
1349 1.1 jdolecek
1350 1.1 jdolecek /*
1351 1.1 jdolecek * Now convert it
1352 1.1 jdolecek */
1353 1.1 jdolecek if (dp) {
1354 1.1 jdolecek if (dp1)
1355 1.1 jdolecek l = dp1 - dp;
1356 1.1 jdolecek else
1357 1.1 jdolecek l = unlen - (dp - un);
1358 1.1 jdolecek for (i = 0, j = 8; i < l && j < 11; i++, j++) {
1359 1.1 jdolecek if (dp[i] != (dn[j] = unix2dos[dp[i]])
1360 1.1 jdolecek && conv != 3)
1361 1.1 jdolecek conv = 2;
1362 1.1 jdolecek if (!dn[j]) {
1363 1.1 jdolecek conv = 3;
1364 1.1 jdolecek dn[j--] = ' ';
1365 1.1 jdolecek }
1366 1.1 jdolecek }
1367 1.1 jdolecek if (i < l)
1368 1.1 jdolecek conv = 3;
1369 1.1 jdolecek dp--;
1370 1.1 jdolecek } else {
1371 1.1 jdolecek for (dp = cp; *--dp == ' ' || *dp == '.';);
1372 1.1 jdolecek dp++;
1373 1.1 jdolecek }
1374 1.1 jdolecek
1375 1.1 jdolecek shortlen = (dp - un) <= 8;
1376 1.1 jdolecek
1377 1.1 jdolecek /*
1378 1.1 jdolecek * Now convert the rest of the name
1379 1.1 jdolecek */
1380 1.1 jdolecek for (i = j = 0; un < dp && j < 8; i++, j++, un++) {
1381 1.1 jdolecek if ((*un == ' ') && shortlen)
1382 1.1 jdolecek dn[j] = ' ';
1383 1.1 jdolecek else
1384 1.1 jdolecek dn[j] = unix2dos[*un];
1385 1.1 jdolecek if ((*un != dn[j])
1386 1.1 jdolecek && conv != 3)
1387 1.1 jdolecek conv = 2;
1388 1.1 jdolecek if (!dn[j]) {
1389 1.1 jdolecek conv = 3;
1390 1.1 jdolecek dn[j--] = ' ';
1391 1.1 jdolecek }
1392 1.1 jdolecek }
1393 1.1 jdolecek if (un < dp)
1394 1.1 jdolecek conv = 3;
1395 1.1 jdolecek /*
1396 1.1 jdolecek * If we didn't have any chars in filename,
1397 1.1 jdolecek * generate a default
1398 1.1 jdolecek */
1399 1.1 jdolecek if (!j)
1400 1.1 jdolecek dn[0] = '_';
1401 1.1 jdolecek
1402 1.1 jdolecek /*
1403 1.1 jdolecek * The first character cannot be E5,
1404 1.1 jdolecek * because that means a deleted entry
1405 1.1 jdolecek */
1406 1.1 jdolecek if (dn[0] == 0xe5)
1407 1.1 jdolecek dn[0] = SLOT_E5;
1408 1.1 jdolecek
1409 1.1 jdolecek /*
1410 1.1 jdolecek * If there wasn't any char dropped,
1411 1.1 jdolecek * there is no place for generation numbers
1412 1.1 jdolecek */
1413 1.1 jdolecek if (conv != 3) {
1414 1.1 jdolecek if (gen > 1)
1415 1.1 jdolecek return 0;
1416 1.1 jdolecek return conv;
1417 1.1 jdolecek }
1418 1.1 jdolecek
1419 1.1 jdolecek /*
1420 1.1 jdolecek * Now insert the generation number into the filename part
1421 1.1 jdolecek */
1422 1.1 jdolecek for (wcp = gentext + sizeof(gentext); wcp > gentext && gen; gen /= 10)
1423 1.1 jdolecek *--wcp = gen % 10 + '0';
1424 1.1 jdolecek if (gen)
1425 1.1 jdolecek return 0;
1426 1.1 jdolecek for (i = 8; dn[--i] == ' ';);
1427 1.1 jdolecek i++;
1428 1.1 jdolecek if (gentext + sizeof(gentext) - wcp + 1 > 8 - i)
1429 1.1 jdolecek i = 8 - (gentext + sizeof(gentext) - wcp + 1);
1430 1.1 jdolecek dn[i++] = '~';
1431 1.1 jdolecek while (wcp < gentext + sizeof(gentext))
1432 1.1 jdolecek dn[i++] = *wcp++;
1433 1.1 jdolecek return 3;
1434 1.1 jdolecek }
1435 1.1 jdolecek
1436 1.1 jdolecek /*
1437 1.1 jdolecek * Create a Win95 long name directory entry
1438 1.1 jdolecek * Note: assumes that the filename is valid,
1439 1.1 jdolecek * i.e. doesn't consist solely of blanks and dots
1440 1.1 jdolecek */
1441 1.1 jdolecek int
1442 1.11 mlelstv unix2winfn(const u_char *un, int unlen, struct winentry *wep, int cnt, int chksum, int utf8)
1443 1.1 jdolecek {
1444 1.11 mlelstv u_int16_t wn[WIN_MAXLEN], *p;
1445 1.11 mlelstv int i, len;
1446 1.11 mlelstv const u_char *cp;
1447 1.1 jdolecek
1448 1.1 jdolecek /*
1449 1.1 jdolecek * Drop trailing blanks and dots
1450 1.1 jdolecek */
1451 1.11 mlelstv for (cp = un + unlen; unlen > 0; unlen--)
1452 1.11 mlelstv if (*--cp != ' ' && *cp != '.')
1453 1.11 mlelstv break;
1454 1.1 jdolecek
1455 1.11 mlelstv /*
1456 1.11 mlelstv * Offset of this entry
1457 1.11 mlelstv */
1458 1.11 mlelstv i = (cnt - 1) * WIN_CHARS;
1459 1.11 mlelstv
1460 1.11 mlelstv /*
1461 1.11 mlelstv * Translate UNIX name to ucs-2
1462 1.11 mlelstv */
1463 1.11 mlelstv len = utf8 ? utf8ucs2str(un, unlen, wn, WIN_MAXLEN) : char8ucs2str(un, unlen, wn, WIN_MAXLEN);
1464 1.11 mlelstv ucs2pad(wn, len, WIN_MAXLEN);
1465 1.1 jdolecek
1466 1.1 jdolecek /*
1467 1.1 jdolecek * Initialize winentry to some useful default
1468 1.1 jdolecek */
1469 1.11 mlelstv memset(wep, 0xff, sizeof(*wep));
1470 1.1 jdolecek wep->weCnt = cnt;
1471 1.1 jdolecek wep->weAttributes = ATTR_WIN95;
1472 1.1 jdolecek wep->weReserved1 = 0;
1473 1.1 jdolecek wep->weChksum = chksum;
1474 1.1 jdolecek wep->weReserved2 = 0;
1475 1.1 jdolecek
1476 1.1 jdolecek /*
1477 1.11 mlelstv * Store name segment into directory entry
1478 1.1 jdolecek */
1479 1.11 mlelstv p = &wn[i];
1480 1.11 mlelstv memcpy(wep->wePart1, p, sizeof(wep->wePart1));
1481 1.11 mlelstv p += sizeof(wep->wePart1) / sizeof(*p);
1482 1.11 mlelstv memcpy(wep->wePart2, p, sizeof(wep->wePart2));
1483 1.11 mlelstv p += sizeof(wep->wePart2) / sizeof(*p);
1484 1.11 mlelstv memcpy(wep->wePart3, p, sizeof(wep->wePart3));
1485 1.11 mlelstv
1486 1.11 mlelstv if (len > i + WIN_CHARS)
1487 1.11 mlelstv return 1;
1488 1.11 mlelstv
1489 1.1 jdolecek wep->weCnt |= WIN_LAST;
1490 1.1 jdolecek return 0;
1491 1.1 jdolecek }
1492 1.1 jdolecek
1493 1.1 jdolecek /*
1494 1.1 jdolecek * Compare our filename to the one in the Win95 entry
1495 1.1 jdolecek * Returns the checksum or -1 if no match
1496 1.1 jdolecek */
1497 1.1 jdolecek int
1498 1.11 mlelstv winChkName(const u_char *un, int unlen, struct winentry *wep, int chksum, int utf8)
1499 1.1 jdolecek {
1500 1.11 mlelstv u_int16_t wn[WIN_MAXLEN], *p;
1501 1.11 mlelstv u_int16_t buf[WIN_CHARS];
1502 1.11 mlelstv int i, len;
1503 1.1 jdolecek
1504 1.1 jdolecek /*
1505 1.1 jdolecek * First compare checksums
1506 1.1 jdolecek */
1507 1.11 mlelstv if (wep->weCnt & WIN_LAST)
1508 1.1 jdolecek chksum = wep->weChksum;
1509 1.1 jdolecek else if (chksum != wep->weChksum)
1510 1.1 jdolecek chksum = -1;
1511 1.1 jdolecek if (chksum == -1)
1512 1.1 jdolecek return -1;
1513 1.1 jdolecek
1514 1.1 jdolecek /*
1515 1.1 jdolecek * Offset of this entry
1516 1.1 jdolecek */
1517 1.11 mlelstv i = ((wep->weCnt & WIN_CNT) - 1) * WIN_CHARS;
1518 1.1 jdolecek
1519 1.1 jdolecek /*
1520 1.11 mlelstv * Translate UNIX name to ucs-2
1521 1.11 mlelstv */
1522 1.11 mlelstv len = utf8 ? utf8ucs2str(un, unlen, wn, WIN_MAXLEN) : char8ucs2str(un, unlen, wn, WIN_MAXLEN);
1523 1.11 mlelstv ucs2pad(wn, len, WIN_MAXLEN);
1524 1.1 jdolecek
1525 1.11 mlelstv if (i >= len + 1)
1526 1.1 jdolecek return -1;
1527 1.1 jdolecek
1528 1.1 jdolecek /*
1529 1.11 mlelstv * Fetch name segment from directory entry
1530 1.11 mlelstv */
1531 1.11 mlelstv p = &buf[0];
1532 1.11 mlelstv memcpy(p, wep->wePart1, sizeof(wep->wePart1));
1533 1.11 mlelstv p += sizeof(wep->wePart1) / sizeof(*p);
1534 1.11 mlelstv memcpy(p, wep->wePart2, sizeof(wep->wePart2));
1535 1.11 mlelstv p += sizeof(wep->wePart2) / sizeof(*p);
1536 1.11 mlelstv memcpy(p, wep->wePart3, sizeof(wep->wePart3));
1537 1.11 mlelstv
1538 1.11 mlelstv /*
1539 1.11 mlelstv * And compare name segment
1540 1.1 jdolecek */
1541 1.11 mlelstv if (! (utf8 ? ucs2match(&wn[i], buf, WIN_CHARS) : char8match(&wn[i], buf, WIN_CHARS)))
1542 1.11 mlelstv return -1;
1543 1.11 mlelstv
1544 1.1 jdolecek return chksum;
1545 1.1 jdolecek }
1546 1.1 jdolecek
1547 1.1 jdolecek /*
1548 1.1 jdolecek * Convert Win95 filename to dirbuf.
1549 1.1 jdolecek * Returns the checksum or -1 if impossible
1550 1.1 jdolecek */
1551 1.1 jdolecek int
1552 1.11 mlelstv win2unixfn(struct winentry *wep, struct dirent *dp, int chksum, int utf8)
1553 1.1 jdolecek {
1554 1.11 mlelstv u_int16_t wn[WIN_CHARS], *p;
1555 1.11 mlelstv u_int8_t buf[WIN_CHARS*3];
1556 1.11 mlelstv int len;
1557 1.1 jdolecek
1558 1.11 mlelstv if ((wep->weCnt & WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS)
1559 1.11 mlelstv || !(wep->weCnt & WIN_CNT))
1560 1.1 jdolecek return -1;
1561 1.1 jdolecek
1562 1.1 jdolecek /*
1563 1.1 jdolecek * First compare checksums
1564 1.1 jdolecek */
1565 1.11 mlelstv if (wep->weCnt & WIN_LAST) {
1566 1.1 jdolecek chksum = wep->weChksum;
1567 1.11 mlelstv dp->d_namlen = 0;
1568 1.1 jdolecek } else if (chksum != wep->weChksum)
1569 1.1 jdolecek chksum = -1;
1570 1.1 jdolecek if (chksum == -1)
1571 1.1 jdolecek return -1;
1572 1.1 jdolecek
1573 1.1 jdolecek /*
1574 1.11 mlelstv * Fetch name segment from directory entry
1575 1.11 mlelstv */
1576 1.11 mlelstv p = &wn[0];
1577 1.11 mlelstv memcpy(p, wep->wePart1, sizeof(wep->wePart1));
1578 1.11 mlelstv p += sizeof(wep->wePart1) / sizeof(*p);
1579 1.11 mlelstv memcpy(p, wep->wePart2, sizeof(wep->wePart2));
1580 1.11 mlelstv p += sizeof(wep->wePart2) / sizeof(*p);
1581 1.11 mlelstv memcpy(p, wep->wePart3, sizeof(wep->wePart3));
1582 1.11 mlelstv
1583 1.11 mlelstv /*
1584 1.11 mlelstv * Don't allow slashes in UNIX names. Discard that entry.
1585 1.1 jdolecek */
1586 1.11 mlelstv if (invalidname(wn, WIN_CHARS))
1587 1.11 mlelstv return -1;
1588 1.1 jdolecek
1589 1.1 jdolecek /*
1590 1.11 mlelstv * Translate ucs-2 to UNIX name
1591 1.1 jdolecek */
1592 1.11 mlelstv len = utf8 ? ucs2utf8str(wn, WIN_CHARS, buf, sizeof(buf)) : ucs2char8str(wn, WIN_CHARS, buf, sizeof(buf));
1593 1.11 mlelstv
1594 1.11 mlelstv /*
1595 1.11 mlelstv * Prepend name segment to directory entry
1596 1.11 mlelstv *
1597 1.11 mlelstv * This ignores the slot number from the windows entry but
1598 1.11 mlelstv * assumes that segments are read in reverse order.
1599 1.11 mlelstv *
1600 1.11 mlelstv * The UCS-2 name (up to 255 chars) can overflow the UNIX
1601 1.11 mlelstv * directory entry (up to 511 bytes). Trailing characters
1602 1.11 mlelstv * are silently discarded. This could also end in multiple
1603 1.11 mlelstv * files using the same (truncated) name.
1604 1.11 mlelstv */
1605 1.11 mlelstv dp->d_namlen += len;
1606 1.11 mlelstv if (dp->d_namlen > sizeof(dp->d_name)-1)
1607 1.11 mlelstv dp->d_namlen = sizeof(dp->d_name)-1;
1608 1.11 mlelstv memmove(&dp->d_name[len], &dp->d_name[0], dp->d_namlen - len);
1609 1.11 mlelstv memcpy(dp->d_name, buf, len);
1610 1.11 mlelstv
1611 1.1 jdolecek return chksum;
1612 1.1 jdolecek }
1613 1.1 jdolecek
1614 1.1 jdolecek /*
1615 1.1 jdolecek * Compute the checksum of a DOS filename for Win95 use
1616 1.1 jdolecek */
1617 1.1 jdolecek u_int8_t
1618 1.6 dsl winChksum(u_int8_t *name)
1619 1.1 jdolecek {
1620 1.1 jdolecek int i;
1621 1.1 jdolecek u_int8_t s;
1622 1.1 jdolecek
1623 1.1 jdolecek for (s = 0, i = 11; --i >= 0; s += *name++)
1624 1.11 mlelstv s = (s << 7) | (s >> 1);
1625 1.1 jdolecek return s;
1626 1.1 jdolecek }
1627 1.1 jdolecek
1628 1.1 jdolecek /*
1629 1.1 jdolecek * Determine the number of slots necessary for Win95 names
1630 1.1 jdolecek */
1631 1.1 jdolecek int
1632 1.11 mlelstv winSlotCnt(const u_char *un, int unlen, int utf8)
1633 1.1 jdolecek {
1634 1.11 mlelstv const u_char *cp;
1635 1.11 mlelstv int len;
1636 1.11 mlelstv
1637 1.11 mlelstv /*
1638 1.11 mlelstv * Drop trailing blanks and dots
1639 1.11 mlelstv */
1640 1.11 mlelstv for (cp = un + unlen; unlen > 0; unlen--)
1641 1.11 mlelstv if (*--cp != ' ' && *cp != '.')
1642 1.1 jdolecek break;
1643 1.11 mlelstv
1644 1.11 mlelstv len = utf8 ? utf8ucs2str(un, unlen, NULL, WIN_MAXLEN) : unlen;
1645 1.11 mlelstv
1646 1.11 mlelstv return howmany(len, WIN_CHARS);
1647 1.11 mlelstv }
1648 1.11 mlelstv
1649 1.11 mlelstv /*
1650 1.11 mlelstv * Scan windows name for characters that must not
1651 1.11 mlelstv * appear in a UNIX filename
1652 1.11 mlelstv */
1653 1.11 mlelstv static int
1654 1.11 mlelstv invalidname(const u_int16_t *in, int n)
1655 1.11 mlelstv {
1656 1.11 mlelstv while (n-- > 0) {
1657 1.11 mlelstv if (*in++ == '/')
1658 1.11 mlelstv return 1;
1659 1.11 mlelstv }
1660 1.11 mlelstv
1661 1.11 mlelstv return 0;
1662 1.11 mlelstv }
1663 1.11 mlelstv
1664 1.11 mlelstv /*
1665 1.11 mlelstv * Convert UCS-2 character into UTF-8
1666 1.11 mlelstv * return number of output bytes or 0 if output
1667 1.11 mlelstv * buffer is too short
1668 1.11 mlelstv */
1669 1.11 mlelstv static int
1670 1.11 mlelstv ucs2utf8(const u_int16_t *in, u_int8_t *out, int n)
1671 1.11 mlelstv {
1672 1.11 mlelstv uint16_t inch = le16toh(in[0]);
1673 1.11 mlelstv
1674 1.11 mlelstv if (inch <= 0x007f) {
1675 1.11 mlelstv if (n < 1) return 0;
1676 1.11 mlelstv if (out)
1677 1.11 mlelstv *out++ = inch;
1678 1.11 mlelstv return 1;
1679 1.11 mlelstv } else if (inch <= 0x07ff) {
1680 1.11 mlelstv if (n < 2) return 0;
1681 1.11 mlelstv if (out) {
1682 1.11 mlelstv *out++ = 0xc0 | (inch >> 6);
1683 1.11 mlelstv *out++ = 0x80 | (inch & 0x3f);
1684 1.11 mlelstv }
1685 1.11 mlelstv return 2;
1686 1.11 mlelstv } else {
1687 1.11 mlelstv if (n < 3) return 0;
1688 1.11 mlelstv if (out) {
1689 1.11 mlelstv *out++ = 0xe0 | (inch >> 12);
1690 1.11 mlelstv *out++ = 0x80 | ((inch >> 6) & 0x3f);
1691 1.11 mlelstv *out++ = 0x80 | (inch & 0x3f);
1692 1.11 mlelstv }
1693 1.11 mlelstv return 3;
1694 1.11 mlelstv }
1695 1.11 mlelstv }
1696 1.11 mlelstv
1697 1.11 mlelstv
1698 1.11 mlelstv /*
1699 1.11 mlelstv * Convert UTF-8 bytes into UCS-2 character
1700 1.11 mlelstv * return number of input bytes, 0 if input
1701 1.11 mlelstv * is too short and -1 if input is invalid
1702 1.11 mlelstv */
1703 1.11 mlelstv static int
1704 1.11 mlelstv utf8ucs2(const u_int8_t *in, int n, u_int16_t *out)
1705 1.11 mlelstv {
1706 1.11 mlelstv uint16_t outch;
1707 1.11 mlelstv
1708 1.11 mlelstv if (n < 1) return 0;
1709 1.11 mlelstv
1710 1.11 mlelstv if (in[0] <= 0x7f) {
1711 1.11 mlelstv outch = in[0];
1712 1.11 mlelstv if (out)
1713 1.11 mlelstv *out = htole16(outch);
1714 1.11 mlelstv return 1;
1715 1.11 mlelstv } else if (in[0] <= 0xdf) {
1716 1.11 mlelstv if (n < 2) return 0;
1717 1.11 mlelstv outch = (in[0] & 0x1f) << 6 | (in[1] & 0x3f);
1718 1.11 mlelstv if (out)
1719 1.11 mlelstv *out = htole16(outch);
1720 1.11 mlelstv return 2;
1721 1.11 mlelstv } else if (in[0] <= 0xef) {
1722 1.11 mlelstv if (n < 3) return 0;
1723 1.11 mlelstv outch = (in[0] & 0x1f) << 12 | (in[1] & 0x3f) << 6 | (in[2] & 0x3f);
1724 1.11 mlelstv if (out)
1725 1.11 mlelstv *out = htole16(outch);
1726 1.11 mlelstv return 3;
1727 1.11 mlelstv }
1728 1.11 mlelstv
1729 1.11 mlelstv return -1;
1730 1.11 mlelstv }
1731 1.11 mlelstv
1732 1.11 mlelstv /*
1733 1.11 mlelstv * Convert UCS-2 string into UTF-8 string
1734 1.11 mlelstv * return total number of output bytes
1735 1.11 mlelstv */
1736 1.11 mlelstv static int
1737 1.11 mlelstv ucs2utf8str(const u_int16_t *in, int n, u_int8_t *out, int m)
1738 1.11 mlelstv {
1739 1.11 mlelstv u_int8_t *p;
1740 1.11 mlelstv int outlen;
1741 1.11 mlelstv
1742 1.11 mlelstv p = out;
1743 1.11 mlelstv while (n > 0 && *in != 0) {
1744 1.11 mlelstv outlen = ucs2utf8(in, out ? p : out, m);
1745 1.11 mlelstv if (outlen == 0)
1746 1.11 mlelstv break;
1747 1.11 mlelstv p += outlen;
1748 1.11 mlelstv m -= outlen;
1749 1.11 mlelstv in += 1;
1750 1.11 mlelstv n -= 1;
1751 1.11 mlelstv }
1752 1.11 mlelstv
1753 1.11 mlelstv return p - out;
1754 1.11 mlelstv }
1755 1.11 mlelstv
1756 1.11 mlelstv /*
1757 1.11 mlelstv * Convert UTF8 string into UCS-2 string
1758 1.11 mlelstv * return total number of output chacters
1759 1.11 mlelstv */
1760 1.11 mlelstv static int
1761 1.11 mlelstv utf8ucs2str(const u_int8_t *in, int n, u_int16_t *out, int m)
1762 1.11 mlelstv {
1763 1.11 mlelstv u_int16_t *p;
1764 1.11 mlelstv int inlen;
1765 1.11 mlelstv
1766 1.11 mlelstv p = out;
1767 1.11 mlelstv while (n > 0 && *in != 0) {
1768 1.11 mlelstv if (m < 1)
1769 1.11 mlelstv break;
1770 1.11 mlelstv inlen = utf8ucs2(in, n, out ? p : out);
1771 1.11 mlelstv if (inlen <= 0)
1772 1.11 mlelstv break;
1773 1.11 mlelstv in += inlen;
1774 1.11 mlelstv n -= inlen;
1775 1.11 mlelstv p += 1;
1776 1.11 mlelstv m -= 1;
1777 1.11 mlelstv }
1778 1.11 mlelstv
1779 1.11 mlelstv return p - out;
1780 1.11 mlelstv }
1781 1.11 mlelstv
1782 1.11 mlelstv /*
1783 1.11 mlelstv * Convert UCS-2 string into 8bit character string
1784 1.11 mlelstv * return total number of output bytes
1785 1.11 mlelstv */
1786 1.11 mlelstv static int
1787 1.11 mlelstv ucs2char8str(const u_int16_t *in, int n, u_int8_t *out, int m)
1788 1.11 mlelstv {
1789 1.11 mlelstv u_int8_t *p;
1790 1.11 mlelstv u_int16_t inch;
1791 1.11 mlelstv
1792 1.11 mlelstv p = out;
1793 1.11 mlelstv while (n > 0 && in[0] != 0) {
1794 1.11 mlelstv if (m < 1)
1795 1.11 mlelstv break;
1796 1.11 mlelstv inch = le16toh(in[0]);
1797 1.11 mlelstv if (inch > 255)
1798 1.11 mlelstv break;
1799 1.11 mlelstv if (p)
1800 1.11 mlelstv p[0] = inch;
1801 1.11 mlelstv p += 1;
1802 1.11 mlelstv m -= 1;
1803 1.11 mlelstv in += 1;
1804 1.11 mlelstv n -= 1;
1805 1.11 mlelstv }
1806 1.11 mlelstv
1807 1.11 mlelstv return p - out;
1808 1.11 mlelstv }
1809 1.11 mlelstv
1810 1.11 mlelstv /*
1811 1.11 mlelstv * Convert 8bit character string into UCS-2 string
1812 1.11 mlelstv * return total number of output chacters
1813 1.11 mlelstv */
1814 1.11 mlelstv static int
1815 1.11 mlelstv char8ucs2str(const u_int8_t *in, int n, u_int16_t *out, int m)
1816 1.11 mlelstv {
1817 1.11 mlelstv u_int16_t *p;
1818 1.11 mlelstv
1819 1.11 mlelstv p = out;
1820 1.11 mlelstv while (n > 0 && in[0] != 0) {
1821 1.11 mlelstv if (m < 1)
1822 1.11 mlelstv break;
1823 1.11 mlelstv if (p)
1824 1.11 mlelstv p[0] = htole16(in[0]);
1825 1.11 mlelstv p += 1;
1826 1.11 mlelstv m -= 1;
1827 1.11 mlelstv in += 1;
1828 1.11 mlelstv n -= 1;
1829 1.11 mlelstv }
1830 1.11 mlelstv
1831 1.11 mlelstv return p - out;
1832 1.11 mlelstv }
1833 1.11 mlelstv
1834 1.11 mlelstv static void
1835 1.11 mlelstv ucs2pad(u_int16_t *buf, int len, int size)
1836 1.11 mlelstv {
1837 1.11 mlelstv
1838 1.11 mlelstv if (len < size-1)
1839 1.11 mlelstv buf[len++] = 0x0000;
1840 1.11 mlelstv while (len < size)
1841 1.11 mlelstv buf[len++] = 0xffff;
1842 1.11 mlelstv }
1843 1.11 mlelstv
1844 1.11 mlelstv /*
1845 1.11 mlelstv * Fold UCS-2 character to uppercase
1846 1.11 mlelstv */
1847 1.11 mlelstv static u_int16_t
1848 1.11 mlelstv ucs2fold(u_int16_t w)
1849 1.11 mlelstv {
1850 1.11 mlelstv int low,high,mid;
1851 1.11 mlelstv u_int16_t check;
1852 1.11 mlelstv
1853 1.11 mlelstv w = le16toh(w);
1854 1.11 mlelstv
1855 1.11 mlelstv low = 0;
1856 1.11 mlelstv high = __arraycount(foldmap) / 2;
1857 1.11 mlelstv while (low < high) {
1858 1.11 mlelstv mid = (low + high)/2;
1859 1.11 mlelstv check = foldmap[2*mid+0];
1860 1.11 mlelstv
1861 1.11 mlelstv if (w == check) {
1862 1.11 mlelstv w = foldmap[2*mid+1];
1863 1.11 mlelstv break;
1864 1.11 mlelstv }
1865 1.11 mlelstv
1866 1.11 mlelstv if (w < check)
1867 1.11 mlelstv high = mid;
1868 1.11 mlelstv else
1869 1.11 mlelstv low = mid+1;
1870 1.11 mlelstv }
1871 1.11 mlelstv
1872 1.11 mlelstv w = le16toh(w);
1873 1.11 mlelstv
1874 1.11 mlelstv return w;
1875 1.11 mlelstv }
1876 1.11 mlelstv
1877 1.11 mlelstv /*
1878 1.11 mlelstv * Compare two UCS-2 strings case-insensitive
1879 1.11 mlelstv *
1880 1.11 mlelstv * uses the Unicode case folding table
1881 1.11 mlelstv */
1882 1.11 mlelstv static int
1883 1.11 mlelstv ucs2match(u_int16_t *w1, u_int16_t *w2, int n)
1884 1.11 mlelstv {
1885 1.11 mlelstv u_int16_t u1, u2;
1886 1.11 mlelstv
1887 1.11 mlelstv while (n > 0) {
1888 1.11 mlelstv if (*w1 == 0 || *w2 == 0)
1889 1.11 mlelstv return *w1 == *w2;
1890 1.11 mlelstv u1 = ucs2fold(*w1);
1891 1.11 mlelstv u2 = ucs2fold(*w2);
1892 1.11 mlelstv if (u1 != u2)
1893 1.11 mlelstv return 0;
1894 1.11 mlelstv ++w1;
1895 1.11 mlelstv ++w2;
1896 1.11 mlelstv --n;
1897 1.11 mlelstv }
1898 1.11 mlelstv
1899 1.11 mlelstv return 1;
1900 1.11 mlelstv }
1901 1.11 mlelstv
1902 1.11 mlelstv /*
1903 1.11 mlelstv * Compare two 8bit char conversions case-insensitive
1904 1.11 mlelstv *
1905 1.11 mlelstv * uses the DOS case folding table
1906 1.11 mlelstv */
1907 1.11 mlelstv static int
1908 1.11 mlelstv char8match(u_int16_t *w1, u_int16_t *w2, int n)
1909 1.11 mlelstv {
1910 1.11 mlelstv u_int16_t u1, u2;
1911 1.11 mlelstv
1912 1.11 mlelstv while (n > 0) {
1913 1.11 mlelstv u1 = le16toh(*w1);
1914 1.11 mlelstv u2 = le16toh(*w2);
1915 1.11 mlelstv if (u1 == 0 || u2 == 0)
1916 1.11 mlelstv return u1 == u2;
1917 1.11 mlelstv if (u1 > 255 || u2 > 255)
1918 1.11 mlelstv return 0;
1919 1.11 mlelstv u1 = u2l[u1 & 0xff];
1920 1.11 mlelstv u2 = u2l[u2 & 0xff];
1921 1.11 mlelstv if (u1 != u2)
1922 1.11 mlelstv return 0;
1923 1.11 mlelstv ++w1;
1924 1.11 mlelstv ++w2;
1925 1.11 mlelstv --n;
1926 1.11 mlelstv }
1927 1.11 mlelstv
1928 1.11 mlelstv return 1;
1929 1.1 jdolecek }
1930 1.11 mlelstv
1931