Upgrade grep from 2.14 => 2.20 on the vendor branch
[dragonfly.git] / contrib / grep / lib / nl_langinfo.c
1 /* nl_langinfo() replacement: query locale dependent information.
2
3    Copyright (C) 2007-2014 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 || !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