OSDN Git Service

* Makefile.am (check-DEJAGNU): New target.
[pf3gnuchains/pf3gnuchains3x.git] / newlib / libc / locale / locale.c
1 /*
2 FUNCTION
3 <<setlocale>>, <<localeconv>>---select or query locale
4
5 INDEX
6         setlocale
7 INDEX
8         localeconv
9 INDEX
10         _setlocale_r
11 INDEX
12         _localeconv_r
13
14 ANSI_SYNOPSIS
15         #include <locale.h>
16         char *setlocale(int <[category]>, const char *<[locale]>);
17         lconv *localeconv(void);
18
19         char *_setlocale_r(void *<[reent]>,
20                         int <[category]>, const char *<[locale]>);
21         lconv *_localeconv_r(void *<[reent]>);
22
23 TRAD_SYNOPSIS
24         #include <locale.h>
25         char *setlocale(<[category]>, <[locale]>)
26         int <[category]>;
27         char *<[locale]>;
28
29         lconv *localeconv();
30
31         char *_setlocale_r(<[reent]>, <[category]>, <[locale]>)
32         char *<[reent]>;
33         int <[category]>;
34         char *<[locale]>;
35
36         lconv *_localeconv_r(<[reent]>);
37         char *<[reent]>;
38
39 DESCRIPTION
40 <<setlocale>> is the facility defined by ANSI C to condition the
41 execution environment for international collating and formatting
42 information; <<localeconv>> reports on the settings of the current
43 locale.
44
45 This is a minimal implementation, supporting only the required <<``C''>>
46 value for <[locale]>; strings representing other locales are not
47 honored unless MB_CAPABLE is defined in which case three new
48 extensions are allowed for LC_CTYPE only: <<''C-JIS''>>, <<''C-EUCJP''>>,
49 and <<''C-SJIS''>>.  (<<``''>> is also accepted; it represents the default locale
50 for an implementation, here equivalent to <<``C''>>.)
51
52 If you use <<NULL>> as the <[locale]> argument, <<setlocale>> returns
53 a pointer to the string representing the current locale (always
54 <<``C''>> in this implementation).  The acceptable values for
55 <[category]> are defined in `<<locale.h>>' as macros beginning with
56 <<"LC_">>, but this implementation does not check the values you pass
57 in the <[category]> argument.
58
59 <<localeconv>> returns a pointer to a structure (also defined in
60 `<<locale.h>>') describing the locale-specific conventions currently
61 in effect.  
62
63 <<_localeconv_r>> and <<_setlocale_r>> are reentrant versions of
64 <<localeconv>> and <<setlocale>> respectively.  The extra argument
65 <[reent]> is a pointer to a reentrancy structure.
66
67 RETURNS
68 <<setlocale>> returns either a pointer to a string naming the locale
69 currently in effect (always <<``C''>> for this implementation, or, if
70 the locale request cannot be honored, <<NULL>>.
71
72 <<localeconv>> returns a pointer to a structure of type <<lconv>>,
73 which describes the formatting and collating conventions in effect (in
74 this implementation, always those of the C locale).
75
76 PORTABILITY
77 ANSI C requires <<setlocale>>, but the only locale required across all
78 implementations is the C locale.
79
80 No supporting OS subroutines are required.
81 */
82
83 /*
84  * setlocale, localeconv : internationalize your locale.
85  *                         (Only "C" or null supported).
86  */
87
88 #include <locale.h>
89 #include <string.h>
90 #include <limits.h>
91 #include <reent.h>
92
93 #ifdef __CYGWIN__
94 int __declspec(dllexport) __mb_cur_max = 1;
95 #else
96 int __mb_cur_max = 1;
97 #endif
98
99 static _CONST struct lconv lconv = 
100 {
101   ".", "", "", "", "", "", "", "", "", "",
102   CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
103   CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
104 };
105
106
107 char *
108 _DEFUN(_setlocale_r, (p, category, locale),
109        struct _reent *p _AND
110        int category _AND
111        _CONST char *locale)
112 {
113 #ifndef MB_CAPABLE
114   if (locale)
115     { 
116       if (strcmp (locale, "C") && strcmp (locale, ""))
117         return 0;
118       p->_current_category = category;  
119       p->_current_locale = locale;
120     }
121   return "C";
122 #else
123   static char lc_ctype[8] = "C";
124   static char last_lc_ctype[8] = "C";
125
126   if (locale)
127     {
128       if (category != LC_CTYPE) 
129         { 
130           if (strcmp (locale, "C") && strcmp (locale, ""))
131             return 0;
132           if (category == LC_ALL)
133             {
134               strcpy (last_lc_ctype, lc_ctype);
135               strcpy (lc_ctype, locale);
136               __mb_cur_max = 1;
137             }
138         }
139       else
140         { 
141           if (strcmp (locale, "C") && strcmp (locale, "") &&
142               strcmp (locale, "C") && strcmp (locale, "C-JIS") && 
143               strcmp (locale, "C-EUCJP") && strcmp (locale, "C-SJIS") &&
144               strcmp (locale, "UTF-8"))
145             return 0;
146
147           strcpy (last_lc_ctype, lc_ctype);
148           strcpy (lc_ctype, locale);
149
150           if (!strcmp (locale, "UTF-8"))
151             __mb_cur_max = 6;
152           else if (!strcmp (locale, "C-JIS"))
153             __mb_cur_max = 8;
154           else if (strlen (locale) > 1)
155             __mb_cur_max = 2;
156           else
157             __mb_cur_max = 1; 
158         }
159       p->_current_category = category;  
160       p->_current_locale = locale;
161
162       if (category == LC_CTYPE)
163         return last_lc_ctype;
164     }
165   else
166     {
167       if (category == LC_CTYPE)
168         return lc_ctype;
169     }
170  
171   return "C";
172 #endif
173   
174 }
175
176
177 struct lconv *
178 _DEFUN(_localeconv_r, (data), 
179       struct _reent *data)
180 {
181   return (struct lconv *) &lconv;
182 }
183
184 #ifndef _REENT_ONLY
185
186 char *
187 _DEFUN(setlocale, (category, locale),
188        int category _AND
189        _CONST char *locale)
190 {
191   return _setlocale_r (_REENT, category, locale);
192 }
193
194
195 struct lconv *
196 _DEFUN_VOID(localeconv)
197 {
198   return _localeconv_r (_REENT);
199 }
200
201 #endif