[newlib-cygwin] Change loadlocale to fill a __locale_t given as parameter

Corinna Vinschen corinna@sourceware.org
Mon Aug 15 09:25:00 GMT 2016


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=1498c79db89ea0e02a49ffa34e71da480e37165e

commit 1498c79db89ea0e02a49ffa34e71da480e37165e
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Thu Jul 21 20:49:42 2016 +0200

    Change loadlocale to fill a __locale_t given as parameter
    
    Don't use global variables.  This allows to call loadlocale from
    the yet to be created newlocale().
    
    Rename _thr_locale_t to __locale_t (these locales are not restricted
    to threads so the name is misleading).
    
    Along these lines, fix _set_ctype to take a __locale_t as parameter.
    
    Signed-off by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 newlib/libc/ctype/ctype_.c      |  17 +++++--
 newlib/libc/include/locale.h    |   6 +--
 newlib/libc/include/sys/reent.h |   6 +--
 newlib/libc/locale/lctype.c     |   2 +-
 newlib/libc/locale/lmessages.c  |   2 +-
 newlib/libc/locale/lmonetary.c  |   2 +-
 newlib/libc/locale/lnumeric.c   |   2 +-
 newlib/libc/locale/locale.c     | 106 +++++++++++++++++++---------------------
 newlib/libc/locale/setlocale.h  |  22 ++++-----
 newlib/libc/locale/timelocal.c  |   2 +-
 winsup/cygwin/ctype.cc          |   6 +--
 winsup/cygwin/nlsfuncs.cc       |   2 +-
 12 files changed, 87 insertions(+), 88 deletions(-)

diff --git a/newlib/libc/ctype/ctype_.c b/newlib/libc/ctype/ctype_.c
index f6ea637..8945c56 100644
--- a/newlib/libc/ctype/ctype_.c
+++ b/newlib/libc/ctype/ctype_.c
@@ -36,6 +36,7 @@ static char sccsid[] = "@(#)ctype_.c	5.6 (Berkeley) 6/1/90";
 #endif /* LIBC_SCCS and not lint */
 
 #include <ctype.h>
+#include "../locale/setlocale.h"
 
 #define _CTYPE_DATA_0_127 \
 	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C, \
@@ -148,7 +149,7 @@ char *__ctype_ptr__ = (char *) _ctype_;
    compatibility with applications built under older Cygwin releases. */
 #ifndef __CYGWIN__
 void
-__set_ctype (struct _reent *, const char *charset)
+__set_ctype (struct __locale_t *loc, const char *charset)
 {
 #if defined(_MB_EXTENDED_CHARSETS_ISO) || defined(_MB_EXTENDED_CHARSETS_WINDOWS)
   int idx;
@@ -184,15 +185,21 @@ __set_ctype (struct _reent *, const char *charset)
   if (!ctype_ptr)
     {
 #  if defined(ALLOW_NEGATIVE_CTYPE_INDEX)
-      ctype_ptr = _ctype_b;
+     ctype_ptr = _ctype_b;
 #  else
-      ctype_ptr = _ctype_;
+     ctype_ptr = _ctype_;
 #  endif
     }
 #  if defined(ALLOW_NEGATIVE_CTYPE_INDEX)
-      __ctype_ptr__ = ctype_ptr + 127;
+  if (loc)
+    loc->ctype_ptr = ctype_ptr + 127;
+  else
+    __ctype_ptr__ = ctype_ptr + 127;
 #  else
-      __ctype_ptr__ = ctype_ptr;
+  if (loc)
+    loc->ctype_ptr = ctype_ptr;
+  else
+    __ctype_ptr__ = ctype_ptr;
 #  endif
 }
 #endif /* !__CYGWIN__ */
diff --git a/newlib/libc/include/locale.h b/newlib/libc/include/locale.h
index c7bfd59..40e4124 100644
--- a/newlib/libc/include/locale.h
+++ b/newlib/libc/include/locale.h
@@ -29,10 +29,10 @@
 #define LC_TIME_MASK		(1 << LC_TIME)
 #define LC_MESSAGES_MASK	(1 << LC_MESSAGES)
 
-#define LC_GLOBAL_LOCALE	((struct _thr_locale_t *) -1)
+#define LC_GLOBAL_LOCALE	((struct __locale_t *) -1)
 
-struct _thr_locale_t;
-typedef struct _thr_locale_t *locale_t;
+struct __locale_t;
+typedef struct __locale_t *locale_t;
 #endif
 
 _BEGIN_STD_C
diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h
index 16716dd..bd32320 100644
--- a/newlib/libc/include/sys/reent.h
+++ b/newlib/libc/include/sys/reent.h
@@ -40,7 +40,7 @@ struct _reent;
 /* TODO: This structure type isn't defined yet.  It's supposed to be used
    by locale-specific functions in case a per-thread locale per SUSv4 has
    been specified. */
-struct _thr_locale_t;
+struct __locale_t;
 
 /*
  * If _REENT_SMALL is defined, we make struct _reent as small as possible,
@@ -391,7 +391,7 @@ struct _reent
 
   /* TODO */
   int _unspecified_locale_info;	/* unused, reserved for locale stuff */
-  struct _thr_locale_t *_locale;/* per-thread locale */
+  struct __locale_t *_locale;/* per-thread locale */
 
   struct _mprec *_mp;
 
@@ -584,7 +584,7 @@ struct _reent
 
   /* TODO */
   int _unspecified_locale_info;	/* unused, reserved for locale stuff */
-  struct _thr_locale_t *_locale;/* per-thread locale */
+  struct __locale_t *_locale;/* per-thread locale */
 
   int __sdidinit;		/* 1 means stdio has been init'd */
 
diff --git a/newlib/libc/locale/lctype.c b/newlib/libc/locale/lctype.c
index d59ae37..8f00539 100644
--- a/newlib/libc/locale/lctype.c
+++ b/newlib/libc/locale/lctype.c
@@ -52,7 +52,7 @@ static char _ctype_locale_buf[_CTYPE_BUF_SIZE];
 
 /* NULL locale indicates global locale (called from setlocale) */
 int
-__ctype_load_locale (struct _thr_locale_t *locale, const char *name,
+__ctype_load_locale (struct __locale_t *locale, const char *name,
 		     void *f_wctomb, const char *charset, int mb_cur_max)
 {
   int ret;
diff --git a/newlib/libc/locale/lmessages.c b/newlib/libc/locale/lmessages.c
index c768e45..751bf08 100644
--- a/newlib/libc/locale/lmessages.c
+++ b/newlib/libc/locale/lmessages.c
@@ -60,7 +60,7 @@ static char	*_messages_locale_buf;
 #endif
 
 int
-__messages_load_locale (struct _thr_locale_t *locale, const char *name,
+__messages_load_locale (struct __locale_t *locale, const char *name,
 			void *f_wctomb, const char *charset)
 {
   int ret;
diff --git a/newlib/libc/locale/lmonetary.c b/newlib/libc/locale/lmonetary.c
index 32e5ee5..fe15c83 100644
--- a/newlib/libc/locale/lmonetary.c
+++ b/newlib/libc/locale/lmonetary.c
@@ -89,7 +89,7 @@ cnv(const char *str) {
 #endif
 
 int
-__monetary_load_locale (struct _thr_locale_t *locale, const char *name ,
+__monetary_load_locale (struct __locale_t *locale, const char *name ,
 			void *f_wctomb, const char *charset)
 {
   int ret;
diff --git a/newlib/libc/locale/lnumeric.c b/newlib/libc/locale/lnumeric.c
index 0e56f16..0de7c23 100644
--- a/newlib/libc/locale/lnumeric.c
+++ b/newlib/libc/locale/lnumeric.c
@@ -51,7 +51,7 @@ static char	*_numeric_locale_buf;
 #endif
 
 int
-__numeric_load_locale (struct _thr_locale_t *locale, const char *name ,
+__numeric_load_locale (struct __locale_t *locale, const char *name ,
 		       void *f_wctomb, const char *charset)
 {
   int ret;
diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c
index 0430f1f..262f689 100644
--- a/newlib/libc/locale/locale.c
+++ b/newlib/libc/locale/locale.c
@@ -226,7 +226,7 @@ static char *categories[_LC_LAST] = {
  */
 char __default_locale[ENCODING_LEN + 1] = DEFAULT_LOCALE;
 
-struct _thr_locale_t __global_locale =
+struct __locale_t __global_locale =
 {
   { "C", "C", DEFAULT_LOCALE, "C", "C", "C", "C", },
 #ifdef __CYGWIN__
@@ -260,19 +260,12 @@ struct _thr_locale_t __global_locale =
 #endif
 };
 
-/*
- * The locales we are going to try and load.  These are only temporary
- * variables and only used in setlocale.
- */
-static char new_categories[_LC_LAST][ENCODING_LEN + 1];
-static char saved_categories[_LC_LAST][ENCODING_LEN + 1];
-
 /* 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 *currentlocale(void);
-static char *loadlocale(struct _reent *, int);
+static char *currentlocale (void);
+static char *loadlocale (struct __locale_t *, int, const char *);
 static const char *__get_locale_env(struct _reent *, int);
 
 #endif /* _MB_CAPABLE */
@@ -283,6 +276,9 @@ _DEFUN(_setlocale_r, (p, category, locale),
        int category _AND
        _CONST char *locale)
 {
+  static char new_categories[_LC_LAST][ENCODING_LEN + 1];
+  static char saved_categories[_LC_LAST][ENCODING_LEN + 1];
+
 #ifndef _MB_CAPABLE
   if (locale)
     { 
@@ -396,21 +392,23 @@ _DEFUN(_setlocale_r, (p, category, locale),
     }
 
   if (category != LC_ALL)
-    return loadlocale (p, category);
+    return loadlocale (__get_global_locale (), category,
+		       new_categories[category]);
 
   for (i = 1; i < _LC_LAST; ++i)
     {
       strcpy (saved_categories[i], __global_locale.categories[i]);
-      if (loadlocale (p, i) == NULL)
+      if (loadlocale (__get_global_locale (), i, new_categories[i]) == NULL)
 	{
 	  saverr = p->_errno;
 	  for (j = 1; j < i; j++)
 	    {
 	      strcpy (new_categories[j], saved_categories[j]);
-	      if (loadlocale (p, j) == NULL)
+	      if (loadlocale (__get_global_locale (), j, new_categories[j])
+		  == NULL)
 		{
 		  strcpy (new_categories[j], "C");
-		  loadlocale (p, j);
+		  loadlocale (__get_global_locale (), j, new_categories[j]);
 		}
 	    }
 	  p->_errno = saverr;
@@ -423,7 +421,7 @@ _DEFUN(_setlocale_r, (p, category, locale),
 
 #ifdef _MB_CAPABLE
 static char *
-currentlocale()
+currentlocale ()
 {
         int i;
 
@@ -444,10 +442,10 @@ currentlocale()
 
 #ifdef _MB_CAPABLE
 
-extern void __set_ctype (struct _reent *, const char *charset);
+extern void __set_ctype (struct __locale_t *, const char *charset);
 
 static char *
-loadlocale(struct _reent *p, int category)
+loadlocale (struct __locale_t *loc, int category, const char *new_locale)
 {
   /* At this point a full-featured system would just load the locale
      specific data from the locale files.
@@ -467,8 +465,8 @@ loadlocale(struct _reent *p, int category)
   int cjknarrow = 0;
 
   /* Avoid doing everything twice if nothing has changed. */
-  if (!strcmp (new_categories[category], __global_locale.categories[category]))
-    return __global_locale.categories[category];
+  if (!strcmp (new_locale, loc->categories[category]))
+    return loc->categories[category];
 
 #ifdef __CYGWIN__
   /* This additional code handles the case that the incoming locale string
@@ -485,7 +483,7 @@ loadlocale(struct _reent *p, int category)
 
 restart:
   if (!locale)
-    locale = new_categories[category];
+    locale = new_locale;
   else if (locale != tmp_locale)
     {
       locale = __set_locale_from_locale_alias (locale, tmp_locale);
@@ -494,7 +492,7 @@ restart:
     }
 # define FAIL	goto restart
 #else
-  locale = new_categories[category];
+  locale = new_locale;
 # define FAIL	return NULL
 #endif
 
@@ -662,7 +660,7 @@ restart:
       c += 4;
       if (*c == '-')
 	++c;
-      val = _strtol_r (p, c, &end, 10);
+      val = strtol (c, &end, 10);
       if (val < 1 || val > 16 || val == 12 || *end)
 	FAIL;
       strcpy (charset, "ISO-8859-");
@@ -685,7 +683,7 @@ restart:
       if (charset[1] != 'P' && charset[1] != 'p')
 	FAIL;
       strncpy (charset, "CP", 2);
-      val = _strtol_r (p, charset + 2, &end, 10);
+      val = strtol (charset + 2, &end, 10);
       if (*end)
 	FAIL;
       switch (val)
@@ -860,60 +858,54 @@ restart:
     {
     case LC_CTYPE:
 #ifndef __HAVE_LOCALE_INFO__
-      strcpy (__global_locale.ctype_codeset, charset);
-      __global_locale.mb_cur_max[0] = mbc_max;
+      strcpy (loc->ctype_codeset, charset);
+      loc->mb_cur_max[0] = mbc_max;
 #endif
 #ifdef __CYGWIN__
       __mb_cur_max = mbc_max;	/* Only for backward compat */
 #endif
-      __global_locale.wctomb = l_wctomb;
-      __global_locale.mbtowc = l_mbtowc;
-      __set_ctype (NULL, charset);
+      loc->wctomb = l_wctomb;
+      loc->mbtowc = l_mbtowc;
+      __set_ctype (loc == __get_global_locale () ? NULL : loc, charset);
       /* Determine the width for the "CJK Ambiguous Width" category of
          characters. This is used in wcwidth(). Assume single width for
          single-byte charsets, and double width for multi-byte charsets
          other than UTF-8. For UTF-8, use double width for the East Asian
          languages ("ja", "ko", "zh"), and single width for everything else.
          Single width can also be forced with the "@cjknarrow" modifier. */
-      __global_locale.cjk_lang = !cjknarrow
-			  && mbc_max > 1
-			  && (charset[0] != 'U'
-			      || strncmp (locale, "ja", 2) == 0
-			      || strncmp (locale, "ko", 2) == 0
-			      || strncmp (locale, "zh", 2) == 0);
+      loc->cjk_lang = !cjknarrow && mbc_max > 1
+		      && (charset[0] != 'U'
+			  || strncmp (locale, "ja", 2) == 0
+			  || strncmp (locale, "ko", 2) == 0
+			  || strncmp (locale, "zh", 2) == 0);
 #ifdef __HAVE_LOCALE_INFO__
-      ret = __ctype_load_locale (__get_global_locale (), locale,
-				 (void *) l_wctomb, charset, mbc_max);
+      ret = __ctype_load_locale (loc, locale, (void *) l_wctomb, charset,
+				 mbc_max);
 #endif /* __HAVE_LOCALE_INFO__ */
       break;
     case LC_MESSAGES:
 #ifdef __HAVE_LOCALE_INFO__
-      ret = __messages_load_locale (__get_global_locale (), locale,
-				    (void *) l_wctomb, charset);
+      ret = __messages_load_locale (loc, locale, (void *) l_wctomb, charset);
       if (!ret)
 #else
-      strcpy (__global_locale.message_codeset, charset);
+      strcpy (loc->message_codeset, charset);
 #endif /* __HAVE_LOCALE_INFO__ */
       break;
 #ifdef __HAVE_LOCALE_INFO__
 #ifdef __CYGWIN__
   /* Right now only Cygwin supports a __collate_load_locale function at all. */
     case LC_COLLATE:
-      ret = __collate_load_locale (__get_global_locale (), locale,
-				   (void *) l_mbtowc, charset);
+      ret = __collate_load_locale (loc, locale, (void *) l_mbtowc, charset);
       break;
 #endif
     case LC_MONETARY:
-      ret = __monetary_load_locale (__get_global_locale (), locale,
-				    (void *) l_wctomb, charset);
+      ret = __monetary_load_locale (loc, locale, (void *) l_wctomb, charset);
       break;
     case LC_NUMERIC:
-      ret = __numeric_load_locale (__get_global_locale (), locale,
-				   (void *) l_wctomb, charset);
+      ret = __numeric_load_locale (loc, locale, (void *) l_wctomb, charset);
       break;
     case LC_TIME:
-      ret = __time_load_locale (__get_global_locale (), locale,
-				(void *) l_wctomb, charset);
+      ret = __time_load_locale (loc, locale, (void *) l_wctomb, charset);
       break;
 #endif /* __HAVE_LOCALE_INFO__ */
     default:
@@ -923,11 +915,11 @@ restart:
   if (ret)
     FAIL;
 #endif /* __HAVE_LOCALE_INFO__ */
-  return strcpy(__global_locale.categories[category], new_categories[category]);
+  return strcpy(loc->categories[category], new_locale);
 }
 
 static const char *
-__get_locale_env(struct _reent *p, int category)
+__get_locale_env (struct _reent *p, int category)
 {
   const char *env;
 
@@ -951,7 +943,7 @@ __get_locale_env(struct _reent *p, int category)
 #endif /* _MB_CAPABLE */
 
 int
-_DEFUN_VOID(__locale_mb_cur_max)
+_DEFUN_VOID (__locale_mb_cur_max)
 {
 #ifdef __HAVE_LOCALE_INFO__
   return __get_current_ctype_locale ()->mb_cur_max[0];
@@ -962,7 +954,7 @@ _DEFUN_VOID(__locale_mb_cur_max)
 
 #ifdef __HAVE_LOCALE_INFO__
 char *
-_DEFUN_VOID(__locale_ctype_ptr)
+_DEFUN_VOID (__locale_ctype_ptr)
 {
   /* Only check if the current thread/reent has a locale.  ctype_ptr is unused
      in __global_locale, rather the global variable __ctype_ptr__ is used. */
@@ -973,8 +965,8 @@ _DEFUN_VOID(__locale_ctype_ptr)
 #endif
 
 struct lconv *
-_DEFUN(_localeconv_r, (data), 
-      struct _reent *data)
+_DEFUN (_localeconv_r, (data), 
+	struct _reent *data)
 {
 #ifdef __HAVE_LOCALE_INFO__
   const struct lc_numeric_T *n = __get_current_numeric_locale ();
@@ -1020,15 +1012,15 @@ _DEFUN(_localeconv_r, (data),
 #ifndef _REENT_ONLY
 
 char *
-_DEFUN(setlocale, (category, locale),
-       int category _AND
-       _CONST char *locale)
+_DEFUN (setlocale, (category, locale),
+	int category _AND
+	_CONST char *locale)
 {
   return _setlocale_r (_REENT, category, locale);
 }
 
 struct lconv *
-_DEFUN_VOID(localeconv)
+_DEFUN_VOID (localeconv)
 {
   return _localeconv_r (_REENT);
 }
diff --git a/newlib/libc/locale/setlocale.h b/newlib/libc/locale/setlocale.h
index 50797db..fe3c566 100644
--- a/newlib/libc/locale/setlocale.h
+++ b/newlib/libc/locale/setlocale.h
@@ -165,7 +165,7 @@ struct lc_collate_T
 extern const struct lc_collate_T _C_collate_locale;
 #endif
 
-struct _thr_locale_t
+struct __locale_t
 {
   char				 categories[_LC_LAST][ENCODING_LEN + 1];
   int				(*wctomb) (struct _reent *, char *, wchar_t,
@@ -197,18 +197,18 @@ struct _thr_locale_t
 #endif
 };
 
-extern struct _thr_locale_t __global_locale;
+extern struct __locale_t __global_locale;
 
 /* In POSIX terms the global locale is the process-wide locale.  Use this
    function to always refer to the global locale. */
-_ELIDABLE_INLINE struct _thr_locale_t *
+_ELIDABLE_INLINE struct __locale_t *
 __get_global_locale ()
 {
   return &__global_locale;
 }
 
 /* Per REENT locale.  This is newlib-internal. */
-_ELIDABLE_INLINE struct _thr_locale_t *
+_ELIDABLE_INLINE struct __locale_t *
 __get_locale_r (struct _reent *r)
 {
   return r->_locale;
@@ -218,7 +218,7 @@ __get_locale_r (struct _reent *r)
    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 _thr_locale_t *
+_ELIDABLE_INLINE struct __locale_t *
 __get_current_locale ()
 {
   return _REENT->_locale ?: &__global_locale;
@@ -292,18 +292,18 @@ __locale_cjk_lang (void)
 #endif
 }
 
-int __ctype_load_locale (struct _thr_locale_t *, const char *, void *,
+int __ctype_load_locale (struct __locale_t *, const char *, void *,
 			 const char *, int);
-int __monetary_load_locale (struct _thr_locale_t *, const char *, void *,
+int __monetary_load_locale (struct __locale_t *, const char *, void *,
 			    const char *);
-int __numeric_load_locale (struct _thr_locale_t *, const char *, void *,
+int __numeric_load_locale (struct __locale_t *, const char *, void *,
 			   const char *);
-int __time_load_locale (struct _thr_locale_t *, const char *, void *,
+int __time_load_locale (struct __locale_t *, const char *, void *,
 			const char *);
-int __messages_load_locale (struct _thr_locale_t *, const char *, void *,
+int __messages_load_locale (struct __locale_t *, const char *, void *,
 			    const char *);
 #ifdef __CYGWIN__
-int __collate_load_locale (struct _thr_locale_t *, const char *, void *,
+int __collate_load_locale (struct __locale_t *, const char *, void *,
 			   const char *);
 
 extern void __set_charset_from_locale (const char *locale, char *charset);
diff --git a/newlib/libc/locale/timelocal.c b/newlib/libc/locale/timelocal.c
index 5e64456..c94fdf7 100644
--- a/newlib/libc/locale/timelocal.c
+++ b/newlib/libc/locale/timelocal.c
@@ -152,7 +152,7 @@ static char *time_locale_buf;
 #endif
 
 int
-__time_load_locale (struct _thr_locale_t *locale, const char *name,
+__time_load_locale (struct __locale_t *locale, const char *name,
 		    void *f_wctomb, const char *charset)
 {
   int	ret;
diff --git a/winsup/cygwin/ctype.cc b/winsup/cygwin/ctype.cc
index 94de81e..a7dc18a 100644
--- a/winsup/cygwin/ctype.cc
+++ b/winsup/cygwin/ctype.cc
@@ -19,7 +19,7 @@ extern const char __ctype_cp[22][128 + 256];		/* Newlib */
 extern const char __ctype_iso[15][128 + 256];		/* Newlib */
 
 void
-__set_ctype (struct _reent *reent, const char *charset)
+__set_ctype (struct __locale_t *loc, const char *charset)
 {
   int idx;
   char *ctype_ptr = NULL;
@@ -63,8 +63,8 @@ __set_ctype (struct _reent *reent, const char *charset)
 	}
       ctype_ptr = (char *) _ctype_b;
     }
-  if (reent)
-    __get_locale_r (reent)->ctype_ptr = ctype_ptr + 127;
+  if (loc)
+    loc->ctype_ptr = ctype_ptr + 127;
   else
     __ctype_ptr__ = ctype_ptr + 127;
 }
diff --git a/winsup/cygwin/nlsfuncs.cc b/winsup/cygwin/nlsfuncs.cc
index 2ba9f32..021af44 100644
--- a/winsup/cygwin/nlsfuncs.cc
+++ b/winsup/cygwin/nlsfuncs.cc
@@ -1070,7 +1070,7 @@ __set_lc_messages_from_win (const char *name,
    LC_COLLATE locale information.  This is subsequently accessed by the
    below functions strcoll, strxfrm, wcscoll, wcsxfrm. */
 extern "C" int
-__collate_load_locale (struct _thr_locale_t *locale, const char *name,
+__collate_load_locale (struct __locale_t *locale, const char *name,
 		       void *f_mbtowc, const char *charset)
 {
   const struct lc_collate_T *ccop;



More information about the Cygwin-cvs mailing list