This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 3/6] newlib: Expose locale structs and function in new header sys/_locale.h


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]