Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/tcl8.5.2/generic/regc_locale.c @ 63

Last change on this file since 63 was 25, checked in by landauf, 17 years ago

added tcl to libs

File size: 42.4 KB
Line 
1/*
2 * regc_locale.c --
3 *
4 *      This file contains the Unicode locale specific regexp routines.
5 *      This file is #included by regcomp.c.
6 *
7 * Copyright (c) 1998 by Scriptics Corporation.
8 *
9 * See the file "license.terms" for information on usage and redistribution of
10 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
11 *
12 * RCS: @(#) $Id: regc_locale.c,v 1.20 2007/12/13 15:23:14 dgp Exp $
13 */
14
15/* ASCII character-name table */
16
17static const struct cname {
18    const char *name;
19    const char code;
20} cnames[] = {
21    {"NUL",             '\0'},
22    {"SOH",             '\001'},
23    {"STX",             '\002'},
24    {"ETX",             '\003'},
25    {"EOT",             '\004'},
26    {"ENQ",             '\005'},
27    {"ACK",             '\006'},
28    {"BEL",             '\007'},
29    {"alert",           '\007'},
30    {"BS",              '\010'},
31    {"backspace",       '\b'},
32    {"HT",              '\011'},
33    {"tab",             '\t'},
34    {"LF",              '\012'},
35    {"newline",         '\n'},
36    {"VT",              '\013'},
37    {"vertical-tab",    '\v'},
38    {"FF",              '\014'},
39    {"form-feed",       '\f'},
40    {"CR",              '\015'},
41    {"carriage-return", '\r'},
42    {"SO",              '\016'},
43    {"SI",              '\017'},
44    {"DLE",             '\020'},
45    {"DC1",             '\021'},
46    {"DC2",             '\022'},
47    {"DC3",             '\023'},
48    {"DC4",             '\024'},
49    {"NAK",             '\025'},
50    {"SYN",             '\026'},
51    {"ETB",             '\027'},
52    {"CAN",             '\030'},
53    {"EM",              '\031'},
54    {"SUB",             '\032'},
55    {"ESC",             '\033'},
56    {"IS4",             '\034'},
57    {"FS",              '\034'},
58    {"IS3",             '\035'},
59    {"GS",              '\035'},
60    {"IS2",             '\036'},
61    {"RS",              '\036'},
62    {"IS1",             '\037'},
63    {"US",              '\037'},
64    {"space",           ' '},
65    {"exclamation-mark",'!'},
66    {"quotation-mark",  '"'},
67    {"number-sign",     '#'},
68    {"dollar-sign",     '$'},
69    {"percent-sign",    '%'},
70    {"ampersand",       '&'},
71    {"apostrophe",      '\''},
72    {"left-parenthesis",'('},
73    {"right-parenthesis", ')'},
74    {"asterisk",        '*'},
75    {"plus-sign",       '+'},
76    {"comma",           ','},
77    {"hyphen",          '-'},
78    {"hyphen-minus",    '-'},
79    {"period",          '.'},
80    {"full-stop",       '.'},
81    {"slash",           '/'},
82    {"solidus",         '/'},
83    {"zero",            '0'},
84    {"one",             '1'},
85    {"two",             '2'},
86    {"three",           '3'},
87    {"four",            '4'},
88    {"five",            '5'},
89    {"six",             '6'},
90    {"seven",           '7'},
91    {"eight",           '8'},
92    {"nine",            '9'},
93    {"colon",           ':'},
94    {"semicolon",       ';'},
95    {"less-than-sign",  '<'},
96    {"equals-sign",     '='},
97    {"greater-than-sign", '>'},
98    {"question-mark",   '?'},
99    {"commercial-at",   '@'},
100    {"left-square-bracket", '['},
101    {"backslash",       '\\'},
102    {"reverse-solidus", '\\'},
103    {"right-square-bracket", ']'},
104    {"circumflex",      '^'},
105    {"circumflex-accent", '^'},
106    {"underscore",      '_'},
107    {"low-line",        '_'},
108    {"grave-accent",    '`'},
109    {"left-brace",      '{'},
110    {"left-curly-bracket", '{'},
111    {"vertical-line",   '|'},
112    {"right-brace",     '}'},
113    {"right-curly-bracket", '}'},
114    {"tilde",           '~'},
115    {"DEL",             '\177'},
116    {NULL,              0}
117};
118
119/*
120 * Unicode character-class tables.
121 */
122
123typedef struct crange {
124    chr start;
125    chr end;
126} crange;
127
128/*
129 *      Declarations of Unicode character ranges.  This code
130 *      is automatically generated by the tools/uniClass.tcl script
131 *      and used in generic/regc_locale.c.  Do not modify by hand.
132 */
133
134/* Unicode: alphabetic characters */
135
136static const crange alphaRangeTable[] = {
137    {0x0041, 0x005a}, {0x0061, 0x007a}, {0x00c0, 0x00d6}, {0x00d8, 0x00f6},
138    {0x00f8, 0x021f}, {0x0222, 0x0233}, {0x0250, 0x02ad}, {0x02b0, 0x02b8},
139    {0x02bb, 0x02c1}, {0x02e0, 0x02e4}, {0x0388, 0x038a}, {0x038e, 0x03a1},
140    {0x03a3, 0x03ce}, {0x03d0, 0x03d7}, {0x03da, 0x03f5}, {0x0400, 0x0481},
141    {0x048c, 0x04c4}, {0x04d0, 0x04f5}, {0x0531, 0x0556}, {0x0561, 0x0587},
142    {0x05d0, 0x05ea}, {0x05f0, 0x05f2}, {0x0621, 0x063a}, {0x0640, 0x064a},
143    {0x0671, 0x06d3}, {0x06fa, 0x06fc}, {0x0712, 0x072c}, {0x0780, 0x07a5},
144    {0x0905, 0x0939}, {0x0958, 0x0961}, {0x0985, 0x098c}, {0x0993, 0x09a8},
145    {0x09aa, 0x09b0}, {0x09b6, 0x09b9}, {0x09df, 0x09e1}, {0x0a05, 0x0a0a},
146    {0x0a13, 0x0a28}, {0x0a2a, 0x0a30}, {0x0a59, 0x0a5c}, {0x0a72, 0x0a74},
147    {0x0a85, 0x0a8b}, {0x0a8f, 0x0a91}, {0x0a93, 0x0aa8}, {0x0aaa, 0x0ab0},
148    {0x0ab5, 0x0ab9}, {0x0b05, 0x0b0c}, {0x0b13, 0x0b28}, {0x0b2a, 0x0b30},
149    {0x0b36, 0x0b39}, {0x0b5f, 0x0b61}, {0x0b85, 0x0b8a}, {0x0b8e, 0x0b90},
150    {0x0b92, 0x0b95}, {0x0ba8, 0x0baa}, {0x0bae, 0x0bb5}, {0x0bb7, 0x0bb9},
151    {0x0c05, 0x0c0c}, {0x0c0e, 0x0c10}, {0x0c12, 0x0c28}, {0x0c2a, 0x0c33},
152    {0x0c35, 0x0c39}, {0x0c85, 0x0c8c}, {0x0c8e, 0x0c90}, {0x0c92, 0x0ca8},
153    {0x0caa, 0x0cb3}, {0x0cb5, 0x0cb9}, {0x0d05, 0x0d0c}, {0x0d0e, 0x0d10},
154    {0x0d12, 0x0d28}, {0x0d2a, 0x0d39}, {0x0d85, 0x0d96}, {0x0d9a, 0x0db1},
155    {0x0db3, 0x0dbb}, {0x0dc0, 0x0dc6}, {0x0e01, 0x0e30}, {0x0e40, 0x0e46},
156    {0x0e94, 0x0e97}, {0x0e99, 0x0e9f}, {0x0ea1, 0x0ea3}, {0x0ead, 0x0eb0},
157    {0x0ec0, 0x0ec4}, {0x0f40, 0x0f47}, {0x0f49, 0x0f6a}, {0x0f88, 0x0f8b},
158    {0x1000, 0x1021}, {0x1023, 0x1027}, {0x1050, 0x1055}, {0x10a0, 0x10c5},
159    {0x10d0, 0x10f6}, {0x1100, 0x1159}, {0x115f, 0x11a2}, {0x11a8, 0x11f9},
160    {0x1200, 0x1206}, {0x1208, 0x1246}, {0x124a, 0x124d}, {0x1250, 0x1256},
161    {0x125a, 0x125d}, {0x1260, 0x1286}, {0x128a, 0x128d}, {0x1290, 0x12ae},
162    {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12ce},
163    {0x12d0, 0x12d6}, {0x12d8, 0x12ee}, {0x12f0, 0x130e}, {0x1312, 0x1315},
164    {0x1318, 0x131e}, {0x1320, 0x1346}, {0x1348, 0x135a}, {0x13a0, 0x13f4},
165    {0x1401, 0x166c}, {0x166f, 0x1676}, {0x1681, 0x169a}, {0x16a0, 0x16ea},
166    {0x1780, 0x17b3}, {0x1820, 0x1877}, {0x1880, 0x18a8}, {0x1e00, 0x1e9b},
167    {0x1ea0, 0x1ef9}, {0x1f00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45},
168    {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4},
169    {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3},
170    {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc},
171    {0x210a, 0x2113}, {0x2119, 0x211d}, {0x212a, 0x212d}, {0x212f, 0x2131},
172    {0x2133, 0x2139}, {0x3031, 0x3035}, {0x3041, 0x3094}, {0x30a1, 0x30fa},
173    {0x30fc, 0x30fe}, {0x3105, 0x312c}, {0x3131, 0x318e}, {0x31a0, 0x31b7},
174    {0x3400, 0x4db5}, {0x4e00, 0x9fa5}, {0xa000, 0xa48c}, {0xac00, 0xd7a3},
175    {0xf900, 0xfa2d}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28},
176    {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d},
177    {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe72},
178    {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe},
179    {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}
180};
181
182#define NUM_ALPHA_RANGE (sizeof(alphaRangeTable)/sizeof(crange))
183
184static const chr alphaCharTable[] = {
185    0x00aa, 0x00b5, 0x00ba, 0x02d0, 0x02d1, 0x02ee, 0x037a, 0x0386, 0x038c,
186    0x04c7, 0x04c8, 0x04cb, 0x04cc, 0x04f8, 0x04f9, 0x0559, 0x06d5, 0x06e5,
187    0x06e6, 0x0710, 0x093d, 0x0950, 0x098f, 0x0990, 0x09b2, 0x09dc, 0x09dd,
188    0x09f0, 0x09f1, 0x0a0f, 0x0a10, 0x0a32, 0x0a33, 0x0a35, 0x0a36, 0x0a38,
189    0x0a39, 0x0a5e, 0x0a8d, 0x0ab2, 0x0ab3, 0x0abd, 0x0ad0, 0x0ae0, 0x0b0f,
190    0x0b10, 0x0b32, 0x0b33, 0x0b3d, 0x0b5c, 0x0b5d, 0x0b99, 0x0b9a, 0x0b9c,
191    0x0b9e, 0x0b9f, 0x0ba3, 0x0ba4, 0x0c60, 0x0c61, 0x0cde, 0x0ce0, 0x0ce1,
192    0x0d60, 0x0d61, 0x0dbd, 0x0e32, 0x0e33, 0x0e81, 0x0e82, 0x0e84, 0x0e87,
193    0x0e88, 0x0e8a, 0x0e8d, 0x0ea5, 0x0ea7, 0x0eaa, 0x0eab, 0x0eb2, 0x0eb3,
194    0x0ebd, 0x0ec6, 0x0edc, 0x0edd, 0x0f00, 0x1029, 0x102a, 0x1248, 0x1258,
195    0x1288, 0x12b0, 0x12c0, 0x1310, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x207f,
196    0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x3005, 0x3006, 0x309d,
197    0x309e, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfe74, 0xfffe
198};
199
200#define NUM_ALPHA_CHAR (sizeof(alphaCharTable)/sizeof(chr))
201
202/*
203 * Unicode: decimal digit characters
204 */
205
206static const crange digitRangeTable[] = {
207    {0x0030, 0x0039}, {0x0660, 0x0669}, {0x06f0, 0x06f9}, {0x0966, 0x096f},
208    {0x09e6, 0x09ef}, {0x0a66, 0x0a6f}, {0x0ae6, 0x0aef}, {0x0b66, 0x0b6f},
209    {0x0be7, 0x0bef}, {0x0c66, 0x0c6f}, {0x0ce6, 0x0cef}, {0x0d66, 0x0d6f},
210    {0x0e50, 0x0e59}, {0x0ed0, 0x0ed9}, {0x0f20, 0x0f29}, {0x1040, 0x1049},
211    {0x1369, 0x1371}, {0x17e0, 0x17e9}, {0x1810, 0x1819}, {0xff10, 0xff19}
212};
213
214#define NUM_DIGIT_RANGE (sizeof(digitRangeTable)/sizeof(crange))
215
216/*
217 * no singletons of digit characters.
218 */
219
220/*
221 * Unicode: punctuation characters.
222 */
223
224static const crange punctRangeTable[] = {
225    {0x0021, 0x0023}, {0x0025, 0x002a}, {0x002c, 0x002f}, {0x005b, 0x005d},
226    {0x055a, 0x055f}, {0x066a, 0x066d}, {0x0700, 0x070d}, {0x0f04, 0x0f12},
227    {0x0f3a, 0x0f3d}, {0x104a, 0x104f}, {0x1361, 0x1368}, {0x16eb, 0x16ed},
228    {0x17d4, 0x17da}, {0x1800, 0x180a}, {0x2010, 0x2027}, {0x2030, 0x2043},
229    {0x2048, 0x204d}, {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f},
230    {0xfe30, 0xfe44}, {0xfe49, 0xfe52}, {0xfe54, 0xfe61}, {0xff01, 0xff03},
231    {0xff05, 0xff0a}, {0xff0c, 0xff0f}, {0xff3b, 0xff3d}, {0xff61, 0xff65}
232};
233
234#define NUM_PUNCT_RANGE (sizeof(punctRangeTable)/sizeof(crange))
235
236static const chr punctCharTable[] = {
237    0x003a, 0x003b, 0x003f, 0x0040, 0x005f, 0x007b, 0x007d, 0x00a1, 0x00ab,
238    0x00ad, 0x00b7, 0x00bb, 0x00bf, 0x037e, 0x0387, 0x0589, 0x058a, 0x05be,
239    0x05c0, 0x05c3, 0x05f3, 0x05f4, 0x060c, 0x061b, 0x061f, 0x06d4, 0x0964,
240    0x0965, 0x0970, 0x0df4, 0x0e4f, 0x0e5a, 0x0e5b, 0x0f85, 0x10fb, 0x166d,
241    0x166e, 0x169b, 0x169c, 0x17dc, 0x2045, 0x2046, 0x207d, 0x207e, 0x208d,
242    0x208e, 0x2329, 0x232a, 0x3030, 0x30fb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68,
243    0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d
244};
245
246#define NUM_PUNCT_CHAR (sizeof(punctCharTable)/sizeof(chr))
247
248/*
249 * Unicode: white space characters.
250 */
251
252static const crange spaceRangeTable[] = {
253    {0x0009, 0x000d}, {0x2000, 0x200b}
254};
255
256#define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange))
257
258static const chr spaceCharTable[] = {
259    0x0020, 0x00a0, 0x1680, 0x2028, 0x2029, 0x202f, 0x3000
260};
261
262#define NUM_SPACE_CHAR (sizeof(spaceCharTable)/sizeof(chr))
263
264/*
265 * Unicode: lowercase characters
266 */
267
268static const crange lowerRangeTable[] = {
269    {0x0061, 0x007a}, {0x00df, 0x00f6}, {0x00f8, 0x00ff}, {0x017e, 0x0180},
270    {0x0199, 0x019b}, {0x01bd, 0x01bf}, {0x0250, 0x02ad}, {0x03ac, 0x03ce},
271    {0x03d5, 0x03d7}, {0x03ef, 0x03f3}, {0x0430, 0x045f}, {0x0561, 0x0587},
272    {0x1e95, 0x1e9b}, {0x1f00, 0x1f07}, {0x1f10, 0x1f15}, {0x1f20, 0x1f27},
273    {0x1f30, 0x1f37}, {0x1f40, 0x1f45}, {0x1f50, 0x1f57}, {0x1f60, 0x1f67},
274    {0x1f70, 0x1f7d}, {0x1f80, 0x1f87}, {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7},
275    {0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4}, {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7},
276    {0x1ff2, 0x1ff4}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a}
277};
278
279#define NUM_LOWER_RANGE (sizeof(lowerRangeTable)/sizeof(crange))
280
281static const chr lowerCharTable[] = {
282    0x00aa, 0x00b5, 0x00ba, 0x0101, 0x0103, 0x0105, 0x0107, 0x0109, 0x010b,
283    0x010d, 0x010f, 0x0111, 0x0113, 0x0115, 0x0117, 0x0119, 0x011b, 0x011d,
284    0x011f, 0x0121, 0x0123, 0x0125, 0x0127, 0x0129, 0x012b, 0x012d, 0x012f,
285    0x0131, 0x0133, 0x0135, 0x0137, 0x0138, 0x013a, 0x013c, 0x013e, 0x0140,
286    0x0142, 0x0144, 0x0146, 0x0148, 0x0149, 0x014b, 0x014d, 0x014f, 0x0151,
287    0x0153, 0x0155, 0x0157, 0x0159, 0x015b, 0x015d, 0x015f, 0x0161, 0x0163,
288    0x0165, 0x0167, 0x0169, 0x016b, 0x016d, 0x016f, 0x0171, 0x0173, 0x0175,
289    0x0177, 0x017a, 0x017c, 0x0183, 0x0185, 0x0188, 0x018c, 0x018d, 0x0192,
290    0x0195, 0x019e, 0x01a1, 0x01a3, 0x01a5, 0x01a8, 0x01aa, 0x01ab, 0x01ad,
291    0x01b0, 0x01b4, 0x01b6, 0x01b9, 0x01ba, 0x01c6, 0x01c9, 0x01cc, 0x01ce,
292    0x01d0, 0x01d2, 0x01d4, 0x01d6, 0x01d8, 0x01da, 0x01dc, 0x01dd, 0x01df,
293    0x01e1, 0x01e3, 0x01e5, 0x01e7, 0x01e9, 0x01eb, 0x01ed, 0x01ef, 0x01f0,
294    0x01f3, 0x01f5, 0x01f9, 0x01fb, 0x01fd, 0x01ff, 0x0201, 0x0203, 0x0205,
295    0x0207, 0x0209, 0x020b, 0x020d, 0x020f, 0x0211, 0x0213, 0x0215, 0x0217,
296    0x0219, 0x021b, 0x021d, 0x021f, 0x0223, 0x0225, 0x0227, 0x0229, 0x022b,
297    0x022d, 0x022f, 0x0231, 0x0233, 0x0390, 0x03d0, 0x03d1, 0x03db, 0x03dd,
298    0x03df, 0x03e1, 0x03e3, 0x03e5, 0x03e7, 0x03e9, 0x03eb, 0x03ed, 0x03f5,
299    0x0461, 0x0463, 0x0465, 0x0467, 0x0469, 0x046b, 0x046d, 0x046f, 0x0471,
300    0x0473, 0x0475, 0x0477, 0x0479, 0x047b, 0x047d, 0x047f, 0x0481, 0x048d,
301    0x048f, 0x0491, 0x0493, 0x0495, 0x0497, 0x0499, 0x049b, 0x049d, 0x049f,
302    0x04a1, 0x04a3, 0x04a5, 0x04a7, 0x04a9, 0x04ab, 0x04ad, 0x04af, 0x04b1,
303    0x04b3, 0x04b5, 0x04b7, 0x04b9, 0x04bb, 0x04bd, 0x04bf, 0x04c2, 0x04c4,
304    0x04c8, 0x04cc, 0x04d1, 0x04d3, 0x04d5, 0x04d7, 0x04d9, 0x04db, 0x04dd,
305    0x04df, 0x04e1, 0x04e3, 0x04e5, 0x04e7, 0x04e9, 0x04eb, 0x04ed, 0x04ef,
306    0x04f1, 0x04f3, 0x04f5, 0x04f9, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09,
307    0x1e0b, 0x1e0d, 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b,
308    0x1e1d, 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d,
309    0x1e2f, 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, 0x1e3f,
310    0x1e41, 0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, 0x1e4f, 0x1e51,
311    0x1e53, 0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d, 0x1e5f, 0x1e61, 0x1e63,
312    0x1e65, 0x1e67, 0x1e69, 0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73, 0x1e75,
313    0x1e77, 0x1e79, 0x1e7b, 0x1e7d, 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87,
314    0x1e89, 0x1e8b, 0x1e8d, 0x1e8f, 0x1e91, 0x1e93, 0x1ea1, 0x1ea3, 0x1ea5,
315    0x1ea7, 0x1ea9, 0x1eab, 0x1ead, 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7,
316    0x1eb9, 0x1ebb, 0x1ebd, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9,
317    0x1ecb, 0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb,
318    0x1edd, 0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, 0x1eed,
319    0x1eef, 0x1ef1, 0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1fb6, 0x1fb7, 0x1fbe,
320    0x1fc6, 0x1fc7, 0x1fd6, 0x1fd7, 0x1ff6, 0x1ff7, 0x207f, 0x210a, 0x210e,
321    0x210f, 0x2113, 0x212f, 0x2134, 0x2139
322};
323
324#define NUM_LOWER_CHAR (sizeof(lowerCharTable)/sizeof(chr))
325
326/*
327 * Unicode: uppercase characters.
328 */
329
330static const crange upperRangeTable[] = {
331    {0x0041, 0x005a}, {0x00c0, 0x00d6}, {0x00d8, 0x00de}, {0x0189, 0x018b},
332    {0x018e, 0x0191}, {0x0196, 0x0198}, {0x01b1, 0x01b3}, {0x01f6, 0x01f8},
333    {0x0388, 0x038a}, {0x0391, 0x03a1}, {0x03a3, 0x03ab}, {0x03d2, 0x03d4},
334    {0x0400, 0x042f}, {0x0531, 0x0556}, {0x10a0, 0x10c5}, {0x1f08, 0x1f0f},
335    {0x1f18, 0x1f1d}, {0x1f28, 0x1f2f}, {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d},
336    {0x1f68, 0x1f6f}, {0x1fb8, 0x1fbb}, {0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb},
337    {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb}, {0x210b, 0x210d}, {0x2110, 0x2112},
338    {0x2119, 0x211d}, {0x212a, 0x212d}, {0xff21, 0xff3a}
339};
340
341#define NUM_UPPER_RANGE (sizeof(upperRangeTable)/sizeof(crange))
342
343static const chr upperCharTable[] = {
344    0x0100, 0x0102, 0x0104, 0x0106, 0x0108, 0x010a, 0x010c, 0x010e, 0x0110,
345    0x0112, 0x0114, 0x0116, 0x0118, 0x011a, 0x011c, 0x011e, 0x0120, 0x0122,
346    0x0124, 0x0126, 0x0128, 0x012a, 0x012c, 0x012e, 0x0130, 0x0132, 0x0134,
347    0x0136, 0x0139, 0x013b, 0x013d, 0x013f, 0x0141, 0x0143, 0x0145, 0x0147,
348    0x014a, 0x014c, 0x014e, 0x0150, 0x0152, 0x0154, 0x0156, 0x0158, 0x015a,
349    0x015c, 0x015e, 0x0160, 0x0162, 0x0164, 0x0166, 0x0168, 0x016a, 0x016c,
350    0x016e, 0x0170, 0x0172, 0x0174, 0x0176, 0x0178, 0x0179, 0x017b, 0x017d,
351    0x0181, 0x0182, 0x0184, 0x0186, 0x0187, 0x0193, 0x0194, 0x019c, 0x019d,
352    0x019f, 0x01a0, 0x01a2, 0x01a4, 0x01a6, 0x01a7, 0x01a9, 0x01ac, 0x01ae,
353    0x01af, 0x01b5, 0x01b7, 0x01b8, 0x01bc, 0x01c4, 0x01c7, 0x01ca, 0x01cd,
354    0x01cf, 0x01d1, 0x01d3, 0x01d5, 0x01d7, 0x01d9, 0x01db, 0x01de, 0x01e0,
355    0x01e2, 0x01e4, 0x01e6, 0x01e8, 0x01ea, 0x01ec, 0x01ee, 0x01f1, 0x01f4,
356    0x01fa, 0x01fc, 0x01fe, 0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020a,
357    0x020c, 0x020e, 0x0210, 0x0212, 0x0214, 0x0216, 0x0218, 0x021a, 0x021c,
358    0x021e, 0x0222, 0x0224, 0x0226, 0x0228, 0x022a, 0x022c, 0x022e, 0x0230,
359    0x0232, 0x0386, 0x038c, 0x038e, 0x038f, 0x03da, 0x03dc, 0x03de, 0x03e0,
360    0x03e2, 0x03e4, 0x03e6, 0x03e8, 0x03ea, 0x03ec, 0x03ee, 0x03f4, 0x0460,
361    0x0462, 0x0464, 0x0466, 0x0468, 0x046a, 0x046c, 0x046e, 0x0470, 0x0472,
362    0x0474, 0x0476, 0x0478, 0x047a, 0x047c, 0x047e, 0x0480, 0x048c, 0x048e,
363    0x0490, 0x0492, 0x0494, 0x0496, 0x0498, 0x049a, 0x049c, 0x049e, 0x04a0,
364    0x04a2, 0x04a4, 0x04a6, 0x04a8, 0x04aa, 0x04ac, 0x04ae, 0x04b0, 0x04b2,
365    0x04b4, 0x04b6, 0x04b8, 0x04ba, 0x04bc, 0x04be, 0x04c0, 0x04c1, 0x04c3,
366    0x04c7, 0x04cb, 0x04d0, 0x04d2, 0x04d4, 0x04d6, 0x04d8, 0x04da, 0x04dc,
367    0x04de, 0x04e0, 0x04e2, 0x04e4, 0x04e6, 0x04e8, 0x04ea, 0x04ec, 0x04ee,
368    0x04f0, 0x04f2, 0x04f4, 0x04f8, 0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08,
369    0x1e0a, 0x1e0c, 0x1e0e, 0x1e10, 0x1e12, 0x1e14, 0x1e16, 0x1e18, 0x1e1a,
370    0x1e1c, 0x1e1e, 0x1e20, 0x1e22, 0x1e24, 0x1e26, 0x1e28, 0x1e2a, 0x1e2c,
371    0x1e2e, 0x1e30, 0x1e32, 0x1e34, 0x1e36, 0x1e38, 0x1e3a, 0x1e3c, 0x1e3e,
372    0x1e40, 0x1e42, 0x1e44, 0x1e46, 0x1e48, 0x1e4a, 0x1e4c, 0x1e4e, 0x1e50,
373    0x1e52, 0x1e54, 0x1e56, 0x1e58, 0x1e5a, 0x1e5c, 0x1e5e, 0x1e60, 0x1e62,
374    0x1e64, 0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e, 0x1e70, 0x1e72, 0x1e74,
375    0x1e76, 0x1e78, 0x1e7a, 0x1e7c, 0x1e7e, 0x1e80, 0x1e82, 0x1e84, 0x1e86,
376    0x1e88, 0x1e8a, 0x1e8c, 0x1e8e, 0x1e90, 0x1e92, 0x1e94, 0x1ea0, 0x1ea2,
377    0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac, 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4,
378    0x1eb6, 0x1eb8, 0x1eba, 0x1ebc, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6,
379    0x1ec8, 0x1eca, 0x1ecc, 0x1ece, 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8,
380    0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2, 0x1ee4, 0x1ee6, 0x1ee8, 0x1eea,
381    0x1eec, 0x1eee, 0x1ef0, 0x1ef2, 0x1ef4, 0x1ef6, 0x1ef8, 0x1f59, 0x1f5b,
382    0x1f5d, 0x1f5f, 0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x2130,
383    0x2131, 0x2133
384};
385
386#define NUM_UPPER_CHAR (sizeof(upperCharTable)/sizeof(chr))
387
388/*
389 * Unicode: unicode print characters excluding space.
390 */
391
392static const crange graphRangeTable[] = {
393    {0x0021, 0x007e}, {0x00a0, 0x011f}, {0x0121, 0x021f}, {0x0222, 0x0233},
394    {0x0250, 0x02ad}, {0x02b0, 0x02ee}, {0x0300, 0x031f}, {0x0321, 0x034e},
395    {0x0360, 0x0362}, {0x0384, 0x038a}, {0x038e, 0x03a1}, {0x03a3, 0x03ce},
396    {0x03d0, 0x03d7}, {0x03da, 0x03f5}, {0x0400, 0x041f}, {0x0421, 0x0486},
397    {0x048c, 0x04c4}, {0x04d0, 0x04f5}, {0x0531, 0x0556}, {0x0559, 0x055f},
398    {0x0561, 0x0587}, {0x0591, 0x05a1}, {0x05a3, 0x05b9}, {0x05bb, 0x05c4},
399    {0x05d0, 0x05ea}, {0x05f0, 0x05f4}, {0x0621, 0x063a}, {0x0640, 0x0655},
400    {0x0660, 0x066d}, {0x0670, 0x06ed}, {0x06f0, 0x06fe}, {0x0700, 0x070d},
401    {0x0710, 0x071f}, {0x0721, 0x072c}, {0x0730, 0x074a}, {0x0780, 0x07b0},
402    {0x0901, 0x0903}, {0x0905, 0x091f}, {0x0921, 0x0939}, {0x093c, 0x094d},
403    {0x0950, 0x0954}, {0x0958, 0x0970}, {0x0981, 0x0983}, {0x0985, 0x098c},
404    {0x0993, 0x09a8}, {0x09aa, 0x09b0}, {0x09b6, 0x09b9}, {0x09be, 0x09c4},
405    {0x09cb, 0x09cd}, {0x09df, 0x09e3}, {0x09e6, 0x09fa}, {0x0a05, 0x0a0a},
406    {0x0a13, 0x0a1f}, {0x0a21, 0x0a28}, {0x0a2a, 0x0a30}, {0x0a3e, 0x0a42},
407    {0x0a4b, 0x0a4d}, {0x0a59, 0x0a5c}, {0x0a66, 0x0a74}, {0x0a81, 0x0a83},
408    {0x0a85, 0x0a8b}, {0x0a8f, 0x0a91}, {0x0a93, 0x0aa8}, {0x0aaa, 0x0ab0},
409    {0x0ab5, 0x0ab9}, {0x0abc, 0x0ac5}, {0x0ac7, 0x0ac9}, {0x0acb, 0x0acd},
410    {0x0ae6, 0x0aef}, {0x0b01, 0x0b03}, {0x0b05, 0x0b0c}, {0x0b13, 0x0b1f},
411    {0x0b21, 0x0b28}, {0x0b2a, 0x0b30}, {0x0b36, 0x0b39}, {0x0b3c, 0x0b43},
412    {0x0b4b, 0x0b4d}, {0x0b5f, 0x0b61}, {0x0b66, 0x0b70}, {0x0b85, 0x0b8a},
413    {0x0b8e, 0x0b90}, {0x0b92, 0x0b95}, {0x0ba8, 0x0baa}, {0x0bae, 0x0bb5},
414    {0x0bb7, 0x0bb9}, {0x0bbe, 0x0bc2}, {0x0bc6, 0x0bc8}, {0x0bca, 0x0bcd},
415    {0x0be7, 0x0bf2}, {0x0c01, 0x0c03}, {0x0c05, 0x0c0c}, {0x0c0e, 0x0c10},
416    {0x0c12, 0x0c1f}, {0x0c21, 0x0c28}, {0x0c2a, 0x0c33}, {0x0c35, 0x0c39},
417    {0x0c3e, 0x0c44}, {0x0c46, 0x0c48}, {0x0c4a, 0x0c4d}, {0x0c66, 0x0c6f},
418    {0x0c85, 0x0c8c}, {0x0c8e, 0x0c90}, {0x0c92, 0x0ca8}, {0x0caa, 0x0cb3},
419    {0x0cb5, 0x0cb9}, {0x0cbe, 0x0cc4}, {0x0cc6, 0x0cc8}, {0x0cca, 0x0ccd},
420    {0x0ce6, 0x0cef}, {0x0d05, 0x0d0c}, {0x0d0e, 0x0d10}, {0x0d12, 0x0d1f},
421    {0x0d21, 0x0d28}, {0x0d2a, 0x0d39}, {0x0d3e, 0x0d43}, {0x0d46, 0x0d48},
422    {0x0d4a, 0x0d4d}, {0x0d66, 0x0d6f}, {0x0d85, 0x0d96}, {0x0d9a, 0x0db1},
423    {0x0db3, 0x0dbb}, {0x0dc0, 0x0dc6}, {0x0dcf, 0x0dd4}, {0x0dd8, 0x0ddf},
424    {0x0df2, 0x0df4}, {0x0e01, 0x0e1f}, {0x0e21, 0x0e3a}, {0x0e3f, 0x0e5b},
425    {0x0e94, 0x0e97}, {0x0e99, 0x0e9f}, {0x0ea1, 0x0ea3}, {0x0ead, 0x0eb9},
426    {0x0ebb, 0x0ebd}, {0x0ec0, 0x0ec4}, {0x0ec8, 0x0ecd}, {0x0ed0, 0x0ed9},
427    {0x0f00, 0x0f1f}, {0x0f21, 0x0f47}, {0x0f49, 0x0f6a}, {0x0f71, 0x0f8b},
428    {0x0f90, 0x0f97}, {0x0f99, 0x0fbc}, {0x0fbe, 0x0fcc}, {0x1000, 0x101f},
429    {0x1023, 0x1027}, {0x102c, 0x1032}, {0x1036, 0x1039}, {0x1040, 0x1059},
430    {0x10a0, 0x10c5}, {0x10d0, 0x10f6}, {0x1100, 0x111f}, {0x1121, 0x1159},
431    {0x115f, 0x11a2}, {0x11a8, 0x11f9}, {0x1200, 0x1206}, {0x1208, 0x121f},
432    {0x1221, 0x1246}, {0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d},
433    {0x1260, 0x1286}, {0x128a, 0x128d}, {0x1290, 0x12ae}, {0x12b2, 0x12b5},
434    {0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12ce}, {0x12d0, 0x12d6},
435    {0x12d8, 0x12ee}, {0x12f0, 0x130e}, {0x1312, 0x1315}, {0x1318, 0x131e},
436    {0x1321, 0x1346}, {0x1348, 0x135a}, {0x1361, 0x137c}, {0x13a0, 0x13f4},
437    {0x1401, 0x141f}, {0x1421, 0x151f}, {0x1521, 0x161f}, {0x1621, 0x1676},
438    {0x1680, 0x169c}, {0x16a0, 0x16f0}, {0x1780, 0x17dc}, {0x17e0, 0x17e9},
439    {0x1800, 0x180a}, {0x1810, 0x1819}, {0x1821, 0x1877}, {0x1880, 0x18a9},
440    {0x1e00, 0x1e1f}, {0x1e21, 0x1e9b}, {0x1ea0, 0x1ef9}, {0x1f00, 0x1f15},
441    {0x1f18, 0x1f1d}, {0x1f21, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57},
442    {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3},
443    {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe},
444    {0x2000, 0x200b}, {0x2010, 0x201f}, {0x2021, 0x2029}, {0x202f, 0x2046},
445    {0x2048, 0x204d}, {0x2074, 0x208e}, {0x20a0, 0x20af}, {0x20d0, 0x20e3},
446    {0x2100, 0x211f}, {0x2121, 0x213a}, {0x2153, 0x2183}, {0x2190, 0x21f3},
447    {0x2200, 0x221f}, {0x2221, 0x22f1}, {0x2300, 0x231f}, {0x2321, 0x237b},
448    {0x237d, 0x239a}, {0x2400, 0x241f}, {0x2421, 0x2426}, {0x2440, 0x244a},
449    {0x2460, 0x24ea}, {0x2500, 0x251f}, {0x2521, 0x2595}, {0x25a0, 0x25f7},
450    {0x2600, 0x2613}, {0x2619, 0x261f}, {0x2621, 0x2671}, {0x2701, 0x2704},
451    {0x2706, 0x2709}, {0x270c, 0x271f}, {0x2721, 0x2727}, {0x2729, 0x274b},
452    {0x274f, 0x2752}, {0x2758, 0x275e}, {0x2761, 0x2767}, {0x2776, 0x2794},
453    {0x2798, 0x27af}, {0x27b1, 0x27be}, {0x2800, 0x281f}, {0x2821, 0x28ff},
454    {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2f1f}, {0x2f21, 0x2fd5},
455    {0x2ff0, 0x2ffb}, {0x3000, 0x301f}, {0x3021, 0x303a}, {0x3041, 0x3094},
456    {0x3099, 0x309e}, {0x30a1, 0x30fe}, {0x3105, 0x311f}, {0x3121, 0x312c},
457    {0x3131, 0x318e}, {0x3190, 0x31b7}, {0x3200, 0x321c}, {0x3221, 0x3243},
458    {0x3260, 0x327b}, {0x327f, 0x32b0}, {0x32c0, 0x32cb}, {0x32d0, 0x32fe},
459    {0x3300, 0x331f}, {0x3321, 0x3376}, {0x337b, 0x33dd}, {0x33e0, 0x33fe},
460    {0x3400, 0x341f}, {0x3421, 0x351f}, {0x3521, 0x361f}, {0x3621, 0x371f},
461    {0x3721, 0x381f}, {0x3821, 0x391f}, {0x3921, 0x3a1f}, {0x3a21, 0x3b1f},
462    {0x3b21, 0x3c1f}, {0x3c21, 0x3d1f}, {0x3d21, 0x3e1f}, {0x3e21, 0x3f1f},
463    {0x3f21, 0x401f}, {0x4021, 0x411f}, {0x4121, 0x421f}, {0x4221, 0x431f},
464    {0x4321, 0x441f}, {0x4421, 0x451f}, {0x4521, 0x461f}, {0x4621, 0x471f},
465    {0x4721, 0x481f}, {0x4821, 0x491f}, {0x4921, 0x4a1f}, {0x4a21, 0x4b1f},
466    {0x4b21, 0x4c1f}, {0x4c21, 0x4d1f}, {0x4d21, 0x4db5}, {0x4e00, 0x4e1f},
467    {0x4e21, 0x4f1f}, {0x4f21, 0x501f}, {0x5021, 0x511f}, {0x5121, 0x521f},
468    {0x5221, 0x531f}, {0x5321, 0x541f}, {0x5421, 0x551f}, {0x5521, 0x561f},
469    {0x5621, 0x571f}, {0x5721, 0x581f}, {0x5821, 0x591f}, {0x5921, 0x5a1f},
470    {0x5a21, 0x5b1f}, {0x5b21, 0x5c1f}, {0x5c21, 0x5d1f}, {0x5d21, 0x5e1f},
471    {0x5e21, 0x5f1f}, {0x5f21, 0x601f}, {0x6021, 0x611f}, {0x6121, 0x621f},
472    {0x6221, 0x631f}, {0x6321, 0x641f}, {0x6421, 0x651f}, {0x6521, 0x661f},
473    {0x6621, 0x671f}, {0x6721, 0x681f}, {0x6821, 0x691f}, {0x6921, 0x6a1f},
474    {0x6a21, 0x6b1f}, {0x6b21, 0x6c1f}, {0x6c21, 0x6d1f}, {0x6d21, 0x6e1f},
475    {0x6e21, 0x6f1f}, {0x6f21, 0x701f}, {0x7021, 0x711f}, {0x7121, 0x721f},
476    {0x7221, 0x731f}, {0x7321, 0x741f}, {0x7421, 0x751f}, {0x7521, 0x761f},
477    {0x7621, 0x771f}, {0x7721, 0x781f}, {0x7821, 0x791f}, {0x7921, 0x7a1f},
478    {0x7a21, 0x7b1f}, {0x7b21, 0x7c1f}, {0x7c21, 0x7d1f}, {0x7d21, 0x7e1f},
479    {0x7e21, 0x7f1f}, {0x7f21, 0x801f}, {0x8021, 0x811f}, {0x8121, 0x821f},
480    {0x8221, 0x831f}, {0x8321, 0x841f}, {0x8421, 0x851f}, {0x8521, 0x861f},
481    {0x8621, 0x871f}, {0x8721, 0x881f}, {0x8821, 0x891f}, {0x8921, 0x8a1f},
482    {0x8a21, 0x8b1f}, {0x8b21, 0x8c1f}, {0x8c21, 0x8d1f}, {0x8d21, 0x8e1f},
483    {0x8e21, 0x8f1f}, {0x8f21, 0x901f}, {0x9021, 0x911f}, {0x9121, 0x921f},
484    {0x9221, 0x931f}, {0x9321, 0x941f}, {0x9421, 0x951f}, {0x9521, 0x961f},
485    {0x9621, 0x971f}, {0x9721, 0x981f}, {0x9821, 0x991f}, {0x9921, 0x9a1f},
486    {0x9a21, 0x9b1f}, {0x9b21, 0x9c1f}, {0x9c21, 0x9d1f}, {0x9d21, 0x9e1f},
487    {0x9e21, 0x9f1f}, {0x9f21, 0x9fa5}, {0xa000, 0xa01f}, {0xa021, 0xa11f},
488    {0xa121, 0xa21f}, {0xa221, 0xa31f}, {0xa321, 0xa41f}, {0xa421, 0xa48c},
489    {0xa490, 0xa4a1}, {0xa4a4, 0xa4b3}, {0xa4b5, 0xa4c0}, {0xa4c2, 0xa4c4},
490    {0xac00, 0xac1f}, {0xac21, 0xad1f}, {0xad21, 0xae1f}, {0xae21, 0xaf1f},
491    {0xaf21, 0xb01f}, {0xb021, 0xb11f}, {0xb121, 0xb21f}, {0xb221, 0xb31f},
492    {0xb321, 0xb41f}, {0xb421, 0xb51f}, {0xb521, 0xb61f}, {0xb621, 0xb71f},
493    {0xb721, 0xb81f}, {0xb821, 0xb91f}, {0xb921, 0xba1f}, {0xba21, 0xbb1f},
494    {0xbb21, 0xbc1f}, {0xbc21, 0xbd1f}, {0xbd21, 0xbe1f}, {0xbe21, 0xbf1f},
495    {0xbf21, 0xc01f}, {0xc021, 0xc11f}, {0xc121, 0xc21f}, {0xc221, 0xc31f},
496    {0xc321, 0xc41f}, {0xc421, 0xc51f}, {0xc521, 0xc61f}, {0xc621, 0xc71f},
497    {0xc721, 0xc81f}, {0xc821, 0xc91f}, {0xc921, 0xca1f}, {0xca21, 0xcb1f},
498    {0xcb21, 0xcc1f}, {0xcc21, 0xcd1f}, {0xcd21, 0xce1f}, {0xce21, 0xcf1f},
499    {0xcf21, 0xd01f}, {0xd021, 0xd11f}, {0xd121, 0xd21f}, {0xd221, 0xd31f},
500    {0xd321, 0xd41f}, {0xd421, 0xd51f}, {0xd521, 0xd61f}, {0xd621, 0xd71f},
501    {0xd721, 0xd7a3}, {0xf900, 0xf91f}, {0xf921, 0xfa1f}, {0xfa21, 0xfa2d},
502    {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb1f}, {0xfb21, 0xfb36},
503    {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfc1f}, {0xfc21, 0xfd1f},
504    {0xfd21, 0xfd3f}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb},
505    {0xfe21, 0xfe23}, {0xfe30, 0xfe44}, {0xfe49, 0xfe52}, {0xfe54, 0xfe66},
506    {0xfe68, 0xfe6b}, {0xfe70, 0xfe72}, {0xfe76, 0xfefc}, {0xff01, 0xff1f},
507    {0xff21, 0xff5e}, {0xff61, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf},
508    {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee},
509    {0xfffc, 0xffff}
510};
511
512#define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange))
513
514static const chr graphCharTable[] = {
515    0x0374, 0x0375, 0x037a, 0x037e, 0x038c, 0x0488, 0x0489, 0x04c7, 0x04c8,
516    0x04cb, 0x04cc, 0x04f8, 0x04f9, 0x0589, 0x058a, 0x060c, 0x061b, 0x061f,
517    0x098f, 0x0990, 0x09b2, 0x09bc, 0x09c7, 0x09c8, 0x09d7, 0x09dc, 0x09dd,
518    0x0a02, 0x0a0f, 0x0a10, 0x0a32, 0x0a33, 0x0a35, 0x0a36, 0x0a38, 0x0a39,
519    0x0a3c, 0x0a47, 0x0a48, 0x0a5e, 0x0a8d, 0x0ab2, 0x0ab3, 0x0ad0, 0x0ae0,
520    0x0b0f, 0x0b10, 0x0b32, 0x0b33, 0x0b47, 0x0b48, 0x0b56, 0x0b57, 0x0b5c,
521    0x0b5d, 0x0b82, 0x0b83, 0x0b99, 0x0b9a, 0x0b9c, 0x0b9e, 0x0b9f, 0x0ba3,
522    0x0ba4, 0x0bd7, 0x0c55, 0x0c56, 0x0c60, 0x0c61, 0x0c82, 0x0c83, 0x0cd5,
523    0x0cd6, 0x0cde, 0x0ce0, 0x0ce1, 0x0d02, 0x0d03, 0x0d57, 0x0d60, 0x0d61,
524    0x0d82, 0x0d83, 0x0dbd, 0x0dca, 0x0dd6, 0x0e81, 0x0e82, 0x0e84, 0x0e87,
525    0x0e88, 0x0e8a, 0x0e8d, 0x0ea5, 0x0ea7, 0x0eaa, 0x0eab, 0x0ec6, 0x0edc,
526    0x0edd, 0x0fcf, 0x1021, 0x1029, 0x102a, 0x10fb, 0x1248, 0x1258, 0x1288,
527    0x12b0, 0x12c0, 0x1310, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x274d, 0x2756,
528    0x303e, 0x303f, 0xa4c6, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfe74
529};
530
531#define NUM_GRAPH_CHAR (sizeof(graphCharTable)/sizeof(chr))
532
533/*
534 * Unicode: unicode print characters including space, i.e. all Letters (class
535 * L*), Numbers (N*), Punctuation (P*), Symbols (S*) and Spaces (Zs).
536 */
537
538static const crange printRangeTable[] = {
539    {0x0020, 0x007E}, {0x00A0, 0x01F5}, {0x01FA, 0x0217}, {0x0250, 0x02A8},
540    {0x02B0, 0x02DE}, {0x02E0, 0x02E9}, {0x0374, 0x0375}, {0x0384, 0x038A},
541    {0x038E, 0x03A1}, {0x03A3, 0x03CE}, {0x03D0, 0x03D6}, {0x03E2, 0x03F3},
542    {0x0401, 0x040C}, {0x040E, 0x044F}, {0x0451, 0x045C}, {0x045E, 0x0482},
543    {0x0490, 0x04C4}, {0x04C7, 0x04C8}, {0x04CB, 0x04CC}, {0x04D0, 0x04EB},
544    {0x04EE, 0x04F5}, {0x04F8, 0x04F9}, {0x0531, 0x0556}, {0x0559, 0x055F},
545    {0x0561, 0x0587}, {0x05D0, 0x05EA}, {0x05F0, 0x05F4}, {0x0621, 0x063A},
546    {0x0640, 0x064A}, {0x0660, 0x066D}, {0x0671, 0x06B7}, {0x06BA, 0x06BE},
547    {0x06C0, 0x06CE}, {0x06D0, 0x06D5}, {0x06E5, 0x06E6}, {0x06F0, 0x06F9},
548    {0x0905, 0x0939}, {0x0958, 0x0961}, {0x0964, 0x0970}, {0x0985, 0x098C},
549    {0x098F, 0x0990}, {0x0993, 0x09A8}, {0x09AA, 0x09B0}, {0x09B6, 0x09B9},
550    {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E6, 0x09FA}, {0x0A05, 0x0A0A},
551    {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, {0x0A32, 0x0A33},
552    {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, {0x0A59, 0x0A5C}, {0x0A66, 0x0A6F},
553    {0x0A72, 0x0A74}, {0x0A85, 0x0A8B}, {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8},
554    {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0AE6, 0x0AEF},
555    {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, {0x0B13, 0x0B28}, {0x0B2A, 0x0B30},
556    {0x0B32, 0x0B33}, {0x0B36, 0x0B39}, {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61},
557    {0x0B66, 0x0B70}, {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95},
558    {0x0B99, 0x0B9A}, {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA},
559    {0x0BAE, 0x0BB5}, {0x0BB7, 0x0BB9}, {0x0BE7, 0x0BF2}, {0x0C05, 0x0C0C},
560    {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, {0x0C2A, 0x0C33}, {0x0C35, 0x0C39},
561    {0x0C60, 0x0C61}, {0x0C66, 0x0C6F}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90},
562    {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, {0x0CE0, 0x0CE1},
563    {0x0CE6, 0x0CEF}, {0x0D05, 0x0D0C}, {0x0D0E, 0x0D10}, {0x0D12, 0x0D28},
564    {0x0D2A, 0x0D39}, {0x0D60, 0x0D61}, {0x0D66, 0x0D6F}, {0x0E3F, 0x0E46},
565    {0x0E4F, 0x0E5B}, {0x0E99, 0x0E9F}, {0x0EA1, 0x0EA3}, {0x0EAA, 0x0EAB},
566    {0x0EAD, 0x0EB0}, {0x0EB2, 0x0EB3}, {0x0EC0, 0x0EC4}, {0x0ED0, 0x0ED9},
567    {0x0EDC, 0x0EDD}, {0x0F00, 0x0F17}, {0x0F1A, 0x0F34}, {0x0F3A, 0x0F3D},
568    {0x0F40, 0x0F47}, {0x0F49, 0x0F69}, {0x0F88, 0x0F8B}, {0x10A0, 0x10C5},
569    {0x10D0, 0x10F6}, {0x1100, 0x1159}, {0x115F, 0x11A2}, {0x11A8, 0x11F9},
570    {0x1E00, 0x1E9B}, {0x1EA0, 0x1EF9}, {0x1F00, 0x1F15}, {0x1F18, 0x1F1D},
571    {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F5F, 0x1F7D},
572    {0x1F80, 0x1FB4}, {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB},
573    {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE}, {0x2000, 0x200B},
574    {0x2010, 0x2027}, {0x2030, 0x2046}, {0x2074, 0x208E}, {0x20A0, 0x20AC},
575    {0x2100, 0x2138}, {0x2153, 0x2182}, {0x2190, 0x21EA}, {0x2200, 0x22F1},
576    {0x2302, 0x237A}, {0x2400, 0x2424}, {0x2440, 0x244A}, {0x2460, 0x24EA},
577    {0x2500, 0x2595}, {0x25A0, 0x25EF}, {0x2600, 0x2613}, {0x261A, 0x266F},
578    {0x2701, 0x2704}, {0x2706, 0x2709}, {0x270C, 0x2727}, {0x2729, 0x274B},
579    {0x274F, 0x2752}, {0x2758, 0x275E}, {0x2761, 0x2767}, {0x2776, 0x2794},
580    {0x2798, 0x27AF}, {0x27B1, 0x27BE}, {0x3000, 0x3029}, {0x3030, 0x3037},
581    {0x3041, 0x3094}, {0x309B, 0x309E}, {0x30A1, 0x30FE}, {0x3105, 0x312C},
582    {0x3131, 0x318E}, {0x3190, 0x319F}, {0x3200, 0x321C}, {0x3220, 0x3243},
583    {0x3260, 0x327B}, {0x327F, 0x32B0}, {0x32C0, 0x32CB}, {0x32D0, 0x32FE},
584    {0x3300, 0x3376}, {0x337B, 0x33DD}, {0x33E0, 0x33FE}, {0x4E00, 0x9FA5},
585    {0xAC00, 0xD7A3}, {0xF900, 0xFA2D}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17},
586    {0xFB1F, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44},
587    {0xFB46, 0xFBB1}, {0xFBD3, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7},
588    {0xFDF0, 0xFDFB}, {0xFE30, 0xFE44}, {0xFE49, 0xFE52}, {0xFE54, 0xFE66},
589    {0xFE68, 0xFE6B}, {0xFE70, 0xFE72}, {0xFE76, 0xFEFC}, {0xFF01, 0xFF5E},
590    {0xFF61, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7},
591    {0xFFDA, 0xFFDC}, {0xFFE0, 0xFFE6}, {0xFFE8, 0xFFEE}, {0xFFFC, 0xFFFD}
592};
593
594#define NUM_PRINT_RANGE (sizeof(printRangeTable)/sizeof(crange))
595
596static const chr printCharTable[] = {
597    0x037A, 0x037E, 0x038C, 0x03DA, 0x03DC, 0x03DE, 0x03E0, 0x0589, 0x05BE,
598    0x05C0, 0x05C3, 0x060C, 0x061B, 0x061F, 0x06E9, 0x093D, 0x0950, 0x09B2,
599    0x0A5E, 0x0A8D, 0x0ABD, 0x0AD0, 0x0AE0, 0x0B3D, 0x0B9C, 0x0CDE, 0x0E01,
600    0x0E32, 0x0E81, 0x0E84, 0x0E87, 0x0E8A, 0x0E8D, 0x0E94, 0x0EA5, 0x0EA7,
601    0x0EBD, 0x0EC6, 0x0F36, 0x0F38, 0x0F85, 0x10FB, 0x1F59, 0x1F5B, 0x1F5D,
602    0x2070, 0x2300, 0x274D, 0x2756, 0x303F, 0xFB3E, 0xFE74
603};
604
605#define NUM_PRINT_CHAR (sizeof(printCharTable)/sizeof(chr))
606
607/*
608 *      End of auto-generated Unicode character ranges declarations.
609 */
610
611#define CH      NOCELT
612
613/*
614 - element - map collating-element name to celt
615 ^ static celt element(struct vars *, const chr *, const chr *);
616 */
617static celt
618element(
619    struct vars *v,             /* context */
620    const chr *startp,          /* points to start of name */
621    const chr *endp)            /* points just past end of name */
622{
623    const struct cname *cn;
624    size_t len;
625    Tcl_DString ds;
626    const char *np;
627
628    /*
629     * Generic: one-chr names stand for themselves.
630     */
631
632    assert(startp < endp);
633    len = endp - startp;
634    if (len == 1) {
635        return *startp;
636    }
637
638    NOTE(REG_ULOCALE);
639
640    /*
641     * Search table.
642     */
643
644    Tcl_DStringInit(&ds);
645    np = Tcl_UniCharToUtfDString(startp, (int)len, &ds);
646    for (cn=cnames; cn->name!=NULL; cn++) {
647        if (strlen(cn->name)==len && strncmp(cn->name, np, len)==0) {
648            break;                      /* NOTE BREAK OUT */
649        }
650    }
651    Tcl_DStringFree(&ds);
652    if (cn->name != NULL) {
653        return CHR(cn->code);
654    }
655
656    /*
657     * Couldn't find it.
658     */
659
660    ERR(REG_ECOLLATE);
661    return 0;
662}
663
664/*
665 - range - supply cvec for a range, including legality check
666 ^ static struct cvec *range(struct vars *, celt, celt, int);
667 */
668static struct cvec *
669range(
670    struct vars *v,             /* context */
671    celt a,                     /* range start */
672    celt b,                     /* range end, might equal a */
673    int cases)                  /* case-independent? */
674{
675    int nchrs;
676    struct cvec *cv;
677    celt c, lc, uc, tc;
678
679    if (a != b && !before(a, b)) {
680        ERR(REG_ERANGE);
681        return NULL;
682    }
683
684    if (!cases) {               /* easy version */
685        cv = getcvec(v, 0, 1);
686        NOERRN();
687        addrange(cv, a, b);
688        return cv;
689    }
690
691    /*
692     * When case-independent, it's hard to decide when cvec ranges are usable,
693     * so for now at least, we won't try. We allocate enough space for two
694     * case variants plus a little extra for the two title case variants.
695     */
696
697    nchrs = (b - a + 1)*2 + 4;
698
699    cv = getcvec(v, nchrs, 0);
700    NOERRN();
701
702    for (c=a; c<=b; c++) {
703        addchr(cv, c);
704        lc = Tcl_UniCharToLower((chr)c);
705        uc = Tcl_UniCharToUpper((chr)c);
706        tc = Tcl_UniCharToTitle((chr)c);
707        if (c != lc) {
708            addchr(cv, lc);
709        }
710        if (c != uc) {
711            addchr(cv, uc);
712        }
713        if (c != tc && tc != uc) {
714            addchr(cv, tc);
715        }
716    }
717
718    return cv;
719}
720
721/*
722 - before - is celt x before celt y, for purposes of range legality?
723 ^ static int before(celt, celt);
724 */
725static int                      /* predicate */
726before(
727    celt x, celt y)             /* collating elements */
728{
729    if (x < y) {
730        return 1;
731    }
732    return 0;
733}
734
735/*
736 - eclass - supply cvec for an equivalence class
737 * Must include case counterparts on request.
738 ^ static struct cvec *eclass(struct vars *, celt, int);
739 */
740static struct cvec *
741eclass(
742    struct vars *v,             /* context */
743    celt c,                     /* Collating element representing the
744                                 * equivalence class. */
745    int cases)                  /* all cases? */
746{
747    struct cvec *cv;
748
749    /*
750     * Crude fake equivalence class for testing.
751     */
752
753    if ((v->cflags&REG_FAKE) && c == 'x') {
754        cv = getcvec(v, 4, 0);
755        addchr(cv, (chr)'x');
756        addchr(cv, (chr)'y');
757        if (cases) {
758            addchr(cv, (chr)'X');
759            addchr(cv, (chr)'Y');
760        }
761        return cv;
762    }
763
764    /*
765     * Otherwise, none.
766     */
767
768    if (cases) {
769        return allcases(v, c);
770    }
771    cv = getcvec(v, 1, 0);
772    assert(cv != NULL);
773    addchr(cv, (chr)c);
774    return cv;
775}
776
777/*
778 - cclass - supply cvec for a character class
779 * Must include case counterparts on request.
780 ^ static struct cvec *cclass(struct vars *, const chr *, const chr *, int);
781 */
782static struct cvec *
783cclass(
784    struct vars *v,             /* context */
785    const chr *startp,          /* where the name starts */
786    const chr *endp,            /* just past the end of the name */
787    int cases)                  /* case-independent? */
788{
789    size_t len;
790    struct cvec *cv = NULL;
791    Tcl_DString ds;
792    const char *np;
793    const char **namePtr;
794    int i, index;
795
796    /*
797     * The following arrays define the valid character class names.
798     */
799
800    static const char *classNames[] = {
801        "alnum", "alpha", "ascii", "blank", "cntrl", "digit", "graph",
802        "lower", "print", "punct", "space", "upper", "xdigit", NULL
803    };
804
805    enum classes {
806        CC_ALNUM, CC_ALPHA, CC_ASCII, CC_BLANK, CC_CNTRL, CC_DIGIT, CC_GRAPH,
807        CC_LOWER, CC_PRINT, CC_PUNCT, CC_SPACE, CC_UPPER, CC_XDIGIT
808    };
809
810
811    /*
812     * Extract the class name
813     */
814
815    len = endp - startp;
816    Tcl_DStringInit(&ds);
817    np = Tcl_UniCharToUtfDString(startp, (int)len, &ds);
818
819    /*
820     * Remap lower and upper to alpha if the match is case insensitive.
821     */
822
823    if (cases && len == 5 && (strncmp("lower", np, 5) == 0
824            || strncmp("upper", np, 5) == 0)) {
825        np = "alpha";
826    }
827
828    /*
829     * Map the name to the corresponding enumerated value.
830     */
831
832    index = -1;
833    for (namePtr=classNames,i=0 ; *namePtr!=NULL ; namePtr++,i++) {
834        if ((strlen(*namePtr) == len) && (strncmp(*namePtr, np, len) == 0)) {
835            index = i;
836            break;
837        }
838    }
839    Tcl_DStringFree(&ds);
840    if (index == -1) {
841        ERR(REG_ECTYPE);
842        return NULL;
843    }
844
845    /*
846     * Now compute the character class contents.
847     */
848
849    switch((enum classes) index) {
850    case CC_PRINT:
851        cv = getcvec(v, NUM_PRINT_CHAR, NUM_PRINT_RANGE);
852        if (cv) {
853            for (i=0 ; (size_t)i<NUM_PRINT_CHAR ; i++) {
854                addchr(cv, printCharTable[i]);
855            }
856            for (i=0 ; (size_t)i<NUM_PRINT_RANGE ; i++) {
857                addrange(cv, printRangeTable[i].start,
858                        printRangeTable[i].end);
859            }
860        }
861        break;
862    case CC_ALNUM:
863        cv = getcvec(v, NUM_ALPHA_CHAR, NUM_DIGIT_RANGE + NUM_ALPHA_RANGE);
864        if (cv) {
865            for (i=0 ; (size_t)i<NUM_ALPHA_CHAR ; i++) {
866                addchr(cv, alphaCharTable[i]);
867            }
868            for (i=0 ; (size_t)i<NUM_ALPHA_RANGE ; i++) {
869                addrange(cv, alphaRangeTable[i].start,
870                        alphaRangeTable[i].end);
871            }
872            for (i=0 ; (size_t)i<NUM_DIGIT_RANGE ; i++) {
873                addrange(cv, digitRangeTable[i].start,
874                        digitRangeTable[i].end);
875            }
876        }
877        break;
878    case CC_ALPHA:
879        cv = getcvec(v, NUM_ALPHA_CHAR, NUM_ALPHA_RANGE);
880        if (cv) {
881            for (i=0 ; (size_t)i<NUM_ALPHA_RANGE ; i++) {
882                addrange(cv, alphaRangeTable[i].start,
883                        alphaRangeTable[i].end);
884            }
885            for (i=0 ; (size_t)i<NUM_ALPHA_CHAR ; i++) {
886                addchr(cv, alphaCharTable[i]);
887            }
888        }
889        break;
890    case CC_ASCII:
891        cv = getcvec(v, 0, 1);
892        if (cv) {
893            addrange(cv, 0, 0x7f);
894        }
895        break;
896    case CC_BLANK:
897        cv = getcvec(v, 2, 0);
898        addchr(cv, '\t');
899        addchr(cv, ' ');
900        break;
901    case CC_CNTRL:
902        cv = getcvec(v, 0, 2);
903        addrange(cv, 0x0, 0x1f);
904        addrange(cv, 0x7f, 0x9f);
905        break;
906    case CC_DIGIT:
907        cv = getcvec(v, 0, NUM_DIGIT_RANGE);
908        if (cv) {
909            for (i=0 ; (size_t)i<NUM_DIGIT_RANGE ; i++) {
910                addrange(cv, digitRangeTable[i].start,
911                        digitRangeTable[i].end);
912            }
913        }
914        break;
915    case CC_PUNCT:
916        cv = getcvec(v, NUM_PUNCT_CHAR, NUM_PUNCT_RANGE);
917        if (cv) {
918            for (i=0 ; (size_t)i<NUM_PUNCT_RANGE ; i++) {
919                addrange(cv, punctRangeTable[i].start,
920                        punctRangeTable[i].end);
921            }
922            for (i=0 ; (size_t)i<NUM_PUNCT_CHAR ; i++) {
923                addchr(cv, punctCharTable[i]);
924            }
925        }
926        break;
927    case CC_XDIGIT:
928        /*
929         * This is a 3 instead of (NUM_DIGIT_RANGE+2) because I've no idea how
930         * to define the digits 'a' through 'f' in non-western locales. The
931         * concept is quite possibly non portable, or only used in contextx
932         * where the characters used would be the western ones anyway!
933         * Whatever is actually the case, the number of ranges is fixed (until
934         * someone comes up with a better arrangement!)
935         */
936
937        cv = getcvec(v, 0, 3);
938        if (cv) {
939            addrange(cv, '0', '9');
940            addrange(cv, 'a', 'f');
941            addrange(cv, 'A', 'F');
942        }
943        break;
944    case CC_SPACE:
945        cv = getcvec(v, NUM_SPACE_CHAR, NUM_SPACE_RANGE);
946        if (cv) {
947            for (i=0 ; (size_t)i<NUM_SPACE_RANGE ; i++) {
948                addrange(cv, spaceRangeTable[i].start,
949                        spaceRangeTable[i].end);
950            }
951            for (i=0 ; (size_t)i<NUM_SPACE_CHAR ; i++) {
952                addchr(cv, spaceCharTable[i]);
953            }
954        }
955        break;
956    case CC_LOWER:
957        cv  = getcvec(v, NUM_LOWER_CHAR, NUM_LOWER_RANGE);
958        if (cv) {
959            for (i=0 ; (size_t)i<NUM_LOWER_RANGE ; i++) {
960                addrange(cv, lowerRangeTable[i].start,
961                        lowerRangeTable[i].end);
962            }
963            for (i=0 ; (size_t)i<NUM_LOWER_CHAR ; i++) {
964                addchr(cv, lowerCharTable[i]);
965            }
966        }
967        break;
968    case CC_UPPER:
969        cv  = getcvec(v, NUM_UPPER_CHAR, NUM_UPPER_RANGE);
970        if (cv) {
971            for (i=0 ; (size_t)i<NUM_UPPER_RANGE ; i++) {
972                addrange(cv, upperRangeTable[i].start,
973                        upperRangeTable[i].end);
974            }
975            for (i=0 ; (size_t)i<NUM_UPPER_CHAR ; i++) {
976                addchr(cv, upperCharTable[i]);
977            }
978        }
979        break;
980    case CC_GRAPH:
981        cv  = getcvec(v, NUM_GRAPH_CHAR, NUM_GRAPH_RANGE);
982        if (cv) {
983            for (i=0 ; (size_t)i<NUM_GRAPH_RANGE ; i++) {
984                addrange(cv, graphRangeTable[i].start,
985                        graphRangeTable[i].end);
986            }
987            for (i=0 ; (size_t)i<NUM_GRAPH_CHAR ; i++) {
988                addchr(cv, graphCharTable[i]);
989            }
990        }
991        break;
992    }
993    if (cv == NULL) {
994        ERR(REG_ESPACE);
995    }
996    return cv;
997}
998
999/*
1000 - allcases - supply cvec for all case counterparts of a chr (including itself)
1001 * This is a shortcut, preferably an efficient one, for simple characters;
1002 * messy cases are done via range().
1003 ^ static struct cvec *allcases(struct vars *, pchr);
1004 */
1005static struct cvec *
1006allcases(
1007    struct vars *v,             /* context */
1008    pchr pc)                    /* character to get case equivs of */
1009{
1010    struct cvec *cv;
1011    chr c = (chr)pc;
1012    chr lc, uc, tc;
1013
1014    lc = Tcl_UniCharToLower((chr)c);
1015    uc = Tcl_UniCharToUpper((chr)c);
1016    tc = Tcl_UniCharToTitle((chr)c);
1017
1018    if (tc != uc) {
1019        cv = getcvec(v, 3, 0);
1020        addchr(cv, tc);
1021    } else {
1022        cv = getcvec(v, 2, 0);
1023    }
1024    addchr(cv, lc);
1025    if (lc != uc) {
1026        addchr(cv, uc);
1027    }
1028    return cv;
1029}
1030
1031/*
1032 - cmp - chr-substring compare
1033 * Backrefs need this.  It should preferably be efficient.
1034 * Note that it does not need to report anything except equal/unequal.
1035 * Note also that the length is exact, and the comparison should not
1036 * stop at embedded NULs!
1037 ^ static int cmp(const chr *, const chr *, size_t);
1038 */
1039static int                      /* 0 for equal, nonzero for unequal */
1040cmp(
1041    const chr *x, const chr *y, /* strings to compare */
1042    size_t len)                 /* exact length of comparison */
1043{
1044    return memcmp(VS(x), VS(y), len*sizeof(chr));
1045}
1046
1047/*
1048 - casecmp - case-independent chr-substring compare
1049 * REG_ICASE backrefs need this.  It should preferably be efficient.
1050 * Note that it does not need to report anything except equal/unequal.
1051 * Note also that the length is exact, and the comparison should not
1052 * stop at embedded NULs!
1053 ^ static int casecmp(const chr *, const chr *, size_t);
1054 */
1055static int                      /* 0 for equal, nonzero for unequal */
1056casecmp(
1057    const chr *x, const chr *y, /* strings to compare */
1058    size_t len)                 /* exact length of comparison */
1059{
1060    for (; len > 0; len--, x++, y++) {
1061        if ((*x!=*y) && (Tcl_UniCharToLower(*x) != Tcl_UniCharToLower(*y))) {
1062            return 1;
1063        }
1064    }
1065    return 0;
1066}
1067
1068/*
1069 * Local Variables:
1070 * mode: c
1071 * c-basic-offset: 4
1072 * fill-column: 78
1073 * End:
1074 */
Note: See TracBrowser for help on using the repository browser.