[PATCH 3/6] newlib: Expose locale structs and function in new header sys/_locale.h
Corinna Vinschen
vinschen@redhat.com
Mon Nov 13 15:59:00 GMT 2017
From: Corinna Vinschen <corinna@vinschen.de>
* This allows to convert some accessor functions for locale_t into
inline functions.
* Use these inline functions in ctype.h to speed up ctype functionality.
* This also exposes ENCODING_LEN. Move it to private namespace by
renaming to _LC_ENCODING_LEN.
* Add a comment to make sure nobody removes the non-inline functions
__locale_ctype_ptr and __locale_ctype_ptr_l. They are required for
backward compatibility on Cygwin at least.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
---
newlib/libc/include/ctype.h | 9 +--
newlib/libc/include/locale.h | 29 +--------
newlib/libc/include/sys/_locale.h | 103 ++++++++++++++++++++++++++++++
newlib/libc/locale/locale.c | 25 ++++----
newlib/libc/locale/newlocale.c | 4 +-
newlib/libc/locale/setlocale.h | 55 +---------------
newlib/libc/sys/linux/include/setlocale.h | 3 +-
7 files changed, 128 insertions(+), 100 deletions(-)
create mode 100644 newlib/libc/include/sys/_locale.h
diff --git a/newlib/libc/include/ctype.h b/newlib/libc/include/ctype.h
index 12b626281d59..2337917bc713 100644
--- a/newlib/libc/include/ctype.h
+++ b/newlib/libc/include/ctype.h
@@ -3,6 +3,7 @@
#include "_ansi.h"
#include <sys/cdefs.h>
+#include <sys/_locale.h>
#if __POSIX_VISIBLE >= 200809 || __MISC_VISIBLE || defined (_COMPILING_NEWLIB)
#include <xlocale.h>
@@ -66,8 +67,7 @@ extern int toascii_l (int __c, locale_t __l);
#define _X 0100
#define _B 0200
-const char *__locale_ctype_ptr (void);
-# define __CTYPE_PTR (__locale_ctype_ptr ())
+# define __CTYPE_PTR (__get_current_locale()->ctype_ptr)
#ifndef __cplusplus
/* These macros are intentionally written in a manner that will trigger
@@ -100,8 +100,9 @@ const char *__locale_ctype_ptr (void);
#endif
#if __POSIX_VISIBLE >= 200809
-const char *__locale_ctype_ptr_l (locale_t);
-#define __ctype_lookup_l(__c,__l) ((__locale_ctype_ptr_l(__l)+sizeof(""[__c]))[(int)(__c)])
+
+#define __locale_ctype_ptr_l(__l) ((__l)->ctype_ptr)
+#define __ctype_lookup_l(__c,__l) ((((const char *)((__l)->ctype_ptr))+sizeof(""[__c]))[(int)(__c)])
#define isalpha_l(__c,__l) (__ctype_lookup_l(__c,__l)&(_U|_L))
#define isupper_l(__c,__l) ((__ctype_lookup_l(__c,__l)&(_U|_L))==_U)
diff --git a/newlib/libc/include/locale.h b/newlib/libc/include/locale.h
index 8ba88a90ca90..587e7637973f 100644
--- a/newlib/libc/include/locale.h
+++ b/newlib/libc/include/locale.h
@@ -9,6 +9,7 @@
#include "_ansi.h"
#include <sys/cdefs.h>
+#include <sys/_locale.h>
#define __need_NULL
#include <stddef.h>
@@ -39,34 +40,6 @@
_BEGIN_STD_C
-struct lconv
-{
- char *decimal_point;
- char *thousands_sep;
- char *grouping;
- char *int_curr_symbol;
- char *currency_symbol;
- char *mon_decimal_point;
- char *mon_thousands_sep;
- char *mon_grouping;
- char *positive_sign;
- char *negative_sign;
- char int_frac_digits;
- char frac_digits;
- char p_cs_precedes;
- char p_sep_by_space;
- char n_cs_precedes;
- char n_sep_by_space;
- char p_sign_posn;
- char n_sign_posn;
- char int_n_cs_precedes;
- char int_n_sep_by_space;
- char int_n_sign_posn;
- char int_p_cs_precedes;
- char int_p_sep_by_space;
- char int_p_sign_posn;
-};
-
struct _reent;
char *_EXFUN(_setlocale_r,(struct _reent *, int, const char *));
struct lconv *_EXFUN(_localeconv_r,(struct _reent *));
diff --git a/newlib/libc/include/sys/_locale.h b/newlib/libc/include/sys/_locale.h
new file mode 100644
index 000000000000..187a2e45a07a
--- /dev/null
+++ b/newlib/libc/include/sys/_locale.h
@@ -0,0 +1,103 @@
+/*
+ sys/_locale.h
+ Definition of userspace exposed locale structs.
+*/
+
+#ifndef _SYS__LOCALE_H_
+#define _SYS__LOCALE_H_
+
+#include <newlib.h>
+#include <sys/config.h>
+#include <sys/reent.h>
+
+#define _LC_LAST 7
+#define _LC_ENCODING_LEN 31
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct lconv
+{
+ char *decimal_point;
+ char *thousands_sep;
+ char *grouping;
+ char *int_curr_symbol;
+ char *currency_symbol;
+ char *mon_decimal_point;
+ char *mon_thousands_sep;
+ char *mon_grouping;
+ char *positive_sign;
+ char *negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ char int_n_cs_precedes;
+ char int_n_sep_by_space;
+ char int_n_sign_posn;
+ char int_p_cs_precedes;
+ char int_p_sep_by_space;
+ char int_p_sign_posn;
+};
+
+struct __lc_cats
+{
+ const void *ptr;
+ char *buf;
+};
+
+struct __locale_t
+{
+ char categories[_LC_LAST][_LC_ENCODING_LEN + 1];
+ int (*wctomb) (struct _reent *, char *, wchar_t,
+ _mbstate_t *);
+ int (*mbtowc) (struct _reent *, wchar_t *,
+ const char *, size_t, _mbstate_t *);
+ int cjk_lang;
+ char *ctype_ptr;
+ struct lconv lconv;
+#ifndef __HAVE_LOCALE_INFO__
+ char mb_cur_max[2];
+ char ctype_codeset[_LC_ENCODING_LEN + 1];
+ char message_codeset[_LC_ENCODING_LEN + 1];
+#else
+ struct __lc_cats lc_cat[_LC_LAST];
+#endif
+};
+
+/* In POSIX terms the global locale is the process-wide locale. Use this
+ function to always refer to the global locale. */
+_ELIDABLE_INLINE struct __locale_t *
+__get_global_locale ()
+{
+ extern struct __locale_t __global_locale;
+ return &__global_locale;
+}
+
+/* Per REENT locale. This is newlib-internal. */
+_ELIDABLE_INLINE struct __locale_t *
+__get_locale_r (struct _reent *r)
+{
+ return r->_locale;
+}
+
+/* In POSIX terms the current locale is the locale used by all functions
+ using locale info without providing a locale as parameter (*_l functions).
+ The current locale is either the locale of the current thread, if the
+ thread called uselocale, or the global locale if not. */
+_ELIDABLE_INLINE struct __locale_t *
+__get_current_locale (void)
+{
+ return _REENT->_locale;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS__LOCALE_H_ */
diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c
index b5402372c3f3..9cb1cb212f49 100644
--- a/newlib/libc/locale/locale.c
+++ b/newlib/libc/locale/locale.c
@@ -217,7 +217,7 @@ static char *categories[_LC_LAST] = {
* This variable can be changed by any outside mechanism. This allows,
* for instance, to load the default locale from a file.
*/
-char __default_locale[ENCODING_LEN + 1] = DEFAULT_LOCALE;
+char __default_locale[_LC_ENCODING_LEN + 1] = DEFAULT_LOCALE;
const struct __locale_t __C_locale =
{
@@ -299,7 +299,7 @@ struct __locale_t __global_locale =
/* 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)];
+static char global_locale_string[_LC_LAST * (_LC_ENCODING_LEN + 1/*"/"*/ + 1)];
static char *currentlocale (void);
#endif /* _MB_CAPABLE */
@@ -319,8 +319,8 @@ _DEFUN(_setlocale_r, (p, category, locale),
}
return "C";
#else /* _MB_CAPABLE */
- static char new_categories[_LC_LAST][ENCODING_LEN + 1];
- static char saved_categories[_LC_LAST][ENCODING_LEN + 1];
+ static char new_categories[_LC_LAST][_LC_ENCODING_LEN + 1];
+ static char saved_categories[_LC_LAST][_LC_ENCODING_LEN + 1];
int i, j, len, saverr;
const char *env, *r;
@@ -350,7 +350,7 @@ _DEFUN(_setlocale_r, (p, category, locale),
for (i = 1; i < _LC_LAST; ++i)
{
env = __get_locale_env (p, i);
- if (strlen (env) > ENCODING_LEN)
+ if (strlen (env) > _LC_ENCODING_LEN)
{
p->_errno = EINVAL;
return NULL;
@@ -361,7 +361,7 @@ _DEFUN(_setlocale_r, (p, category, locale),
else
{
env = __get_locale_env (p, category);
- if (strlen (env) > ENCODING_LEN)
+ if (strlen (env) > _LC_ENCODING_LEN)
{
p->_errno = EINVAL;
return NULL;
@@ -371,7 +371,7 @@ _DEFUN(_setlocale_r, (p, category, locale),
}
else if (category != LC_ALL)
{
- if (strlen (locale) > ENCODING_LEN)
+ if (strlen (locale) > _LC_ENCODING_LEN)
{
p->_errno = EINVAL;
return NULL;
@@ -382,7 +382,7 @@ _DEFUN(_setlocale_r, (p, category, locale),
{
if ((r = strchr (locale, '/')) == NULL)
{
- if (strlen (locale) > ENCODING_LEN)
+ if (strlen (locale) > _LC_ENCODING_LEN)
{
p->_errno = EINVAL;
return NULL;
@@ -403,7 +403,7 @@ _DEFUN(_setlocale_r, (p, category, locale),
{
if (i == _LC_LAST)
break; /* Too many slashes... */
- if ((len = r - locale) > ENCODING_LEN)
+ if ((len = r - locale) > _LC_ENCODING_LEN)
{
p->_errno = EINVAL;
return NULL;
@@ -490,7 +490,7 @@ __loadlocale (struct __locale_t *loc, int category, const char *new_locale)
is extracted and stored in ctype_codeset or message_charset
dependent on the cateogry. */
char *locale = NULL;
- char charset[ENCODING_LEN + 1];
+ char charset[_LC_ENCODING_LEN + 1];
long val = 0;
char *end, *c = NULL;
int mbc_max;
@@ -516,7 +516,7 @@ __loadlocale (struct __locale_t *loc, int category, const char *new_locale)
"th_TH.TIS-620". If successful, the function returns with a pointer
to the second argument, which is a buffer in which the replacement locale
gets stored. Otherwise the function returns NULL. */
- char tmp_locale[ENCODING_LEN + 1];
+ char tmp_locale[_LC_ENCODING_LEN + 1];
int ret = 0;
restart:
@@ -991,6 +991,9 @@ _DEFUN_VOID (__locale_mb_cur_max)
#endif
}
+/* __locale_ctype_ptr_l and __locale_ctype_ptr have been exported and
+ needs to be retained for backward compat on Cygwin. */
+#undef __locale_ctype_ptr_l
const char *
__locale_ctype_ptr_l (struct __locale_t *locale)
{
diff --git a/newlib/libc/locale/newlocale.c b/newlib/libc/locale/newlocale.c
index c8176256e09c..72660707038b 100644
--- a/newlib/libc/locale/newlocale.c
+++ b/newlib/libc/locale/newlocale.c
@@ -89,7 +89,7 @@ _newlocale_r (struct _reent *p, int category_mask, const char *locale,
#ifndef _MB_CAPABLE
return __get_C_locale ();
#else /* _MB_CAPABLE */
- char new_categories[_LC_LAST][ENCODING_LEN + 1];
+ char new_categories[_LC_LAST][_LC_ENCODING_LEN + 1];
struct __locale_t tmp_locale, *new_locale;
int i;
@@ -123,7 +123,7 @@ _newlocale_r (struct _reent *p, int category_mask, const char *locale,
name verbatim. */
const char *cat = (locale[0] == '\0') ? __get_locale_env (p, i)
: locale;
- if (strlen (cat) > ENCODING_LEN)
+ if (strlen (cat) > _LC_ENCODING_LEN)
{
p->_errno = EINVAL;
return NULL;
diff --git a/newlib/libc/locale/setlocale.h b/newlib/libc/locale/setlocale.h
index 7f648caafded..13599915f3c5 100644
--- a/newlib/libc/locale/setlocale.h
+++ b/newlib/libc/locale/setlocale.h
@@ -39,9 +39,7 @@
__BEGIN_DECLS
-#define ENCODING_LEN 31
#define CATEGORY_LEN 11
-#define _LC_LAST 7
#ifdef __CYGWIN__
struct lc_collate_T
@@ -49,7 +47,7 @@ struct lc_collate_T
__uint32_t lcid;
int (*mbtowc) (struct _reent *, wchar_t *, const char *, size_t,
mbstate_t *);
- char codeset[ENCODING_LEN + 1];
+ char codeset[_LC_ENCODING_LEN + 1];
};
extern const struct lc_collate_T _C_collate_locale;
#endif
@@ -169,31 +167,6 @@ struct lc_messages_T
};
extern const struct lc_messages_T _C_messages_locale;
-struct __lc_cats
-{
- const void *ptr;
- char *buf;
-};
-
-struct __locale_t
-{
- char categories[_LC_LAST][ENCODING_LEN + 1];
- int (*wctomb) (struct _reent *, char *, wchar_t,
- mbstate_t *);
- int (*mbtowc) (struct _reent *, wchar_t *,
- const char *, size_t, mbstate_t *);
- int cjk_lang;
- char *ctype_ptr;
- struct lconv lconv;
-#ifndef __HAVE_LOCALE_INFO__
- char mb_cur_max[2];
- char ctype_codeset[ENCODING_LEN + 1];
- char message_codeset[ENCODING_LEN + 1];
-#else
- struct __lc_cats lc_cat[_LC_LAST];
-#endif
-};
-
#ifdef _MB_CAPABLE
extern char *__loadlocale (struct __locale_t *, int, const char *);
extern const char *__get_locale_env(struct _reent *, int);
@@ -204,32 +177,6 @@ extern struct lconv *__localeconv_l (struct __locale_t *locale);
extern size_t _wcsnrtombs_l (struct _reent *, char *, const wchar_t **,
size_t, size_t, mbstate_t *, struct __locale_t *);
-/* In POSIX terms the global locale is the process-wide locale. Use this
- function to always refer to the global locale. */
-_ELIDABLE_INLINE struct __locale_t *
-__get_global_locale ()
-{
- extern struct __locale_t __global_locale;
- return &__global_locale;
-}
-
-/* Per REENT locale. This is newlib-internal. */
-_ELIDABLE_INLINE struct __locale_t *
-__get_locale_r (struct _reent *r)
-{
- return r->_locale;
-}
-
-/* In POSIX terms the current locale is the locale used by all functions
- using locale info without providing a locale as parameter (*_l functions).
- The current locale is either the locale of the current thread, if the
- thread called uselocale, or the global locale if not. */
-_ELIDABLE_INLINE struct __locale_t *
-__get_current_locale (void)
-{
- return _REENT->_locale;
-}
-
/* Only access fixed "C" locale using this function. Fake for !_MB_CAPABLE
targets by returning ptr to globale locale. */
_ELIDABLE_INLINE struct __locale_t *
diff --git a/newlib/libc/sys/linux/include/setlocale.h b/newlib/libc/sys/linux/include/setlocale.h
index 3eb769863c69..964056bb5288 100644
--- a/newlib/libc/sys/linux/include/setlocale.h
+++ b/newlib/libc/sys/linux/include/setlocale.h
@@ -29,7 +29,8 @@
#ifndef _SETLOCALE_H_
#define _SETLOCALE_H_
-#define ENCODING_LEN 31
+#define _LC_ENCODING_LEN 31
+#define ENCODING_LEN _LC_ENCODING_LEN
#define CATEGORY_LEN 11
extern char *_PathLocale;
--
2.9.5
More information about the Newlib
mailing list