regc_locale.c

Go to the documentation of this file.
00001 /*
00002  * regc_locale.c --
00003  *
00004  *      This file contains the Unicode locale specific regexp routines.
00005  *      This file is #included by regcomp.c.
00006  *
00007  * Copyright (c) 1998 by Scriptics Corporation.
00008  *
00009  * See the file "license.terms" for information on usage and redistribution of
00010  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
00011  *
00012  * RCS: @(#) $Id: regc_locale.c,v 1.20 2007/12/13 15:23:14 dgp Exp $
00013  */
00014 
00015 /* ASCII character-name table */
00016 
00017 static const struct cname {
00018     const char *name;
00019     const char code;
00020 } cnames[] = {
00021     {"NUL",             '\0'},
00022     {"SOH",             '\001'},
00023     {"STX",             '\002'},
00024     {"ETX",             '\003'},
00025     {"EOT",             '\004'},
00026     {"ENQ",             '\005'},
00027     {"ACK",             '\006'},
00028     {"BEL",             '\007'},
00029     {"alert",           '\007'},
00030     {"BS",              '\010'},
00031     {"backspace",       '\b'},
00032     {"HT",              '\011'},
00033     {"tab",             '\t'},
00034     {"LF",              '\012'},
00035     {"newline",         '\n'},
00036     {"VT",              '\013'},
00037     {"vertical-tab",    '\v'},
00038     {"FF",              '\014'},
00039     {"form-feed",       '\f'},
00040     {"CR",              '\015'},
00041     {"carriage-return", '\r'},
00042     {"SO",              '\016'},
00043     {"SI",              '\017'},
00044     {"DLE",             '\020'},
00045     {"DC1",             '\021'},
00046     {"DC2",             '\022'},
00047     {"DC3",             '\023'},
00048     {"DC4",             '\024'},
00049     {"NAK",             '\025'},
00050     {"SYN",             '\026'},
00051     {"ETB",             '\027'},
00052     {"CAN",             '\030'},
00053     {"EM",              '\031'},
00054     {"SUB",             '\032'},
00055     {"ESC",             '\033'},
00056     {"IS4",             '\034'},
00057     {"FS",              '\034'},
00058     {"IS3",             '\035'},
00059     {"GS",              '\035'},
00060     {"IS2",             '\036'},
00061     {"RS",              '\036'},
00062     {"IS1",             '\037'},
00063     {"US",              '\037'},
00064     {"space",           ' '},
00065     {"exclamation-mark",'!'},
00066     {"quotation-mark",  '"'},
00067     {"number-sign",     '#'},
00068     {"dollar-sign",     '$'},
00069     {"percent-sign",    '%'},
00070     {"ampersand",       '&'},
00071     {"apostrophe",      '\''},
00072     {"left-parenthesis",'('},
00073     {"right-parenthesis", ')'},
00074     {"asterisk",        '*'},
00075     {"plus-sign",       '+'},
00076     {"comma",           ','},
00077     {"hyphen",          '-'},
00078     {"hyphen-minus",    '-'},
00079     {"period",          '.'},
00080     {"full-stop",       '.'},
00081     {"slash",           '/'},
00082     {"solidus",         '/'},
00083     {"zero",            '0'},
00084     {"one",             '1'},
00085     {"two",             '2'},
00086     {"three",           '3'},
00087     {"four",            '4'},
00088     {"five",            '5'},
00089     {"six",             '6'},
00090     {"seven",           '7'},
00091     {"eight",           '8'},
00092     {"nine",            '9'},
00093     {"colon",           ':'},
00094     {"semicolon",       ';'},
00095     {"less-than-sign",  '<'},
00096     {"equals-sign",     '='},
00097     {"greater-than-sign", '>'},
00098     {"question-mark",   '?'},
00099     {"commercial-at",   '@'},
00100     {"left-square-bracket", '['},
00101     {"backslash",       '\\'},
00102     {"reverse-solidus", '\\'},
00103     {"right-square-bracket", ']'},
00104     {"circumflex",      '^'},
00105     {"circumflex-accent", '^'},
00106     {"underscore",      '_'},
00107     {"low-line",        '_'},
00108     {"grave-accent",    '`'},
00109     {"left-brace",      '{'},
00110     {"left-curly-bracket", '{'},
00111     {"vertical-line",   '|'},
00112     {"right-brace",     '}'},
00113     {"right-curly-bracket", '}'},
00114     {"tilde",           '~'},
00115     {"DEL",             '\177'},
00116     {NULL,              0}
00117 };
00118 
00119 /*
00120  * Unicode character-class tables.
00121  */
00122 
00123 typedef struct crange {
00124     chr start;
00125     chr end;
00126 } crange;
00127 
00128 /*
00129  *      Declarations of Unicode character ranges.  This code
00130  *      is automatically generated by the tools/uniClass.tcl script
00131  *      and used in generic/regc_locale.c.  Do not modify by hand.
00132  */
00133 
00134 /* Unicode: alphabetic characters */
00135 
00136 static const crange alphaRangeTable[] = {
00137     {0x0041, 0x005a}, {0x0061, 0x007a}, {0x00c0, 0x00d6}, {0x00d8, 0x00f6},
00138     {0x00f8, 0x021f}, {0x0222, 0x0233}, {0x0250, 0x02ad}, {0x02b0, 0x02b8},
00139     {0x02bb, 0x02c1}, {0x02e0, 0x02e4}, {0x0388, 0x038a}, {0x038e, 0x03a1},
00140     {0x03a3, 0x03ce}, {0x03d0, 0x03d7}, {0x03da, 0x03f5}, {0x0400, 0x0481},
00141     {0x048c, 0x04c4}, {0x04d0, 0x04f5}, {0x0531, 0x0556}, {0x0561, 0x0587},
00142     {0x05d0, 0x05ea}, {0x05f0, 0x05f2}, {0x0621, 0x063a}, {0x0640, 0x064a},
00143     {0x0671, 0x06d3}, {0x06fa, 0x06fc}, {0x0712, 0x072c}, {0x0780, 0x07a5},
00144     {0x0905, 0x0939}, {0x0958, 0x0961}, {0x0985, 0x098c}, {0x0993, 0x09a8},
00145     {0x09aa, 0x09b0}, {0x09b6, 0x09b9}, {0x09df, 0x09e1}, {0x0a05, 0x0a0a},
00146     {0x0a13, 0x0a28}, {0x0a2a, 0x0a30}, {0x0a59, 0x0a5c}, {0x0a72, 0x0a74},
00147     {0x0a85, 0x0a8b}, {0x0a8f, 0x0a91}, {0x0a93, 0x0aa8}, {0x0aaa, 0x0ab0},
00148     {0x0ab5, 0x0ab9}, {0x0b05, 0x0b0c}, {0x0b13, 0x0b28}, {0x0b2a, 0x0b30},
00149     {0x0b36, 0x0b39}, {0x0b5f, 0x0b61}, {0x0b85, 0x0b8a}, {0x0b8e, 0x0b90},
00150     {0x0b92, 0x0b95}, {0x0ba8, 0x0baa}, {0x0bae, 0x0bb5}, {0x0bb7, 0x0bb9},
00151     {0x0c05, 0x0c0c}, {0x0c0e, 0x0c10}, {0x0c12, 0x0c28}, {0x0c2a, 0x0c33},
00152     {0x0c35, 0x0c39}, {0x0c85, 0x0c8c}, {0x0c8e, 0x0c90}, {0x0c92, 0x0ca8},
00153     {0x0caa, 0x0cb3}, {0x0cb5, 0x0cb9}, {0x0d05, 0x0d0c}, {0x0d0e, 0x0d10},
00154     {0x0d12, 0x0d28}, {0x0d2a, 0x0d39}, {0x0d85, 0x0d96}, {0x0d9a, 0x0db1},
00155     {0x0db3, 0x0dbb}, {0x0dc0, 0x0dc6}, {0x0e01, 0x0e30}, {0x0e40, 0x0e46},
00156     {0x0e94, 0x0e97}, {0x0e99, 0x0e9f}, {0x0ea1, 0x0ea3}, {0x0ead, 0x0eb0},
00157     {0x0ec0, 0x0ec4}, {0x0f40, 0x0f47}, {0x0f49, 0x0f6a}, {0x0f88, 0x0f8b},
00158     {0x1000, 0x1021}, {0x1023, 0x1027}, {0x1050, 0x1055}, {0x10a0, 0x10c5},
00159     {0x10d0, 0x10f6}, {0x1100, 0x1159}, {0x115f, 0x11a2}, {0x11a8, 0x11f9},
00160     {0x1200, 0x1206}, {0x1208, 0x1246}, {0x124a, 0x124d}, {0x1250, 0x1256},
00161     {0x125a, 0x125d}, {0x1260, 0x1286}, {0x128a, 0x128d}, {0x1290, 0x12ae},
00162     {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12ce},
00163     {0x12d0, 0x12d6}, {0x12d8, 0x12ee}, {0x12f0, 0x130e}, {0x1312, 0x1315},
00164     {0x1318, 0x131e}, {0x1320, 0x1346}, {0x1348, 0x135a}, {0x13a0, 0x13f4},
00165     {0x1401, 0x166c}, {0x166f, 0x1676}, {0x1681, 0x169a}, {0x16a0, 0x16ea},
00166     {0x1780, 0x17b3}, {0x1820, 0x1877}, {0x1880, 0x18a8}, {0x1e00, 0x1e9b},
00167     {0x1ea0, 0x1ef9}, {0x1f00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45},
00168     {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4},
00169     {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3},
00170     {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc},
00171     {0x210a, 0x2113}, {0x2119, 0x211d}, {0x212a, 0x212d}, {0x212f, 0x2131},
00172     {0x2133, 0x2139}, {0x3031, 0x3035}, {0x3041, 0x3094}, {0x30a1, 0x30fa},
00173     {0x30fc, 0x30fe}, {0x3105, 0x312c}, {0x3131, 0x318e}, {0x31a0, 0x31b7},
00174     {0x3400, 0x4db5}, {0x4e00, 0x9fa5}, {0xa000, 0xa48c}, {0xac00, 0xd7a3},
00175     {0xf900, 0xfa2d}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28},
00176     {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d},
00177     {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe72},
00178     {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe},
00179     {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}
00180 };
00181 
00182 #define NUM_ALPHA_RANGE (sizeof(alphaRangeTable)/sizeof(crange))
00183 
00184 static const chr alphaCharTable[] = {
00185     0x00aa, 0x00b5, 0x00ba, 0x02d0, 0x02d1, 0x02ee, 0x037a, 0x0386, 0x038c,
00186     0x04c7, 0x04c8, 0x04cb, 0x04cc, 0x04f8, 0x04f9, 0x0559, 0x06d5, 0x06e5,
00187     0x06e6, 0x0710, 0x093d, 0x0950, 0x098f, 0x0990, 0x09b2, 0x09dc, 0x09dd,
00188     0x09f0, 0x09f1, 0x0a0f, 0x0a10, 0x0a32, 0x0a33, 0x0a35, 0x0a36, 0x0a38,
00189     0x0a39, 0x0a5e, 0x0a8d, 0x0ab2, 0x0ab3, 0x0abd, 0x0ad0, 0x0ae0, 0x0b0f,
00190     0x0b10, 0x0b32, 0x0b33, 0x0b3d, 0x0b5c, 0x0b5d, 0x0b99, 0x0b9a, 0x0b9c,
00191     0x0b9e, 0x0b9f, 0x0ba3, 0x0ba4, 0x0c60, 0x0c61, 0x0cde, 0x0ce0, 0x0ce1,
00192     0x0d60, 0x0d61, 0x0dbd, 0x0e32, 0x0e33, 0x0e81, 0x0e82, 0x0e84, 0x0e87,
00193     0x0e88, 0x0e8a, 0x0e8d, 0x0ea5, 0x0ea7, 0x0eaa, 0x0eab, 0x0eb2, 0x0eb3,
00194     0x0ebd, 0x0ec6, 0x0edc, 0x0edd, 0x0f00, 0x1029, 0x102a, 0x1248, 0x1258,
00195     0x1288, 0x12b0, 0x12c0, 0x1310, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x207f,
00196     0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x3005, 0x3006, 0x309d,
00197     0x309e, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfe74, 0xfffe
00198 };
00199 
00200 #define NUM_ALPHA_CHAR (sizeof(alphaCharTable)/sizeof(chr))
00201 
00202 /*
00203  * Unicode: decimal digit characters
00204  */
00205 
00206 static const crange digitRangeTable[] = {
00207     {0x0030, 0x0039}, {0x0660, 0x0669}, {0x06f0, 0x06f9}, {0x0966, 0x096f},
00208     {0x09e6, 0x09ef}, {0x0a66, 0x0a6f}, {0x0ae6, 0x0aef}, {0x0b66, 0x0b6f},
00209     {0x0be7, 0x0bef}, {0x0c66, 0x0c6f}, {0x0ce6, 0x0cef}, {0x0d66, 0x0d6f},
00210     {0x0e50, 0x0e59}, {0x0ed0, 0x0ed9}, {0x0f20, 0x0f29}, {0x1040, 0x1049},
00211     {0x1369, 0x1371}, {0x17e0, 0x17e9}, {0x1810, 0x1819}, {0xff10, 0xff19}
00212 };
00213 
00214 #define NUM_DIGIT_RANGE (sizeof(digitRangeTable)/sizeof(crange))
00215 
00216 /*
00217  * no singletons of digit characters.
00218  */
00219 
00220 /*
00221  * Unicode: punctuation characters.
00222  */
00223 
00224 static const crange punctRangeTable[] = {
00225     {0x0021, 0x0023}, {0x0025, 0x002a}, {0x002c, 0x002f}, {0x005b, 0x005d},
00226     {0x055a, 0x055f}, {0x066a, 0x066d}, {0x0700, 0x070d}, {0x0f04, 0x0f12},
00227     {0x0f3a, 0x0f3d}, {0x104a, 0x104f}, {0x1361, 0x1368}, {0x16eb, 0x16ed},
00228     {0x17d4, 0x17da}, {0x1800, 0x180a}, {0x2010, 0x2027}, {0x2030, 0x2043},
00229     {0x2048, 0x204d}, {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f},
00230     {0xfe30, 0xfe44}, {0xfe49, 0xfe52}, {0xfe54, 0xfe61}, {0xff01, 0xff03},
00231     {0xff05, 0xff0a}, {0xff0c, 0xff0f}, {0xff3b, 0xff3d}, {0xff61, 0xff65}
00232 };
00233 
00234 #define NUM_PUNCT_RANGE (sizeof(punctRangeTable)/sizeof(crange))
00235 
00236 static const chr punctCharTable[] = {
00237     0x003a, 0x003b, 0x003f, 0x0040, 0x005f, 0x007b, 0x007d, 0x00a1, 0x00ab,
00238     0x00ad, 0x00b7, 0x00bb, 0x00bf, 0x037e, 0x0387, 0x0589, 0x058a, 0x05be,
00239     0x05c0, 0x05c3, 0x05f3, 0x05f4, 0x060c, 0x061b, 0x061f, 0x06d4, 0x0964,
00240     0x0965, 0x0970, 0x0df4, 0x0e4f, 0x0e5a, 0x0e5b, 0x0f85, 0x10fb, 0x166d,
00241     0x166e, 0x169b, 0x169c, 0x17dc, 0x2045, 0x2046, 0x207d, 0x207e, 0x208d,
00242     0x208e, 0x2329, 0x232a, 0x3030, 0x30fb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68,
00243     0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d
00244 };
00245 
00246 #define NUM_PUNCT_CHAR (sizeof(punctCharTable)/sizeof(chr))
00247 
00248 /*
00249  * Unicode: white space characters.
00250  */
00251 
00252 static const crange spaceRangeTable[] = {
00253     {0x0009, 0x000d}, {0x2000, 0x200b}
00254 };
00255 
00256 #define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange))
00257 
00258 static const chr spaceCharTable[] = {
00259     0x0020, 0x00a0, 0x1680, 0x2028, 0x2029, 0x202f, 0x3000
00260 };
00261 
00262 #define NUM_SPACE_CHAR (sizeof(spaceCharTable)/sizeof(chr))
00263 
00264 /*
00265  * Unicode: lowercase characters
00266  */
00267 
00268 static const crange lowerRangeTable[] = {
00269     {0x0061, 0x007a}, {0x00df, 0x00f6}, {0x00f8, 0x00ff}, {0x017e, 0x0180},
00270     {0x0199, 0x019b}, {0x01bd, 0x01bf}, {0x0250, 0x02ad}, {0x03ac, 0x03ce},
00271     {0x03d5, 0x03d7}, {0x03ef, 0x03f3}, {0x0430, 0x045f}, {0x0561, 0x0587},
00272     {0x1e95, 0x1e9b}, {0x1f00, 0x1f07}, {0x1f10, 0x1f15}, {0x1f20, 0x1f27},
00273     {0x1f30, 0x1f37}, {0x1f40, 0x1f45}, {0x1f50, 0x1f57}, {0x1f60, 0x1f67},
00274     {0x1f70, 0x1f7d}, {0x1f80, 0x1f87}, {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7},
00275     {0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4}, {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7},
00276     {0x1ff2, 0x1ff4}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a}
00277 };
00278 
00279 #define NUM_LOWER_RANGE (sizeof(lowerRangeTable)/sizeof(crange))
00280 
00281 static const chr lowerCharTable[] = {
00282     0x00aa, 0x00b5, 0x00ba, 0x0101, 0x0103, 0x0105, 0x0107, 0x0109, 0x010b,
00283     0x010d, 0x010f, 0x0111, 0x0113, 0x0115, 0x0117, 0x0119, 0x011b, 0x011d,
00284     0x011f, 0x0121, 0x0123, 0x0125, 0x0127, 0x0129, 0x012b, 0x012d, 0x012f,
00285     0x0131, 0x0133, 0x0135, 0x0137, 0x0138, 0x013a, 0x013c, 0x013e, 0x0140,
00286     0x0142, 0x0144, 0x0146, 0x0148, 0x0149, 0x014b, 0x014d, 0x014f, 0x0151,
00287     0x0153, 0x0155, 0x0157, 0x0159, 0x015b, 0x015d, 0x015f, 0x0161, 0x0163,
00288     0x0165, 0x0167, 0x0169, 0x016b, 0x016d, 0x016f, 0x0171, 0x0173, 0x0175,
00289     0x0177, 0x017a, 0x017c, 0x0183, 0x0185, 0x0188, 0x018c, 0x018d, 0x0192,
00290     0x0195, 0x019e, 0x01a1, 0x01a3, 0x01a5, 0x01a8, 0x01aa, 0x01ab, 0x01ad,
00291     0x01b0, 0x01b4, 0x01b6, 0x01b9, 0x01ba, 0x01c6, 0x01c9, 0x01cc, 0x01ce,
00292     0x01d0, 0x01d2, 0x01d4, 0x01d6, 0x01d8, 0x01da, 0x01dc, 0x01dd, 0x01df,
00293     0x01e1, 0x01e3, 0x01e5, 0x01e7, 0x01e9, 0x01eb, 0x01ed, 0x01ef, 0x01f0,
00294     0x01f3, 0x01f5, 0x01f9, 0x01fb, 0x01fd, 0x01ff, 0x0201, 0x0203, 0x0205,
00295     0x0207, 0x0209, 0x020b, 0x020d, 0x020f, 0x0211, 0x0213, 0x0215, 0x0217,
00296     0x0219, 0x021b, 0x021d, 0x021f, 0x0223, 0x0225, 0x0227, 0x0229, 0x022b,
00297     0x022d, 0x022f, 0x0231, 0x0233, 0x0390, 0x03d0, 0x03d1, 0x03db, 0x03dd,
00298     0x03df, 0x03e1, 0x03e3, 0x03e5, 0x03e7, 0x03e9, 0x03eb, 0x03ed, 0x03f5,
00299     0x0461, 0x0463, 0x0465, 0x0467, 0x0469, 0x046b, 0x046d, 0x046f, 0x0471,
00300     0x0473, 0x0475, 0x0477, 0x0479, 0x047b, 0x047d, 0x047f, 0x0481, 0x048d,
00301     0x048f, 0x0491, 0x0493, 0x0495, 0x0497, 0x0499, 0x049b, 0x049d, 0x049f,
00302     0x04a1, 0x04a3, 0x04a5, 0x04a7, 0x04a9, 0x04ab, 0x04ad, 0x04af, 0x04b1,
00303     0x04b3, 0x04b5, 0x04b7, 0x04b9, 0x04bb, 0x04bd, 0x04bf, 0x04c2, 0x04c4,
00304     0x04c8, 0x04cc, 0x04d1, 0x04d3, 0x04d5, 0x04d7, 0x04d9, 0x04db, 0x04dd,
00305     0x04df, 0x04e1, 0x04e3, 0x04e5, 0x04e7, 0x04e9, 0x04eb, 0x04ed, 0x04ef,
00306     0x04f1, 0x04f3, 0x04f5, 0x04f9, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09,
00307     0x1e0b, 0x1e0d, 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b,
00308     0x1e1d, 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d,
00309     0x1e2f, 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, 0x1e3f,
00310     0x1e41, 0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, 0x1e4f, 0x1e51,
00311     0x1e53, 0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d, 0x1e5f, 0x1e61, 0x1e63,
00312     0x1e65, 0x1e67, 0x1e69, 0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73, 0x1e75,
00313     0x1e77, 0x1e79, 0x1e7b, 0x1e7d, 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87,
00314     0x1e89, 0x1e8b, 0x1e8d, 0x1e8f, 0x1e91, 0x1e93, 0x1ea1, 0x1ea3, 0x1ea5,
00315     0x1ea7, 0x1ea9, 0x1eab, 0x1ead, 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7,
00316     0x1eb9, 0x1ebb, 0x1ebd, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9,
00317     0x1ecb, 0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb,
00318     0x1edd, 0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, 0x1eed,
00319     0x1eef, 0x1ef1, 0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1fb6, 0x1fb7, 0x1fbe,
00320     0x1fc6, 0x1fc7, 0x1fd6, 0x1fd7, 0x1ff6, 0x1ff7, 0x207f, 0x210a, 0x210e,
00321     0x210f, 0x2113, 0x212f, 0x2134, 0x2139
00322 };
00323 
00324 #define NUM_LOWER_CHAR (sizeof(lowerCharTable)/sizeof(chr))
00325 
00326 /*
00327  * Unicode: uppercase characters.
00328  */
00329 
00330 static const crange upperRangeTable[] = {
00331     {0x0041, 0x005a}, {0x00c0, 0x00d6}, {0x00d8, 0x00de}, {0x0189, 0x018b},
00332     {0x018e, 0x0191}, {0x0196, 0x0198}, {0x01b1, 0x01b3}, {0x01f6, 0x01f8},
00333     {0x0388, 0x038a}, {0x0391, 0x03a1}, {0x03a3, 0x03ab}, {0x03d2, 0x03d4},
00334     {0x0400, 0x042f}, {0x0531, 0x0556}, {0x10a0, 0x10c5}, {0x1f08, 0x1f0f},
00335     {0x1f18, 0x1f1d}, {0x1f28, 0x1f2f}, {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d},
00336     {0x1f68, 0x1f6f}, {0x1fb8, 0x1fbb}, {0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb},
00337     {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb}, {0x210b, 0x210d}, {0x2110, 0x2112},
00338     {0x2119, 0x211d}, {0x212a, 0x212d}, {0xff21, 0xff3a}
00339 };
00340 
00341 #define NUM_UPPER_RANGE (sizeof(upperRangeTable)/sizeof(crange))
00342 
00343 static const chr upperCharTable[] = {
00344     0x0100, 0x0102, 0x0104, 0x0106, 0x0108, 0x010a, 0x010c, 0x010e, 0x0110,
00345     0x0112, 0x0114, 0x0116, 0x0118, 0x011a, 0x011c, 0x011e, 0x0120, 0x0122,
00346     0x0124, 0x0126, 0x0128, 0x012a, 0x012c, 0x012e, 0x0130, 0x0132, 0x0134,
00347     0x0136, 0x0139, 0x013b, 0x013d, 0x013f, 0x0141, 0x0143, 0x0145, 0x0147,
00348     0x014a, 0x014c, 0x014e, 0x0150, 0x0152, 0x0154, 0x0156, 0x0158, 0x015a,
00349     0x015c, 0x015e, 0x0160, 0x0162, 0x0164, 0x0166, 0x0168, 0x016a, 0x016c,
00350     0x016e, 0x0170, 0x0172, 0x0174, 0x0176, 0x0178, 0x0179, 0x017b, 0x017d,
00351     0x0181, 0x0182, 0x0184, 0x0186, 0x0187, 0x0193, 0x0194, 0x019c, 0x019d,
00352     0x019f, 0x01a0, 0x01a2, 0x01a4, 0x01a6, 0x01a7, 0x01a9, 0x01ac, 0x01ae,
00353     0x01af, 0x01b5, 0x01b7, 0x01b8, 0x01bc, 0x01c4, 0x01c7, 0x01ca, 0x01cd,
00354     0x01cf, 0x01d1, 0x01d3, 0x01d5, 0x01d7, 0x01d9, 0x01db, 0x01de, 0x01e0,
00355     0x01e2, 0x01e4, 0x01e6, 0x01e8, 0x01ea, 0x01ec, 0x01ee, 0x01f1, 0x01f4,
00356     0x01fa, 0x01fc, 0x01fe, 0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020a,
00357     0x020c, 0x020e, 0x0210, 0x0212, 0x0214, 0x0216, 0x0218, 0x021a, 0x021c,
00358     0x021e, 0x0222, 0x0224, 0x0226, 0x0228, 0x022a, 0x022c, 0x022e, 0x0230,
00359     0x0232, 0x0386, 0x038c, 0x038e, 0x038f, 0x03da, 0x03dc, 0x03de, 0x03e0,
00360     0x03e2, 0x03e4, 0x03e6, 0x03e8, 0x03ea, 0x03ec, 0x03ee, 0x03f4, 0x0460,
00361     0x0462, 0x0464, 0x0466, 0x0468, 0x046a, 0x046c, 0x046e, 0x0470, 0x0472,
00362     0x0474, 0x0476, 0x0478, 0x047a, 0x047c, 0x047e, 0x0480, 0x048c, 0x048e,
00363     0x0490, 0x0492, 0x0494, 0x0496, 0x0498, 0x049a, 0x049c, 0x049e, 0x04a0,
00364     0x04a2, 0x04a4, 0x04a6, 0x04a8, 0x04aa, 0x04ac, 0x04ae, 0x04b0, 0x04b2,
00365     0x04b4, 0x04b6, 0x04b8, 0x04ba, 0x04bc, 0x04be, 0x04c0, 0x04c1, 0x04c3,
00366     0x04c7, 0x04cb, 0x04d0, 0x04d2, 0x04d4, 0x04d6, 0x04d8, 0x04da, 0x04dc,
00367     0x04de, 0x04e0, 0x04e2, 0x04e4, 0x04e6, 0x04e8, 0x04ea, 0x04ec, 0x04ee,
00368     0x04f0, 0x04f2, 0x04f4, 0x04f8, 0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08,
00369     0x1e0a, 0x1e0c, 0x1e0e, 0x1e10, 0x1e12, 0x1e14, 0x1e16, 0x1e18, 0x1e1a,
00370     0x1e1c, 0x1e1e, 0x1e20, 0x1e22, 0x1e24, 0x1e26, 0x1e28, 0x1e2a, 0x1e2c,
00371     0x1e2e, 0x1e30, 0x1e32, 0x1e34, 0x1e36, 0x1e38, 0x1e3a, 0x1e3c, 0x1e3e,
00372     0x1e40, 0x1e42, 0x1e44, 0x1e46, 0x1e48, 0x1e4a, 0x1e4c, 0x1e4e, 0x1e50,
00373     0x1e52, 0x1e54, 0x1e56, 0x1e58, 0x1e5a, 0x1e5c, 0x1e5e, 0x1e60, 0x1e62,
00374     0x1e64, 0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e, 0x1e70, 0x1e72, 0x1e74,
00375     0x1e76, 0x1e78, 0x1e7a, 0x1e7c, 0x1e7e, 0x1e80, 0x1e82, 0x1e84, 0x1e86,
00376     0x1e88, 0x1e8a, 0x1e8c, 0x1e8e, 0x1e90, 0x1e92, 0x1e94, 0x1ea0, 0x1ea2,
00377     0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac, 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4,
00378     0x1eb6, 0x1eb8, 0x1eba, 0x1ebc, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6,
00379     0x1ec8, 0x1eca, 0x1ecc, 0x1ece, 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8,
00380     0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2, 0x1ee4, 0x1ee6, 0x1ee8, 0x1eea,
00381     0x1eec, 0x1eee, 0x1ef0, 0x1ef2, 0x1ef4, 0x1ef6, 0x1ef8, 0x1f59, 0x1f5b,
00382     0x1f5d, 0x1f5f, 0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x2130,
00383     0x2131, 0x2133
00384 };
00385 
00386 #define NUM_UPPER_CHAR (sizeof(upperCharTable)/sizeof(chr))
00387 
00388 /*
00389  * Unicode: unicode print characters excluding space.
00390  */
00391 
00392 static const crange graphRangeTable[] = {
00393     {0x0021, 0x007e}, {0x00a0, 0x011f}, {0x0121, 0x021f}, {0x0222, 0x0233},
00394     {0x0250, 0x02ad}, {0x02b0, 0x02ee}, {0x0300, 0x031f}, {0x0321, 0x034e},
00395     {0x0360, 0x0362}, {0x0384, 0x038a}, {0x038e, 0x03a1}, {0x03a3, 0x03ce},
00396     {0x03d0, 0x03d7}, {0x03da, 0x03f5}, {0x0400, 0x041f}, {0x0421, 0x0486},
00397     {0x048c, 0x04c4}, {0x04d0, 0x04f5}, {0x0531, 0x0556}, {0x0559, 0x055f},
00398     {0x0561, 0x0587}, {0x0591, 0x05a1}, {0x05a3, 0x05b9}, {0x05bb, 0x05c4},
00399     {0x05d0, 0x05ea}, {0x05f0, 0x05f4}, {0x0621, 0x063a}, {0x0640, 0x0655},
00400     {0x0660, 0x066d}, {0x0670, 0x06ed}, {0x06f0, 0x06fe}, {0x0700, 0x070d},
00401     {0x0710, 0x071f}, {0x0721, 0x072c}, {0x0730, 0x074a}, {0x0780, 0x07b0},
00402     {0x0901, 0x0903}, {0x0905, 0x091f}, {0x0921, 0x0939}, {0x093c, 0x094d},
00403     {0x0950, 0x0954}, {0x0958, 0x0970}, {0x0981, 0x0983}, {0x0985, 0x098c},
00404     {0x0993, 0x09a8}, {0x09aa, 0x09b0}, {0x09b6, 0x09b9}, {0x09be, 0x09c4},
00405     {0x09cb, 0x09cd}, {0x09df, 0x09e3}, {0x09e6, 0x09fa}, {0x0a05, 0x0a0a},
00406     {0x0a13, 0x0a1f}, {0x0a21, 0x0a28}, {0x0a2a, 0x0a30}, {0x0a3e, 0x0a42},
00407     {0x0a4b, 0x0a4d}, {0x0a59, 0x0a5c}, {0x0a66, 0x0a74}, {0x0a81, 0x0a83},
00408     {0x0a85, 0x0a8b}, {0x0a8f, 0x0a91}, {0x0a93, 0x0aa8}, {0x0aaa, 0x0ab0},
00409     {0x0ab5, 0x0ab9}, {0x0abc, 0x0ac5}, {0x0ac7, 0x0ac9}, {0x0acb, 0x0acd},
00410     {0x0ae6, 0x0aef}, {0x0b01, 0x0b03}, {0x0b05, 0x0b0c}, {0x0b13, 0x0b1f},
00411     {0x0b21, 0x0b28}, {0x0b2a, 0x0b30}, {0x0b36, 0x0b39}, {0x0b3c, 0x0b43},
00412     {0x0b4b, 0x0b4d}, {0x0b5f, 0x0b61}, {0x0b66, 0x0b70}, {0x0b85, 0x0b8a},
00413     {0x0b8e, 0x0b90}, {0x0b92, 0x0b95}, {0x0ba8, 0x0baa}, {0x0bae, 0x0bb5},
00414     {0x0bb7, 0x0bb9}, {0x0bbe, 0x0bc2}, {0x0bc6, 0x0bc8}, {0x0bca, 0x0bcd},
00415     {0x0be7, 0x0bf2}, {0x0c01, 0x0c03}, {0x0c05, 0x0c0c}, {0x0c0e, 0x0c10},
00416     {0x0c12, 0x0c1f}, {0x0c21, 0x0c28}, {0x0c2a, 0x0c33}, {0x0c35, 0x0c39},
00417     {0x0c3e, 0x0c44}, {0x0c46, 0x0c48}, {0x0c4a, 0x0c4d}, {0x0c66, 0x0c6f},
00418     {0x0c85, 0x0c8c}, {0x0c8e, 0x0c90}, {0x0c92, 0x0ca8}, {0x0caa, 0x0cb3},
00419     {0x0cb5, 0x0cb9}, {0x0cbe, 0x0cc4}, {0x0cc6, 0x0cc8}, {0x0cca, 0x0ccd},
00420     {0x0ce6, 0x0cef}, {0x0d05, 0x0d0c}, {0x0d0e, 0x0d10}, {0x0d12, 0x0d1f},
00421     {0x0d21, 0x0d28}, {0x0d2a, 0x0d39}, {0x0d3e, 0x0d43}, {0x0d46, 0x0d48},
00422     {0x0d4a, 0x0d4d}, {0x0d66, 0x0d6f}, {0x0d85, 0x0d96}, {0x0d9a, 0x0db1},
00423     {0x0db3, 0x0dbb}, {0x0dc0, 0x0dc6}, {0x0dcf, 0x0dd4}, {0x0dd8, 0x0ddf},
00424     {0x0df2, 0x0df4}, {0x0e01, 0x0e1f}, {0x0e21, 0x0e3a}, {0x0e3f, 0x0e5b},
00425     {0x0e94, 0x0e97}, {0x0e99, 0x0e9f}, {0x0ea1, 0x0ea3}, {0x0ead, 0x0eb9},
00426     {0x0ebb, 0x0ebd}, {0x0ec0, 0x0ec4}, {0x0ec8, 0x0ecd}, {0x0ed0, 0x0ed9},
00427     {0x0f00, 0x0f1f}, {0x0f21, 0x0f47}, {0x0f49, 0x0f6a}, {0x0f71, 0x0f8b},
00428     {0x0f90, 0x0f97}, {0x0f99, 0x0fbc}, {0x0fbe, 0x0fcc}, {0x1000, 0x101f},
00429     {0x1023, 0x1027}, {0x102c, 0x1032}, {0x1036, 0x1039}, {0x1040, 0x1059},
00430     {0x10a0, 0x10c5}, {0x10d0, 0x10f6}, {0x1100, 0x111f}, {0x1121, 0x1159},
00431     {0x115f, 0x11a2}, {0x11a8, 0x11f9}, {0x1200, 0x1206}, {0x1208, 0x121f},
00432     {0x1221, 0x1246}, {0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d},
00433     {0x1260, 0x1286}, {0x128a, 0x128d}, {0x1290, 0x12ae}, {0x12b2, 0x12b5},
00434     {0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12ce}, {0x12d0, 0x12d6},
00435     {0x12d8, 0x12ee}, {0x12f0, 0x130e}, {0x1312, 0x1315}, {0x1318, 0x131e},
00436     {0x1321, 0x1346}, {0x1348, 0x135a}, {0x1361, 0x137c}, {0x13a0, 0x13f4},
00437     {0x1401, 0x141f}, {0x1421, 0x151f}, {0x1521, 0x161f}, {0x1621, 0x1676},
00438     {0x1680, 0x169c}, {0x16a0, 0x16f0}, {0x1780, 0x17dc}, {0x17e0, 0x17e9},
00439     {0x1800, 0x180a}, {0x1810, 0x1819}, {0x1821, 0x1877}, {0x1880, 0x18a9},
00440     {0x1e00, 0x1e1f}, {0x1e21, 0x1e9b}, {0x1ea0, 0x1ef9}, {0x1f00, 0x1f15},
00441     {0x1f18, 0x1f1d}, {0x1f21, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57},
00442     {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3},
00443     {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe},
00444     {0x2000, 0x200b}, {0x2010, 0x201f}, {0x2021, 0x2029}, {0x202f, 0x2046},
00445     {0x2048, 0x204d}, {0x2074, 0x208e}, {0x20a0, 0x20af}, {0x20d0, 0x20e3},
00446     {0x2100, 0x211f}, {0x2121, 0x213a}, {0x2153, 0x2183}, {0x2190, 0x21f3},
00447     {0x2200, 0x221f}, {0x2221, 0x22f1}, {0x2300, 0x231f}, {0x2321, 0x237b},
00448     {0x237d, 0x239a}, {0x2400, 0x241f}, {0x2421, 0x2426}, {0x2440, 0x244a},
00449     {0x2460, 0x24ea}, {0x2500, 0x251f}, {0x2521, 0x2595}, {0x25a0, 0x25f7},
00450     {0x2600, 0x2613}, {0x2619, 0x261f}, {0x2621, 0x2671}, {0x2701, 0x2704},
00451     {0x2706, 0x2709}, {0x270c, 0x271f}, {0x2721, 0x2727}, {0x2729, 0x274b},
00452     {0x274f, 0x2752}, {0x2758, 0x275e}, {0x2761, 0x2767}, {0x2776, 0x2794},
00453     {0x2798, 0x27af}, {0x27b1, 0x27be}, {0x2800, 0x281f}, {0x2821, 0x28ff},
00454     {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2f1f}, {0x2f21, 0x2fd5},
00455     {0x2ff0, 0x2ffb}, {0x3000, 0x301f}, {0x3021, 0x303a}, {0x3041, 0x3094},
00456     {0x3099, 0x309e}, {0x30a1, 0x30fe}, {0x3105, 0x311f}, {0x3121, 0x312c},
00457     {0x3131, 0x318e}, {0x3190, 0x31b7}, {0x3200, 0x321c}, {0x3221, 0x3243},
00458     {0x3260, 0x327b}, {0x327f, 0x32b0}, {0x32c0, 0x32cb}, {0x32d0, 0x32fe},
00459     {0x3300, 0x331f}, {0x3321, 0x3376}, {0x337b, 0x33dd}, {0x33e0, 0x33fe},
00460     {0x3400, 0x341f}, {0x3421, 0x351f}, {0x3521, 0x361f}, {0x3621, 0x371f},
00461     {0x3721, 0x381f}, {0x3821, 0x391f}, {0x3921, 0x3a1f}, {0x3a21, 0x3b1f},
00462     {0x3b21, 0x3c1f}, {0x3c21, 0x3d1f}, {0x3d21, 0x3e1f}, {0x3e21, 0x3f1f},
00463     {0x3f21, 0x401f}, {0x4021, 0x411f}, {0x4121, 0x421f}, {0x4221, 0x431f},
00464     {0x4321, 0x441f}, {0x4421, 0x451f}, {0x4521, 0x461f}, {0x4621, 0x471f},
00465     {0x4721, 0x481f}, {0x4821, 0x491f}, {0x4921, 0x4a1f}, {0x4a21, 0x4b1f},
00466     {0x4b21, 0x4c1f}, {0x4c21, 0x4d1f}, {0x4d21, 0x4db5}, {0x4e00, 0x4e1f},
00467     {0x4e21, 0x4f1f}, {0x4f21, 0x501f}, {0x5021, 0x511f}, {0x5121, 0x521f},
00468     {0x5221, 0x531f}, {0x5321, 0x541f}, {0x5421, 0x551f}, {0x5521, 0x561f},
00469     {0x5621, 0x571f}, {0x5721, 0x581f}, {0x5821, 0x591f}, {0x5921, 0x5a1f},
00470     {0x5a21, 0x5b1f}, {0x5b21, 0x5c1f}, {0x5c21, 0x5d1f}, {0x5d21, 0x5e1f},
00471     {0x5e21, 0x5f1f}, {0x5f21, 0x601f}, {0x6021, 0x611f}, {0x6121, 0x621f},
00472     {0x6221, 0x631f}, {0x6321, 0x641f}, {0x6421, 0x651f}, {0x6521, 0x661f},
00473     {0x6621, 0x671f}, {0x6721, 0x681f}, {0x6821, 0x691f}, {0x6921, 0x6a1f},
00474     {0x6a21, 0x6b1f}, {0x6b21, 0x6c1f}, {0x6c21, 0x6d1f}, {0x6d21, 0x6e1f},
00475     {0x6e21, 0x6f1f}, {0x6f21, 0x701f}, {0x7021, 0x711f}, {0x7121, 0x721f},
00476     {0x7221, 0x731f}, {0x7321, 0x741f}, {0x7421, 0x751f}, {0x7521, 0x761f},
00477     {0x7621, 0x771f}, {0x7721, 0x781f}, {0x7821, 0x791f}, {0x7921, 0x7a1f},
00478     {0x7a21, 0x7b1f}, {0x7b21, 0x7c1f}, {0x7c21, 0x7d1f}, {0x7d21, 0x7e1f},
00479     {0x7e21, 0x7f1f}, {0x7f21, 0x801f}, {0x8021, 0x811f}, {0x8121, 0x821f},
00480     {0x8221, 0x831f}, {0x8321, 0x841f}, {0x8421, 0x851f}, {0x8521, 0x861f},
00481     {0x8621, 0x871f}, {0x8721, 0x881f}, {0x8821, 0x891f}, {0x8921, 0x8a1f},
00482     {0x8a21, 0x8b1f}, {0x8b21, 0x8c1f}, {0x8c21, 0x8d1f}, {0x8d21, 0x8e1f},
00483     {0x8e21, 0x8f1f}, {0x8f21, 0x901f}, {0x9021, 0x911f}, {0x9121, 0x921f},
00484     {0x9221, 0x931f}, {0x9321, 0x941f}, {0x9421, 0x951f}, {0x9521, 0x961f},
00485     {0x9621, 0x971f}, {0x9721, 0x981f}, {0x9821, 0x991f}, {0x9921, 0x9a1f},
00486     {0x9a21, 0x9b1f}, {0x9b21, 0x9c1f}, {0x9c21, 0x9d1f}, {0x9d21, 0x9e1f},
00487     {0x9e21, 0x9f1f}, {0x9f21, 0x9fa5}, {0xa000, 0xa01f}, {0xa021, 0xa11f},
00488     {0xa121, 0xa21f}, {0xa221, 0xa31f}, {0xa321, 0xa41f}, {0xa421, 0xa48c},
00489     {0xa490, 0xa4a1}, {0xa4a4, 0xa4b3}, {0xa4b5, 0xa4c0}, {0xa4c2, 0xa4c4},
00490     {0xac00, 0xac1f}, {0xac21, 0xad1f}, {0xad21, 0xae1f}, {0xae21, 0xaf1f},
00491     {0xaf21, 0xb01f}, {0xb021, 0xb11f}, {0xb121, 0xb21f}, {0xb221, 0xb31f},
00492     {0xb321, 0xb41f}, {0xb421, 0xb51f}, {0xb521, 0xb61f}, {0xb621, 0xb71f},
00493     {0xb721, 0xb81f}, {0xb821, 0xb91f}, {0xb921, 0xba1f}, {0xba21, 0xbb1f},
00494     {0xbb21, 0xbc1f}, {0xbc21, 0xbd1f}, {0xbd21, 0xbe1f}, {0xbe21, 0xbf1f},
00495     {0xbf21, 0xc01f}, {0xc021, 0xc11f}, {0xc121, 0xc21f}, {0xc221, 0xc31f},
00496     {0xc321, 0xc41f}, {0xc421, 0xc51f}, {0xc521, 0xc61f}, {0xc621, 0xc71f},
00497     {0xc721, 0xc81f}, {0xc821, 0xc91f}, {0xc921, 0xca1f}, {0xca21, 0xcb1f},
00498     {0xcb21, 0xcc1f}, {0xcc21, 0xcd1f}, {0xcd21, 0xce1f}, {0xce21, 0xcf1f},
00499     {0xcf21, 0xd01f}, {0xd021, 0xd11f}, {0xd121, 0xd21f}, {0xd221, 0xd31f},
00500     {0xd321, 0xd41f}, {0xd421, 0xd51f}, {0xd521, 0xd61f}, {0xd621, 0xd71f},
00501     {0xd721, 0xd7a3}, {0xf900, 0xf91f}, {0xf921, 0xfa1f}, {0xfa21, 0xfa2d},
00502     {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb1f}, {0xfb21, 0xfb36},
00503     {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfc1f}, {0xfc21, 0xfd1f},
00504     {0xfd21, 0xfd3f}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb},
00505     {0xfe21, 0xfe23}, {0xfe30, 0xfe44}, {0xfe49, 0xfe52}, {0xfe54, 0xfe66},
00506     {0xfe68, 0xfe6b}, {0xfe70, 0xfe72}, {0xfe76, 0xfefc}, {0xff01, 0xff1f},
00507     {0xff21, 0xff5e}, {0xff61, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf},
00508     {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee},
00509     {0xfffc, 0xffff}
00510 };
00511 
00512 #define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange))
00513 
00514 static const chr graphCharTable[] = {
00515     0x0374, 0x0375, 0x037a, 0x037e, 0x038c, 0x0488, 0x0489, 0x04c7, 0x04c8,
00516     0x04cb, 0x04cc, 0x04f8, 0x04f9, 0x0589, 0x058a, 0x060c, 0x061b, 0x061f,
00517     0x098f, 0x0990, 0x09b2, 0x09bc, 0x09c7, 0x09c8, 0x09d7, 0x09dc, 0x09dd,
00518     0x0a02, 0x0a0f, 0x0a10, 0x0a32, 0x0a33, 0x0a35, 0x0a36, 0x0a38, 0x0a39,
00519     0x0a3c, 0x0a47, 0x0a48, 0x0a5e, 0x0a8d, 0x0ab2, 0x0ab3, 0x0ad0, 0x0ae0,
00520     0x0b0f, 0x0b10, 0x0b32, 0x0b33, 0x0b47, 0x0b48, 0x0b56, 0x0b57, 0x0b5c,
00521     0x0b5d, 0x0b82, 0x0b83, 0x0b99, 0x0b9a, 0x0b9c, 0x0b9e, 0x0b9f, 0x0ba3,
00522     0x0ba4, 0x0bd7, 0x0c55, 0x0c56, 0x0c60, 0x0c61, 0x0c82, 0x0c83, 0x0cd5,
00523     0x0cd6, 0x0cde, 0x0ce0, 0x0ce1, 0x0d02, 0x0d03, 0x0d57, 0x0d60, 0x0d61,
00524     0x0d82, 0x0d83, 0x0dbd, 0x0dca, 0x0dd6, 0x0e81, 0x0e82, 0x0e84, 0x0e87,
00525     0x0e88, 0x0e8a, 0x0e8d, 0x0ea5, 0x0ea7, 0x0eaa, 0x0eab, 0x0ec6, 0x0edc,
00526     0x0edd, 0x0fcf, 0x1021, 0x1029, 0x102a, 0x10fb, 0x1248, 0x1258, 0x1288,
00527     0x12b0, 0x12c0, 0x1310, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x274d, 0x2756,
00528     0x303e, 0x303f, 0xa4c6, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfe74
00529 };
00530 
00531 #define NUM_GRAPH_CHAR (sizeof(graphCharTable)/sizeof(chr))
00532 
00533 /*
00534  * Unicode: unicode print characters including space, i.e. all Letters (class
00535  * L*), Numbers (N*), Punctuation (P*), Symbols (S*) and Spaces (Zs).
00536  */
00537 
00538 static const crange printRangeTable[] = {
00539     {0x0020, 0x007E}, {0x00A0, 0x01F5}, {0x01FA, 0x0217}, {0x0250, 0x02A8},
00540     {0x02B0, 0x02DE}, {0x02E0, 0x02E9}, {0x0374, 0x0375}, {0x0384, 0x038A},
00541     {0x038E, 0x03A1}, {0x03A3, 0x03CE}, {0x03D0, 0x03D6}, {0x03E2, 0x03F3},
00542     {0x0401, 0x040C}, {0x040E, 0x044F}, {0x0451, 0x045C}, {0x045E, 0x0482},
00543     {0x0490, 0x04C4}, {0x04C7, 0x04C8}, {0x04CB, 0x04CC}, {0x04D0, 0x04EB},
00544     {0x04EE, 0x04F5}, {0x04F8, 0x04F9}, {0x0531, 0x0556}, {0x0559, 0x055F},
00545     {0x0561, 0x0587}, {0x05D0, 0x05EA}, {0x05F0, 0x05F4}, {0x0621, 0x063A},
00546     {0x0640, 0x064A}, {0x0660, 0x066D}, {0x0671, 0x06B7}, {0x06BA, 0x06BE},
00547     {0x06C0, 0x06CE}, {0x06D0, 0x06D5}, {0x06E5, 0x06E6}, {0x06F0, 0x06F9},
00548     {0x0905, 0x0939}, {0x0958, 0x0961}, {0x0964, 0x0970}, {0x0985, 0x098C},
00549     {0x098F, 0x0990}, {0x0993, 0x09A8}, {0x09AA, 0x09B0}, {0x09B6, 0x09B9},
00550     {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E6, 0x09FA}, {0x0A05, 0x0A0A},
00551     {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, {0x0A32, 0x0A33},
00552     {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, {0x0A59, 0x0A5C}, {0x0A66, 0x0A6F},
00553     {0x0A72, 0x0A74}, {0x0A85, 0x0A8B}, {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8},
00554     {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0AE6, 0x0AEF},
00555     {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, {0x0B13, 0x0B28}, {0x0B2A, 0x0B30},
00556     {0x0B32, 0x0B33}, {0x0B36, 0x0B39}, {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61},
00557     {0x0B66, 0x0B70}, {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95},
00558     {0x0B99, 0x0B9A}, {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA},
00559     {0x0BAE, 0x0BB5}, {0x0BB7, 0x0BB9}, {0x0BE7, 0x0BF2}, {0x0C05, 0x0C0C},
00560     {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, {0x0C2A, 0x0C33}, {0x0C35, 0x0C39},
00561     {0x0C60, 0x0C61}, {0x0C66, 0x0C6F}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90},
00562     {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, {0x0CE0, 0x0CE1},
00563     {0x0CE6, 0x0CEF}, {0x0D05, 0x0D0C}, {0x0D0E, 0x0D10}, {0x0D12, 0x0D28},
00564     {0x0D2A, 0x0D39}, {0x0D60, 0x0D61}, {0x0D66, 0x0D6F}, {0x0E3F, 0x0E46},
00565     {0x0E4F, 0x0E5B}, {0x0E99, 0x0E9F}, {0x0EA1, 0x0EA3}, {0x0EAA, 0x0EAB},
00566     {0x0EAD, 0x0EB0}, {0x0EB2, 0x0EB3}, {0x0EC0, 0x0EC4}, {0x0ED0, 0x0ED9},
00567     {0x0EDC, 0x0EDD}, {0x0F00, 0x0F17}, {0x0F1A, 0x0F34}, {0x0F3A, 0x0F3D},
00568     {0x0F40, 0x0F47}, {0x0F49, 0x0F69}, {0x0F88, 0x0F8B}, {0x10A0, 0x10C5},
00569     {0x10D0, 0x10F6}, {0x1100, 0x1159}, {0x115F, 0x11A2}, {0x11A8, 0x11F9},
00570     {0x1E00, 0x1E9B}, {0x1EA0, 0x1EF9}, {0x1F00, 0x1F15}, {0x1F18, 0x1F1D},
00571     {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F5F, 0x1F7D},
00572     {0x1F80, 0x1FB4}, {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB},
00573     {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE}, {0x2000, 0x200B},
00574     {0x2010, 0x2027}, {0x2030, 0x2046}, {0x2074, 0x208E}, {0x20A0, 0x20AC},
00575     {0x2100, 0x2138}, {0x2153, 0x2182}, {0x2190, 0x21EA}, {0x2200, 0x22F1},
00576     {0x2302, 0x237A}, {0x2400, 0x2424}, {0x2440, 0x244A}, {0x2460, 0x24EA},
00577     {0x2500, 0x2595}, {0x25A0, 0x25EF}, {0x2600, 0x2613}, {0x261A, 0x266F},
00578     {0x2701, 0x2704}, {0x2706, 0x2709}, {0x270C, 0x2727}, {0x2729, 0x274B},
00579     {0x274F, 0x2752}, {0x2758, 0x275E}, {0x2761, 0x2767}, {0x2776, 0x2794},
00580     {0x2798, 0x27AF}, {0x27B1, 0x27BE}, {0x3000, 0x3029}, {0x3030, 0x3037},
00581     {0x3041, 0x3094}, {0x309B, 0x309E}, {0x30A1, 0x30FE}, {0x3105, 0x312C},
00582     {0x3131, 0x318E}, {0x3190, 0x319F}, {0x3200, 0x321C}, {0x3220, 0x3243},
00583     {0x3260, 0x327B}, {0x327F, 0x32B0}, {0x32C0, 0x32CB}, {0x32D0, 0x32FE},
00584     {0x3300, 0x3376}, {0x337B, 0x33DD}, {0x33E0, 0x33FE}, {0x4E00, 0x9FA5},
00585     {0xAC00, 0xD7A3}, {0xF900, 0xFA2D}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17},
00586     {0xFB1F, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44},
00587     {0xFB46, 0xFBB1}, {0xFBD3, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7},
00588     {0xFDF0, 0xFDFB}, {0xFE30, 0xFE44}, {0xFE49, 0xFE52}, {0xFE54, 0xFE66},
00589     {0xFE68, 0xFE6B}, {0xFE70, 0xFE72}, {0xFE76, 0xFEFC}, {0xFF01, 0xFF5E},
00590     {0xFF61, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7},
00591     {0xFFDA, 0xFFDC}, {0xFFE0, 0xFFE6}, {0xFFE8, 0xFFEE}, {0xFFFC, 0xFFFD}
00592 };
00593 
00594 #define NUM_PRINT_RANGE (sizeof(printRangeTable)/sizeof(crange))
00595 
00596 static const chr printCharTable[] = {
00597     0x037A, 0x037E, 0x038C, 0x03DA, 0x03DC, 0x03DE, 0x03E0, 0x0589, 0x05BE,
00598     0x05C0, 0x05C3, 0x060C, 0x061B, 0x061F, 0x06E9, 0x093D, 0x0950, 0x09B2,
00599     0x0A5E, 0x0A8D, 0x0ABD, 0x0AD0, 0x0AE0, 0x0B3D, 0x0B9C, 0x0CDE, 0x0E01,
00600     0x0E32, 0x0E81, 0x0E84, 0x0E87, 0x0E8A, 0x0E8D, 0x0E94, 0x0EA5, 0x0EA7,
00601     0x0EBD, 0x0EC6, 0x0F36, 0x0F38, 0x0F85, 0x10FB, 0x1F59, 0x1F5B, 0x1F5D,
00602     0x2070, 0x2300, 0x274D, 0x2756, 0x303F, 0xFB3E, 0xFE74
00603 };
00604 
00605 #define NUM_PRINT_CHAR (sizeof(printCharTable)/sizeof(chr))
00606 
00607 /*
00608  *      End of auto-generated Unicode character ranges declarations.
00609  */
00610 
00611 #define CH      NOCELT
00612 
00613 /*
00614  - element - map collating-element name to celt
00615  ^ static celt element(struct vars *, const chr *, const chr *);
00616  */
00617 static celt
00618 element(
00619     struct vars *v,             /* context */
00620     const chr *startp,          /* points to start of name */
00621     const chr *endp)            /* points just past end of name */
00622 {
00623     const struct cname *cn;
00624     size_t len;
00625     Tcl_DString ds;
00626     const char *np;
00627 
00628     /*
00629      * Generic: one-chr names stand for themselves.
00630      */
00631 
00632     assert(startp < endp);
00633     len = endp - startp;
00634     if (len == 1) {
00635         return *startp;
00636     }
00637 
00638     NOTE(REG_ULOCALE);
00639 
00640     /*
00641      * Search table.
00642      */
00643 
00644     Tcl_DStringInit(&ds);
00645     np = Tcl_UniCharToUtfDString(startp, (int)len, &ds);
00646     for (cn=cnames; cn->name!=NULL; cn++) {
00647         if (strlen(cn->name)==len && strncmp(cn->name, np, len)==0) {
00648             break;                      /* NOTE BREAK OUT */
00649         }
00650     }
00651     Tcl_DStringFree(&ds);
00652     if (cn->name != NULL) {
00653         return CHR(cn->code);
00654     }
00655 
00656     /*
00657      * Couldn't find it.
00658      */
00659 
00660     ERR(REG_ECOLLATE);
00661     return 0;
00662 }
00663 
00664 /*
00665  - range - supply cvec for a range, including legality check
00666  ^ static struct cvec *range(struct vars *, celt, celt, int);
00667  */
00668 static struct cvec *
00669 range(
00670     struct vars *v,             /* context */
00671     celt a,                     /* range start */
00672     celt b,                     /* range end, might equal a */
00673     int cases)                  /* case-independent? */
00674 {
00675     int nchrs;
00676     struct cvec *cv;
00677     celt c, lc, uc, tc;
00678 
00679     if (a != b && !before(a, b)) {
00680         ERR(REG_ERANGE);
00681         return NULL;
00682     }
00683 
00684     if (!cases) {               /* easy version */
00685         cv = getcvec(v, 0, 1);
00686         NOERRN();
00687         addrange(cv, a, b);
00688         return cv;
00689     }
00690 
00691     /*
00692      * When case-independent, it's hard to decide when cvec ranges are usable,
00693      * so for now at least, we won't try. We allocate enough space for two
00694      * case variants plus a little extra for the two title case variants.
00695      */
00696 
00697     nchrs = (b - a + 1)*2 + 4;
00698 
00699     cv = getcvec(v, nchrs, 0);
00700     NOERRN();
00701 
00702     for (c=a; c<=b; c++) {
00703         addchr(cv, c);
00704         lc = Tcl_UniCharToLower((chr)c);
00705         uc = Tcl_UniCharToUpper((chr)c);
00706         tc = Tcl_UniCharToTitle((chr)c);
00707         if (c != lc) {
00708             addchr(cv, lc);
00709         }
00710         if (c != uc) {
00711             addchr(cv, uc);
00712         }
00713         if (c != tc && tc != uc) {
00714             addchr(cv, tc);
00715         }
00716     }
00717 
00718     return cv;
00719 }
00720 
00721 /*
00722  - before - is celt x before celt y, for purposes of range legality?
00723  ^ static int before(celt, celt);
00724  */
00725 static int                      /* predicate */
00726 before(
00727     celt x, celt y)             /* collating elements */
00728 {
00729     if (x < y) {
00730         return 1;
00731     }
00732     return 0;
00733 }
00734 
00735 /*
00736  - eclass - supply cvec for an equivalence class
00737  * Must include case counterparts on request.
00738  ^ static struct cvec *eclass(struct vars *, celt, int);
00739  */
00740 static struct cvec *
00741 eclass(
00742     struct vars *v,             /* context */
00743     celt c,                     /* Collating element representing the
00744                                  * equivalence class. */
00745     int cases)                  /* all cases? */
00746 {
00747     struct cvec *cv;
00748 
00749     /*
00750      * Crude fake equivalence class for testing.
00751      */
00752 
00753     if ((v->cflags&REG_FAKE) && c == 'x') {
00754         cv = getcvec(v, 4, 0);
00755         addchr(cv, (chr)'x');
00756         addchr(cv, (chr)'y');
00757         if (cases) {
00758             addchr(cv, (chr)'X');
00759             addchr(cv, (chr)'Y');
00760         }
00761         return cv;
00762     }
00763 
00764     /*
00765      * Otherwise, none.
00766      */
00767 
00768     if (cases) {
00769         return allcases(v, c);
00770     }
00771     cv = getcvec(v, 1, 0);
00772     assert(cv != NULL);
00773     addchr(cv, (chr)c);
00774     return cv;
00775 }
00776 
00777 /*
00778  - cclass - supply cvec for a character class
00779  * Must include case counterparts on request.
00780  ^ static struct cvec *cclass(struct vars *, const chr *, const chr *, int);
00781  */
00782 static struct cvec *
00783 cclass(
00784     struct vars *v,             /* context */
00785     const chr *startp,          /* where the name starts */
00786     const chr *endp,            /* just past the end of the name */
00787     int cases)                  /* case-independent? */
00788 {
00789     size_t len;
00790     struct cvec *cv = NULL;
00791     Tcl_DString ds;
00792     const char *np;
00793     const char **namePtr;
00794     int i, index;
00795 
00796     /*
00797      * The following arrays define the valid character class names.
00798      */
00799 
00800     static const char *classNames[] = {
00801         "alnum", "alpha", "ascii", "blank", "cntrl", "digit", "graph",
00802         "lower", "print", "punct", "space", "upper", "xdigit", NULL
00803     };
00804 
00805     enum classes {
00806         CC_ALNUM, CC_ALPHA, CC_ASCII, CC_BLANK, CC_CNTRL, CC_DIGIT, CC_GRAPH,
00807         CC_LOWER, CC_PRINT, CC_PUNCT, CC_SPACE, CC_UPPER, CC_XDIGIT
00808     };
00809 
00810 
00811     /*
00812      * Extract the class name
00813      */
00814 
00815     len = endp - startp;
00816     Tcl_DStringInit(&ds);
00817     np = Tcl_UniCharToUtfDString(startp, (int)len, &ds);
00818 
00819     /*
00820      * Remap lower and upper to alpha if the match is case insensitive.
00821      */
00822 
00823     if (cases && len == 5 && (strncmp("lower", np, 5) == 0
00824             || strncmp("upper", np, 5) == 0)) {
00825         np = "alpha";
00826     }
00827 
00828     /*
00829      * Map the name to the corresponding enumerated value.
00830      */
00831 
00832     index = -1;
00833     for (namePtr=classNames,i=0 ; *namePtr!=NULL ; namePtr++,i++) {
00834         if ((strlen(*namePtr) == len) && (strncmp(*namePtr, np, len) == 0)) {
00835             index = i;
00836             break;
00837         }
00838     }
00839     Tcl_DStringFree(&ds);
00840     if (index == -1) {
00841         ERR(REG_ECTYPE);
00842         return NULL;
00843     }
00844 
00845     /*
00846      * Now compute the character class contents.
00847      */
00848 
00849     switch((enum classes) index) {
00850     case CC_PRINT:
00851         cv = getcvec(v, NUM_PRINT_CHAR, NUM_PRINT_RANGE);
00852         if (cv) {
00853             for (i=0 ; (size_t)i<NUM_PRINT_CHAR ; i++) {
00854                 addchr(cv, printCharTable[i]);
00855             }
00856             for (i=0 ; (size_t)i<NUM_PRINT_RANGE ; i++) {
00857                 addrange(cv, printRangeTable[i].start,
00858                         printRangeTable[i].end);
00859             }
00860         }
00861         break;
00862     case CC_ALNUM:
00863         cv = getcvec(v, NUM_ALPHA_CHAR, NUM_DIGIT_RANGE + NUM_ALPHA_RANGE);
00864         if (cv) {
00865             for (i=0 ; (size_t)i<NUM_ALPHA_CHAR ; i++) {
00866                 addchr(cv, alphaCharTable[i]);
00867             }
00868             for (i=0 ; (size_t)i<NUM_ALPHA_RANGE ; i++) {
00869                 addrange(cv, alphaRangeTable[i].start,
00870                         alphaRangeTable[i].end);
00871             }
00872             for (i=0 ; (size_t)i<NUM_DIGIT_RANGE ; i++) {
00873                 addrange(cv, digitRangeTable[i].start,
00874                         digitRangeTable[i].end);
00875             }
00876         }
00877         break;
00878     case CC_ALPHA:
00879         cv = getcvec(v, NUM_ALPHA_CHAR, NUM_ALPHA_RANGE);
00880         if (cv) {
00881             for (i=0 ; (size_t)i<NUM_ALPHA_RANGE ; i++) {
00882                 addrange(cv, alphaRangeTable[i].start,
00883                         alphaRangeTable[i].end);
00884             }
00885             for (i=0 ; (size_t)i<NUM_ALPHA_CHAR ; i++) {
00886                 addchr(cv, alphaCharTable[i]);
00887             }
00888         }
00889         break;
00890     case CC_ASCII:
00891         cv = getcvec(v, 0, 1);
00892         if (cv) {
00893             addrange(cv, 0, 0x7f);
00894         }
00895         break;
00896     case CC_BLANK:
00897         cv = getcvec(v, 2, 0);
00898         addchr(cv, '\t');
00899         addchr(cv, ' ');
00900         break;
00901     case CC_CNTRL:
00902         cv = getcvec(v, 0, 2);
00903         addrange(cv, 0x0, 0x1f);
00904         addrange(cv, 0x7f, 0x9f);
00905         break;
00906     case CC_DIGIT:
00907         cv = getcvec(v, 0, NUM_DIGIT_RANGE);
00908         if (cv) {
00909             for (i=0 ; (size_t)i<NUM_DIGIT_RANGE ; i++) {
00910                 addrange(cv, digitRangeTable[i].start,
00911                         digitRangeTable[i].end);
00912             }
00913         }
00914         break;
00915     case CC_PUNCT:
00916         cv = getcvec(v, NUM_PUNCT_CHAR, NUM_PUNCT_RANGE);
00917         if (cv) {
00918             for (i=0 ; (size_t)i<NUM_PUNCT_RANGE ; i++) {
00919                 addrange(cv, punctRangeTable[i].start,
00920                         punctRangeTable[i].end);
00921             }
00922             for (i=0 ; (size_t)i<NUM_PUNCT_CHAR ; i++) {
00923                 addchr(cv, punctCharTable[i]);
00924             }
00925         }
00926         break;
00927     case CC_XDIGIT:
00928         /*
00929          * This is a 3 instead of (NUM_DIGIT_RANGE+2) because I've no idea how
00930          * to define the digits 'a' through 'f' in non-western locales. The
00931          * concept is quite possibly non portable, or only used in contextx
00932          * where the characters used would be the western ones anyway!
00933          * Whatever is actually the case, the number of ranges is fixed (until
00934          * someone comes up with a better arrangement!)
00935          */
00936 
00937         cv = getcvec(v, 0, 3);
00938         if (cv) {
00939             addrange(cv, '0', '9');
00940             addrange(cv, 'a', 'f');
00941             addrange(cv, 'A', 'F');
00942         }
00943         break;
00944     case CC_SPACE:
00945         cv = getcvec(v, NUM_SPACE_CHAR, NUM_SPACE_RANGE);
00946         if (cv) {
00947             for (i=0 ; (size_t)i<NUM_SPACE_RANGE ; i++) {
00948                 addrange(cv, spaceRangeTable[i].start,
00949                         spaceRangeTable[i].end);
00950             }
00951             for (i=0 ; (size_t)i<NUM_SPACE_CHAR ; i++) {
00952                 addchr(cv, spaceCharTable[i]);
00953             }
00954         }
00955         break;
00956     case CC_LOWER:
00957         cv  = getcvec(v, NUM_LOWER_CHAR, NUM_LOWER_RANGE);
00958         if (cv) {
00959             for (i=0 ; (size_t)i<NUM_LOWER_RANGE ; i++) {
00960                 addrange(cv, lowerRangeTable[i].start,
00961                         lowerRangeTable[i].end);
00962             }
00963             for (i=0 ; (size_t)i<NUM_LOWER_CHAR ; i++) {
00964                 addchr(cv, lowerCharTable[i]);
00965             }
00966         }
00967         break;
00968     case CC_UPPER:
00969         cv  = getcvec(v, NUM_UPPER_CHAR, NUM_UPPER_RANGE);
00970         if (cv) {
00971             for (i=0 ; (size_t)i<NUM_UPPER_RANGE ; i++) {
00972                 addrange(cv, upperRangeTable[i].start,
00973                         upperRangeTable[i].end);
00974             }
00975             for (i=0 ; (size_t)i<NUM_UPPER_CHAR ; i++) {
00976                 addchr(cv, upperCharTable[i]);
00977             }
00978         }
00979         break;
00980     case CC_GRAPH:
00981         cv  = getcvec(v, NUM_GRAPH_CHAR, NUM_GRAPH_RANGE);
00982         if (cv) {
00983             for (i=0 ; (size_t)i<NUM_GRAPH_RANGE ; i++) {
00984                 addrange(cv, graphRangeTable[i].start,
00985                         graphRangeTable[i].end);
00986             }
00987             for (i=0 ; (size_t)i<NUM_GRAPH_CHAR ; i++) {
00988                 addchr(cv, graphCharTable[i]);
00989             }
00990         }
00991         break;
00992     }
00993     if (cv == NULL) {
00994         ERR(REG_ESPACE);
00995     }
00996     return cv;
00997 }
00998 
00999 /*
01000  - allcases - supply cvec for all case counterparts of a chr (including itself)
01001  * This is a shortcut, preferably an efficient one, for simple characters;
01002  * messy cases are done via range().
01003  ^ static struct cvec *allcases(struct vars *, pchr);
01004  */
01005 static struct cvec *
01006 allcases(
01007     struct vars *v,             /* context */
01008     pchr pc)                    /* character to get case equivs of */
01009 {
01010     struct cvec *cv;
01011     chr c = (chr)pc;
01012     chr lc, uc, tc;
01013 
01014     lc = Tcl_UniCharToLower((chr)c);
01015     uc = Tcl_UniCharToUpper((chr)c);
01016     tc = Tcl_UniCharToTitle((chr)c);
01017 
01018     if (tc != uc) {
01019         cv = getcvec(v, 3, 0);
01020         addchr(cv, tc);
01021     } else {
01022         cv = getcvec(v, 2, 0);
01023     }
01024     addchr(cv, lc);
01025     if (lc != uc) {
01026         addchr(cv, uc);
01027     }
01028     return cv;
01029 }
01030 
01031 /*
01032  - cmp - chr-substring compare
01033  * Backrefs need this.  It should preferably be efficient.
01034  * Note that it does not need to report anything except equal/unequal.
01035  * Note also that the length is exact, and the comparison should not
01036  * stop at embedded NULs!
01037  ^ static int cmp(const chr *, const chr *, size_t);
01038  */
01039 static int                      /* 0 for equal, nonzero for unequal */
01040 cmp(
01041     const chr *x, const chr *y, /* strings to compare */
01042     size_t len)                 /* exact length of comparison */
01043 {
01044     return memcmp(VS(x), VS(y), len*sizeof(chr));
01045 }
01046 
01047 /*
01048  - casecmp - case-independent chr-substring compare
01049  * REG_ICASE backrefs need this.  It should preferably be efficient.
01050  * Note that it does not need to report anything except equal/unequal.
01051  * Note also that the length is exact, and the comparison should not
01052  * stop at embedded NULs!
01053  ^ static int casecmp(const chr *, const chr *, size_t);
01054  */
01055 static int                      /* 0 for equal, nonzero for unequal */
01056 casecmp(
01057     const chr *x, const chr *y, /* strings to compare */
01058     size_t len)                 /* exact length of comparison */
01059 {
01060     for (; len > 0; len--, x++, y++) {
01061         if ((*x!=*y) && (Tcl_UniCharToLower(*x) != Tcl_UniCharToLower(*y))) {
01062             return 1;
01063         }
01064     }
01065     return 0;
01066 }
01067 
01068 /*
01069  * Local Variables:
01070  * mode: c
01071  * c-basic-offset: 4
01072  * fill-column: 78
01073  * End:
01074  */



Generated on Wed Mar 12 12:18:10 2008 by  doxygen 1.5.1