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