equal
deleted
inserted
replaced
9 * http://www.illumos.org/license/CDDL. |
9 * http://www.illumos.org/license/CDDL. |
10 */ |
10 */ |
11 |
11 |
12 /* |
12 /* |
13 * Copyright 2010,2011 Nexenta Systems, Inc. All rights reserved. |
13 * Copyright 2010,2011 Nexenta Systems, Inc. All rights reserved. |
14 * Copyright 2012 Garrett D'Amore <[email protected]> All rights reserved. |
14 * Copyright 2012 Garrett D'Amore <[email protected]> |
|
15 * Copyright 2013 DEY Storage Systems, Inc. |
15 */ |
16 */ |
16 |
17 |
17 /* |
18 /* |
18 * LC_CTYPE database generation routines for localedef. |
19 * LC_CTYPE database generation routines for localedef. |
19 */ |
20 */ |
25 #include <sys/avl.h> |
26 #include <sys/avl.h> |
26 #include <wchar.h> |
27 #include <wchar.h> |
27 #include <ctype.h> |
28 #include <ctype.h> |
28 #include <wctype.h> |
29 #include <wctype.h> |
29 #include <unistd.h> |
30 #include <unistd.h> |
|
31 #include "_ctype.h" |
30 #include "localedef.h" |
32 #include "localedef.h" |
31 #include "parser.tab.h" |
33 #include "parser.tab.h" |
32 #include "runefile.h" |
34 #include "runefile.h" |
33 |
35 |
34 static avl_tree_t ctypes; |
36 static avl_tree_t ctypes; |
41 int32_t toupper; |
43 int32_t toupper; |
42 int32_t tolower; |
44 int32_t tolower; |
43 avl_node_t avl; |
45 avl_node_t avl; |
44 } ctype_node_t; |
46 } ctype_node_t; |
45 |
47 |
|
48 typedef struct width_node { |
|
49 wchar_t start; |
|
50 wchar_t end; |
|
51 int8_t width; |
|
52 avl_node_t avl; |
|
53 } width_node_t; |
|
54 |
46 static int |
55 static int |
47 ctype_compare(const void *n1, const void *n2) |
56 ctype_compare(const void *n1, const void *n2) |
48 { |
57 { |
49 const ctype_node_t *c1 = n1; |
58 const ctype_node_t *c1 = n1; |
50 const ctype_node_t *c2 = n2; |
59 const ctype_node_t *c2 = n2; |
174 } |
183 } |
175 add_ctype_impl(ctn); |
184 add_ctype_impl(ctn); |
176 } |
185 } |
177 last_ctype = end; |
186 last_ctype = end; |
178 |
187 |
|
188 } |
|
189 |
|
190 /* |
|
191 * A word about widths: if the width mask is specified, then libc |
|
192 * unconditionally honors it. Otherwise, it assumes printable |
|
193 * characters have width 1, and non-printable characters have width |
|
194 * -1 (except for NULL which is special with with 0). Hence, we have |
|
195 * no need to inject defaults here -- the "default" unset value of 0 |
|
196 * indicates that libc should use its own logic in wcwidth as described. |
|
197 */ |
|
198 void |
|
199 add_width(int wc, int width) |
|
200 { |
|
201 ctype_node_t *ctn; |
|
202 |
|
203 if ((ctn = get_ctype(wc)) == NULL) { |
|
204 INTERR; |
|
205 return; |
|
206 } |
|
207 ctn->ctype &= ~(_CTYPE_SWM); |
|
208 switch (width) { |
|
209 case 0: |
|
210 ctn->ctype |= _CTYPE_SW0; |
|
211 break; |
|
212 case 1: |
|
213 ctn->ctype |= _CTYPE_SW1; |
|
214 break; |
|
215 case 2: |
|
216 ctn->ctype |= _CTYPE_SW2; |
|
217 break; |
|
218 case 3: |
|
219 ctn->ctype |= _CTYPE_SW3; |
|
220 break; |
|
221 } |
|
222 } |
|
223 |
|
224 void |
|
225 add_width_range(int start, int end, int width) |
|
226 { |
|
227 for (; start <= end; start++) { |
|
228 add_width(start, width); |
|
229 } |
179 } |
230 } |
180 |
231 |
181 void |
232 void |
182 add_caseconv(int val, int wc) |
233 add_caseconv(int val, int wc) |
183 { |
234 { |
232 rl.mapupper[wc] = wc; |
283 rl.mapupper[wc] = wc; |
233 } |
284 } |
234 |
285 |
235 for (ctn = avl_first(&ctypes); ctn; ctn = AVL_NEXT(&ctypes, ctn)) { |
286 for (ctn = avl_first(&ctypes); ctn; ctn = AVL_NEXT(&ctypes, ctn)) { |
236 int conflict = 0; |
287 int conflict = 0; |
|
288 |
237 |
289 |
238 wc = ctn->wc; |
290 wc = ctn->wc; |
239 |
291 |
240 /* |
292 /* |
241 * POSIX requires certain portable characters have |
293 * POSIX requires certain portable characters have |