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 32char * 33rpl_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 133char * 134nl_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 272