1 /*-
2 * Copyright (C) 1997 by Andrey A. Chernov, Moscow, Russia.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: src/lib/libc/locale/setlocale.h,v 1.4 2001/12/20 18:28:52 phantom Exp $
27 */
28
29 #ifndef _SETLOCALE_H_
30 #define _SETLOCALE_H_
31
32 #include <errno.h>
33 #include <limits.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <wchar.h>
37 #include <locale.h>
38 #include <langinfo.h>
39
40 __BEGIN_DECLS
41
42 extern struct __locale_t __global_locale;
43
44 #define __get_global_locale() (&__global_locale)
45
46 #define ENCODING_LEN 31
47 #define CATEGORY_LEN 11
48 #define _LC_LAST 7
49
50
51 struct lc_ctype_T
52 {
53 const char *codeset; /* codeset for mbtowc conversion */
54 const char *mb_cur_max;
55 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
56 const char *outdigits[10];
57 const wchar_t *woutdigits[10];
58 #endif
59 };
60 extern const struct lc_ctype_T _C_ctype_locale;
61
62 struct lc_monetary_T
63 {
64 const char *int_curr_symbol;
65 const char *currency_symbol;
66 const char *mon_decimal_point;
67 const char *mon_thousands_sep;
68 const char *mon_grouping;
69 const char *positive_sign;
70 const char *negative_sign;
71 const char *int_frac_digits;
72 const char *frac_digits;
73 const char *p_cs_precedes;
74 const char *p_sep_by_space;
75 const char *n_cs_precedes;
76 const char *n_sep_by_space;
77 const char *p_sign_posn;
78 const char *n_sign_posn;
79 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
80 const char *int_p_cs_precedes;
81 const char *int_p_sep_by_space;
82 const char *int_n_cs_precedes;
83 const char *int_n_sep_by_space;
84 const char *int_p_sign_posn;
85 const char *int_n_sign_posn;
86 const char *codeset; /* codeset for mbtowc conversion */
87 const wchar_t *wint_curr_symbol;
88 const wchar_t *wcurrency_symbol;
89 const wchar_t *wmon_decimal_point;
90 const wchar_t *wmon_thousands_sep;
91 const wchar_t *wpositive_sign;
92 const wchar_t *wnegative_sign;
93 #endif
94 };
95 extern const struct lc_monetary_T _C_monetary_locale;
96
97 struct lc_numeric_T
98 {
99 const char *decimal_point;
100 const char *thousands_sep;
101 const char *grouping;
102 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
103 const char *codeset; /* codeset for mbtowc conversion */
104 const wchar_t *wdecimal_point;
105 const wchar_t *wthousands_sep;
106 #endif
107 };
108 extern const struct lc_numeric_T _C_numeric_locale;
109
110 struct lc_time_T
111 {
112 const char *mon[12];
113 const char *month[12];
114 const char *wday[7];
115 const char *weekday[7];
116 const char *X_fmt;
117 const char *x_fmt;
118 const char *c_fmt;
119 const char *am_pm[2];
120 const char *date_fmt;
121 const char *alt_month[12]; /* unused */
122 const char *md_order;
123 const char *ampm_fmt;
124 const char *era;
125 const char *era_d_fmt;
126 const char *era_d_t_fmt;
127 const char *era_t_fmt;
128 const char *alt_digits;
129 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
130 const char *codeset; /* codeset for mbtowc conversion */
131 const wchar_t *wmon[12];
132 const wchar_t *wmonth[12];
133 const wchar_t *wwday[7];
134 const wchar_t *wweekday[7];
135 const wchar_t *wX_fmt;
136 const wchar_t *wx_fmt;
137 const wchar_t *wc_fmt;
138 const wchar_t *wam_pm[2];
139 const wchar_t *wdate_fmt;
140 const wchar_t *wampm_fmt;
141 const wchar_t *wera;
142 const wchar_t *wera_d_fmt;
143 const wchar_t *wera_d_t_fmt;
144 const wchar_t *wera_t_fmt;
145 const wchar_t *walt_digits;
146 #endif
147 };
148 extern const struct lc_time_T _C_time_locale;
149
150 struct lc_messages_T
151 {
152 const char *yesexpr;
153 const char *noexpr;
154 const char *yesstr;
155 const char *nostr;
156 #ifdef __HAVE_LOCALE_INFO__
157 const char *codeset; /* codeset for mbtowc conversion */
158 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
159 const wchar_t *wyesexpr;
160 const wchar_t *wnoexpr;
161 const wchar_t *wyesstr;
162 const wchar_t *wnostr;
163 #endif
164 #endif
165 };
166 extern const struct lc_messages_T _C_messages_locale;
167
168 struct __lc_cats
169 {
170 const void *ptr;
171 char *buf;
172 };
173
174 struct __locale_t
175 {
176 char categories[_LC_LAST][ENCODING_LEN + 1];
177 int (*wctomb) (char *, wchar_t,
178 mbstate_t *);
179 int (*mbtowc) (wchar_t *,
180 const char *, size_t, mbstate_t *);
181 int cjk_lang;
182 const char *ctype_ptr;
183 struct lconv lconv;
184 #ifndef __HAVE_LOCALE_INFO__
185 char mb_cur_max[2];
186 char ctype_codeset[ENCODING_LEN + 1];
187 char message_codeset[ENCODING_LEN + 1];
188 #else
189 struct __lc_cats lc_cat[_LC_LAST];
190 #endif
191 };
192
193 #ifdef _MB_CAPABLE
194 extern char *__loadlocale (struct __locale_t *, int, char *);
195 extern const char *__get_locale_env(int);
196 #endif /* _MB_CAPABLE */
197
198 extern struct lconv *__localeconv_l (struct __locale_t *locale);
199
200 extern size_t _wcsnrtombs_l (char *, const wchar_t **,
201 size_t, size_t, mbstate_t *, struct __locale_t *);
202
203 #ifdef __HAVE_LOCALE_INFO__
204 #define NEWLIB_THREAD_LOCAL_LOCALE NEWLIB_THREAD_LOCAL
205 extern NEWLIB_THREAD_LOCAL_LOCALE struct __locale_t *_locale;
206 #endif
207
208 /* In POSIX terms the current locale is the locale used by all functions
209 using locale info without providing a locale as parameter (*_l functions).
210 The current locale is either the locale of the current thread, if the
211 thread called uselocale, or the global locale if not. */
212 _ELIDABLE_INLINE struct __locale_t *
__get_current_locale(void)213 __get_current_locale (void)
214 {
215 #ifdef __HAVE_LOCALE_INFO__
216 return _locale ?: __get_global_locale ();
217 #else
218 return __get_global_locale();
219 #endif
220 }
221
222 /* Only access fixed "C" locale using this function. Fake for !_MB_CAPABLE
223 targets by returning ptr to globale locale. */
224 _ELIDABLE_INLINE struct __locale_t *
__get_C_locale(void)225 __get_C_locale (void)
226 {
227 #ifndef _MB_CAPABLE
228 return __get_global_locale ();
229 #else
230 extern const struct __locale_t __C_locale;
231 return (struct __locale_t *) &__C_locale;
232 #endif
233 }
234
235
236 #ifdef __HAVE_LOCALE_INFO__
237 _ELIDABLE_INLINE const struct lc_ctype_T *
__get_ctype_locale(struct __locale_t * locale)238 __get_ctype_locale (struct __locale_t *locale)
239 {
240 return (const struct lc_ctype_T *) (locale)->lc_cat[LC_CTYPE].ptr;
241 }
242
243 _ELIDABLE_INLINE const struct lc_ctype_T *
__get_current_ctype_locale(void)244 __get_current_ctype_locale (void)
245 {
246 return (const struct lc_ctype_T *)
247 _locale->lc_cat[LC_CTYPE].ptr;
248 }
249 #endif
250
251 _ELIDABLE_INLINE int
__locale_mb_cur_max_l(struct __locale_t * locale)252 __locale_mb_cur_max_l (struct __locale_t *locale)
253 {
254 #ifdef __HAVE_LOCALE_INFO__
255 return __get_ctype_locale (locale)->mb_cur_max[0];
256 #else
257 return locale->mb_cur_max[0];
258 #endif
259 }
260
261 #ifdef __HAVE_LOCALE_INFO__
262 _ELIDABLE_INLINE const struct lc_monetary_T *
__get_monetary_locale(struct __locale_t * locale)263 __get_monetary_locale (struct __locale_t *locale)
264 {
265 return (const struct lc_monetary_T *) (locale)->lc_cat[LC_MONETARY].ptr;
266 }
267
268 _ELIDABLE_INLINE const struct lc_monetary_T *
__get_current_monetary_locale(void)269 __get_current_monetary_locale (void)
270 {
271 return (const struct lc_monetary_T *)
272 _locale->lc_cat[LC_MONETARY].ptr;
273 }
274
275 _ELIDABLE_INLINE const struct lc_numeric_T *
__get_numeric_locale(struct __locale_t * locale)276 __get_numeric_locale (struct __locale_t *locale)
277 {
278 return (const struct lc_numeric_T *) (locale)->lc_cat[LC_NUMERIC].ptr;
279 }
280
281 _ELIDABLE_INLINE const struct lc_numeric_T *
__get_current_numeric_locale(void)282 __get_current_numeric_locale (void)
283 {
284 return (const struct lc_numeric_T *)
285 _locale->lc_cat[LC_NUMERIC].ptr;
286 }
287
288 _ELIDABLE_INLINE const struct lc_time_T *
__get_time_locale(struct __locale_t * locale)289 __get_time_locale (struct __locale_t *locale)
290 {
291 return (const struct lc_time_T *) (locale)->lc_cat[LC_TIME].ptr;
292 }
293
294 _ELIDABLE_INLINE const struct lc_time_T *
__get_current_time_locale(void)295 __get_current_time_locale (void)
296 {
297 return (const struct lc_time_T *)
298 _locale->lc_cat[LC_TIME].ptr;
299 }
300
301 _ELIDABLE_INLINE const struct lc_messages_T *
__get_messages_locale(struct __locale_t * locale)302 __get_messages_locale (struct __locale_t *locale)
303 {
304 return (const struct lc_messages_T *) (locale)->lc_cat[_LC_MESSAGES].ptr;
305 }
306
307 _ELIDABLE_INLINE const struct lc_messages_T *
__get_current_messages_locale(void)308 __get_current_messages_locale (void)
309 {
310 return (const struct lc_messages_T *)
311 _locale->lc_cat[_LC_MESSAGES].ptr;
312 }
313
314 #else /* ! __HAVE_LOCALE_INFO__ */
315 _ELIDABLE_INLINE const struct lc_monetary_T *
__get_monetary_locale(struct __locale_t * locale)316 __get_monetary_locale (struct __locale_t *locale)
317 {
318 (void) locale;
319 return &_C_monetary_locale;
320 }
321
322 _ELIDABLE_INLINE const struct lc_monetary_T *
__get_current_monetary_locale(void)323 __get_current_monetary_locale (void)
324 {
325 return &_C_monetary_locale;
326 }
327
328 _ELIDABLE_INLINE const struct lc_numeric_T *
__get_numeric_locale(struct __locale_t * locale)329 __get_numeric_locale (struct __locale_t *locale)
330 {
331 (void) locale;
332 return &_C_numeric_locale;
333 }
334
335 _ELIDABLE_INLINE const struct lc_numeric_T *
__get_current_numeric_locale(void)336 __get_current_numeric_locale (void)
337 {
338 return &_C_numeric_locale;
339 }
340
341 _ELIDABLE_INLINE const struct lc_time_T *
__get_time_locale(struct __locale_t * locale)342 __get_time_locale (struct __locale_t *locale)
343 {
344 (void) locale;
345 return &_C_time_locale;
346 }
347
348 _ELIDABLE_INLINE const struct lc_time_T *
__get_current_time_locale(void)349 __get_current_time_locale (void)
350 {
351 return &_C_time_locale;
352 }
353
354 _ELIDABLE_INLINE const struct lc_messages_T *
__get_messages_locale(struct __locale_t * locale)355 __get_messages_locale (struct __locale_t *locale)
356 {
357 (void) locale;
358 return &_C_messages_locale;
359 }
360
361 _ELIDABLE_INLINE const struct lc_messages_T *
__get_current_messages_locale(void)362 __get_current_messages_locale (void)
363 {
364 return &_C_messages_locale;
365 }
366 #endif /* !__HAVE_LOCALE_INFO__ */
367
368 _ELIDABLE_INLINE const char *
__locale_charset(struct __locale_t * locale)369 __locale_charset (struct __locale_t *locale)
370 {
371 (void) locale;
372 #ifdef __HAVE_LOCALE_INFO__
373 return __get_ctype_locale (locale)->codeset;
374 #else
375 return locale->ctype_codeset;
376 #endif
377 }
378
379 _ELIDABLE_INLINE const char *
__current_locale_charset(void)380 __current_locale_charset (void)
381 {
382 #ifdef __HAVE_LOCALE_INFO__
383 return __get_current_ctype_locale ()->codeset;
384 #else
385 return __get_current_locale()->ctype_codeset;
386 #endif
387 }
388
389 _ELIDABLE_INLINE const char *
__locale_msgcharset(void)390 __locale_msgcharset (void)
391 {
392 #ifdef __HAVE_LOCALE_INFO__
393 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
394 return (char *) __get_current_messages_locale ()->codeset;
395 #else
396 return (char *) __get_current_ctype_locale ()->codeset;
397 #endif
398 #else
399 return (char *) __get_current_locale()->message_codeset;
400 #endif
401 }
402
403 _ELIDABLE_INLINE int
__locale_cjk_lang(void)404 __locale_cjk_lang (void)
405 {
406 return __get_current_locale()->cjk_lang;
407 }
408
409 int __ctype_load_locale (struct __locale_t *, const char *, void *,
410 const char *, int);
411 int __monetary_load_locale (struct __locale_t *, const char *, void *,
412 const char *);
413 int __messages_load_locale (struct __locale_t *, const char *, void *,
414 const char *);
415
416 __END_DECLS
417
418 #endif /* !_SETLOCALE_H_ */
419