Commit | Line | Data |
---|---|---|
eb4a14ed LC |
1 | /* nl_langinfo() replacement: query locale dependent information. |
2 | ||
5e69ceb7 | 3 | Copyright (C) 2007-2014 Free Software Foundation, Inc. |
eb4a14ed LC |
4 | |
5 | This program is free software: you can redistribute it and/or modify | |
6 | it under the terms of the GNU Lesser General Public License as published by | |
7 | the Free Software Foundation; either version 3 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public License | |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
17 | ||
18 | #include <config.h> | |
19 | ||
20 | /* Specification. */ | |
21 | #include <langinfo.h> | |
22 | ||
23 | #if REPLACE_NL_LANGINFO | |
24 | ||
25 | /* Override nl_langinfo with support for added nl_item values. */ | |
26 | ||
27 | # include <locale.h> | |
28 | # include <string.h> | |
29 | ||
30 | # undef nl_langinfo | |
31 | ||
32 | char * | |
33 | rpl_nl_langinfo (nl_item item) | |
34 | { | |
35 | switch (item) | |
36 | { | |
37 | # if GNULIB_defined_CODESET | |
38 | case CODESET: | |
39 | { | |
40 | const char *locale; | |
41 | static char buf[2 + 10 + 1]; | |
42 | ||
43 | locale = setlocale (LC_CTYPE, NULL); | |
44 | if (locale != NULL && locale[0] != '\0') | |
45 | { | |
46 | /* If the locale name contains an encoding after the dot, return | |
47 | it. */ | |
48 | const char *dot = strchr (locale, '.'); | |
49 | ||
50 | if (dot != NULL) | |
51 | { | |
52 | const char *modifier; | |
53 | ||
54 | dot++; | |
55 | /* Look for the possible @... trailer and remove it, if any. */ | |
56 | modifier = strchr (dot, '@'); | |
57 | if (modifier == NULL) | |
58 | return dot; | |
59 | if (modifier - dot < sizeof (buf)) | |
60 | { | |
61 | memcpy (buf, dot, modifier - dot); | |
62 | buf [modifier - dot] = '\0'; | |
63 | return buf; | |
64 | } | |
65 | } | |
66 | } | |
67 | return ""; | |
68 | } | |
69 | # endif | |
70 | # if GNULIB_defined_T_FMT_AMPM | |
71 | case T_FMT_AMPM: | |
72 | return "%I:%M:%S %p"; | |
73 | # endif | |
74 | # if GNULIB_defined_ERA | |
75 | case ERA: | |
76 | /* The format is not standardized. In glibc it is a sequence of strings | |
77 | of the form "direction:offset:start_date:end_date:era_name:era_format" | |
78 | with an empty string at the end. */ | |
79 | return ""; | |
80 | case ERA_D_FMT: | |
81 | /* The %Ex conversion in strftime behaves like %x if the locale does not | |
82 | have an alternative time format. */ | |
83 | item = D_FMT; | |
84 | break; | |
85 | case ERA_D_T_FMT: | |
86 | /* The %Ec conversion in strftime behaves like %c if the locale does not | |
87 | have an alternative time format. */ | |
88 | item = D_T_FMT; | |
89 | break; | |
90 | case ERA_T_FMT: | |
91 | /* The %EX conversion in strftime behaves like %X if the locale does not | |
92 | have an alternative time format. */ | |
93 | item = T_FMT; | |
94 | break; | |
95 | case ALT_DIGITS: | |
96 | /* The format is not standardized. In glibc it is a sequence of 10 | |
97 | strings, appended in memory. */ | |
98 | return "\0\0\0\0\0\0\0\0\0\0"; | |
99 | # endif | |
100 | # if GNULIB_defined_YESEXPR || !FUNC_NL_LANGINFO_YESEXPR_WORKS | |
101 | case YESEXPR: | |
102 | return "^[yY]"; | |
103 | case NOEXPR: | |
104 | return "^[nN]"; | |
105 | # endif | |
106 | default: | |
107 | break; | |
108 | } | |
109 | return nl_langinfo (item); | |
110 | } | |
111 | ||
112 | #else | |
113 | ||
114 | /* Provide nl_langinfo from scratch. */ | |
115 | ||
116 | # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | |
117 | ||
118 | /* Native Windows platforms. */ | |
119 | ||
120 | # define WIN32_LEAN_AND_MEAN /* avoid including junk */ | |
121 | # include <windows.h> | |
122 | ||
123 | # include <stdio.h> | |
124 | ||
125 | # else | |
126 | ||
127 | /* An old Unix platform without locales, such as Linux libc5 or BeOS. */ | |
128 | ||
129 | # endif | |
130 | ||
131 | # include <locale.h> | |
132 | ||
133 | char * | |
134 | nl_langinfo (nl_item item) | |
135 | { | |
136 | switch (item) | |
137 | { | |
138 | /* nl_langinfo items of the LC_CTYPE category */ | |
139 | case CODESET: | |
140 | # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | |
141 | { | |
142 | static char buf[2 + 10 + 1]; | |
143 | ||
144 | /* The Windows API has a function returning the locale's codepage as | |
145 | a number. */ | |
146 | sprintf (buf, "CP%u", GetACP ()); | |
147 | return buf; | |
148 | } | |
149 | # elif defined __BEOS__ | |
150 | return "UTF-8"; | |
151 | # else | |
152 | return "ISO-8859-1"; | |
153 | # endif | |
154 | /* nl_langinfo items of the LC_NUMERIC category */ | |
155 | case RADIXCHAR: | |
156 | return localeconv () ->decimal_point; | |
157 | case THOUSEP: | |
158 | return localeconv () ->thousands_sep; | |
159 | /* nl_langinfo items of the LC_TIME category. | |
160 | TODO: Really use the locale. */ | |
161 | case D_T_FMT: | |
162 | case ERA_D_T_FMT: | |
163 | return "%a %b %e %H:%M:%S %Y"; | |
164 | case D_FMT: | |
165 | case ERA_D_FMT: | |
166 | return "%m/%d/%y"; | |
167 | case T_FMT: | |
168 | case ERA_T_FMT: | |
169 | return "%H:%M:%S"; | |
170 | case T_FMT_AMPM: | |
171 | return "%I:%M:%S %p"; | |
172 | case AM_STR: | |
173 | return "AM"; | |
174 | case PM_STR: | |
175 | return "PM"; | |
176 | case DAY_1: | |
177 | return "Sunday"; | |
178 | case DAY_2: | |
179 | return "Monday"; | |
180 | case DAY_3: | |
181 | return "Tuesday"; | |
182 | case DAY_4: | |
183 | return "Wednesday"; | |
184 | case DAY_5: | |
185 | return "Thursday"; | |
186 | case DAY_6: | |
187 | return "Friday"; | |
188 | case DAY_7: | |
189 | return "Saturday"; | |
190 | case ABDAY_1: | |
191 | return "Sun"; | |
192 | case ABDAY_2: | |
193 | return "Mon"; | |
194 | case ABDAY_3: | |
195 | return "Tue"; | |
196 | case ABDAY_4: | |
197 | return "Wed"; | |
198 | case ABDAY_5: | |
199 | return "Thu"; | |
200 | case ABDAY_6: | |
201 | return "Fri"; | |
202 | case ABDAY_7: | |
203 | return "Sat"; | |
204 | case MON_1: | |
205 | return "January"; | |
206 | case MON_2: | |
207 | return "February"; | |
208 | case MON_3: | |
209 | return "March"; | |
210 | case MON_4: | |
211 | return "April"; | |
212 | case MON_5: | |
213 | return "May"; | |
214 | case MON_6: | |
215 | return "June"; | |
216 | case MON_7: | |
217 | return "July"; | |
218 | case MON_8: | |
219 | return "August"; | |
220 | case MON_9: | |
221 | return "September"; | |
222 | case MON_10: | |
223 | return "October"; | |
224 | case MON_11: | |
225 | return "November"; | |
226 | case MON_12: | |
227 | return "December"; | |
228 | case ABMON_1: | |
229 | return "Jan"; | |
230 | case ABMON_2: | |
231 | return "Feb"; | |
232 | case ABMON_3: | |
233 | return "Mar"; | |
234 | case ABMON_4: | |
235 | return "Apr"; | |
236 | case ABMON_5: | |
237 | return "May"; | |
238 | case ABMON_6: | |
239 | return "Jun"; | |
240 | case ABMON_7: | |
241 | return "Jul"; | |
242 | case ABMON_8: | |
243 | return "Aug"; | |
244 | case ABMON_9: | |
245 | return "Sep"; | |
246 | case ABMON_10: | |
247 | return "Oct"; | |
248 | case ABMON_11: | |
249 | return "Nov"; | |
250 | case ABMON_12: | |
251 | return "Dec"; | |
252 | case ERA: | |
253 | return ""; | |
254 | case ALT_DIGITS: | |
255 | return "\0\0\0\0\0\0\0\0\0\0"; | |
256 | /* nl_langinfo items of the LC_MONETARY category | |
257 | TODO: Really use the locale. */ | |
258 | case CRNCYSTR: | |
259 | return "-"; | |
260 | /* nl_langinfo items of the LC_MESSAGES category | |
261 | TODO: Really use the locale. */ | |
262 | case YESEXPR: | |
263 | return "^[yY]"; | |
264 | case NOEXPR: | |
265 | return "^[nN]"; | |
266 | default: | |
267 | return ""; | |
268 | } | |
269 | } | |
270 | ||
271 | #endif |