2002-08-28  Ulrich Drepper  <drepper@redhat.com>

	* include/wchar.h: Declare __mbsrtowcs_l.
	* wcsmbs/Makefile (routines): Add mbsrtowcs_l.
	* wcsmbs/mbsrtowcs.c: Add support for compilation with
	USE_IN_EXTENDED_LOCALE_MODEL.
	* wcsmbs/mbsrtowcs_l: New file.
	* wcsmbs/wcsmbsload.c (__wcsmbs_to_wc): Renamed from to_wc.  Don't
	define as static.  Change all uses.
	(__wcsmbs_getfct): Renamed from getfct.  Don't define as static.
	Change all callers.
	* wcsmbs/wcsmbsload.h: Declare __wcsmbs_to_wc and __wcsmbs_getfct.
	* time/strftime.c: When translating for the extended locale model
	use the _l functions.
	* time/Makefile (tests): Add tst-ftime_l.
	* time/tst-ftime_l.c: New file.
This commit is contained in:
Ulrich Drepper 2002-08-29 06:50:10 +00:00
parent 653e589512
commit 01beb5b9ff
9 changed files with 185 additions and 36 deletions

View File

@ -1,3 +1,20 @@
2002-08-28 Ulrich Drepper <drepper@redhat.com>
* include/wchar.h: Declare __mbsrtowcs_l.
* wcsmbs/Makefile (routines): Add mbsrtowcs_l.
* wcsmbs/mbsrtowcs.c: Add support for compilation with
USE_IN_EXTENDED_LOCALE_MODEL.
* wcsmbs/mbsrtowcs_l: New file.
* wcsmbs/wcsmbsload.c (__wcsmbs_to_wc): Renamed from to_wc. Don't
define as static. Change all uses.
(__wcsmbs_getfct): Renamed from getfct. Don't define as static.
Change all callers.
* wcsmbs/wcsmbsload.h: Declare __wcsmbs_to_wc and __wcsmbs_getfct.
* time/strftime.c: When translating for the extended locale model
use the _l functions.
* time/Makefile (tests): Add tst-ftime_l.
* time/tst-ftime_l.c: New file.
2002-08-28 Roland McGrath <roland@redhat.com> 2002-08-28 Roland McGrath <roland@redhat.com>
* locale/findlocale.c [NL_CURRENT_INDIRECT] (_nl_C): New variable. * locale/findlocale.c [NL_CURRENT_INDIRECT] (_nl_C): New variable.

View File

@ -108,5 +108,9 @@ extern int __vfwprintf (__FILE *__restrict __s,
__gnuc_va_list __arg) __gnuc_va_list __arg)
/* __attribute__ ((__format__ (__wprintf__, 3, 0))) */; /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */;
/* Internal functions. */
extern size_t __mbsrtowcs_l (wchar_t *dst, const char **src, size_t len,
mbstate_t *ps, __locale_t l) attribute_hidden;
# endif # endif
#endif #endif

View File

@ -34,7 +34,7 @@ aux := era alt_digit lc-time-cleanup
distribute := datemsk distribute := datemsk
tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
tst-getdate tst-mktime tst-getdate tst-mktime tst-ftime_l
include ../Rules include ../Rules

View File

@ -283,13 +283,24 @@ static const CHAR_T zeroes[16] = /* "0000000000000000" */
#define cpy(n, s) \ #define cpy(n, s) \
add ((n), \ add ((n), \
if (to_lowcase) \ if (to_lowcase) \
memcpy_lowcase (p, (s), _n); \ memcpy_lowcase (p, (s), _n LOCALE_ARG); \
else if (to_uppcase) \ else if (to_uppcase) \
memcpy_uppcase (p, (s), _n); \ memcpy_uppcase (p, (s), _n LOCALE_ARG); \
else \ else \
MEMCPY ((PTR) p, (const PTR) (s), _n)) MEMCPY ((PTR) p, (const PTR) (s), _n))
#ifdef COMPILE_WIDE #ifdef COMPILE_WIDE
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
# define widen(os, ws, l) \
{ \
mbstate_t __st; \
const char *__s = os; \
memset (&__st, '\0', sizeof (__st)); \
l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
ws = alloca ((l + 1) * sizeof (wchar_t)); \
(void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
}
# else
# define widen(os, ws, l) \ # define widen(os, ws, l) \
{ \ { \
mbstate_t __st; \ mbstate_t __st; \
@ -300,6 +311,7 @@ static const CHAR_T zeroes[16] = /* "0000000000000000" */
(void) __mbsrtowcs (ws, &__s, l, &__st); \ (void) __mbsrtowcs (ws, &__s, l, &__st); \
} }
# endif # endif
#endif
#if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
@ -315,9 +327,11 @@ static const CHAR_T zeroes[16] = /* "0000000000000000" */
# define LOCALE_PARAM , loc # define LOCALE_PARAM , loc
# define LOCALE_ARG , loc # define LOCALE_ARG , loc
# define LOCALE_PARAM_DECL __locale_t loc; # define LOCALE_PARAM_DECL __locale_t loc;
# define LOCALE_PARAM_PROTO , __locale_t loc
# define HELPER_LOCALE_ARG , current # define HELPER_LOCALE_ARG , current
#else #else
# define LOCALE_PARAM # define LOCALE_PARAM
# define LOCALE_PARAM_PROTO
# define LOCALE_ARG # define LOCALE_ARG
# define LOCALE_PARAM_DECL # define LOCALE_PARAM_DECL
# ifdef _LIBC # ifdef _LIBC
@ -328,15 +342,25 @@ static const CHAR_T zeroes[16] = /* "0000000000000000" */
#endif #endif
#ifdef COMPILE_WIDE #ifdef COMPILE_WIDE
# define TOUPPER(Ch) towupper (Ch) # ifdef USE_IN_EXTENDED_LOCALE_MODEL
# define TOLOWER(Ch) towlower (Ch) # define TOUPPER(Ch, L) __towupper_l (Ch, L)
# define TOLOWER(Ch, L) __towlower_l (Ch, L)
# else
# define TOUPPER(Ch, L) towupper (Ch)
# define TOLOWER(Ch, L) towlower (Ch)
# endif
#else #else
# ifdef _LIBC # ifdef _LIBC
# define TOUPPER(Ch) toupper (Ch) # ifdef USE_IN_EXTENDED_LOCALE_MODEL
# define TOLOWER(Ch) tolower (Ch) # define TOUPPER(Ch, L) __toupper_l (Ch, L)
# define TOLOWER(Ch, L) __tolower_l (Ch, L)
# else # else
# define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch)) # define TOUPPER(Ch, L) toupper (Ch)
# define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) # define TOLOWER(Ch, L) tolower (Ch)
# endif
# else
# define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
# define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
# endif # endif
#endif #endif
/* We don't use `isdigit' here since the locale dependent /* We don't use `isdigit' here since the locale dependent
@ -346,30 +370,32 @@ static const CHAR_T zeroes[16] = /* "0000000000000000" */
#define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9) #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
static CHAR_T *memcpy_lowcase __P ((CHAR_T *dest, const CHAR_T *src, static CHAR_T *memcpy_lowcase __P ((CHAR_T *dest, const CHAR_T *src,
size_t len)); size_t len LOCALE_PARAM_PROTO));
static CHAR_T * static CHAR_T *
memcpy_lowcase (dest, src, len) memcpy_lowcase (dest, src, len LOCALE_PARAM)
CHAR_T *dest; CHAR_T *dest;
const CHAR_T *src; const CHAR_T *src;
size_t len; size_t len;
LOCALE_PARAM_DECL
{ {
while (len-- > 0) while (len-- > 0)
dest[len] = TOLOWER ((UCHAR_T) src[len]); dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
return dest; return dest;
} }
static CHAR_T *memcpy_uppcase __P ((CHAR_T *dest, const CHAR_T *src, static CHAR_T *memcpy_uppcase __P ((CHAR_T *dest, const CHAR_T *src,
size_t len)); size_t len LOCALE_PARAM_PROTO));
static CHAR_T * static CHAR_T *
memcpy_uppcase (dest, src, len) memcpy_uppcase (dest, src, len LOCALE_PARAM)
CHAR_T *dest; CHAR_T *dest;
const CHAR_T *src; const CHAR_T *src;
size_t len; size_t len;
LOCALE_PARAM_DECL
{ {
while (len-- > 0) while (len-- > 0)
dest[len] = TOUPPER ((UCHAR_T) src[len]); dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
return dest; return dest;
} }
@ -844,7 +870,7 @@ my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
if (to_uppcase) if (to_uppcase)
while (old_start < p) while (old_start < p)
{ {
*old_start = TOUPPER ((UCHAR_T) *old_start); *old_start = TOUPPER ((UCHAR_T) *old_start, loc);
++old_start; ++old_start;
} }
} }

View File

@ -1,4 +1,4 @@
# Copyright (C) 1995,1996,1997,1998,1999,2000 Free Software Foundation, Inc. # Copyright (C) 1995-2000, 2002 Free Software Foundation, Inc.
# This file is part of the GNU C Library. # This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or # The GNU C Library is free software; you can redistribute it and/or
@ -37,7 +37,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
wcwidth wcswidth \ wcwidth wcswidth \
wcscoll_l wcsxfrm_l \ wcscoll_l wcsxfrm_l \
wcscasecmp wcsncase wcscasecmp_l wcsncase_l \ wcscasecmp wcsncase wcscasecmp_l wcsncase_l \
wcsmbsload wcsmbsload mbsrtowcs_l
tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
tst-wcrtomb tst-wcrtomb

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. /* Copyright (C) 1996,1997,1998,1999,2000,2002 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.org>, 1996. Contributed by Ulrich Drepper <drepper@gnu.org>, 1996.
@ -32,6 +32,16 @@
#endif #endif
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
size_t
attribute_hidden
__mbsrtowcs_l (dst, src, len, ps, l)
wchar_t *dst;
const char **src;
size_t len;
mbstate_t *ps;
__locale_t l;
#else
/* This is the private state used if PS is NULL. */ /* This is the private state used if PS is NULL. */
static mbstate_t state; static mbstate_t state;
@ -41,6 +51,7 @@ __mbsrtowcs (dst, src, len, ps)
const char **src; const char **src;
size_t len; size_t len;
mbstate_t *ps; mbstate_t *ps;
#endif
{ {
struct __gconv_step_data data; struct __gconv_step_data data;
size_t result; size_t result;
@ -52,14 +63,23 @@ __mbsrtowcs (dst, src, len, ps)
data.__invocation_counter = 0; data.__invocation_counter = 0;
data.__internal_use = 1; data.__internal_use = 1;
data.__flags = __GCONV_IS_LAST; data.__flags = __GCONV_IS_LAST;
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
data.__statep = ps;
#else
data.__statep = ps ?: &state; data.__statep = ps ?: &state;
#endif
data.__trans = NULL; data.__trans = NULL;
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
/* Get the conversion function matching the locale. */
towc = wcsmbs_get_towc_func (l);
#else
/* Make sure we use the correct function. */ /* Make sure we use the correct function. */
update_conversion_ptrs (); update_conversion_ptrs ();
/* Get the structure with the function pointers. */ /* Get the structure with the function pointers. */
towc = __wcsmbs_gconv_fcts.towc; towc = __wcsmbs_gconv_fcts.towc;
#endif
/* We have to handle DST == NULL special. */ /* We have to handle DST == NULL special. */
if (dst == NULL) if (dst == NULL)
@ -140,6 +160,13 @@ __mbsrtowcs (dst, src, len, ps)
__set_errno (EILSEQ); __set_errno (EILSEQ);
} }
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
/* Free the conversion function data structures. */
wcsmbs_free_funcs (towc);
#endif
return result; return result;
} }
#ifndef USE_IN_EXTENDED_LOCALE_MODEL
weak_alias (__mbsrtowcs, mbsrtowcs) weak_alias (__mbsrtowcs, mbsrtowcs)
#endif

55
wcsmbs/mbsrtowcs_l.c Normal file
View File

@ -0,0 +1,55 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.org>, 2002.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <ctype.h>
#include <string.h>
#include "wcsmbsload.h"
static inline struct __gconv_step *
wcsmbs_get_towc_func (__locale_t l)
{
const char *charset;
int use_translit;
char *norm;
size_t nsteps;
charset = l->__locales[LC_CTYPE]->values[_NL_ITEM_INDEX(CODESET)].string;
/* Transliteration requested? */
use_translit = l->__locales[LC_CTYPE]->use_translit;
/* Normalize the name. */
norm = norm_add_slashes (charset, use_translit ? "TRANSLIT" : NULL);
return __wcsmbs_getfct ("INTERNAL", charset, &nsteps) ?: &__wcsmbs_to_wc;
}
static inline void
wcsmbs_free_funcs (struct __gconv_step *step)
{
if (step != &__wcsmbs_to_wc)
/* There is only one step. */
__gconv_close_transform (step, 1);
}
#define USE_IN_EXTENDED_LOCALE_MODEL 1
#include "mbsrtowcs.c"

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. /* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@ -26,7 +26,6 @@
#include <locale/localeinfo.h> #include <locale/localeinfo.h>
#include <wcsmbsload.h> #include <wcsmbsload.h>
#include <bits/libc-lock.h> #include <bits/libc-lock.h>
#include <iconv/gconv_int.h>
/* Last loaded locale for LC_CTYPE. We initialize for the C locale /* Last loaded locale for LC_CTYPE. We initialize for the C locale
@ -36,7 +35,7 @@ const struct locale_data *__wcsmbs_last_locale = &_nl_C_LC_CTYPE;
/* These are the descriptions for the default conversion functions. */ /* These are the descriptions for the default conversion functions. */
static struct __gconv_step to_wc = struct __gconv_step __wcsmbs_to_wc attribute_hidden =
{ {
.__shlib_handle = NULL, .__shlib_handle = NULL,
.__modname = NULL, .__modname = NULL,
@ -76,15 +75,16 @@ static struct __gconv_step to_mb =
/* For the default locale we only have to handle ANSI_X3.4-1968. */ /* For the default locale we only have to handle ANSI_X3.4-1968. */
struct gconv_fcts __wcsmbs_gconv_fcts = struct gconv_fcts __wcsmbs_gconv_fcts =
{ {
.towc = &to_wc, .towc = &__wcsmbs_to_wc,
.towc_nsteps = 1, .towc_nsteps = 1,
.tomb = &to_mb, .tomb = &to_mb,
.tomb_nsteps = 1 .tomb_nsteps = 1
}; };
static inline struct __gconv_step * struct __gconv_step *
getfct (const char *to, const char *from, size_t *nstepsp) attribute_hidden
__wcsmbs_getfct (const char *to, const char *from, size_t *nstepsp)
{ {
size_t nsteps; size_t nsteps;
struct __gconv_step *result; struct __gconv_step *result;
@ -167,7 +167,7 @@ __wcsmbs_load_conv (const struct locale_data *new_category)
if (new_category->name == _nl_C_name) /* Yes, pointer comparison. */ if (new_category->name == _nl_C_name) /* Yes, pointer comparison. */
{ {
failed: failed:
__wcsmbs_gconv_fcts.towc = &to_wc; __wcsmbs_gconv_fcts.towc = &__wcsmbs_to_wc;
__wcsmbs_gconv_fcts.tomb = &to_mb; __wcsmbs_gconv_fcts.tomb = &to_mb;
} }
else else
@ -185,7 +185,7 @@ __wcsmbs_load_conv (const struct locale_data *new_category)
if (__wcsmbs_gconv_fcts.tomb != &to_mb) if (__wcsmbs_gconv_fcts.tomb != &to_mb)
__gconv_close_transform (__wcsmbs_gconv_fcts.tomb, __gconv_close_transform (__wcsmbs_gconv_fcts.tomb,
__wcsmbs_gconv_fcts.tomb_nsteps); __wcsmbs_gconv_fcts.tomb_nsteps);
if (__wcsmbs_gconv_fcts.towc != &to_wc) if (__wcsmbs_gconv_fcts.towc != &__wcsmbs_to_wc)
__gconv_close_transform (__wcsmbs_gconv_fcts.towc, __gconv_close_transform (__wcsmbs_gconv_fcts.towc,
__wcsmbs_gconv_fcts.towc_nsteps); __wcsmbs_gconv_fcts.towc_nsteps);
@ -203,9 +203,11 @@ __wcsmbs_load_conv (const struct locale_data *new_category)
/* It is not necessary to use transliteration in this direction /* It is not necessary to use transliteration in this direction
since the internal character set is supposed to be able to since the internal character set is supposed to be able to
represent all others. */ represent all others. */
new_towc = getfct ("INTERNAL", complete_name, &new_towc_nsteps); new_towc = __wcsmbs_getfct ("INTERNAL", complete_name,
&new_towc_nsteps);
new_tomb = (new_towc != NULL new_tomb = (new_towc != NULL
? getfct (complete_name, "INTERNAL", &new_tomb_nsteps) ? __wcsmbs_getfct (complete_name, "INTERNAL",
&new_tomb_nsteps)
: NULL); : NULL);
/* If any of the conversion functions is not available we don't /* If any of the conversion functions is not available we don't
@ -262,10 +264,10 @@ int
internal_function internal_function
__wcsmbs_named_conv (struct gconv_fcts *copy, const char *name) __wcsmbs_named_conv (struct gconv_fcts *copy, const char *name)
{ {
copy->towc = getfct ("INTERNAL", name, &copy->towc_nsteps); copy->towc = __wcsmbs_getfct ("INTERNAL", name, &copy->towc_nsteps);
if (copy->towc != NULL) if (copy->towc != NULL)
{ {
copy->tomb = getfct (name, "INTERNAL", &copy->tomb_nsteps); copy->tomb = __wcsmbs_getfct (name, "INTERNAL", &copy->tomb_nsteps);
if (copy->tomb == NULL) if (copy->tomb == NULL)
__gconv_close_transform (copy->towc, copy->towc_nsteps); __gconv_close_transform (copy->towc, copy->towc_nsteps);
} }
@ -287,11 +289,11 @@ free_mem (void)
__gconv_release_cache (old, nold); __gconv_release_cache (old, nold);
} }
if (__wcsmbs_gconv_fcts.towc != &to_wc) if (__wcsmbs_gconv_fcts.towc != &__wcsmbs_to_wc)
{ {
struct __gconv_step *old = __wcsmbs_gconv_fcts.towc; struct __gconv_step *old = __wcsmbs_gconv_fcts.towc;
size_t nold = __wcsmbs_gconv_fcts.towc_nsteps; size_t nold = __wcsmbs_gconv_fcts.towc_nsteps;
__wcsmbs_gconv_fcts.towc = &to_wc; __wcsmbs_gconv_fcts.towc = &__wcsmbs_to_wc;
__wcsmbs_gconv_fcts.towc_nsteps = 1; __wcsmbs_gconv_fcts.towc_nsteps = 1;
__gconv_release_cache (old, nold); __gconv_release_cache (old, nold);
} }

View File

@ -17,6 +17,9 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA. */
#ifndef _WCSMBSLOAD_H
#define _WCSMBSLOAD_H 1
#include <locale.h> #include <locale.h>
#include <wchar.h> #include <wchar.h>
#include <locale/localeinfo.h> #include <locale/localeinfo.h>
@ -52,6 +55,19 @@ extern int __wcsmbs_named_conv (struct gconv_fcts *copy, const char *name)
internal_function; internal_function;
#include <iconv/gconv_int.h>
/* Variable for conversion from ASCII to wchar_t. */
extern struct __gconv_step __wcsmbs_to_wc attribute_hidden;
/* Load the function implementation if necessary. */
extern struct __gconv_step *__wcsmbs_getfct (const char *to, const char *from,
size_t *nstepsp)
attribute_hidden;
/* Check whether the LC_CTYPE locale changed since the last call. /* Check whether the LC_CTYPE locale changed since the last call.
Update the pointers appropriately. */ Update the pointers appropriately. */
static inline void static inline void
@ -60,3 +76,5 @@ update_conversion_ptrs (void)
if (__wcsmbs_last_locale != _NL_CURRENT_DATA (LC_CTYPE)) if (__wcsmbs_last_locale != _NL_CURRENT_DATA (LC_CTYPE))
__wcsmbs_load_conv (_NL_CURRENT_DATA (LC_CTYPE)); __wcsmbs_load_conv (_NL_CURRENT_DATA (LC_CTYPE));
} }
#endif /* wcsmbsload.h */