a3d0d11eb3d233648938b842b3700ace621067ce
[dragonfly.git] / contrib / grep / lib / nl_langinfo.c
1 /* nl_langinfo() replacement: query locale dependent information.
2
3    Copyright (C) 2007-2010 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU 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 General Public License for more details.
14
15    You should have received a copy of the GNU 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
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         /* Woe32 has a function returning the locale's codepage as a number.  */
145         sprintf (buf, "CP%u", GetACP ());
146         return buf;
147       }
148 # elif defined __BEOS__
149       return "UTF-8";
150 # else
151       return "ISO-8859-1";
152 # endif
153     /* nl_langinfo items of the LC_NUMERIC category */
154     case RADIXCHAR:
155       return localeconv () ->decimal_point;
156     case THOUSEP:
157       return localeconv () ->thousands_sep;
158     /* nl_langinfo items of the LC_TIME category.
159        TODO: Really use the locale.  */
160     case D_T_FMT:
161     case ERA_D_T_FMT:
162       return "%a %b %e %H:%M:%S %Y";
163     case D_FMT:
164     case ERA_D_FMT:
165       return "%m/%d/%y";
166     case T_FMT:
167     case ERA_T_FMT:
168       return "%H:%M:%S";
169     case T_FMT_AMPM:
170       return "%I:%M:%S %p";
171     case AM_STR:
172       return "AM";
173     case PM_STR:
174       return "PM";
175     case DAY_1:
176       return "Sunday";
177     case DAY_2:
178       return "Monday";
179     case DAY_3:
180       return "Tuesday";
181     case DAY_4:
182       return "Wednesday";
183     case DAY_5:
184       return "Thursday";
185     case DAY_6:
186       return "Friday";
187     case DAY_7:
188       return "Saturday";
189     case ABDAY_1:
190       return "Sun";
191     case ABDAY_2:
192       return "Mon";
193     case ABDAY_3:
194       return "Tue";
195     case ABDAY_4:
196       return "Wed";
197     case ABDAY_5:
198       return "Thu";
199     case ABDAY_6:
200       return "Fri";
201     case ABDAY_7:
202       return "Sat";
203     case MON_1:
204       return "January";
205     case MON_2:
206       return "February";
207     case MON_3:
208       return "March";
209     case MON_4:
210       return "April";
211     case MON_5:
212       return "May";
213     case MON_6:
214       return "June";
215     case MON_7:
216       return "July";
217     case MON_8:
218       return "August";
219     case MON_9:
220       return "September";
221     case MON_10:
222       return "October";
223     case MON_11:
224       return "November";
225     case MON_12:
226       return "December";
227     case ABMON_1:
228       return "Jan";
229     case ABMON_2:
230       return "Feb";
231     case ABMON_3:
232       return "Mar";
233     case ABMON_4:
234       return "Apr";
235     case ABMON_5:
236       return "May";
237     case ABMON_6:
238       return "Jun";
239     case ABMON_7:
240       return "Jul";
241     case ABMON_8:
242       return "Aug";
243     case ABMON_9:
244       return "Sep";
245     case ABMON_10:
246       return "Oct";
247     case ABMON_11:
248       return "Nov";
249     case ABMON_12:
250       return "Dec";
251     case ERA:
252       return "";
253     case ALT_DIGITS:
254       return "\0\0\0\0\0\0\0\0\0\0";
255     /* nl_langinfo items of the LC_MONETARY category
256        TODO: Really use the locale. */
257     case CRNCYSTR:
258       return "-";
259     /* nl_langinfo items of the LC_MESSAGES category
260        TODO: Really use the locale. */
261     case YESEXPR:
262       return "^[yY]";
263     case NOEXPR:
264       return "^[nN]";
265     default:
266       return "";
267     }
268 }
269
270 #endif