1 /* Copyright (C) 2002, 2003 Manuel Novoa III 2 * 3 * This library is free software; you can redistribute it and/or 4 * modify it under the terms of the GNU Lesser General Public 5 * License as published by the Free Software Foundation; either 6 * version 2.1 of the License, or (at your option) any later version. 7 * 8 * The GNU C Library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public 14 * License along with the GNU C Library; see the file COPYING.LIB. If 15 * not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 /* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! 19 * 20 * Besides uClibc, I'm using this code in my libc for elks, which is 21 * a 16-bit environment with a fairly limited compiler. It would make 22 * things much easier for me if this file isn't modified unnecessarily. 23 * In particular, please put any new or replacement functions somewhere 24 * else, and modify the makefile to use your version instead. 25 * Thanks. Manuel 26 * 27 * ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */ 28 29 #ifndef _UCLIBC_LOCALE_H 30 #define _UCLIBC_LOCALE_H 31 32 /**********************************************************************/ 33 /* uClibc compatibilty stuff */ 34 35 #ifdef __UCLIBC_HAS_LOCALE__ 36 37 # undef __LOCALE_C_ONLY 38 39 #else 40 41 # define __LOCALE_C_ONLY 42 43 # ifdef _LIBC 44 # define __XL_NPP(N) N 45 # define __LOCALE_PARAM 46 # define __LOCALE_ARG 47 # endif 48 49 #endif 50 51 /**********************************************************************/ 52 53 #define __NL_ITEM_CATEGORY_SHIFT 8 54 #define __NL_ITEM_INDEX_MASK 0xff 55 56 /* TODO: Make sure these agree with the locale mmap file gererator! */ 57 58 #define __LC_CTYPE 0 59 #define __LC_NUMERIC 1 60 #define __LC_MONETARY 2 61 #define __LC_TIME 3 62 #define __LC_COLLATE 4 63 #define __LC_MESSAGES 5 64 #define __LC_ALL 6 65 66 /**********************************************************************/ 67 #ifndef __LOCALE_C_ONLY 68 69 enum { 70 __ctype_encoding_7_bit, /* C/POSIX */ 71 __ctype_encoding_utf8, /* UTF-8 */ 72 __ctype_encoding_8_bit /* for 8-bit codeset locales */ 73 }; 74 75 #define LOCALE_STRING_SIZE (2 * __LC_ALL + 2) 76 77 /* 78 * '#' + 2_per_category + '\0' 79 * {locale row # : 0 = C|POSIX} + 0x8001 80 * encoded in two chars as (((N+1) >> 8) | 0x80) and ((N+1) & 0xff) 81 * so decode is ((((uint16_t)(*s & 0x7f)) << 8) + s[1]) - 1 82 * 83 * Note: 0s are not used as they are nul-terminators for strings. 84 * Note: 0xff, 0xff is the encoding for a non-selected locale. 85 * (see setlocale() below). 86 * In particular, C/POSIX locale is '#' + "\x80\x01"}*LC_ALL + nul. 87 */ 88 89 struct __uclibc_locale_struct; 90 typedef struct __uclibc_locale_struct *__locale_t; 91 92 #ifdef _LIBC 93 94 /* extern void _locale_set(const unsigned char *p); */ 95 extern void weak_function _locale_init(void) attribute_hidden; 96 97 #include <stddef.h> 98 #include <stdint.h> 99 #include <bits/uClibc_touplow.h> 100 #ifndef __UCLIBC_GEN_LOCALE 101 # include <bits/uClibc_locale_data.h> 102 #endif 103 104 #ifndef __UCLIBC_GEN_LOCALE /* && (defined IS_IN_libc || defined NOT_IN_libc) */ 105 typedef struct { 106 uint16_t num_weights; 107 uint16_t num_starters; 108 uint16_t ii_shift; 109 uint16_t ti_shift; 110 uint16_t ii_len; 111 uint16_t ti_len; 112 uint16_t max_weight; 113 uint16_t num_col_base; 114 uint16_t max_col_index; 115 uint16_t undefined_idx; 116 uint16_t range_low; 117 uint16_t range_count; 118 uint16_t range_base_weight; 119 uint16_t range_rule_offset; /* change name to index? */ 120 121 uint16_t ii_mask; 122 uint16_t ti_mask; 123 124 const uint16_t *index2weight_tbl; 125 const uint16_t *index2ruleidx_tbl; 126 const uint16_t *multistart_tbl; 127 /* uint16_t wcs2colidt_offset_low; */ 128 /* uint16_t wcs2colidt_offset_hi; */ 129 const uint16_t *wcs2colidt_tbl; 130 131 /* uint16_t undefined_idx; */ 132 const uint16_t *overrides_tbl; 133 /* uint16_t *multistart_tbl; */ 134 135 const uint16_t *weightstr; 136 const uint16_t *ruletable; 137 138 139 uint16_t *index2weight; 140 uint16_t *index2ruleidx; 141 142 uint16_t MAX_WEIGHTS; 143 } __collate_t; 144 145 /* static unsigned char cur_locale[LOCALE_STRING_SIZE]; */ 146 147 struct __uclibc_locale_struct { 148 #ifdef __UCLIBC_HAS_XLOCALE__ 149 const __ctype_mask_t *__ctype_b; 150 const __ctype_touplow_t *__ctype_tolower; 151 const __ctype_touplow_t *__ctype_toupper; 152 #endif 153 154 /* For now, just embed this in the structure. */ 155 __ctype_mask_t __ctype_b_data[256 + __UCLIBC_CTYPE_B_TBL_OFFSET]; 156 __ctype_touplow_t __ctype_tolower_data[256 + __UCLIBC_CTYPE_TO_TBL_OFFSET]; 157 __ctype_touplow_t __ctype_toupper_data[256 + __UCLIBC_CTYPE_TO_TBL_OFFSET]; 158 159 /* int tables_loaded; */ 160 /* unsigned char lctypes[LOCALE_STRING_SIZE]; */ 161 unsigned char cur_locale[LOCALE_STRING_SIZE]; 162 163 /* NL_LANGINFO stuff. BEWARE ORDERING!!! must agree with NL_* constants! */ 164 /* Also, numeric must be followed by monetary and the items must be in 165 * the "struct lconv" order. */ 166 167 uint16_t category_offsets[__LC_ALL]; /* TODO -- fix? */ 168 unsigned char category_item_count[__LC_ALL]; /* TODO - fix */ 169 170 /* ctype */ 171 unsigned char encoding; /* C/POSIX, 8-bit, UTF-8 */ 172 unsigned char mb_cur_max; /* determined by encoding _AND_ translit!!! */ 173 const unsigned char outdigit_length[10]; 174 175 #ifdef __CTYPE_HAS_8_BIT_LOCALES 176 const unsigned char *idx8ctype; 177 const unsigned char *tbl8ctype; 178 const unsigned char *idx8uplow; 179 const unsigned char *tbl8uplow; 180 # ifdef __UCLIBC_HAS_WCHAR__ 181 const unsigned char *idx8c2wc; 182 const uint16_t *tbl8c2wc; /* char > 0x7f to wide char */ 183 const unsigned char *idx8wc2c; 184 const unsigned char *tbl8wc2c; 185 /* translit */ 186 # endif 187 #endif /* __CTYPE_HAS_8_BIT_LOCALES */ 188 #ifdef __UCLIBC_HAS_WCHAR__ 189 190 const uint16_t *code2flag; 191 192 const unsigned char *tblwctype; 193 const unsigned char *tblwuplow; 194 /* const unsigned char *tblwcomb; */ 195 const int16_t *tblwuplow_diff; /* yes... signed */ 196 /* width?? */ 197 198 wchar_t decimal_point_wc; 199 wchar_t thousands_sep_wc; 200 int decimal_point_len; 201 int thousands_sep_len; 202 203 #endif /* __UCLIBC_HAS_WCHAR__ */ 204 205 /* ctype */ 206 const char *outdigit0_mb; 207 const char *outdigit1_mb; 208 const char *outdigit2_mb; 209 const char *outdigit3_mb; 210 const char *outdigit4_mb; 211 const char *outdigit5_mb; 212 const char *outdigit6_mb; 213 const char *outdigit7_mb; 214 const char *outdigit8_mb; 215 const char *outdigit9_mb; 216 const char *codeset; /* MUST BE LAST!!! */ 217 218 /* numeric */ 219 const char *decimal_point; 220 const char *thousands_sep; 221 const char *grouping; 222 223 /* monetary */ 224 const char *int_curr_symbol; 225 const char *currency_symbol; 226 const char *mon_decimal_point; 227 const char *mon_thousands_sep; 228 const char *mon_grouping; 229 const char *positive_sign; 230 const char *negative_sign; 231 const char *int_frac_digits; 232 const char *frac_digits; 233 const char *p_cs_precedes; 234 const char *p_sep_by_space; 235 const char *n_cs_precedes; 236 const char *n_sep_by_space; 237 const char *p_sign_posn; 238 const char *n_sign_posn; 239 const char *int_p_cs_precedes; 240 const char *int_p_sep_by_space; 241 const char *int_n_cs_precedes; 242 const char *int_n_sep_by_space; 243 const char *int_p_sign_posn; 244 const char *int_n_sign_posn; 245 246 const char *crncystr; /* not returned by localeconv */ 247 248 /* time */ 249 const char *abday_1; 250 const char *abday_2; 251 const char *abday_3; 252 const char *abday_4; 253 const char *abday_5; 254 const char *abday_6; 255 const char *abday_7; 256 257 const char *day_1; 258 const char *day_2; 259 const char *day_3; 260 const char *day_4; 261 const char *day_5; 262 const char *day_6; 263 const char *day_7; 264 265 const char *abmon_1; 266 const char *abmon_2; 267 const char *abmon_3; 268 const char *abmon_4; 269 const char *abmon_5; 270 const char *abmon_6; 271 const char *abmon_7; 272 const char *abmon_8; 273 const char *abmon_9; 274 const char *abmon_10; 275 const char *abmon_11; 276 const char *abmon_12; 277 278 const char *mon_1; 279 const char *mon_2; 280 const char *mon_3; 281 const char *mon_4; 282 const char *mon_5; 283 const char *mon_6; 284 const char *mon_7; 285 const char *mon_8; 286 const char *mon_9; 287 const char *mon_10; 288 const char *mon_11; 289 const char *mon_12; 290 291 const char *am_str; 292 const char *pm_str; 293 294 const char *d_t_fmt; 295 const char *d_fmt; 296 const char *t_fmt; 297 const char *t_fmt_ampm; 298 const char *era; 299 300 const char *era_year; /* non SUSv3 */ 301 const char *era_d_fmt; 302 const char *alt_digits; 303 const char *era_d_t_fmt; 304 const char *era_t_fmt; 305 306 /* messages */ 307 const char *yesexpr; 308 const char *noexpr; 309 const char *yesstr; 310 const char *nostr; 311 312 /* collate is at the end */ 313 __collate_t collate; 314 }; 315 316 extern struct __uclibc_locale_struct __global_locale_data; 317 extern struct __uclibc_locale_struct *__global_locale; 318 #endif /* !__UCLIBC_GEN_LOCALE */ 319 320 #if defined IS_IN_libc || defined NOT_IN_libc 321 /* If you plan to remove xxx_IN_libc guards, 322 * remove attribute_hidden, it won't work. 323 */ 324 extern int __locale_mbrtowc_l(wchar_t *__restrict dst, 325 const char *__restrict src, 326 __locale_t loc) attribute_hidden; 327 #endif 328 329 #ifdef L_setlocale 330 /* so we only get the warning once... */ 331 #warning need thread version of CUR_LOCALE! 332 #endif 333 334 /**********************************************************************/ 335 #ifdef __UCLIBC_HAS_XLOCALE__ 336 337 extern __locale_t __curlocale_var; 338 # ifdef __UCLIBC_HAS_THREADS__ 339 extern __locale_t __curlocale(void) __THROW __attribute__ ((__const__)); 340 libc_hidden_proto(__curlocale) 341 extern __locale_t __curlocale_set(__locale_t newloc); 342 libc_hidden_proto(__curlocale_set) 343 # define __UCLIBC_CURLOCALE (__curlocale()) 344 # else 345 # define __UCLIBC_CURLOCALE (__curlocale_var) 346 # endif 347 348 #elif defined(__UCLIBC_HAS_LOCALE__) 349 350 # define __UCLIBC_CURLOCALE (__global_locale) 351 352 #endif 353 /**********************************************************************/ 354 #if defined(__UCLIBC_HAS_XLOCALE__) && defined(__UCLIBC_DO_XLOCALE) 355 356 # define __XL_NPP(N) N ## _l 357 # define __LOCALE_PARAM , __locale_t locale_arg 358 # define __LOCALE_ARG , locale_arg 359 # define __LOCALE_PTR locale_arg 360 361 #else 362 363 # define __XL_NPP(N) N 364 # define __LOCALE_PARAM 365 # define __LOCALE_ARG 366 # define __LOCALE_PTR __UCLIBC_CURLOCALE 367 368 #endif 369 /**********************************************************************/ 370 371 #endif /* _LIBC */ 372 373 #endif /* !defined(__LOCALE_C_ONLY) */ 374 375 #endif /* _UCLIBC_LOCALE_H */ 376