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 <_ansi.h>
33 #include <sys/cdefs.h>
34 #include <limits.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <wchar.h>
38 #include <locale.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 #ifdef __CYGWIN__
51 struct lc_collate_T
52 {
53   int	       (*mbtowc) (wchar_t *, const char *, size_t,
54 			  mbstate_t *);
55   char		 codeset[ENCODING_LEN + 1];
56 };
57 extern const struct lc_collate_T _C_collate_locale;
58 #endif
59 
60 struct lc_ctype_T
61 {
62   const char	*codeset;	 /* codeset for mbtowc conversion */
63   const char	*mb_cur_max;
64 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
65   const char	*outdigits[10];
66   const wchar_t	*woutdigits[10];
67 #endif
68 };
69 extern const struct lc_ctype_T _C_ctype_locale;
70 #ifdef __CYGWIN__
71 extern const struct lc_ctype_T _C_utf8_ctype_locale;
72 #endif
73 
74 struct lc_monetary_T
75 {
76   const char	*int_curr_symbol;
77   const char	*currency_symbol;
78   const char	*mon_decimal_point;
79   const char	*mon_thousands_sep;
80   const char	*mon_grouping;
81   const char	*positive_sign;
82   const char	*negative_sign;
83   const char	*int_frac_digits;
84   const char	*frac_digits;
85   const char	*p_cs_precedes;
86   const char	*p_sep_by_space;
87   const char	*n_cs_precedes;
88   const char	*n_sep_by_space;
89   const char	*p_sign_posn;
90   const char	*n_sign_posn;
91 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
92   const char	*int_p_cs_precedes;
93   const char	*int_p_sep_by_space;
94   const char	*int_n_cs_precedes;
95   const char	*int_n_sep_by_space;
96   const char	*int_p_sign_posn;
97   const char	*int_n_sign_posn;
98   const char	*codeset;	 /* codeset for mbtowc conversion */
99   const wchar_t	*wint_curr_symbol;
100   const wchar_t	*wcurrency_symbol;
101   const wchar_t	*wmon_decimal_point;
102   const wchar_t	*wmon_thousands_sep;
103   const wchar_t	*wpositive_sign;
104   const wchar_t	*wnegative_sign;
105 #endif
106 };
107 extern const struct lc_monetary_T _C_monetary_locale;
108 
109 struct lc_numeric_T
110 {
111   const char	*decimal_point;
112   const char	*thousands_sep;
113   const char	*grouping;
114 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
115   const char	*codeset;	 /* codeset for mbtowc conversion */
116   const wchar_t	*wdecimal_point;
117   const wchar_t	*wthousands_sep;
118 #endif
119 };
120 extern const struct lc_numeric_T _C_numeric_locale;
121 
122 struct lc_time_T
123 {
124   const char	*mon[12];
125   const char	*month[12];
126   const char	*wday[7];
127   const char	*weekday[7];
128   const char	*X_fmt;
129   const char	*x_fmt;
130   const char	*c_fmt;
131   const char	*am_pm[2];
132   const char	*date_fmt;
133   const char	*alt_month[12];	/* unused */
134   const char	*md_order;
135   const char	*ampm_fmt;
136   const char	*era;
137   const char	*era_d_fmt;
138   const char	*era_d_t_fmt;
139   const char	*era_t_fmt;
140   const char	*alt_digits;
141 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
142   const char	*codeset;	 /* codeset for mbtowc conversion */
143   const wchar_t	*wmon[12];
144   const wchar_t	*wmonth[12];
145   const wchar_t	*wwday[7];
146   const wchar_t	*wweekday[7];
147   const wchar_t	*wX_fmt;
148   const wchar_t	*wx_fmt;
149   const wchar_t	*wc_fmt;
150   const wchar_t	*wam_pm[2];
151   const wchar_t	*wdate_fmt;
152   const wchar_t	*wampm_fmt;
153   const wchar_t	*wera;
154   const wchar_t	*wera_d_fmt;
155   const wchar_t	*wera_d_t_fmt;
156   const wchar_t	*wera_t_fmt;
157   const wchar_t	*walt_digits;
158 #endif
159 };
160 extern const struct lc_time_T _C_time_locale;
161 
162 struct	lc_messages_T
163 {
164   const char	*yesexpr;
165   const char	*noexpr;
166   const char	*yesstr;
167   const char	*nostr;
168 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
169   const char	*codeset;	 /* codeset for mbtowc conversion */
170   const wchar_t	*wyesexpr;
171   const wchar_t	*wnoexpr;
172   const wchar_t	*wyesstr;
173   const wchar_t	*wnostr;
174 #endif
175 };
176 extern const struct lc_messages_T _C_messages_locale;
177 
178 struct __lc_cats
179 {
180   const void	*ptr;
181   char		*buf;
182 };
183 
184 struct __locale_t
185 {
186   char			 categories[_LC_LAST][ENCODING_LEN + 1];
187   int			(*wctomb) (char *, wchar_t,
188 				   mbstate_t *);
189   int			(*mbtowc) (wchar_t *,
190 				   const char *, size_t, mbstate_t *);
191   int			 cjk_lang;
192   const char		 *ctype_ptr;
193   struct lconv		 lconv;
194 #ifndef __HAVE_LOCALE_INFO__
195   char			 mb_cur_max[2];
196   char			 ctype_codeset[ENCODING_LEN + 1];
197   char			 message_codeset[ENCODING_LEN + 1];
198 #else
199   struct __lc_cats	 lc_cat[_LC_LAST];
200 #endif
201 };
202 
203 #ifdef _MB_CAPABLE
204 extern char *__loadlocale (struct __locale_t *, int, char *);
205 extern const char *__get_locale_env(int);
206 #endif /* _MB_CAPABLE */
207 
208 extern struct lconv *__localeconv_l (struct __locale_t *locale);
209 
210 extern size_t _wcsnrtombs_l (char *, const wchar_t **,
211 			     size_t, size_t, mbstate_t *, struct __locale_t *);
212 
213 #ifdef __HAVE_LOCALE_INFO__
214 #define NEWLIB_THREAD_LOCAL_LOCALE NEWLIB_THREAD_LOCAL
215 extern NEWLIB_THREAD_LOCAL_LOCALE struct __locale_t *_locale;
216 #endif
217 
218 /* In POSIX terms the current locale is the locale used by all functions
219    using locale info without providing a locale as parameter (*_l functions).
220    The current locale is either the locale of the current thread, if the
221    thread called uselocale, or the global locale if not. */
222 _ELIDABLE_INLINE struct __locale_t *
__get_current_locale(void)223 __get_current_locale (void)
224 {
225 #ifdef __HAVE_LOCALE_INFO__
226   return _locale ?: __get_global_locale ();
227 #else
228   return __get_global_locale();
229 #endif
230 }
231 
232 /* Only access fixed "C" locale using this function.  Fake for !_MB_CAPABLE
233    targets by returning ptr to globale locale. */
234 _ELIDABLE_INLINE struct __locale_t *
__get_C_locale(void)235 __get_C_locale (void)
236 {
237 #ifndef _MB_CAPABLE
238   return __get_global_locale ();
239 #else
240   extern const struct __locale_t __C_locale;
241   return (struct __locale_t *) &__C_locale;
242 #endif
243 }
244 
245 #ifdef __CYGWIN__
246 _ELIDABLE_INLINE const struct lc_collate_T *
__get_collate_locale(struct __locale_t * locale)247 __get_collate_locale (struct __locale_t *locale)
248 {
249   return (const struct lc_collate_T *) locale->lc_cat[LC_COLLATE].ptr;
250 }
251 
252 _ELIDABLE_INLINE const struct lc_collate_T *
__get_current_collate_locale(void)253 __get_current_collate_locale (void)
254 {
255   return (const struct lc_collate_T *)
256 	 _locale->lc_cat[LC_COLLATE].ptr;
257 }
258 #endif
259 
260 #ifdef __HAVE_LOCALE_INFO__
261 _ELIDABLE_INLINE const struct lc_ctype_T *
__get_ctype_locale(struct __locale_t * locale)262 __get_ctype_locale (struct __locale_t *locale)
263 {
264   return (const struct lc_ctype_T *) (locale)->lc_cat[LC_CTYPE].ptr;
265 }
266 
267 _ELIDABLE_INLINE const struct lc_ctype_T *
__get_current_ctype_locale(void)268 __get_current_ctype_locale (void)
269 {
270   return (const struct lc_ctype_T *)
271 	 _locale->lc_cat[LC_CTYPE].ptr;
272 }
273 #endif
274 
275 _ELIDABLE_INLINE int
__locale_mb_cur_max_l(struct __locale_t * locale)276 __locale_mb_cur_max_l (struct __locale_t *locale)
277 {
278 #ifdef __HAVE_LOCALE_INFO__
279   return __get_ctype_locale (locale)->mb_cur_max[0];
280 #else
281   return locale->mb_cur_max[0];
282 #endif
283 }
284 
285 #ifdef __HAVE_LOCALE_INFO__
286 _ELIDABLE_INLINE const struct lc_monetary_T *
__get_monetary_locale(struct __locale_t * locale)287 __get_monetary_locale (struct __locale_t *locale)
288 {
289   return (const struct lc_monetary_T *) (locale)->lc_cat[LC_MONETARY].ptr;
290 }
291 
292 _ELIDABLE_INLINE const struct lc_monetary_T *
__get_current_monetary_locale(void)293 __get_current_monetary_locale (void)
294 {
295   return (const struct lc_monetary_T *)
296 	 _locale->lc_cat[LC_MONETARY].ptr;
297 }
298 
299 _ELIDABLE_INLINE const struct lc_numeric_T *
__get_numeric_locale(struct __locale_t * locale)300 __get_numeric_locale (struct __locale_t *locale)
301 {
302   return (const struct lc_numeric_T *) (locale)->lc_cat[LC_NUMERIC].ptr;
303 }
304 
305 _ELIDABLE_INLINE const struct lc_numeric_T *
__get_current_numeric_locale(void)306 __get_current_numeric_locale (void)
307 {
308   return (const struct lc_numeric_T *)
309 	 _locale->lc_cat[LC_NUMERIC].ptr;
310 }
311 
312 _ELIDABLE_INLINE const struct lc_time_T *
__get_time_locale(struct __locale_t * locale)313 __get_time_locale (struct __locale_t *locale)
314 {
315   return (const struct lc_time_T *) (locale)->lc_cat[LC_TIME].ptr;
316 }
317 
318 _ELIDABLE_INLINE const struct lc_time_T *
__get_current_time_locale(void)319 __get_current_time_locale (void)
320 {
321   return (const struct lc_time_T *)
322 	 _locale->lc_cat[LC_TIME].ptr;
323 }
324 
325 _ELIDABLE_INLINE const struct lc_messages_T *
__get_messages_locale(struct __locale_t * locale)326 __get_messages_locale (struct __locale_t *locale)
327 {
328   return (const struct lc_messages_T *) (locale)->lc_cat[LC_MESSAGES].ptr;
329 }
330 
331 _ELIDABLE_INLINE const struct lc_messages_T *
__get_current_messages_locale(void)332 __get_current_messages_locale (void)
333 {
334   return (const struct lc_messages_T *)
335 	 _locale->lc_cat[LC_MESSAGES].ptr;
336 }
337 #else /* ! __HAVE_LOCALE_INFO__ */
338 _ELIDABLE_INLINE const struct lc_monetary_T *
__get_monetary_locale(struct __locale_t * locale)339 __get_monetary_locale (struct __locale_t *locale)
340 {
341   (void) locale;
342   return &_C_monetary_locale;
343 }
344 
345 _ELIDABLE_INLINE const struct lc_monetary_T *
__get_current_monetary_locale(void)346 __get_current_monetary_locale (void)
347 {
348   return &_C_monetary_locale;
349 }
350 
351 _ELIDABLE_INLINE const struct lc_numeric_T *
__get_numeric_locale(struct __locale_t * locale)352 __get_numeric_locale (struct __locale_t *locale)
353 {
354   (void) locale;
355   return &_C_numeric_locale;
356 }
357 
358 _ELIDABLE_INLINE const struct lc_numeric_T *
__get_current_numeric_locale(void)359 __get_current_numeric_locale (void)
360 {
361   return &_C_numeric_locale;
362 }
363 
364 _ELIDABLE_INLINE const struct lc_time_T *
__get_time_locale(struct __locale_t * locale)365 __get_time_locale (struct __locale_t *locale)
366 {
367   (void) locale;
368   return &_C_time_locale;
369 }
370 
371 _ELIDABLE_INLINE const struct lc_time_T *
__get_current_time_locale(void)372 __get_current_time_locale (void)
373 {
374   return &_C_time_locale;
375 }
376 
377 _ELIDABLE_INLINE const struct lc_messages_T *
__get_messages_locale(struct __locale_t * locale)378 __get_messages_locale (struct __locale_t *locale)
379 {
380   (void) locale;
381   return &_C_messages_locale;
382 }
383 
384 _ELIDABLE_INLINE const struct lc_messages_T *
__get_current_messages_locale(void)385 __get_current_messages_locale (void)
386 {
387   return &_C_messages_locale;
388 }
389 #endif /* !__HAVE_LOCALE_INFO__ */
390 
391 _ELIDABLE_INLINE const char *
__locale_charset(struct __locale_t * locale)392 __locale_charset (struct __locale_t *locale)
393 {
394   (void) locale;
395 #ifdef __HAVE_LOCALE_INFO__
396   return __get_ctype_locale (locale)->codeset;
397 #else
398   return locale->ctype_codeset;
399 #endif
400 }
401 
402 _ELIDABLE_INLINE const char *
__current_locale_charset(void)403 __current_locale_charset (void)
404 {
405 #ifdef __HAVE_LOCALE_INFO__
406   return __get_current_ctype_locale ()->codeset;
407 #else
408   return __get_current_locale()->ctype_codeset;
409 #endif
410 }
411 
412 _ELIDABLE_INLINE const char *
__locale_msgcharset(void)413 __locale_msgcharset (void)
414 {
415 #ifdef __HAVE_LOCALE_INFO__
416 #ifdef __HAVE_LOCALE_INFO_EXTENDED__
417   return (char *) __get_current_messages_locale ()->codeset;
418 #else
419   return (char *) __get_current_ctype_locale ()->codeset;
420 #endif
421 #else
422   return (char *) __get_current_locale()->message_codeset;
423 #endif
424 }
425 
426 _ELIDABLE_INLINE int
__locale_cjk_lang(void)427 __locale_cjk_lang (void)
428 {
429   return __get_current_locale()->cjk_lang;
430 }
431 
432 int __ctype_load_locale (struct __locale_t *, const char *, void *,
433 			 const char *, int);
434 int __monetary_load_locale (struct __locale_t *, const char *, void *,
435 			    const char *);
436 #ifdef __CYGWIN__
437 int __numeric_load_locale (struct __locale_t *, const char *, void *,
438 			   const char *);
439 int __time_load_locale (struct __locale_t *, const char *, void *,
440 			const char *);
441 #endif
442 int __messages_load_locale (struct __locale_t *, const char *, void *,
443 			    const char *);
444 #ifdef __CYGWIN__
445 int __collate_load_locale (struct __locale_t *, const char *, void *,
446 			   const char *);
447 
448 extern void __set_charset_from_locale (const char *locale, char *charset);
449 extern char *__set_locale_from_locale_alias (const char *, char *);
450 #endif
451 
452 __END_DECLS
453 
454 #endif /* !_SETLOCALE_H_ */
455