diff options
Diffstat (limited to 'gl/nl_langinfo.c')
| -rw-r--r-- | gl/nl_langinfo.c | 138 |
1 files changed, 86 insertions, 52 deletions
diff --git a/gl/nl_langinfo.c b/gl/nl_langinfo.c index 64ff93b0..ff8fd89e 100644 --- a/gl/nl_langinfo.c +++ b/gl/nl_langinfo.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* nl_langinfo() replacement: query locale dependent information. | 1 | /* nl_langinfo() replacement: query locale dependent information. |
| 2 | 2 | ||
| 3 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2007-2026 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -79,15 +79,13 @@ ctype_codeset (void) | |||
| 79 | /* This function is only used on platforms which don't have uselocale(). | 79 | /* This function is only used on platforms which don't have uselocale(). |
| 80 | Therefore we don't need to look at the per-thread locale first, here. */ | 80 | Therefore we don't need to look at the per-thread locale first, here. */ |
| 81 | static char result[2 + 10 + 1]; | 81 | static char result[2 + 10 + 1]; |
| 82 | char buf[2 + 10 + 1]; | ||
| 83 | char locale[SETLOCALE_NULL_MAX]; | ||
| 84 | char *codeset; | ||
| 85 | size_t codesetlen; | ||
| 86 | 82 | ||
| 83 | char locale[SETLOCALE_NULL_MAX]; | ||
| 87 | if (setlocale_null_r (LC_CTYPE, locale, sizeof (locale))) | 84 | if (setlocale_null_r (LC_CTYPE, locale, sizeof (locale))) |
| 88 | locale[0] = '\0'; | 85 | locale[0] = '\0'; |
| 89 | 86 | ||
| 90 | codeset = buf; | 87 | char buf[2 + 10 + 1]; |
| 88 | char *codeset = buf; | ||
| 91 | codeset[0] = '\0'; | 89 | codeset[0] = '\0'; |
| 92 | 90 | ||
| 93 | if (locale[0]) | 91 | if (locale[0]) |
| @@ -105,7 +103,7 @@ ctype_codeset (void) | |||
| 105 | codeset = codeset_start; | 103 | codeset = codeset_start; |
| 106 | else | 104 | else |
| 107 | { | 105 | { |
| 108 | codesetlen = modifier - codeset_start; | 106 | size_t codesetlen = modifier - codeset_start; |
| 109 | if (codesetlen < sizeof buf) | 107 | if (codesetlen < sizeof buf) |
| 110 | { | 108 | { |
| 111 | codeset = memcpy (buf, codeset_start, codesetlen); | 109 | codeset = memcpy (buf, codeset_start, codesetlen); |
| @@ -121,14 +119,14 @@ ctype_codeset (void) | |||
| 121 | GetACP, which returns the locale's codepage as a number (although | 119 | GetACP, which returns the locale's codepage as a number (although |
| 122 | this doesn't change according to what the 'setlocale' call specified). | 120 | this doesn't change according to what the 'setlocale' call specified). |
| 123 | Either way, prepend "CP" to make it a valid codeset name. */ | 121 | Either way, prepend "CP" to make it a valid codeset name. */ |
| 124 | codesetlen = strlen (codeset); | 122 | size_t codesetlen = strlen (codeset); |
| 125 | if (0 < codesetlen && codesetlen < sizeof buf - 2) | 123 | if (0 < codesetlen && codesetlen < sizeof buf - 2) |
| 126 | memmove (buf + 2, codeset, codesetlen + 1); | 124 | memmove (buf + 2, codeset, codesetlen + 1); |
| 127 | else | 125 | else |
| 128 | sprintf (buf + 2, "%u", GetACP ()); | 126 | sprintf (buf + 2, "%u", GetACP ()); |
| 129 | /* For a locale name such as "French_France.65001", in Windows 10, | 127 | /* For a locale name such as "French_France.65001", in Windows 10, |
| 130 | setlocale now returns "French_France.utf8" instead. */ | 128 | setlocale now returns "French_France.utf8" instead. */ |
| 131 | if (strcmp (buf + 2, "65001") == 0 || strcmp (buf + 2, "utf8") == 0) | 129 | if (streq (buf + 2, "65001") || streq (buf + 2, "utf8")) |
| 132 | return (char *) "UTF-8"; | 130 | return (char *) "UTF-8"; |
| 133 | else | 131 | else |
| 134 | { | 132 | { |
| @@ -154,11 +152,15 @@ ctype_codeset (void) | |||
| 154 | "thread5 disturbed by threadN!", even when threadN invokes only | 152 | "thread5 disturbed by threadN!", even when threadN invokes only |
| 155 | nl_langinfo (CODESET); | 153 | nl_langinfo (CODESET); |
| 156 | nl_langinfo (CRNCYSTR); | 154 | nl_langinfo (CRNCYSTR); |
| 157 | Similarly on Solaris 10. */ | 155 | Similarly on Solaris 10 and macOS 26. */ |
| 158 | 156 | ||
| 159 | # if !NL_LANGINFO_MTSAFE /* Solaris */ | 157 | # if !NL_LANGINFO_MTSAFE /* macOS, Solaris */ |
| 160 | 158 | ||
| 161 | # define ITEMS (MAXSTRMSG + 1) | 159 | # ifdef __sun /* Solaris */ |
| 160 | # define ITEMS (MAXSTRMSG + 1) | ||
| 161 | # else /* macOS */ | ||
| 162 | # define ITEMS (CRNCYSTR + 20) | ||
| 163 | # endif | ||
| 162 | # define MAX_RESULT_LEN 80 | 164 | # define MAX_RESULT_LEN 80 |
| 163 | 165 | ||
| 164 | static char * | 166 | static char * |
| @@ -205,10 +207,9 @@ static char * | |||
| 205 | nl_langinfo_with_lock (nl_item item) | 207 | nl_langinfo_with_lock (nl_item item) |
| 206 | { | 208 | { |
| 207 | CRITICAL_SECTION *lock = gl_get_nl_langinfo_lock (); | 209 | CRITICAL_SECTION *lock = gl_get_nl_langinfo_lock (); |
| 208 | char *ret; | ||
| 209 | 210 | ||
| 210 | EnterCriticalSection (lock); | 211 | EnterCriticalSection (lock); |
| 211 | ret = nl_langinfo_unlocked (item); | 212 | char *ret = nl_langinfo_unlocked (item); |
| 212 | LeaveCriticalSection (lock); | 213 | LeaveCriticalSection (lock); |
| 213 | 214 | ||
| 214 | return ret; | 215 | return ret; |
| @@ -244,11 +245,10 @@ nl_langinfo_with_lock (nl_item item) | |||
| 244 | if (pthread_in_use()) | 245 | if (pthread_in_use()) |
| 245 | { | 246 | { |
| 246 | pthread_mutex_t *lock = gl_get_nl_langinfo_lock (); | 247 | pthread_mutex_t *lock = gl_get_nl_langinfo_lock (); |
| 247 | char *ret; | ||
| 248 | 248 | ||
| 249 | if (pthread_mutex_lock (lock)) | 249 | if (pthread_mutex_lock (lock)) |
| 250 | abort (); | 250 | abort (); |
| 251 | ret = nl_langinfo_unlocked (item); | 251 | char *ret = nl_langinfo_unlocked (item); |
| 252 | if (pthread_mutex_unlock (lock)) | 252 | if (pthread_mutex_unlock (lock)) |
| 253 | abort (); | 253 | abort (); |
| 254 | 254 | ||
| @@ -266,11 +266,10 @@ static char * | |||
| 266 | nl_langinfo_with_lock (nl_item item) | 266 | nl_langinfo_with_lock (nl_item item) |
| 267 | { | 267 | { |
| 268 | mtx_t *lock = gl_get_nl_langinfo_lock (); | 268 | mtx_t *lock = gl_get_nl_langinfo_lock (); |
| 269 | char *ret; | ||
| 270 | 269 | ||
| 271 | if (mtx_lock (lock) != thrd_success) | 270 | if (mtx_lock (lock) != thrd_success) |
| 272 | abort (); | 271 | abort (); |
| 273 | ret = nl_langinfo_unlocked (item); | 272 | char *ret = nl_langinfo_unlocked (item); |
| 274 | if (mtx_unlock (lock) != thrd_success) | 273 | if (mtx_unlock (lock) != thrd_success) |
| 275 | abort (); | 274 | abort (); |
| 276 | 275 | ||
| @@ -295,10 +294,6 @@ rpl_nl_langinfo (nl_item item) | |||
| 295 | case CODESET: | 294 | case CODESET: |
| 296 | return ctype_codeset (); | 295 | return ctype_codeset (); |
| 297 | # endif | 296 | # endif |
| 298 | # if GNULIB_defined_T_FMT_AMPM | ||
| 299 | case T_FMT_AMPM: | ||
| 300 | return (char *) "%I:%M:%S %p"; | ||
| 301 | # endif | ||
| 302 | # if GNULIB_defined_ALTMON | 297 | # if GNULIB_defined_ALTMON |
| 303 | case ALTMON_1: | 298 | case ALTMON_1: |
| 304 | case ALTMON_2: | 299 | case ALTMON_2: |
| @@ -317,6 +312,24 @@ rpl_nl_langinfo (nl_item item) | |||
| 317 | item = item - ALTMON_1 + MON_1; | 312 | item = item - ALTMON_1 + MON_1; |
| 318 | break; | 313 | break; |
| 319 | # endif | 314 | # endif |
| 315 | # if GNULIB_defined_ABALTMON | ||
| 316 | case ABALTMON_1: | ||
| 317 | case ABALTMON_2: | ||
| 318 | case ABALTMON_3: | ||
| 319 | case ABALTMON_4: | ||
| 320 | case ABALTMON_5: | ||
| 321 | case ABALTMON_6: | ||
| 322 | case ABALTMON_7: | ||
| 323 | case ABALTMON_8: | ||
| 324 | case ABALTMON_9: | ||
| 325 | case ABALTMON_10: | ||
| 326 | case ABALTMON_11: | ||
| 327 | case ABALTMON_12: | ||
| 328 | /* We don't ship the appropriate localizations with gnulib. Therefore, | ||
| 329 | treat ABALTMON_i like ABMON_i. */ | ||
| 330 | item = item - ABALTMON_1 + ABMON_1; | ||
| 331 | break; | ||
| 332 | # endif | ||
| 320 | # if GNULIB_defined_ERA | 333 | # if GNULIB_defined_ERA |
| 321 | case ERA: | 334 | case ERA: |
| 322 | /* The format is not standardized. In glibc it is a sequence of strings | 335 | /* The format is not standardized. In glibc it is a sequence of strings |
| @@ -343,12 +356,6 @@ rpl_nl_langinfo (nl_item item) | |||
| 343 | strings, appended in memory. */ | 356 | strings, appended in memory. */ |
| 344 | return (char *) "\0\0\0\0\0\0\0\0\0\0"; | 357 | return (char *) "\0\0\0\0\0\0\0\0\0\0"; |
| 345 | # endif | 358 | # endif |
| 346 | # if GNULIB_defined_YESEXPR || !FUNC_NL_LANGINFO_YESEXPR_WORKS | ||
| 347 | case YESEXPR: | ||
| 348 | return (char *) "^[yY]"; | ||
| 349 | case NOEXPR: | ||
| 350 | return (char *) "^[nN]"; | ||
| 351 | # endif | ||
| 352 | default: | 359 | default: |
| 353 | break; | 360 | break; |
| 354 | } | 361 | } |
| @@ -510,30 +517,57 @@ nl_langinfo (nl_item item) | |||
| 510 | return result[item - ALTMON_1]; | 517 | return result[item - ALTMON_1]; |
| 511 | } | 518 | } |
| 512 | } | 519 | } |
| 513 | case ABMON_1: | 520 | { |
| 514 | case ABMON_2: | 521 | static char const abmonths[][sizeof "Jan"] = { |
| 515 | case ABMON_3: | 522 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", |
| 516 | case ABMON_4: | 523 | "Aug", "Sep", "Oct", "Nov", "Dec" |
| 517 | case ABMON_5: | 524 | }; |
| 518 | case ABMON_6: | 525 | case ABMON_1: |
| 519 | case ABMON_7: | 526 | case ABMON_2: |
| 520 | case ABMON_8: | 527 | case ABMON_3: |
| 521 | case ABMON_9: | 528 | case ABMON_4: |
| 522 | case ABMON_10: | 529 | case ABMON_5: |
| 523 | case ABMON_11: | 530 | case ABMON_6: |
| 524 | case ABMON_12: | 531 | case ABMON_7: |
| 525 | { | 532 | case ABMON_8: |
| 526 | static char result[12][30]; | 533 | case ABMON_9: |
| 527 | static char const abmonths[][sizeof "Jan"] = { | 534 | case ABMON_10: |
| 528 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", | 535 | case ABMON_11: |
| 529 | "Aug", "Sep", "Oct", "Nov", "Dec" | 536 | case ABMON_12: |
| 530 | }; | 537 | { |
| 531 | tmm.tm_mon = item - ABMON_1; | 538 | static char result[12][30]; |
| 532 | if (!strftime (buf, sizeof result[0], "%b", &tmm)) | 539 | tmm.tm_mon = item - ABMON_1; |
| 533 | return (char *) abmonths[item - ABMON_1]; | 540 | if (!strftime (buf, sizeof result[0], "%b", &tmm)) |
| 534 | strcpy (result[item - ABMON_1], buf); | 541 | return (char *) abmonths[item - ABMON_1]; |
| 535 | return result[item - ABMON_1]; | 542 | strcpy (result[item - ABMON_1], buf); |
| 536 | } | 543 | return result[item - ABMON_1]; |
| 544 | } | ||
| 545 | case ABALTMON_1: | ||
| 546 | case ABALTMON_2: | ||
| 547 | case ABALTMON_3: | ||
| 548 | case ABALTMON_4: | ||
| 549 | case ABALTMON_5: | ||
| 550 | case ABALTMON_6: | ||
| 551 | case ABALTMON_7: | ||
| 552 | case ABALTMON_8: | ||
| 553 | case ABALTMON_9: | ||
| 554 | case ABALTMON_10: | ||
| 555 | case ABALTMON_11: | ||
| 556 | case ABALTMON_12: | ||
| 557 | { | ||
| 558 | static char result[12][50]; | ||
| 559 | tmm.tm_mon = item - ABALTMON_1; | ||
| 560 | /* The platforms without nl_langinfo() don't support strftime with | ||
| 561 | %Ob. We don't even need to try. */ | ||
| 562 | #if 0 | ||
| 563 | if (!strftime (buf, sizeof result[0], "%Ob", &tmm)) | ||
| 564 | #endif | ||
| 565 | if (!strftime (buf, sizeof result[0], "%b", &tmm)) | ||
| 566 | return (char *) abmonths[item - ABALTMON_1]; | ||
| 567 | strcpy (result[item - ABALTMON_1], buf); | ||
| 568 | return result[item - ABALTMON_1]; | ||
| 569 | } | ||
| 570 | } | ||
| 537 | case ERA: | 571 | case ERA: |
| 538 | return (char *) ""; | 572 | return (char *) ""; |
| 539 | case ALT_DIGITS: | 573 | case ALT_DIGITS: |
