diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2025-03-24 21:17:47 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2025-03-24 21:28:43 +0100 |
commit | e5a9f552ecf908f1639b08729edc191c66f4e7d0 (patch) | |
tree | d60c7d83f28e49348a9f7e0277182db8f6f7bddb /newlib | |
parent | e635174dd1f9cbdda5755c4a2703f0ca85215fa1 (diff) | |
download | newlib-e5a9f552ecf908f1639b08729edc191c66f4e7d0.zip newlib-e5a9f552ecf908f1639b08729edc191c66f4e7d0.tar.gz newlib-e5a9f552ecf908f1639b08729edc191c66f4e7d0.tar.bz2 |
locale: drop global_locale_string, add locale_string to locale_t
After 71511d4ac868 ("getlocalename_l: implement per SUS Base
Specifications Issue 8 draft") the Austin Group changed the definition
of getlocalename_l() to return setlocale-compatible strings if LC_ALL
has been specified. In contrast to the former definition which
disallowed LC_ALL as category.
In preparation, add a locale_string to every locale_t, and drop
the static global_locale_string.
This in turn requires to change currentlocale() to work locale-agnostic.
Rename to __currentlocale and take two parameters, the locale object
and a target string to store the locale string. The latter is required
to allow specifiying a target string not in the current locale.
Link: https://www.austingroupbugs.net/view.php?id=1741
Fixes: 71511d4ac868 ("getlocalename_l: implement per SUS Base Specifications Issue 8 draft")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'newlib')
-rw-r--r-- | newlib/libc/locale/locale.c | 46 | ||||
-rw-r--r-- | newlib/libc/locale/setlocale.h | 5 |
2 files changed, 29 insertions, 22 deletions
diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c index b16ec15..9e950a5 100644 --- a/newlib/libc/locale/locale.c +++ b/newlib/libc/locale/locale.c @@ -199,6 +199,7 @@ static char *categories[_LC_LAST] = { */ #ifndef DEFAULT_LOCALE #define DEFAULT_LOCALE "C" +#define DEFAULT_LOCALE_IS_C #endif #ifdef _MB_CAPABLE @@ -211,6 +212,9 @@ char __default_locale[ENCODING_LEN + 1] = DEFAULT_LOCALE; const struct __locale_t __C_locale = { { "C", "C", "C", "C", "C", "C", "C", }, +#ifdef _MB_CAPABLE + "C", +#endif __ascii_wctomb, __ascii_mbtowc, 0, @@ -247,6 +251,13 @@ const struct __locale_t __C_locale = struct __locale_t __global_locale = { { "C", "C", DEFAULT_LOCALE, "C", "C", "C", "C", }, +#ifdef _MB_CAPABLE +# ifdef DEFAULT_LOCALE_IS_C + "C", +# else + "C/" DEFAULT_LOCALE "/C/C/C/C", +# endif +#endif #ifdef __CYGWIN__ __utf8_wctomb, __utf8_mbtowc, @@ -285,16 +296,6 @@ struct __locale_t __global_locale = #endif /* __HAVE_LOCALE_INFO__ */ }; -#ifdef _MB_CAPABLE -/* Renamed from current_locale_string to make clear this is only the - *global* string for setlocale (LC_ALL, NULL). There's no equivalent - functionality for uselocale. */ -static char global_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)] - = "C"; -static char *currentlocale (void); - -#endif /* _MB_CAPABLE */ - char * _setlocale_r (struct _reent *p, int category, @@ -323,7 +324,7 @@ _setlocale_r (struct _reent *p, if (locale == NULL) return category != LC_ALL ? __get_global_locale ()->categories[category] - : global_locale_string; + : __get_global_locale ()->locale_string; /* * Default to the current locale for everything. @@ -420,7 +421,8 @@ _setlocale_r (struct _reent *p, { ret = __loadlocale (__get_global_locale (), category, new_categories[category]); - currentlocale (); + __currentlocale (__get_global_locale (), + __get_global_locale ()->locale_string); return ret; } @@ -444,31 +446,31 @@ _setlocale_r (struct _reent *p, return NULL; } } - return currentlocale (); + return __currentlocale (__get_global_locale (), + __get_global_locale ()->locale_string); #endif /* _MB_CAPABLE */ } #ifdef _MB_CAPABLE -static char * -currentlocale () +char * +__currentlocale (struct __locale_t *locobj, char *locale_string) { int i; - strcpy (global_locale_string, __get_global_locale ()->categories[1]); + strcpy (locale_string, locobj->categories[1]); for (i = 2; i < _LC_LAST; ++i) - if (strcmp (__get_global_locale ()->categories[1], - __get_global_locale ()->categories[i])) + if (strcmp (locobj->categories[1], + locobj->categories[i])) { for (i = 2; i < _LC_LAST; ++i) { - (void)strcat(global_locale_string, "/"); - (void)strcat(global_locale_string, - __get_global_locale ()->categories[i]); + (void)strcat(locale_string, "/"); + (void)strcat(locale_string, locobj->categories[i]); } break; } - return global_locale_string; + return locale_string; } extern void __set_ctype (struct __locale_t *, const char *charset); diff --git a/newlib/libc/locale/setlocale.h b/newlib/libc/locale/setlocale.h index e91034a..572b198 100644 --- a/newlib/libc/locale/setlocale.h +++ b/newlib/libc/locale/setlocale.h @@ -183,6 +183,10 @@ struct __lc_cats struct __locale_t { char categories[_LC_LAST][ENCODING_LEN + 1]; +#ifdef _MB_CAPABLE + char locale_string[_LC_LAST + * (ENCODING_LEN + 1/*"/"*/ + 1)]; +#endif int (*wctomb) (struct _reent *, char *, wchar_t, mbstate_t *); int (*mbtowc) (struct _reent *, wchar_t *, @@ -200,6 +204,7 @@ struct __locale_t }; #ifdef _MB_CAPABLE +char *__currentlocale (struct __locale_t *, char *); extern char *__loadlocale (struct __locale_t *, int, char *); extern const char *__get_locale_env(struct _reent *, int); #endif /* _MB_CAPABLE */ |