summaryrefslogtreecommitdiffstats
path: root/gl/nl_langinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/nl_langinfo.c')
-rw-r--r--gl/nl_langinfo.c138
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
164static char * 166static char *
@@ -205,10 +207,9 @@ static char *
205nl_langinfo_with_lock (nl_item item) 207nl_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 *
266nl_langinfo_with_lock (nl_item item) 266nl_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: