1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-06-05 00:22:17 +03:00

* locale/localeinfo.h (struct locale_data): Add private.ctype.

* wcsmbs/wcsmbsload.h (__wcsmbs_gconv_fcts, __wcsmbs_last_locale,
	__wcsmbs_to_wc, update_conversion_ptrs): Removed.
	(__wcsmbs_gconv_fcts_c, _nl_C_LC_CTYPE): New externs.
	(__wcsmbs_load_conv): Remove const from argument.
	(_nl_cleanup_ctype): New proto.
	(get_gconv_fcts): New function.
	* wcsmbs/wcsmbsload.c (__wcsmbs_last_locale): Removed.
	(__wcsmbs_to_wc): Rename back to...
	(to_wc): ... this.
	(__wcsmbs_gconv_fcts): Rename to...
	(__wcsmbs_gconv_fcts_c): ... this.  Make const.  Use to_wc.
	(lock): Removed.
	(__libc_setlocale_lock): New extern.
	(__wcsmbs_load_conv): Remove const from argument.
	Initialize new_category->private.ctype instead of a global
	variable.
	(__wcsmbs_clone_conv): Use get_gconv_fcts instead of
	update_function_ptrs.  No locking is necessary.
	(_nl_cleanup_ctype): New function.
	* wcsmbs/btowc.c (__btowc): Use get_gconv_fcts instead of
	update_function_ptrs and a global __wcsmbs_gconv_fcts variable.
	* wcsmbs/mbrtowc.c (__mbrtowc): Likewise.
	* wcsmbs/mbsnrtowcs.c (__mbsnrtowcs): Likewise.
	* wcsmbs/wcrtomb.c (__wcrtomb): Likewise.
	* wcsmbs/wcsnrtombs.c (__wcsnrtombs): Likewise.
	* wcsmbs/wcsrtombs.c (__wcsrtombs): Likewise.
	* wcsmbs/wctob.c (wctob): Likewise.
	* stdlib/mblen.c (mblen): Likewise.
	* stdlib/mbtowc.c (mbtowc): Likewise.
	* stdlib/wctomb.c (wctomb): Likewise.
	* wcsmbs/mbsrtowcs.c (__mbsrtowcs): Likewise.
	Remove calls to wcsmbs_get_towc_func and wcsmbs_free_funcs.
	* wcsmbs/mbsrtowcs_l.c (wcsmbs_get_towc_func, wcsmbs_free_funcs):
	Removed.
This commit is contained in:
Roland McGrath 2002-09-02 19:34:39 +00:00
parent 1977e59058
commit 963102971d
16 changed files with 181 additions and 200 deletions

View File

@ -1,3 +1,41 @@
2002-09-02 Jakub Jelinek <jakub@redhat.com>
* locale/localeinfo.h (struct locale_data): Add private.ctype.
* wcsmbs/wcsmbsload.h (__wcsmbs_gconv_fcts, __wcsmbs_last_locale,
__wcsmbs_to_wc, update_conversion_ptrs): Removed.
(__wcsmbs_gconv_fcts_c, _nl_C_LC_CTYPE): New externs.
(__wcsmbs_load_conv): Remove const from argument.
(_nl_cleanup_ctype): New proto.
(get_gconv_fcts): New function.
* wcsmbs/wcsmbsload.c (__wcsmbs_last_locale): Removed.
(__wcsmbs_to_wc): Rename back to...
(to_wc): ... this.
(__wcsmbs_gconv_fcts): Rename to...
(__wcsmbs_gconv_fcts_c): ... this. Make const. Use to_wc.
(lock): Removed.
(__libc_setlocale_lock): New extern.
(__wcsmbs_load_conv): Remove const from argument.
Initialize new_category->private.ctype instead of a global
variable.
(__wcsmbs_clone_conv): Use get_gconv_fcts instead of
update_function_ptrs. No locking is necessary.
(_nl_cleanup_ctype): New function.
* wcsmbs/btowc.c (__btowc): Use get_gconv_fcts instead of
update_function_ptrs and a global __wcsmbs_gconv_fcts variable.
* wcsmbs/mbrtowc.c (__mbrtowc): Likewise.
* wcsmbs/mbsnrtowcs.c (__mbsnrtowcs): Likewise.
* wcsmbs/wcrtomb.c (__wcrtomb): Likewise.
* wcsmbs/wcsnrtombs.c (__wcsnrtombs): Likewise.
* wcsmbs/wcsrtombs.c (__wcsrtombs): Likewise.
* wcsmbs/wctob.c (wctob): Likewise.
* stdlib/mblen.c (mblen): Likewise.
* stdlib/mbtowc.c (mbtowc): Likewise.
* stdlib/wctomb.c (wctomb): Likewise.
* wcsmbs/mbsrtowcs.c (__mbsrtowcs): Likewise.
Remove calls to wcsmbs_get_towc_func and wcsmbs_free_funcs.
* wcsmbs/mbsrtowcs_l.c (wcsmbs_get_towc_func, wcsmbs_free_funcs):
Removed.
2002-09-02 Roland McGrath <roland@frob.com> 2002-09-02 Roland McGrath <roland@frob.com>
* sysdeps/mach/hurd/Versions (ld: GLIBC_2.0): Add __fxstat64. * sysdeps/mach/hurd/Versions (ld: GLIBC_2.0): Add __fxstat64.

View File

@ -64,6 +64,7 @@ struct locale_data
{ {
void *data; void *data;
struct lc_time_data *time; struct lc_time_data *time;
const struct gconv_fcts *ctype;
}; };
} private; } private;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. /* Copyright (C) 1991,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.
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
@ -40,13 +40,15 @@ mblen (const char *s, size_t n)
not. */ not. */
if (s == NULL) if (s == NULL)
{ {
/* Make sure we use the correct value. */ const struct gconv_fcts *fcts;
update_conversion_ptrs ();
/* Get the conversion functions. */
fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
/* Reset the state. */ /* Reset the state. */
memset (&state, '\0', sizeof state); memset (&state, '\0', sizeof state);
result = __wcsmbs_gconv_fcts.towc->__stateful; result = fcts->towc->__stateful;
} }
else if (*s == '\0') else if (*s == '\0')
/* According to the ISO C 89 standard this is the expected behaviour. */ /* According to the ISO C 89 standard this is the expected behaviour. */

View File

@ -44,14 +44,16 @@ mbtowc (wchar_t *pwc, const char *s, size_t n)
not. */ not. */
if (s == NULL) if (s == NULL)
{ {
/* Make sure we use the correct value. */ const struct gconv_fcts *fcts;
update_conversion_ptrs ();
/* Get the conversion functions. */
fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
/* This is an extension in the Unix standard which does not directly /* This is an extension in the Unix standard which does not directly
violate ISO C. */ violate ISO C. */
memset (&__no_r_state, '\0', sizeof __no_r_state); memset (&__no_r_state, '\0', sizeof __no_r_state);
result = __wcsmbs_gconv_fcts.towc->__stateful; result = fcts->towc->__stateful;
} }
else if (*s == '\0') else if (*s == '\0')
{ {

View File

@ -40,14 +40,16 @@ wctomb (char *s, wchar_t wchar)
not. */ not. */
if (s == NULL) if (s == NULL)
{ {
/* Make sure we use the correct value. */ const struct gconv_fcts *fcts;
update_conversion_ptrs ();
/* Get the conversion functions. */
fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
/* This is an extension in the Unix standard which does not directly /* This is an extension in the Unix standard which does not directly
violate ISO C. */ violate ISO C. */
memset (&__no_r_state, '\0', sizeof __no_r_state); memset (&__no_r_state, '\0', sizeof __no_r_state);
return __wcsmbs_gconv_fcts.tomb->__stateful; return fcts->tomb->__stateful;
} }
return __wcrtomb (s, wchar, &__no_r_state); return __wcrtomb (s, wchar, &__no_r_state);

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.
@ -36,6 +36,7 @@ __btowc (c)
const unsigned char *inptr = inbuf; const unsigned char *inptr = inbuf;
size_t dummy; size_t dummy;
int status; int status;
const struct gconv_fcts *fcts;
/* If the parameter does not fit into one byte or it is the EOF value /* If the parameter does not fit into one byte or it is the EOF value
we can give the answer now. */ we can give the answer now. */
@ -54,14 +55,14 @@ __btowc (c)
/* Make sure we start in the initial state. */ /* Make sure we start in the initial state. */
memset (&data.__state, '\0', sizeof (mbstate_t)); memset (&data.__state, '\0', sizeof (mbstate_t));
/* Make sure we use the correct function. */ /* Get the conversion functions. */
update_conversion_ptrs (); fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
/* Create the input string. */ /* Create the input string. */
inbuf[0] = c; inbuf[0] = c;
status = DL_CALL_FCT (__wcsmbs_gconv_fcts.towc->__fct, status = DL_CALL_FCT (fcts->towc->__fct,
(__wcsmbs_gconv_fcts.towc, &data, &inptr, inptr + 1, (fcts->towc, &data, &inptr, inptr + 1,
NULL, &dummy, 0, 1)); NULL, &dummy, 0, 1));
/* The conversion failed. */ /* The conversion failed. */
if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT

View File

@ -42,6 +42,7 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
size_t dummy; size_t dummy;
const unsigned char *inbuf; const unsigned char *inbuf;
char *outbuf = (char *) (pwc ?: buf); char *outbuf = (char *) (pwc ?: buf);
const struct gconv_fcts *fcts;
/* Set information for this step. */ /* Set information for this step. */
data.__invocation_counter = 0; data.__invocation_counter = 0;
@ -63,13 +64,13 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
data.__outbuf = outbuf; data.__outbuf = outbuf;
data.__outbufend = outbuf + sizeof (wchar_t); data.__outbufend = outbuf + sizeof (wchar_t);
/* Make sure we use the correct function. */ /* Get the conversion functions. */
update_conversion_ptrs (); fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
/* Do a normal conversion. */ /* Do a normal conversion. */
inbuf = (const unsigned char *) s; inbuf = (const unsigned char *) s;
status = DL_CALL_FCT (__wcsmbs_gconv_fcts.towc->__fct, status = DL_CALL_FCT (fcts->towc->__fct,
(__wcsmbs_gconv_fcts.towc, &data, &inbuf, inbuf + n, (fcts->towc, &data, &inbuf, inbuf + n,
NULL, &dummy, 0, 1)); NULL, &dummy, 0, 1));
/* There must not be any problems with the conversion but illegal input /* There must not be any problems with the conversion but illegal input

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.
@ -51,6 +51,7 @@ __mbsnrtowcs (dst, src, nmc, len, ps)
int status; int status;
struct __gconv_step *towc; struct __gconv_step *towc;
size_t dummy; size_t dummy;
const struct gconv_fcts *fcts;
/* Tell where we want the result. */ /* Tell where we want the result. */
data.__invocation_counter = 0; data.__invocation_counter = 0;
@ -63,11 +64,11 @@ __mbsnrtowcs (dst, src, nmc, len, ps)
return 0; return 0;
srcend = *src + __strnlen (*src, nmc - 1) + 1; srcend = *src + __strnlen (*src, nmc - 1) + 1;
/* Make sure we use the correct function. */ /* Get the conversion functions. */
update_conversion_ptrs (); fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
/* Get the structure with the function pointers. */ /* Get the structure with the function pointers. */
towc = __wcsmbs_gconv_fcts.towc; towc = fcts->towc;
/* We have to handle DST == NULL special. */ /* We have to handle DST == NULL special. */
if (dst == NULL) if (dst == NULL)

View File

@ -58,6 +58,7 @@ __mbsrtowcs (dst, src, len, ps)
int status; int status;
struct __gconv_step *towc; struct __gconv_step *towc;
size_t non_reversible; size_t non_reversible;
const struct gconv_fcts *fcts;
/* Tell where we want the result. */ /* Tell where we want the result. */
data.__invocation_counter = 0; data.__invocation_counter = 0;
@ -70,16 +71,15 @@ __mbsrtowcs (dst, src, len, ps)
#endif #endif
data.__trans = NULL; data.__trans = NULL;
/* Get the conversion functions. */
#ifdef USE_IN_EXTENDED_LOCALE_MODEL #ifdef USE_IN_EXTENDED_LOCALE_MODEL
/* Get the conversion function matching the locale. */ fcts = get_gconv_fcts (l->__locales[LC_CTYPE]);
towc = wcsmbs_get_towc_func (l);
#else #else
/* Make sure we use the correct function. */ fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
update_conversion_ptrs (); #endif
/* Get the structure with the function pointers. */ /* Get the structure with the function pointers. */
towc = __wcsmbs_gconv_fcts.towc; towc = fcts->towc;
#endif
/* We have to handle DST == NULL special. */ /* We have to handle DST == NULL special. */
if (dst == NULL) if (dst == NULL)
@ -160,11 +160,6 @@ __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 #ifndef USE_IN_EXTENDED_LOCALE_MODEL

View File

@ -21,35 +21,5 @@
#include <string.h> #include <string.h>
#include "wcsmbsload.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 #define USE_IN_EXTENDED_LOCALE_MODEL 1
#include "mbsrtowcs.c" #include "mbsrtowcs.c"

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc. /* Copyright (C) 1996,1997,1998,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@cygnus.com>, 1996. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@ -42,6 +42,7 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
int status; int status;
size_t result; size_t result;
size_t dummy; size_t dummy;
const struct gconv_fcts *fcts;
/* Set information for this step. */ /* Set information for this step. */
data.__invocation_counter = 0; data.__invocation_counter = 0;
@ -62,16 +63,16 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
data.__outbuf = s; data.__outbuf = s;
data.__outbufend = s + MB_CUR_MAX; data.__outbufend = s + MB_CUR_MAX;
/* Make sure we use the correct function. */ /* Get the conversion functions. */
update_conversion_ptrs (); fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
/* If WC is the NUL character we write into the output buffer the byte /* If WC is the NUL character we write into the output buffer the byte
sequence necessary for PS to get into the initial state, followed sequence necessary for PS to get into the initial state, followed
by a NUL byte. */ by a NUL byte. */
if (wc == L'\0') if (wc == L'\0')
{ {
status = DL_CALL_FCT (__wcsmbs_gconv_fcts.tomb->__fct, status = DL_CALL_FCT (fcts->tomb->__fct,
(__wcsmbs_gconv_fcts.tomb, &data, NULL, NULL, (fcts->tomb, &data, NULL, NULL,
NULL, &dummy, 1, 1)); NULL, &dummy, 1, 1));
if (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT) if (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT)
@ -82,8 +83,8 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
/* Do a normal conversion. */ /* Do a normal conversion. */
const unsigned char *inbuf = (const unsigned char *) &wc; const unsigned char *inbuf = (const unsigned char *) &wc;
status = DL_CALL_FCT (__wcsmbs_gconv_fcts.tomb->__fct, status = DL_CALL_FCT (fcts->tomb->__fct,
(__wcsmbs_gconv_fcts.tomb, &data, &inbuf, (fcts->tomb, &data, &inbuf,
inbuf + sizeof (wchar_t), NULL, &dummy, 0, 1)); inbuf + sizeof (wchar_t), NULL, &dummy, 0, 1));
} }

View File

@ -28,14 +28,8 @@
#include <bits/libc-lock.h> #include <bits/libc-lock.h>
/* Last loaded locale for LC_CTYPE. We initialize for the C locale
which is enabled at startup. */
extern const struct locale_data _nl_C_LC_CTYPE;
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. */
struct __gconv_step __wcsmbs_to_wc attribute_hidden = static struct __gconv_step to_wc =
{ {
.__shlib_handle = NULL, .__shlib_handle = NULL,
.__modname = NULL, .__modname = NULL,
@ -73,9 +67,9 @@ 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 = const struct gconv_fcts __wcsmbs_gconv_fcts_c =
{ {
.towc = &__wcsmbs_to_wc, .towc = &to_wc,
.towc_nsteps = 1, .towc_nsteps = 1,
.tomb = &to_mb, .tomb = &to_mb,
.tomb_nsteps = 1 .tomb_nsteps = 1
@ -148,90 +142,73 @@ __wcsmbs_getfct (const char *to, const char *from, size_t *nstepsp)
}) })
/* We must modify global data. */ /* Some of the functions here must not be used while setlocale is called. */
__libc_lock_define_initialized (static, lock) __libc_lock_define (extern, __libc_setlocale_lock attribute_hidden)
/* Load conversion functions for the currently selected locale. */ /* Load conversion functions for the currently selected locale. */
void void
internal_function internal_function
__wcsmbs_load_conv (const struct locale_data *new_category) __wcsmbs_load_conv (struct locale_data *new_category)
{ {
/* Acquire the lock. */ /* Acquire the lock. */
__libc_lock_lock (lock); __libc_lock_lock (__libc_setlocale_lock);
/* We should repeat the test since while we waited some other thread /* We should repeat the test since while we waited some other thread
might have run this function. */ might have run this function. */
if (__builtin_expect (__wcsmbs_last_locale != new_category, 1)) if (__builtin_expect (new_category->private.ctype == NULL, 1))
{ {
if (new_category->name == _nl_C_name) /* Yes, pointer comparison. */ /* We must find the real functions. */
const char *charset_name;
const char *complete_name;
struct gconv_fcts *new_fcts;
int use_translit;
/* Allocate the gconv_fcts structure. */
new_fcts = malloc (sizeof *new_fcts);
if (new_fcts == NULL)
{ {
failed: failed:
__wcsmbs_gconv_fcts.towc = &__wcsmbs_to_wc; new_category->private.ctype = &__wcsmbs_gconv_fcts_c;
__wcsmbs_gconv_fcts.tomb = &to_mb;
} }
else
/* Get name of charset of the locale. */
charset_name = new_category->values[_NL_ITEM_INDEX(CODESET)].string;
/* Does the user want transliteration? */
use_translit = new_category->use_translit;
/* Normalize the name and add the slashes necessary for a
complete lookup. */
complete_name = norm_add_slashes (charset_name,
use_translit ? "TRANSLIT" : NULL);
/* It is not necessary to use transliteration in this direction
since the internal character set is supposed to be able to
represent all others. */
new_fcts->towc = __wcsmbs_getfct ("INTERNAL", complete_name,
&new_fcts->towc_nsteps);
new_fcts->tomb = (new_fcts->towc != NULL
? __wcsmbs_getfct (complete_name, "INTERNAL",
&new_fcts->tomb_nsteps)
: NULL);
/* If any of the conversion functions is not available we don't
use any since this would mean we cannot convert back and
forth.*/
if (new_fcts->tomb == NULL)
{ {
/* We must find the real functions. */ if (new_fcts->towc != NULL)
const char *charset_name; __gconv_close_transform (new_fcts->towc, new_fcts->towc_nsteps);
const char *complete_name;
struct __gconv_step *new_towc;
size_t new_towc_nsteps;
struct __gconv_step *new_tomb;
size_t new_tomb_nsteps;
int use_translit;
/* Free the old conversions. */ free (new_fcts);
if (__wcsmbs_gconv_fcts.tomb != &to_mb) goto failed;
__gconv_close_transform (__wcsmbs_gconv_fcts.tomb,
__wcsmbs_gconv_fcts.tomb_nsteps);
if (__wcsmbs_gconv_fcts.towc != &__wcsmbs_to_wc)
__gconv_close_transform (__wcsmbs_gconv_fcts.towc,
__wcsmbs_gconv_fcts.towc_nsteps);
/* Get name of charset of the locale. */
charset_name = new_category->values[_NL_ITEM_INDEX(CODESET)].string;
/* Does the user want transliteration? */
use_translit = new_category->use_translit;
/* Normalize the name and add the slashes necessary for a
complete lookup. */
complete_name = norm_add_slashes (charset_name,
use_translit ? "TRANSLIT" : NULL);
/* It is not necessary to use transliteration in this direction
since the internal character set is supposed to be able to
represent all others. */
new_towc = __wcsmbs_getfct ("INTERNAL", complete_name,
&new_towc_nsteps);
new_tomb = (new_towc != NULL
? __wcsmbs_getfct (complete_name, "INTERNAL",
&new_tomb_nsteps)
: NULL);
/* If any of the conversion functions is not available we don't
use any since this would mean we cannot convert back and
forth.*/
if (new_towc == NULL || new_tomb == NULL)
{
if (new_towc != NULL)
__gconv_close_transform (new_towc, 1);
goto failed;
}
__wcsmbs_gconv_fcts.tomb = new_tomb;
__wcsmbs_gconv_fcts.tomb_nsteps = new_tomb_nsteps;
__wcsmbs_gconv_fcts.towc = new_towc;
__wcsmbs_gconv_fcts.towc_nsteps = new_towc_nsteps;
} }
/* Set last-used variable for current locale. */ new_category->private.ctype = new_fcts;
__wcsmbs_last_locale = new_category; new_category->private.cleanup = &_nl_cleanup_ctype;
} }
__libc_lock_unlock (lock); __libc_lock_unlock (__libc_setlocale_lock);
} }
@ -240,22 +217,18 @@ void
internal_function internal_function
__wcsmbs_clone_conv (struct gconv_fcts *copy) __wcsmbs_clone_conv (struct gconv_fcts *copy)
{ {
/* First make sure the function table is up-to-date. */ const struct gconv_fcts *orig;
update_conversion_ptrs ();
/* Make sure the data structures remain the same until we are finished. */ orig = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
__libc_lock_lock (lock);
/* Copy the data. */ /* Copy the data. */
*copy = __wcsmbs_gconv_fcts; *copy = *orig;
/* Now increment the usage counters. */ /* Now increment the usage counters. */
if (copy->towc->__shlib_handle != NULL) if (copy->towc->__shlib_handle != NULL)
++copy->towc->__counter; ++copy->towc->__counter;
if (copy->tomb->__shlib_handle != NULL) if (copy->tomb->__shlib_handle != NULL)
++copy->tomb->__counter; ++copy->tomb->__counter;
__libc_lock_unlock (lock);
} }
@ -275,28 +248,18 @@ __wcsmbs_named_conv (struct gconv_fcts *copy, const char *name)
return copy->towc == NULL || copy->tomb == NULL ? 1 : 0; return copy->towc == NULL || copy->tomb == NULL ? 1 : 0;
} }
void internal_function
/* Free all resources if necessary. */ _nl_cleanup_ctype (struct locale_data *locale)
static void __attribute__ ((unused))
free_mem (void)
{ {
if (__wcsmbs_gconv_fcts.tomb != &to_mb) const struct gconv_fcts *const data = locale->private.ctype;
if (data != NULL)
{ {
struct __gconv_step *old = __wcsmbs_gconv_fcts.tomb; locale->private.ctype = NULL;
size_t nold = __wcsmbs_gconv_fcts.tomb_nsteps; locale->private.cleanup = NULL;
__wcsmbs_gconv_fcts.tomb = &to_mb;
__wcsmbs_gconv_fcts.tomb_nsteps = 1;
__gconv_release_cache (old, nold);
}
if (__wcsmbs_gconv_fcts.towc != &__wcsmbs_to_wc) /* Free the old conversions. */
{ __gconv_close_transform (data->tomb, data->tomb_nsteps);
struct __gconv_step *old = __wcsmbs_gconv_fcts.towc; __gconv_close_transform (data->towc, data->towc_nsteps);
size_t nold = __wcsmbs_gconv_fcts.towc_nsteps; free ((char *) data);
__wcsmbs_gconv_fcts.towc = &__wcsmbs_to_wc;
__wcsmbs_gconv_fcts.towc_nsteps = 1;
__gconv_release_cache (old, nold);
} }
} }
text_set_element (__libc_subfreeres, free_mem);

View File

@ -35,15 +35,10 @@ struct gconv_fcts
}; };
/* Set of currently active conversion functions. */ /* Set of currently active conversion functions. */
extern struct gconv_fcts __wcsmbs_gconv_fcts attribute_hidden; extern const struct gconv_fcts __wcsmbs_gconv_fcts_c attribute_hidden;
/* Last loaded locale for LC_CTYPE. */
extern const struct locale_data *__wcsmbs_last_locale attribute_hidden;
/* Load conversion functions for the currently selected locale. */ /* Load conversion functions for the currently selected locale. */
extern void __wcsmbs_load_conv (const struct locale_data *new_category) extern void __wcsmbs_load_conv (struct locale_data *new_category)
internal_function; internal_function;
/* Clone the current `__wcsmbs_load_conv' value. */ /* Clone the current `__wcsmbs_load_conv' value. */
@ -54,27 +49,33 @@ extern void __wcsmbs_clone_conv (struct gconv_fcts *copy)
extern int __wcsmbs_named_conv (struct gconv_fcts *copy, const char *name) extern int __wcsmbs_named_conv (struct gconv_fcts *copy, const char *name)
internal_function; internal_function;
/* Function used for the `private.cleanup' hook. */
extern void _nl_cleanup_ctype (struct locale_data *)
internal_function attribute_hidden;
#include <iconv/gconv_int.h> #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. */ /* Load the function implementation if necessary. */
extern struct __gconv_step *__wcsmbs_getfct (const char *to, const char *from, extern struct __gconv_step *__wcsmbs_getfct (const char *to, const char *from,
size_t *nstepsp) size_t *nstepsp)
attribute_hidden; attribute_hidden;
extern const struct locale_data _nl_C_LC_CTYPE 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 const struct gconv_fcts *
update_conversion_ptrs (void) get_gconv_fcts (struct locale_data *data)
{ {
if (__wcsmbs_last_locale != _NL_CURRENT_DATA (LC_CTYPE)) if (__builtin_expect (data->private.ctype == NULL, 0))
__wcsmbs_load_conv (_NL_CURRENT_DATA (LC_CTYPE)); {
if (__builtin_expect (data == &_nl_C_LC_CTYPE, 0))
return &__wcsmbs_gconv_fcts_c;
__wcsmbs_load_conv (data);
}
return data->private.ctype;
} }
#endif /* wcsmbsload.h */ #endif /* wcsmbsload.h */

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.
@ -49,6 +49,7 @@ __wcsnrtombs (dst, src, nwc, len, ps)
int status; int status;
size_t result; size_t result;
struct __gconv_step *tomb; struct __gconv_step *tomb;
const struct gconv_fcts *fcts;
/* Tell where we want the result. */ /* Tell where we want the result. */
data.__invocation_counter = 0; data.__invocation_counter = 0;
@ -61,11 +62,11 @@ __wcsnrtombs (dst, src, nwc, len, ps)
return 0; return 0;
srcend = *src + __wcsnlen (*src, nwc - 1) + 1; srcend = *src + __wcsnlen (*src, nwc - 1) + 1;
/* Make sure we use the correct function. */ /* Get the conversion functions. */
update_conversion_ptrs (); fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
/* Get the structure with the function pointers. */ /* Get the structure with the function pointers. */
tomb = __wcsmbs_gconv_fcts.tomb; tomb = fcts->tomb;
/* We have to handle DST == NULL special. */ /* We have to handle DST == NULL special. */
if (dst == NULL) if (dst == NULL)

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.
@ -45,6 +45,7 @@ __wcsrtombs (dst, src, len, ps)
int status; int status;
size_t result; size_t result;
struct __gconv_step *tomb; struct __gconv_step *tomb;
const struct gconv_fcts *fcts;
/* Tell where we want the result. */ /* Tell where we want the result. */
data.__invocation_counter = 0; data.__invocation_counter = 0;
@ -53,11 +54,11 @@ __wcsrtombs (dst, src, len, ps)
data.__statep = ps ?: &state; data.__statep = ps ?: &state;
data.__trans = NULL; data.__trans = NULL;
/* Make sure we use the correct function. */ /* Get the conversion functions. */
update_conversion_ptrs (); fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
/* Get the structure with the function pointers. */ /* Get the structure with the function pointers. */
tomb = __wcsmbs_gconv_fcts.tomb; tomb = fcts->tomb;
/* We have to handle DST == NULL special. */ /* We have to handle DST == NULL special. */
if (dst == NULL) if (dst == NULL)

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.ai.mit.edu>, 1996. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
@ -35,6 +35,7 @@ wctob (c)
wchar_t *inptr = inbuf; wchar_t *inptr = inbuf;
size_t dummy; size_t dummy;
int status; int status;
const struct gconv_fcts *fcts;
if (c == WEOF) if (c == WEOF)
return EOF; return EOF;
@ -51,14 +52,14 @@ wctob (c)
/* Make sure we start in the initial state. */ /* Make sure we start in the initial state. */
memset (&data.__state, '\0', sizeof (mbstate_t)); memset (&data.__state, '\0', sizeof (mbstate_t));
/* Make sure we use the correct function. */ /* Get the conversion functions. */
update_conversion_ptrs (); fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
/* Create the input string. */ /* Create the input string. */
inbuf[0] = c; inbuf[0] = c;
status = DL_CALL_FCT (__wcsmbs_gconv_fcts.tomb->__fct, status = DL_CALL_FCT (fcts->tomb->__fct,
(__wcsmbs_gconv_fcts.tomb, &data, (fcts->tomb, &data,
(const unsigned char **) &inptr, (const unsigned char **) &inptr,
(const unsigned char *) &inbuf[1], (const unsigned char *) &inbuf[1],
NULL, &dummy, 0, 1)); NULL, &dummy, 0, 1));