• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <wctype.h>
2 #ifndef __LITEOS__
3 #include <ctype.h>
4 #include <dlfcn.h>
5 #include <stddef.h>
6 #endif
7 
8 static const unsigned char tab[];
9 
10 static const unsigned char rulebases[512];
11 static const int rules[];
12 
13 static const unsigned char exceptions[][2];
14 
15 #include "casemap.h"
16 
casemap(unsigned c,int dir)17 static int casemap(unsigned c, int dir)
18 {
19 	unsigned b, x, y, v, rt, xb, xn;
20 	int r, rd, c0 = c;
21 
22 	if (c >= 0x20000) return c;
23 
24 	b = c>>8;
25 	c &= 255;
26 	x = c/3;
27 	y = c%3;
28 
29 	/* lookup entry in two-level base-6 table */
30 	v = tab[tab[b]*86+x];
31 	static const int mt[] = { 2048, 342, 57 };
32 	v = (v*mt[y]>>11)%6;
33 
34 	/* use the bit vector out of the tables as an index into
35 	 * a block-specific set of rules and decode the rule into
36 	 * a type and a case-mapping delta. */
37 	r = rules[rulebases[b]+v];
38 	rt = r & 255;
39 	rd = r >> 8;
40 
41 	/* rules 0/1 are simple lower/upper case with a delta.
42 	 * apply according to desired mapping direction. */
43 	if (rt < 2) return c0 + (rd & -(rt^dir));
44 
45 	/* binary search. endpoints of the binary search for
46 	 * this block are stored in the rule delta field. */
47 	xn = rd & 0xff;
48 	xb = (unsigned)rd >> 8;
49 	while (xn) {
50 		unsigned try = exceptions[xb+xn/2][0];
51 		if (try == c) {
52 			r = rules[exceptions[xb+xn/2][1]];
53 			rt = r & 255;
54 			rd = r >> 8;
55 			if (rt < 2) return c0 + (rd & -(rt^dir));
56 			/* Hard-coded for the four exceptional titlecase */
57 			return c0 + (dir ? -1 : 1);
58 		} else if (try > c) {
59 			xn /= 2;
60 		} else {
61 			xb += xn/2;
62 			xn -= xn/2;
63 		}
64 	}
65 	return c0;
66 }
67 
68 #ifndef __LITEOS__
69 static void* g_hmicu_handle = NULL;
70 static wint_t (*g_hm_ucase_toupper)(wint_t);
71 
find_hmicu_symbol(const char * symbol_name)72 static void* find_hmicu_symbol(const char* symbol_name) {
73   if (!g_hmicu_handle) {
74 	g_hmicu_handle = dlopen("libhmicuuc.z.so", RTLD_LOCAL);
75   }
76   return g_hmicu_handle ? dlsym(g_hmicu_handle, symbol_name) : NULL;
77 }
78 #endif
79 
towlower(wint_t wc)80 wint_t towlower(wint_t wc)
81 {
82 #ifndef __LITEOS__
83 	if (wc < 0x80) {
84 		if (wc >= 'A' && wc <= 'Z') return wc | 0x20;
85 		return wc;
86 	}
87 #endif
88 	return casemap(wc, 0);
89 }
90 
towupper(wint_t wc)91 wint_t towupper(wint_t wc)
92 {
93 #ifndef __LITEOS__
94 	if (wc < 0x80) {
95 		if (wc >= 'a' && wc <= 'z') return wc ^ 0x20;
96 		return wc;
97 	}
98 	if (!g_hm_ucase_toupper) {
99 		typedef wint_t (*f)(wint_t);
100 		g_hm_ucase_toupper = (f)find_hmicu_symbol("ucase_toupper_72");
101 	}
102 	return g_hm_ucase_toupper ? g_hm_ucase_toupper(wc) : casemap(wc, 1);
103 #else
104 	return casemap(wc, 1);
105 #endif
106 }
107 
__towupper_l(wint_t c,locale_t l)108 wint_t __towupper_l(wint_t c, locale_t l)
109 {
110 	return towupper(c);
111 }
112 
__towlower_l(wint_t c,locale_t l)113 wint_t __towlower_l(wint_t c, locale_t l)
114 {
115 	return towlower(c);
116 }
117 
118 weak_alias(__towupper_l, towupper_l);
119 weak_alias(__towlower_l, towlower_l);
120