summaryrefslogtreecommitdiff
path: root/wcsmbs
diff options
context:
space:
mode:
Diffstat (limited to 'wcsmbs')
-rw-r--r--wcsmbs/Makefile4
-rw-r--r--wcsmbs/mbsrtowcs.c29
-rw-r--r--wcsmbs/mbsrtowcs_l.c55
-rw-r--r--wcsmbs/wcsmbsload.c30
-rw-r--r--wcsmbs/wcsmbsload.h18
5 files changed, 119 insertions, 17 deletions
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index 1b403f3a4c..882084db1e 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -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.
# 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 \
wcscoll_l wcsxfrm_l \
wcscasecmp wcsncase wcscasecmp_l wcsncase_l \
- wcsmbsload
+ wcsmbsload mbsrtowcs_l
tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
tst-wcrtomb
diff --git a/wcsmbs/mbsrtowcs.c b/wcsmbs/mbsrtowcs.c
index aa93426a5c..097e462110 100644
--- a/wcsmbs/mbsrtowcs.c
+++ b/wcsmbs/mbsrtowcs.c
@@ -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.
Contributed by Ulrich Drepper <drepper@gnu.org>, 1996.
@@ -32,6 +32,16 @@
#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. */
static mbstate_t state;
@@ -41,6 +51,7 @@ __mbsrtowcs (dst, src, len, ps)
const char **src;
size_t len;
mbstate_t *ps;
+#endif
{
struct __gconv_step_data data;
size_t result;
@@ -52,14 +63,23 @@ __mbsrtowcs (dst, src, len, ps)
data.__invocation_counter = 0;
data.__internal_use = 1;
data.__flags = __GCONV_IS_LAST;
+#ifdef USE_IN_EXTENDED_LOCALE_MODEL
+ data.__statep = ps;
+#else
data.__statep = ps ?: &state;
+#endif
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. */
update_conversion_ptrs ();
/* Get the structure with the function pointers. */
towc = __wcsmbs_gconv_fcts.towc;
+#endif
/* We have to handle DST == NULL special. */
if (dst == NULL)
@@ -140,6 +160,13 @@ __mbsrtowcs (dst, src, len, ps)
__set_errno (EILSEQ);
}
+#ifdef USE_IN_EXTENDED_LOCALE_MODEL
+ /* Free the conversion function data structures. */
+ wcsmbs_free_funcs (towc);
+#endif
+
return result;
}
+#ifndef USE_IN_EXTENDED_LOCALE_MODEL
weak_alias (__mbsrtowcs, mbsrtowcs)
+#endif
diff --git a/wcsmbs/mbsrtowcs_l.c b/wcsmbs/mbsrtowcs_l.c
new file mode 100644
index 0000000000..47ba82fecf
--- /dev/null
+++ b/wcsmbs/mbsrtowcs_l.c
@@ -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"
diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c
index c096804a68..fc846c7237 100644
--- a/wcsmbs/wcsmbsload.c
+++ b/wcsmbs/wcsmbsload.c
@@ -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.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -26,7 +26,6 @@
#include <locale/localeinfo.h>
#include <wcsmbsload.h>
#include <bits/libc-lock.h>
-#include <iconv/gconv_int.h>
/* 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. */
-static struct __gconv_step to_wc =
+struct __gconv_step __wcsmbs_to_wc attribute_hidden =
{
.__shlib_handle = 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. */
struct gconv_fcts __wcsmbs_gconv_fcts =
{
- .towc = &to_wc,
+ .towc = &__wcsmbs_to_wc,
.towc_nsteps = 1,
.tomb = &to_mb,
.tomb_nsteps = 1
};
-static inline struct __gconv_step *
-getfct (const char *to, const char *from, size_t *nstepsp)
+struct __gconv_step *
+attribute_hidden
+__wcsmbs_getfct (const char *to, const char *from, size_t *nstepsp)
{
size_t nsteps;
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. */
{
failed:
- __wcsmbs_gconv_fcts.towc = &to_wc;
+ __wcsmbs_gconv_fcts.towc = &__wcsmbs_to_wc;
__wcsmbs_gconv_fcts.tomb = &to_mb;
}
else
@@ -185,7 +185,7 @@ __wcsmbs_load_conv (const struct locale_data *new_category)
if (__wcsmbs_gconv_fcts.tomb != &to_mb)
__gconv_close_transform (__wcsmbs_gconv_fcts.tomb,
__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,
__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
since the internal character set is supposed to be able to
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
- ? getfct (complete_name, "INTERNAL", &new_tomb_nsteps)
+ ? __wcsmbs_getfct (complete_name, "INTERNAL",
+ &new_tomb_nsteps)
: NULL);
/* If any of the conversion functions is not available we don't
@@ -262,10 +264,10 @@ int
internal_function
__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)
{
- copy->tomb = getfct (name, "INTERNAL", &copy->tomb_nsteps);
+ copy->tomb = __wcsmbs_getfct (name, "INTERNAL", &copy->tomb_nsteps);
if (copy->tomb == NULL)
__gconv_close_transform (copy->towc, copy->towc_nsteps);
}
@@ -287,11 +289,11 @@ free_mem (void)
__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;
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;
__gconv_release_cache (old, nold);
}
diff --git a/wcsmbs/wcsmbsload.h b/wcsmbs/wcsmbsload.h
index 1fcb42c033..b7594ce5e9 100644
--- a/wcsmbs/wcsmbsload.h
+++ b/wcsmbs/wcsmbsload.h
@@ -17,6 +17,9 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#ifndef _WCSMBSLOAD_H
+#define _WCSMBSLOAD_H 1
+
#include <locale.h>
#include <wchar.h>
#include <locale/localeinfo.h>
@@ -52,6 +55,19 @@ extern int __wcsmbs_named_conv (struct gconv_fcts *copy, const char *name)
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.
Update the pointers appropriately. */
static inline void
@@ -60,3 +76,5 @@ update_conversion_ptrs (void)
if (__wcsmbs_last_locale != _NL_CURRENT_DATA (LC_CTYPE))
__wcsmbs_load_conv (_NL_CURRENT_DATA (LC_CTYPE));
}
+
+#endif /* wcsmbsload.h */