Link failure with locale routines (when _MB_CAPABLE undefined)
Richard Earnshaw (lists)
Richard.Earnshaw@arm.com
Wed Aug 24 10:56:00 GMT 2016
My builds last night all failed with:
In file included from
/arm/scratch/rearnsha/gnusrc/gcc-cross/trunk/newlib/libc/stdlib/../locale/setlocale.h:38:0,
from
/arm/scratch/rearnsha/gnusrc/gcc-cross/trunk/newlib/libc/stdlib/local.h:8,
from
/arm/scratch/rearnsha/gnusrc/gcc-cross/trunk/newlib/libc/stdlib/efgcvt.c:140:
/arm/scratch/rearnsha/gnusrc/newlib/newlib/libc/include/locale.h:74:1:
error: unknown type name 'locale_t'; did you mean 'clockid_t'?
locale_t _newlocale_r (struct _reent *, int, const char *, locale_t);
^~~~~~~~
clockid_t
/arm/scratch/rearnsha/gnusrc/newlib/newlib/libc/include/locale.h:74:60:
error: unknown type name 'locale_t'; did you mean 'clockid_t'?
locale_t _newlocale_r (struct _reent *, int, const char *, locale_t);
^~~~~~~~
clockid_t
/arm/scratch/rearnsha/gnusrc/newlib/newlib/libc/include/locale.h:75:38:
error: unknown type name 'locale_t'; did you mean 'clockid_t'?
void _freelocale_r (struct _reent *, locale_t);
^~~~~~~~
clockid_t
/arm/scratch/rearnsha/gnusrc/newlib/newlib/libc/include/locale.h:76:1:
error: unknown type name 'locale_t'; did you mean 'clockid_t'?
locale_t _duplocale_r (struct _reent *, locale_t);
^~~~~~~~
clockid_t
/arm/scratch/rearnsha/gnusrc/newlib/newlib/libc/include/locale.h:76:41:
error: unknown type name 'locale_t'; did you mean 'clockid_t'?
locale_t _duplocale_r (struct _reent *, locale_t);
^~~~~~~~
clockid_t
/arm/scratch/rearnsha/gnusrc/newlib/newlib/libc/include/locale.h:77:1:
error: unknown type name 'locale_t'; did you mean 'clockid_t'?
locale_t _uselocale_r (struct _reent *, locale_t);
^~~~~~~~
clockid_t
/arm/scratch/rearnsha/gnusrc/newlib/newlib/libc/include/locale.h:77:41:
error: unknown type name 'locale_t'; did you mean 'clockid_t'?
locale_t _uselocale_r (struct _reent *, locale_t);
^~~~~~~~
clockid_t
Should the header be using struct __locale_t *?
R.
On 23/08/16 13:18, Corinna Vinschen wrote:
> 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
>
>
> 0001-Add-__get_C_locale-inline-function-and-fix-new-local.patch
>
>
> 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)
>
More information about the Newlib
mailing list