#include #include #if 0 static const unsigned char tab0[] = {0}; static const unsigned char tab1[] = {0}; static const unsigned char tab2[] = {0}; static const unsigned char rulebases[512] = {0}; static const int rules[] = {0}; static const unsigned char exceptions[][2] = {0}; #else extern const unsigned char tab0[]; extern const unsigned char tab1[]; extern const unsigned char tab2[]; extern const unsigned char rulebases[512]; extern const int rules[]; extern const unsigned char exceptions[][2]; #endif static int casing_delta(unsigned c, int dir) { unsigned b, x, y, v, rt, xb, xn; int r, rd; if (c >= 0x20000) return 0; b = c>>8; c &= 255; x = c>>3; y = c&7; v = (tab0[tab0[b]*32+x]>>y&1) + (tab1[tab1[b]*32+x]>>y&1)*2 + (tab2[tab2[b]*32+x]>>y&1)*4; /* use the bit vector out of the tables as an index into * a block-specific set of rules and decode the rule into * a type and a case-mapping delta. */ r = rules[rulebases[b]+v]; rt = r & 255; rd = r >> 8; /* rules 0/1 are simple lower/upper case with a delta. * apply according to desired mapping direction. */ if (rt < 2) return rd & -(rt^dir); /* binary search. endpoints of the binary search for * this block are stored in the rule delta field. */ xn = rd & 0xff; xb = (unsigned)rd >> 8; while (xn) { unsigned try = exceptions[xb+xn/2][0]; if (try == c) { r = rules[exceptions[xb+xn/2][1]]; rt = r & 255; rd = r >> 8; if (rt < 2) return rd & -(rt^dir); /* Hard-coded for the four exceptional titlecase */ return dir ? -1 : 1; } else if (try > c) { xn /= 2; } else { xb += xn/2; xn -= xn/2; } } return 0; } wint_t towlower(wint_t wc) { return wc + casing_delta(wc, 0); } wint_t towupper(wint_t wc) { return wc + casing_delta(wc, 1); }