aboutsummaryrefslogtreecommitdiff
path: root/newlib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc')
-rw-r--r--newlib/libc/include/sys/reent.h11
-rw-r--r--newlib/libc/locale/getlocalename_l.c15
-rw-r--r--newlib/libc/locale/locale.c46
-rw-r--r--newlib/libc/locale/setlocale.h5
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 */