diff options
Diffstat (limited to 'newlib/libc')
-rw-r--r-- | newlib/libc/include/sys/reent.h | 11 | ||||
-rw-r--r-- | newlib/libc/locale/getlocalename_l.c | 15 | ||||
-rw-r--r-- | newlib/libc/locale/locale.c | 46 | ||||
-rw-r--r-- | newlib/libc/locale/setlocale.h | 5 |
4 files changed, 49 insertions, 28 deletions
diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h index 0cba166..5ce5387 100644 --- a/newlib/libc/include/sys/reent.h +++ b/newlib/libc/include/sys/reent.h @@ -370,7 +370,7 @@ struct _misc_reent _mbstate_t _wcrtomb_state; _mbstate_t _wcsrtombs_state; #ifdef _MB_CAPABLE - char _getlocalename_l_buf[32 /*ENCODING + 1*/]; + char _getlocalename_l_buf[7 /* _LC_LAST */ * 32 /*ENCODING + 1*/]; #endif }; @@ -570,7 +570,9 @@ struct _reent #define _REENT_WCSRTOMBS_STATE(ptr) ((ptr)->_misc->_wcsrtombs_state) #define _REENT_L64A_BUF(ptr) ((ptr)->_misc->_l64a_buf) #define _REENT_GETDATE_ERR_P(ptr) (&((ptr)->_misc->_getdate_err)) +#ifdef _MB_CAPABLE #define _REENT_GETLOCALENAME_L_BUF(ptr) ((ptr)->_misc->_getlocalename_l_buf) +#endif #define _REENT_SIGNAL_BUF(ptr) ((ptr)->_signal_buf) #else /* !_REENT_SMALL */ @@ -641,10 +643,13 @@ struct _reent _mbstate_t _mbrtoc16_state; _mbstate_t _mbrtoc32_state; #endif +#ifdef _MB_CAPABLE /* No errors are defined for getlocalename_l. So we can't use buffer allocation which might lead to an ENOMEM error. We have to use a "static" buffer here instead. */ - char _getlocalename_l_buf[32 /* ENCODING_LEN + 1 */]; + char _getlocalename_l_buf[7 /* _LC_LAST */ + * 32 /* ENCODING_LEN + 1 */]; +#endif } _reent; #ifdef _REENT_BACKWARD_BINARY_COMPAT struct @@ -764,7 +769,9 @@ struct _reent #define _REENT_L64A_BUF(ptr) ((ptr)->_new._reent._l64a_buf) #define _REENT_SIGNAL_BUF(ptr) ((ptr)->_new._reent._signal_buf) #define _REENT_GETDATE_ERR_P(ptr) (&((ptr)->_new._reent._getdate_err)) +#ifdef _MB_CAPABLE #define _REENT_GETLOCALENAME_L_BUF(ptr)((ptr)->_new._reent._getlocalename_l_buf) +#endif #endif /* !_REENT_SMALL */ diff --git a/newlib/libc/locale/getlocalename_l.c b/newlib/libc/locale/getlocalename_l.c index 7060c8d..1f18f82 100644 --- a/newlib/libc/locale/getlocalename_l.c +++ b/newlib/libc/locale/getlocalename_l.c @@ -44,7 +44,7 @@ shall remain valid until the locale object locobj is used in a call to No errors are defined. PORTABILITY -<<getlocalename_l>> is POSIX-1.2008 since Base Specification Issue 8 +<<getlocalename_l>> is POSIX-1.2024 */ #include <newlib.h> @@ -53,18 +53,25 @@ PORTABILITY const char * _getlocalename_l_r (struct _reent *ptr, int category, struct __locale_t *locobj) { - if (category <= LC_ALL || category > LC_MESSAGES) + if (category < LC_ALL || category > LC_MESSAGES) return NULL; #ifndef _MB_CAPABLE return "C"; #else + if (category == LC_ALL) + { + if (locobj == LC_GLOBAL_LOCALE) + return __currentlocale (__get_global_locale (), + _REENT_GETLOCALENAME_L_BUF (ptr)); + return __currentlocale (locobj, locobj->locale_string); + } if (locobj == LC_GLOBAL_LOCALE) { /* getlocalename_l is supposed to return the value in a thread-safe manner. This requires to copy over the category string into thread-local storage. */ - strcpy (_REENT_GETLOCALENAME_L_BUF (ptr), - __get_global_locale ()->categories[category]); + return strcpy (_REENT_GETLOCALENAME_L_BUF (ptr), + __get_global_locale ()->categories[category]); } return locobj->categories[category]; #endif 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 */ |