Link failure with locale routines (when _MB_CAPABLE undefined)

Corinna Vinschen vinschen@redhat.com
Tue Aug 23 12:18:00 GMT 2016


On Aug 23 12:59, Corinna Vinschen wrote:
> [...]
> So I came up with the attached patch, which enables __global_locale
> for !_MB_CAPABLE targets, like your patch, but then accommodates those
> targets throughout the new functions instead of disabling them.
> 
> Would you mind to give it a try?

Use the one attached here, against current master.  I screwed up
while creating the latest pacthes using `git gui' somehow so master
had a stray closing brace.  Fixed now, thanks to Jon Turney.


Thanks,
Corinna

-- 
Corinna Vinschen
Cygwin Maintainer
Red Hat
-------------- next part --------------
From 40b8e91e9a5f46a9fb7ba36dbb10eb2b41f1d1fd Mon Sep 17 00:00:00 2001
From: Corinna Vinschen <corinna@vinschen.de>
Date: Tue, 23 Aug 2016 12:49:23 +0200
Subject: [PATCH] Add __get_C_locale inline function and fix new locale code
 for !_MB_CAPABLE targets

Only access "C" locale using the new __get_C_locale inline function.
Enable __global_locale for !_MB_CAPABLE targets.  Accommodate !_MB_CAPABLE
targets in new locale code.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
---
 newlib/libc/locale/duplocale.c  |  8 ++++++--
 newlib/libc/locale/freelocale.c |  5 ++++-
 newlib/libc/locale/locale.c     |  5 +++++
 newlib/libc/locale/newlocale.c  |  8 ++++++--
 newlib/libc/locale/setlocale.h  | 16 +++++++++++++++-
 5 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/newlib/libc/locale/duplocale.c b/newlib/libc/locale/duplocale.c
index 263a2b5..06ebfcd 100644
--- a/newlib/libc/locale/duplocale.c
+++ b/newlib/libc/locale/duplocale.c
@@ -45,12 +45,15 @@ _duplocale_r (struct _reent *p, struct __locale_t *locobj)
   struct __locale_t tmp_locale, *new_locale;
   int i;
 
+#ifndef _MB_CAPABLE
+  return __get_C_locale ();
+#else /* _MB_CAPABLE */
   /* LC_GLOBAL_LOCALE denotes the global locale. */
   if (locobj == LC_GLOBAL_LOCALE)
     locobj = __get_global_locale ();
   /* The "C" locale is used statically, never copied. */
-  else if (locobj == &__C_locale)
-    return (struct __locale_t *) &__C_locale;
+  else if (locobj == __get_C_locale ())
+    return __get_C_locale ();
   /* Copy locale content. */
   tmp_locale = *locobj;
 #ifdef __HAVE_LOCALE_INFO__
@@ -86,6 +89,7 @@ error:
 #endif /* __HAVE_LOCALE_INFO__ */
 
   return NULL;
+#endif /* _MB_CAPABLE */
 }
 
 #ifndef _REENT_ONLY
diff --git a/newlib/libc/locale/freelocale.c b/newlib/libc/locale/freelocale.c
index eba439e..dd3c0f9 100644
--- a/newlib/libc/locale/freelocale.c
+++ b/newlib/libc/locale/freelocale.c
@@ -40,8 +40,10 @@ PORTABILITY
 void
 _freelocale_r (struct _reent *p, struct __locale_t *locobj)
 {
+  /* Nothing to do on !_MB_CAPABLE targets. */
+#ifdef _MB_CAPABLE
   /* Sanity check.  The "C" locale is static, don't try to free it. */
-  if (!locobj || locobj == &__C_locale || locobj == LC_GLOBAL_LOCALE)
+  if (!locobj || locobj == __get_C_locale () || locobj == LC_GLOBAL_LOCALE)
     return;
 #ifdef __HAVE_LOCALE_INFO__
   for (int i = 1; i < _LC_LAST; ++i)
@@ -52,6 +54,7 @@ _freelocale_r (struct _reent *p, struct __locale_t *locobj)
       }
 #endif /* __HAVE_LOCALE_INFO__ */
   _free_r (p, locobj);
+#endif /* _MB_CAPABLE */
 }
 
 void
diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c
index 9808022..fe04395 100644
--- a/newlib/libc/locale/locale.c
+++ b/newlib/libc/locale/locale.c
@@ -203,6 +203,7 @@ static char *categories[_LC_LAST] = {
   "LC_TIME",
   "LC_MESSAGES",
 };
+#endif /* _MB_CAPABLE */
 
 /*
  * Default locale per POSIX.  Can be overridden on a per-target base.
@@ -210,6 +211,8 @@ static char *categories[_LC_LAST] = {
 #ifndef DEFAULT_LOCALE
 #define DEFAULT_LOCALE	"C"
 #endif
+
+#ifdef _MB_CAPABLE
 /*
  * This variable can be changed by any outside mechanism.  This allows,
  * for instance, to load the default locale from a file.
@@ -250,6 +253,7 @@ const struct __locale_t __C_locale =
   },
 #endif /* __HAVE_LOCALE_INFO__ */
 };
+#endif /* _MB_CAPABLE */
 
 struct __locale_t __global_locale =
 {
@@ -291,6 +295,7 @@ 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. */
diff --git a/newlib/libc/locale/newlocale.c b/newlib/libc/locale/newlocale.c
index b4a4778..bd4e385 100644
--- a/newlib/libc/locale/newlocale.c
+++ b/newlib/libc/locale/newlocale.c
@@ -86,6 +86,9 @@ struct __locale_t *
 _newlocale_r (struct _reent *p, int category_mask, const char *locale,
 	      struct __locale_t *base)
 {
+#ifndef _MB_CAPABLE
+  return __get_C_locale ();
+#else /* _MB_CAPABLE */
   char new_categories[_LC_LAST][ENCODING_LEN + 1];
   struct __locale_t tmp_locale, *new_locale;
   int i;
@@ -108,9 +111,9 @@ _newlocale_r (struct _reent *p, int category_mask, const char *locale,
   if ((!base && category_mask == 0)
       || (category_mask == LC_VALID_MASK
 	  && (!strcmp (locale, "C") || !strcmp (locale, "POSIX"))))
-    return (struct __locale_t *) &__C_locale;
+    return __get_C_locale ();
   /* Start with setting all values to the default locale values. */
-  tmp_locale = __C_locale;
+  tmp_locale = *__get_C_locale ();
   /* Fill out new category strings. */
   for (i = 1; i < _LC_LAST; ++i)
     {
@@ -206,6 +209,7 @@ error:
 #endif /* __HAVE_LOCALE_INFO__ */
 
   return NULL;
+#endif /* _MB_CAPABLE */
 }
 
 struct __locale_t *
diff --git a/newlib/libc/locale/setlocale.h b/newlib/libc/locale/setlocale.h
index 86b638b..daf9323 100644
--- a/newlib/libc/locale/setlocale.h
+++ b/newlib/libc/locale/setlocale.h
@@ -194,9 +194,10 @@ struct __locale_t
 #endif
 };
 
-extern const struct __locale_t __C_locale;
+#ifdef _MB_CAPABLE
 extern char *__loadlocale (struct __locale_t *, int, const char *);
 extern const char *__get_locale_env(struct _reent *, int);
+#endif /* _MB_CAPABLE */
 
 extern struct lconv *__localeconv_l (struct __locale_t *locale);
 
@@ -229,6 +230,19 @@ __get_current_locale ()
   return _REENT->_locale ?: __get_global_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 *
+__get_C_locale ()
+{
+#ifndef _MB_CAPABLE
+  return __get_global_locale ();
+#else
+  extern const struct __locale_t __C_locale;
+  return (struct __locale_t *) &__C_locale;
+#endif
+}
+
 #ifdef __CYGWIN__
 _ELIDABLE_INLINE const struct lc_collate_T *
 __get_collate_locale (struct __locale_t *locale)
-- 
2.5.5

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/newlib/attachments/20160823/acebc64a/attachment.sig>


More information about the Newlib mailing list