| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/nl_langinfo.c |
| Source code | Switch to Preprocessed file |
| Line | Source | Count |
|---|---|---|
| 1 | /* nl_langinfo() replacement: query locale dependent information. | - |
| 2 | - | |
| 3 | Copyright (C) 2007-2018 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 <https://www.gnu.org/licenses/>. */ | - |
| 17 | - | |
| 18 | #include <config.h> | - |
| 19 | - | |
| 20 | /* Specification. */ | - |
| 21 | #include <langinfo.h> | - |
| 22 | - | |
| 23 | #include <locale.h> | - |
| 24 | #include <string.h> | - |
| 25 | #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | - |
| 26 | # define WIN32_LEAN_AND_MEAN /* avoid including junk */ | - |
| 27 | # include <windows.h> | - |
| 28 | # include <stdio.h> | - |
| 29 | #endif | - |
| 30 | - | |
| 31 | #if !REPLACE_NL_LANGINFO || GNULIB_defined_CODESET | - |
| 32 | /* Return the codeset of the current locale, if this is easily deducible. | - |
| 33 | Otherwise, return "". */ | - |
| 34 | static char * | - |
| 35 | ctype_codeset (void) | - |
| 36 | { | - |
| 37 | static char buf[2 + 10 + 1]; | - |
| 38 | char const *locale = setlocale (LC_CTYPE, NULL); | - |
| 39 | char *codeset = buf; | - |
| 40 | size_t codesetlen; | - |
| 41 | codeset[0] = '\0'; | - |
| 42 | - | |
| 43 | if (locale && locale[0]) | - |
| 44 | { | - |
| 45 | /* If the locale name contains an encoding after the dot, return it. */ | - |
| 46 | char *dot = strchr (locale, '.'); | - |
| 47 | - | |
| 48 | if (dot) | - |
| 49 | { | - |
| 50 | /* Look for the possible @... trailer and remove it, if any. */ | - |
| 51 | char *codeset_start = dot + 1; | - |
| 52 | char const *modifier = strchr (codeset_start, '@'); | - |
| 53 | - | |
| 54 | if (! modifier) | - |
| 55 | codeset = codeset_start; | - |
| 56 | else | - |
| 57 | { | - |
| 58 | codesetlen = modifier - codeset_start; | - |
| 59 | if (codesetlen < sizeof buf) | - |
| 60 | { | - |
| 61 | codeset = memcpy (buf, codeset_start, codesetlen); | - |
| 62 | codeset[codesetlen] = '\0'; | - |
| 63 | } | - |
| 64 | } | - |
| 65 | } | - |
| 66 | } | - |
| 67 | - | |
| 68 | # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | - |
| 69 | /* If setlocale is successful, it returns the number of the | - |
| 70 | codepage, as a string. Otherwise, fall back on Windows API | - |
| 71 | GetACP, which returns the locale's codepage as a number (although | - |
| 72 | this doesn't change according to what the 'setlocale' call specified). | - |
| 73 | Either way, prepend "CP" to make it a valid codeset name. */ | - |
| 74 | codesetlen = strlen (codeset); | - |
| 75 | if (0 < codesetlen && codesetlen < sizeof buf - 2) | - |
| 76 | memmove (buf + 2, codeset, codesetlen + 1); | - |
| 77 | else | - |
| 78 | sprintf (buf + 2, "%u", GetACP ()); | - |
| 79 | codeset = memcpy (buf, "CP", 2); | - |
| 80 | # endif | - |
| 81 | return codeset; | - |
| 82 | } | - |
| 83 | #endif | - |
| 84 | - | |
| 85 | - | |
| 86 | #if REPLACE_NL_LANGINFO | - |
| 87 | - | |
| 88 | /* Override nl_langinfo with support for added nl_item values. */ | - |
| 89 | - | |
| 90 | # undef nl_langinfo | - |
| 91 | - | |
| 92 | char * | - |
| 93 | rpl_nl_langinfo (nl_item item) | - |
| 94 | { | - |
| 95 | switch (item) | - |
| 96 | { | - |
| 97 | # if GNULIB_defined_CODESET | - |
| 98 | case CODESET: | - |
| 99 | return ctype_codeset (); | - |
| 100 | # endif | - |
| 101 | # if GNULIB_defined_T_FMT_AMPM | - |
| 102 | case T_FMT_AMPM: | - |
| 103 | return (char *) "%I:%M:%S %p"; | - |
| 104 | # endif | - |
| 105 | # if GNULIB_defined_ALTMON | - |
| 106 | case ALTMON_1: never executed: case 10200 : | 0 |
| 107 | case ALTMON_2: never executed: case (10200 + 1) : | 0 |
| 108 | case ALTMON_3: never executed: case (10200 + 2) : | 0 |
| 109 | case ALTMON_4: never executed: case (10200 + 3) : | 0 |
| 110 | case ALTMON_5: never executed: case (10200 + 4) : | 0 |
| 111 | case ALTMON_6: never executed: case (10200 + 5) : | 0 |
| 112 | case ALTMON_7: never executed: case (10200 + 6) : | 0 |
| 113 | case ALTMON_8: never executed: case (10200 + 7) : | 0 |
| 114 | case ALTMON_9: never executed: case (10200 + 8) : | 0 |
| 115 | case ALTMON_10: never executed: case (10200 + 9) : | 0 |
| 116 | case ALTMON_11: never executed: case (10200 + 10) : | 0 |
| 117 | case ALTMON_12: never executed: case (10200 + 11) : | 0 |
| 118 | /* We don't ship the appropriate localizations with gnulib. Therefore, | - |
| 119 | treat ALTMON_i like MON_i. */ | - |
| 120 | item = item - ALTMON_1 + MON_1; | - |
| 121 | break; never executed: break; | 0 |
| 122 | # endif | - |
| 123 | # if GNULIB_defined_ERA | - |
| 124 | case ERA: | - |
| 125 | /* The format is not standardized. In glibc it is a sequence of strings | - |
| 126 | of the form "direction:offset:start_date:end_date:era_name:era_format" | - |
| 127 | with an empty string at the end. */ | - |
| 128 | return (char *) ""; | - |
| 129 | case ERA_D_FMT: | - |
| 130 | /* The %Ex conversion in strftime behaves like %x if the locale does not | - |
| 131 | have an alternative time format. */ | - |
| 132 | item = D_FMT; | - |
| 133 | break; | - |
| 134 | case ERA_D_T_FMT: | - |
| 135 | /* The %Ec conversion in strftime behaves like %c if the locale does not | - |
| 136 | have an alternative time format. */ | - |
| 137 | item = D_T_FMT; | - |
| 138 | break; | - |
| 139 | case ERA_T_FMT: | - |
| 140 | /* The %EX conversion in strftime behaves like %X if the locale does not | - |
| 141 | have an alternative time format. */ | - |
| 142 | item = T_FMT; | - |
| 143 | break; | - |
| 144 | case ALT_DIGITS: | - |
| 145 | /* The format is not standardized. In glibc it is a sequence of 10 | - |
| 146 | strings, appended in memory. */ | - |
| 147 | return (char *) "\0\0\0\0\0\0\0\0\0\0"; | - |
| 148 | # endif | - |
| 149 | # if GNULIB_defined_YESEXPR || !FUNC_NL_LANGINFO_YESEXPR_WORKS | - |
| 150 | case YESEXPR: | - |
| 151 | return (char *) "^[yY]"; | - |
| 152 | case NOEXPR: | - |
| 153 | return (char *) "^[nN]"; | - |
| 154 | # endif | - |
| 155 | default: executed 5506 times by 58 tests: default:Executed by:
| 5506 |
| 156 | break; executed 5506 times by 58 tests: break;Executed by:
| 5506 |
| 157 | } | - |
| 158 | return nl_langinfo (item); executed 5506 times by 58 tests: return nl_langinfo (item);Executed by:
| 5506 |
| 159 | } | - |
| 160 | - | |
| 161 | #else | - |
| 162 | - | |
| 163 | /* Provide nl_langinfo from scratch, either for native MS-Windows, or | - |
| 164 | for old Unix platforms without locales, such as Linux libc5 or | - |
| 165 | BeOS. */ | - |
| 166 | - | |
| 167 | # include <time.h> | - |
| 168 | - | |
| 169 | char * | - |
| 170 | nl_langinfo (nl_item item) | - |
| 171 | { | - |
| 172 | static char nlbuf[100]; | - |
| 173 | struct tm tmm = { 0 }; | - |
| 174 | - | |
| 175 | switch (item) | - |
| 176 | { | - |
| 177 | /* nl_langinfo items of the LC_CTYPE category */ | - |
| 178 | case CODESET: | - |
| 179 | { | - |
| 180 | char *codeset = ctype_codeset (); | - |
| 181 | if (*codeset) | - |
| 182 | return codeset; | - |
| 183 | } | - |
| 184 | # ifdef __BEOS__ | - |
| 185 | return (char *) "UTF-8"; | - |
| 186 | # else | - |
| 187 | return (char *) "ISO-8859-1"; | - |
| 188 | # endif | - |
| 189 | /* nl_langinfo items of the LC_NUMERIC category */ | - |
| 190 | case RADIXCHAR: | - |
| 191 | return localeconv () ->decimal_point; | - |
| 192 | case THOUSEP: | - |
| 193 | return localeconv () ->thousands_sep; | - |
| 194 | case GROUPING: | - |
| 195 | return localeconv () ->grouping; | - |
| 196 | /* nl_langinfo items of the LC_TIME category. | - |
| 197 | TODO: Really use the locale. */ | - |
| 198 | case D_T_FMT: | - |
| 199 | case ERA_D_T_FMT: | - |
| 200 | return (char *) "%a %b %e %H:%M:%S %Y"; | - |
| 201 | case D_FMT: | - |
| 202 | case ERA_D_FMT: | - |
| 203 | return (char *) "%m/%d/%y"; | - |
| 204 | case T_FMT: | - |
| 205 | case ERA_T_FMT: | - |
| 206 | return (char *) "%H:%M:%S"; | - |
| 207 | case T_FMT_AMPM: | - |
| 208 | return (char *) "%I:%M:%S %p"; | - |
| 209 | case AM_STR: | - |
| 210 | if (!strftime (nlbuf, sizeof nlbuf, "%p", &tmm)) | - |
| 211 | return (char *) "AM"; | - |
| 212 | return nlbuf; | - |
| 213 | case PM_STR: | - |
| 214 | tmm.tm_hour = 12; | - |
| 215 | if (!strftime (nlbuf, sizeof nlbuf, "%p", &tmm)) | - |
| 216 | return (char *) "PM"; | - |
| 217 | return nlbuf; | - |
| 218 | case DAY_1: | - |
| 219 | case DAY_2: | - |
| 220 | case DAY_3: | - |
| 221 | case DAY_4: | - |
| 222 | case DAY_5: | - |
| 223 | case DAY_6: | - |
| 224 | case DAY_7: | - |
| 225 | { | - |
| 226 | static char const days[][sizeof "Wednesday"] = { | - |
| 227 | "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", | - |
| 228 | "Friday", "Saturday" | - |
| 229 | }; | - |
| 230 | tmm.tm_wday = item - DAY_1; | - |
| 231 | if (!strftime (nlbuf, sizeof nlbuf, "%A", &tmm)) | - |
| 232 | return (char *) days[item - DAY_1]; | - |
| 233 | return nlbuf; | - |
| 234 | } | - |
| 235 | case ABDAY_1: | - |
| 236 | case ABDAY_2: | - |
| 237 | case ABDAY_3: | - |
| 238 | case ABDAY_4: | - |
| 239 | case ABDAY_5: | - |
| 240 | case ABDAY_6: | - |
| 241 | case ABDAY_7: | - |
| 242 | { | - |
| 243 | static char const abdays[][sizeof "Sun"] = { | - |
| 244 | "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" | - |
| 245 | }; | - |
| 246 | tmm.tm_wday = item - ABDAY_1; | - |
| 247 | if (!strftime (nlbuf, sizeof nlbuf, "%a", &tmm)) | - |
| 248 | return (char *) abdays[item - ABDAY_1]; | - |
| 249 | return nlbuf; | - |
| 250 | } | - |
| 251 | { | - |
| 252 | static char const months[][sizeof "September"] = { | - |
| 253 | "January", "February", "March", "April", "May", "June", "July", | - |
| 254 | "September", "October", "November", "December" | - |
| 255 | }; | - |
| 256 | case MON_1: | - |
| 257 | case MON_2: | - |
| 258 | case MON_3: | - |
| 259 | case MON_4: | - |
| 260 | case MON_5: | - |
| 261 | case MON_6: | - |
| 262 | case MON_7: | - |
| 263 | case MON_8: | - |
| 264 | case MON_9: | - |
| 265 | case MON_10: | - |
| 266 | case MON_11: | - |
| 267 | case MON_12: | - |
| 268 | tmm.tm_mon = item - MON_1; | - |
| 269 | if (!strftime (nlbuf, sizeof nlbuf, "%B", &tmm)) | - |
| 270 | return (char *) months[item - MON_1]; | - |
| 271 | return nlbuf; | - |
| 272 | case ALTMON_1: | - |
| 273 | case ALTMON_2: | - |
| 274 | case ALTMON_3: | - |
| 275 | case ALTMON_4: | - |
| 276 | case ALTMON_5: | - |
| 277 | case ALTMON_6: | - |
| 278 | case ALTMON_7: | - |
| 279 | case ALTMON_8: | - |
| 280 | case ALTMON_9: | - |
| 281 | case ALTMON_10: | - |
| 282 | case ALTMON_11: | - |
| 283 | case ALTMON_12: | - |
| 284 | tmm.tm_mon = item - ALTMON_1; | - |
| 285 | /* The platforms without nl_langinfo() don't support strftime with %OB. | - |
| 286 | We don't even need to try. */ | - |
| 287 | #if 0 | - |
| 288 | if (!strftime (nlbuf, sizeof nlbuf, "%OB", &tmm)) | - |
| 289 | #endif | - |
| 290 | if (!strftime (nlbuf, sizeof nlbuf, "%B", &tmm)) | - |
| 291 | return (char *) months[item - ALTMON_1]; | - |
| 292 | return nlbuf; | - |
| 293 | } | - |
| 294 | case ABMON_1: | - |
| 295 | case ABMON_2: | - |
| 296 | case ABMON_3: | - |
| 297 | case ABMON_4: | - |
| 298 | case ABMON_5: | - |
| 299 | case ABMON_6: | - |
| 300 | case ABMON_7: | - |
| 301 | case ABMON_8: | - |
| 302 | case ABMON_9: | - |
| 303 | case ABMON_10: | - |
| 304 | case ABMON_11: | - |
| 305 | case ABMON_12: | - |
| 306 | { | - |
| 307 | static char const abmonths[][sizeof "Jan"] = { | - |
| 308 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", | - |
| 309 | "Sep", "Oct", "Nov", "Dec" | - |
| 310 | }; | - |
| 311 | tmm.tm_mon = item - ABMON_1; | - |
| 312 | if (!strftime (nlbuf, sizeof nlbuf, "%b", &tmm)) | - |
| 313 | return (char *) abmonths[item - ABMON_1]; | - |
| 314 | return nlbuf; | - |
| 315 | } | - |
| 316 | case ERA: | - |
| 317 | return (char *) ""; | - |
| 318 | case ALT_DIGITS: | - |
| 319 | return (char *) "\0\0\0\0\0\0\0\0\0\0"; | - |
| 320 | /* nl_langinfo items of the LC_MONETARY category. */ | - |
| 321 | case CRNCYSTR: | - |
| 322 | return localeconv () ->currency_symbol; | - |
| 323 | case INT_CURR_SYMBOL: | - |
| 324 | return localeconv () ->int_curr_symbol; | - |
| 325 | case MON_DECIMAL_POINT: | - |
| 326 | return localeconv () ->mon_decimal_point; | - |
| 327 | case MON_THOUSANDS_SEP: | - |
| 328 | return localeconv () ->mon_thousands_sep; | - |
| 329 | case MON_GROUPING: | - |
| 330 | return localeconv () ->mon_grouping; | - |
| 331 | case POSITIVE_SIGN: | - |
| 332 | return localeconv () ->positive_sign; | - |
| 333 | case NEGATIVE_SIGN: | - |
| 334 | return localeconv () ->negative_sign; | - |
| 335 | case FRAC_DIGITS: | - |
| 336 | return & localeconv () ->frac_digits; | - |
| 337 | case INT_FRAC_DIGITS: | - |
| 338 | return & localeconv () ->int_frac_digits; | - |
| 339 | case P_CS_PRECEDES: | - |
| 340 | return & localeconv () ->p_cs_precedes; | - |
| 341 | case N_CS_PRECEDES: | - |
| 342 | return & localeconv () ->n_cs_precedes; | - |
| 343 | case P_SEP_BY_SPACE: | - |
| 344 | return & localeconv () ->p_sep_by_space; | - |
| 345 | case N_SEP_BY_SPACE: | - |
| 346 | return & localeconv () ->n_sep_by_space; | - |
| 347 | case P_SIGN_POSN: | - |
| 348 | return & localeconv () ->p_sign_posn; | - |
| 349 | case N_SIGN_POSN: | - |
| 350 | return & localeconv () ->n_sign_posn; | - |
| 351 | /* nl_langinfo items of the LC_MESSAGES category | - |
| 352 | TODO: Really use the locale. */ | - |
| 353 | case YESEXPR: | - |
| 354 | return (char *) "^[yY]"; | - |
| 355 | case NOEXPR: | - |
| 356 | return (char *) "^[nN]"; | - |
| 357 | default: | - |
| 358 | return (char *) ""; | - |
| 359 | } | - |
| 360 | } | - |
| 361 | - | |
| 362 | #endif | - |
| Source code | Switch to Preprocessed file |