diff options
45 files changed, 727 insertions, 908 deletions
diff --git a/ChangeLog b/ChangeLog index 4141af493e..8b8305a9ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,68 @@ +2000-06-19 Ulrich Drepper <drepper@redhat.com> + + * iconv/gconv.h (__gconv_trans_fct): Add new parameter. + General namespace cleanup. + (struct __gconv_trans_data): Add next field. + (struct __gconv_step_data): Make __trans a pointer. + * iconv/gconv_conf.c: Split out code to find gconv directories from + __gconv_read_conf in new functions. + * iconv/gconv_int.h: Define new data structure and declare new + functions for handling of gconv directory list. + * iconv/gconv_open.c: Allow more than one error handling step being + used. Call function to load error handling module if it is none + of the builtin transformations. + * iconv/gconv_close.c: Add code to free transliteration data. + * iconv/gconv_trans.c: Add functions to load and unload modules + implementing transliteration etc. + * iconv/skeleton.c: Call all context functions now that more than + one module is allowed. + * iconv/loop.c (STANDARD_ERR_HANDLING): New macro. + * iconv/gconv_simple.c: Use STANDARD_ERR_HANDLING macro for places + where the full error handling using transliteration is needed. + * iconvdata/8bit-gap.c: Likewise. + * iconvdata/8bit-generic.c: Likewise. + * iconvdata/ansi_x3.110.c: Likewise. + * iconvdata/big5.c: Likewise. + * iconvdata/big5hkscs.c: Likewise. + * iconvdata/euc-cn.c: Likewise. + * iconvdata/euc-jp.c: Likewise. + * iconvdata/euc-kr.c: Likewise. + * iconvdata/euc-tw.c: Likewise. + * iconvdata/gbgbk.c: Likewise. + * iconvdata/gbk.c: Likewise. + * iconvdata/iso-2022-cn.c: Likewise. + * iconvdata/iso-2022-jp.c: Likewise. + * iconvdata/iso-2022-kr.c: Likewise. + * iconvdata/iso646.c: Likewise. + * iconvdata/iso8859-1.c: Likewise. + * iconvdata/iso_6937-2.c: Likewise. + * iconvdata/iso_6937.c: Likewise. + * iconvdata/johab.c: Likewise. + * iconvdata/sjis.c: Likewise. + * iconvdata/t.61.c: Likewise. + * iconvdata/uhc.c: Likewise. + * iconvdata/unicode.c: Likewise. + * iconvdata/utf-16.c: Likewise. + * libio/iofwide.c: Reset __trans member of __gconv_trans_data + structure correctly after last change. + * wcsmbs/btowc.c: Likewise. + * wcsmbs/mbrtowc.c: Likewise. + * wcsmbs/mbsnrtowcs.c: Likewise. + * wcsmbs/mbsrtowcs.c: Likewise. + * wcsmbs/wcrtomb.c: Likewise. + * wcsmbs/wcsnrtombs.c: Likewise. + * wcsmbs/wcsrtombs.c: Likewise. + * wcsmbs/wctob.c: Likewise. + + * localedata/Makefile: Set -Wno-format for some files since gcc does + not know all the format specifiers. + +2000-06-18 Ulrich Drepper <drepper@redhat.com> + + * locale/loadlocale.c (_nl_unload_locale): Remove a bit of + unneeded code. + * locale/lc-time.c (_nl_init_era_entries): Likewise. + 2000-06-18 Andreas Jaeger <aj@suse.de> * sysdeps/mips/dl-machine.h: Always use $25 as jump register. diff --git a/iconv/gconv.h b/iconv/gconv.h index 0164b62c8b..50458e2aeb 100644 --- a/iconv/gconv.h +++ b/iconv/gconv.h @@ -76,21 +76,22 @@ typedef void (*__gconv_end_fct) (struct __gconv_step *); /* Type of a transliteration/transscription function. */ -typedef int (*__gconv_trans_fct) (struct __gconv_step *step, - struct __gconv_step_data *step_data, +typedef int (*__gconv_trans_fct) (struct __gconv_step *, + struct __gconv_step_data *, void *, __const unsigned char *, __const unsigned char **, __const unsigned char *, unsigned char **, size_t *); /* Function to call to provide transliteration module with context. */ -typedef int (*__gconv_trans_context_fct) (struct __gconv_trans_data *data, +typedef int (*__gconv_trans_context_fct) (struct __gconv_trans_data *, __const unsigned char *, __const unsigned char *, unsigned char *, unsigned char *); /* Function to query module about supported encoded character sets. */ -typedef int (*__gconv_trans_query_fct) (__const char **, size_t *); +typedef int (*__gconv_trans_query_fct) (__const char *, __const char ***, + size_t *); /* Constructor and destructor for local data for transliteration. */ typedef int (*__gconv_trans_init_fct) (void **, const char *); @@ -103,6 +104,7 @@ struct __gconv_trans_data __gconv_trans_context_fct __trans_context_fct; __gconv_trans_end_fct __trans_end_fct; void *__data; + struct __gconv_trans_data *__next; }; @@ -158,7 +160,7 @@ struct __gconv_step_data any module; always use STATEP! */ /* Transliteration information. */ - struct __gconv_trans_data __trans; + struct __gconv_trans_data *__trans; }; diff --git a/iconv/gconv_close.c b/iconv/gconv_close.c index 79dcb0b3a1..002e2c4dce 100644 --- a/iconv/gconv_close.c +++ b/iconv/gconv_close.c @@ -38,6 +38,20 @@ __gconv_close (__gconv_t cd) drunp = cd->__data; do { + struct __gconv_trans_data *transp; + + transp = drunp->__trans; + while (transp != NULL) + { + struct __gconv_trans_data *curp = transp; + transp = transp->__next; + + if (__builtin_expect (curp->__trans_end_fct != NULL, 0)) + curp->__trans_end_fct (curp->__data); + + free (curp); + } + if (!(drunp->__flags & __GCONV_IS_LAST) && drunp->__outbuf != NULL) free (drunp->__outbuf); } diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c index 0d25c22416..480b459134 100644 --- a/iconv/gconv_conf.c +++ b/iconv/gconv_conf.c @@ -1,5 +1,5 @@ /* Handle configuration data. - Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <assert.h> #include <ctype.h> #include <errno.h> #include <limits.h> @@ -34,6 +35,14 @@ /* This is the default path where we look for module lists. */ static const char default_gconv_path[] = GCONV_PATH; +/* The path element in use. */ +const struct path_elem *__gconv_path_elem; +/* Maximum length of a single path element. */ +size_t __gconv_max_path_elem_len; + +/* We use the following struct if we couldn't allocate memory. */ +static const struct path_elem empty_path_elem; + /* Name of the file containing the module information in the directories along the path. */ static const char gconv_conf_filename[] = "gconv-modules"; @@ -497,48 +506,125 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len, /* Otherwise ignore the line. */ } - if (line != NULL) - free (line); + free (line); + fclose (fp); } +/* Determine the directories we are looking for data in. */ +void +__gconv_get_path (void) +{ + struct path_elem *result; + __libc_lock_define_initialized (static, lock); + + __libc_lock_lock (lock); + + /* Make sure there wasn't a second thread doing it already. */ + result = (struct path_elem *) __gconv_path_elem; + if (result == NULL) + { + /* Determine the complete path first. */ + const char *user_path; + char *gconv_path; + size_t gconv_path_len; + char *elem; + char *oldp; + char *cp; + int nelems; + + user_path = __secure_getenv ("GCONV_PATH"); + if (user_path == NULL) + { + /* No user-defined path. Make a modifiable copy of the + default path. */ + gconv_path = strdupa (default_gconv_path); + gconv_path_len = sizeof (default_gconv_path); + } + else + { + /* Append the default path to the user-defined path. */ + size_t user_len = strlen (user_path); + + gconv_path_len = user_len + 1 + sizeof (default_gconv_path); + gconv_path = alloca (gconv_path_len); + __mempcpy (__mempcpy (__mempcpy (gconv_path, user_path, user_len), + ":", 1), + default_gconv_path, sizeof (default_gconv_path)); + } + + /* In a first pass we calculate the number of elements. */ + oldp = NULL; + cp = strchr (gconv_path, ':'); + nelems = 1; + while (cp != NULL) + { + if (cp != oldp + 1) + ++nelems; + oldp = cp; + cp = strchr (cp + 1, ':'); + } + + /* Allocate the memory for the result. */ + result = (struct path_elem *) malloc ((nelems + 1) + * sizeof (struct path_elem) + + gconv_path_len + nelems); + if (result != NULL) + { + char *strspace = (char *) &result[nelems + 1]; + int n = 0; + + /* Separate the individual parts. */ + __gconv_max_path_elem_len = 0; + elem = __strtok_r (gconv_path, ":", &gconv_path); + assert (elem != NULL); + do + { + result[n].name = strspace; + strspace = __stpcpy (strspace, elem); + if (strspace[-1] != '/') + *strspace++ = '/'; + + result[n].len = strspace - result[n].name; + if (result[n].len > __gconv_max_path_elem_len) + __gconv_max_path_elem_len = result[n].len; + + *strspace++ = '\0'; + ++n; + } + while ((elem = __strtok_r (NULL, ":", &gconv_path)) != NULL); + + result[n].name = NULL; + result[n].len = 0; + } + + __gconv_path_elem = result ?: &empty_path_elem; + } + + __libc_lock_unlock (lock); +} + + /* Read all configuration files found in the user-specified and the default path. */ void __gconv_read_conf (void) { - const char *user_path = __secure_getenv ("GCONV_PATH"); - char *gconv_path, *elem; void *modules = NULL; size_t nmodules = 0; int save_errno = errno; size_t cnt; - if (user_path == NULL) - /* No user-defined path. Make a modifiable copy of the default path. */ - gconv_path = strdupa (default_gconv_path); - else - { - /* Append the default path to the user-defined path. */ - size_t user_len = strlen (user_path); - - gconv_path = alloca (user_len + 1 + sizeof (default_gconv_path)); - __mempcpy (__mempcpy (__mempcpy (gconv_path, user_path, user_len), - ":", 1), - default_gconv_path, sizeof (default_gconv_path)); - } + /* Find out where we have to look. */ + if (__gconv_path_elem == NULL) + __gconv_get_path (); - elem = __strtok_r (gconv_path, ":", &gconv_path); - while (elem != NULL) + for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt) { -#ifndef MAXPATHLEN - /* We define a reasonable limit. */ -# define MAXPATHLEN 4096 -#endif - char real_elem[MAXPATHLEN]; + char real_elem[__gconv_max_path_elem_len + sizeof (gconv_conf_filename)]; - if (__realpath (elem, real_elem) != NULL) + if (__realpath (__gconv_path_elem[cnt].name, real_elem) != NULL) { size_t elem_len = strlen (real_elem); char *filename; @@ -551,9 +637,6 @@ __gconv_read_conf (void) /* Read the next configuration file. */ read_conf_file (filename, real_elem, elem_len, &modules, &nmodules); } - - /* Get next element in the path. */ - elem = __strtok_r (NULL, ":", &gconv_path); } /* Add the internal modules. */ @@ -586,3 +669,15 @@ __gconv_read_conf (void) /* Restore the error number. */ __set_errno (save_errno); } + + + +/* Free all resources if necessary. */ +static void __attribute__ ((unused)) +free_mem (void) +{ + if (__gconv_path_elem != NULL && __gconv_path_elem != &empty_path_elem) + free ((void *) __gconv_path_elem); +} + +text_set_element (__libc_subfreeres, free_mem); diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h index 5bdf7143e6..6d199715ca 100644 --- a/iconv/gconv_int.h +++ b/iconv/gconv_int.h @@ -26,6 +26,19 @@ __BEGIN_DECLS +/* Type to represent search path. */ +struct path_elem +{ + const char *name; + size_t len; +}; + +/* Variable with search path for `gconv' implementation. */ +extern const struct path_elem *__gconv_path_elem; +/* Maximum length of a single path element. */ +extern size_t __gconv_max_path_elem_len; + + /* Structure for alias definition. Simply to strings. */ struct gconv_alias { @@ -83,6 +96,21 @@ struct gconv_module }; +/* Internal data structure to represent transliteration module. */ +struct trans_struct +{ + const char *name; + struct trans_struct *next; + + const char **csnames; + size_t ncsnames; + __gconv_trans_fct trans_fct; + __gconv_trans_context_fct trans_context_fct; + __gconv_trans_init_fct trans_init_fct; + __gconv_trans_end_fct trans_end_fct; +}; + + /* Flags for `gconv_open'. */ enum { @@ -161,6 +189,9 @@ extern int __gconv_find_transform (const char *toset, const char *fromset, /* Read all the configuration data and cache it. */ extern void __gconv_read_conf (void); +/* Determine the directories we are looking in. */ +extern void __gconv_get_path (void); + /* Comparison function to search alias. */ extern int __gconv_alias_compare (const void *p1, const void *p2); @@ -185,9 +216,14 @@ extern void __gconv_get_builtin_trans (const char *name, struct __gconv_step *step) internal_function; +/* Try to load transliteration step module. */ +extern int __gconv_translit_find (struct trans_struct *trans) + internal_function; + /* Transliteration using the locale's data. */ extern int __gconv_transliterate (struct __gconv_step *step, struct __gconv_step_data *step_data, + void *trans_data, __const unsigned char *inbufstart, __const unsigned char **inbufp, __const unsigned char *inbufend, diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c index d2963fa8ee..2374703e21 100644 --- a/iconv/gconv_open.c +++ b/iconv/gconv_open.c @@ -38,6 +38,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, int conv_flags = 0; const char *errhand; const char *ignore; + struct trans_struct *trans = NULL; /* Find out whether any error handling method is specified. */ errhand = strchr (toset, '/'); @@ -51,17 +52,85 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, { /* Make copy without the error handling description. */ char *newtoset = (char *) alloca (errhand - toset + 1); + char *tok; + char *ptr; newtoset[errhand - toset] = '\0'; toset = memcpy (newtoset, toset, errhand - toset); - flags = __GCONV_IGNORE_ERRORS; + /* Find the appropriate transliteration handlers. */ + tok = strdupa (errhand); - if (__strcasecmp (errhand, "IGNORE") == 0) + tok = __strtok_r (tok, ",", &ptr); + while (tok != NULL) { - /* Found it. This means we should ignore conversion errors. */ - flags = __GCONV_IGNORE_ERRORS; - errhand = NULL; + if (__strcasecmp (tok, "TRANSLIT") == 0) + { + /* It's the builtin transliteration handling. We only + support it for working on the internal encoding. */ + static const char *internal_trans_names[1] = { "INTERNAL" }; + struct trans_struct *lastp = NULL; + struct trans_struct *runp; + + for (runp = trans; runp != NULL; runp = runp->next) + if (runp->trans_fct == __gconv_transliterate) + break; + else + lastp = runp; + + if (runp == NULL) + { + struct trans_struct *newp; + + newp = (struct trans_struct *) alloca (sizeof (*newp)); + memset (newp, '\0', sizeof (*newp)); + + /* We leave the `name' field zero to signal that + this is an internal transliteration step. */ + newp->csnames = internal_trans_names; + newp->ncsnames = 1; + newp->trans_fct = __gconv_transliterate; + + if (lastp == NULL) + trans = newp; + else + lastp->next = newp; + } + } + else if (__strcasecmp (tok, "IGNORE") == 0) + /* Set the flag to ignore all errors. */ + flags = __GCONV_IGNORE_ERRORS; + else + { + /* `tok' is possibly a module name. We'll see later + whether we can find it. But first see that we do + not already a module of this name. */ + struct trans_struct *lastp = NULL; + struct trans_struct *runp; + + for (runp = trans; runp != NULL; runp = runp->next) + if (runp->name != NULL + && __strcasecmp (tok, runp->name) == 0) + break; + else + lastp = runp; + + if (runp == NULL) + { + struct trans_struct *newp; + + newp = (struct trans_struct *) alloca (sizeof (*newp)); + memset (newp, '\0', sizeof (*newp)); + newp->name = tok; + + if (lastp == NULL) + trans = newp; + else + lastp->next = newp; + } + } + + tok = __strtok_r (NULL, ",", &ptr); } } } @@ -81,31 +150,18 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, res = __gconv_find_transform (toset, fromset, &steps, &nsteps, flags); if (res == __GCONV_OK) { - const char **csnames = NULL; - size_t ncsnames = 0; - __gconv_trans_fct trans_fct = NULL; - __gconv_trans_context_fct trans_context_fct = NULL; - __gconv_trans_init_fct trans_init_fct = NULL; - __gconv_trans_end_fct trans_end_fct = NULL; - - if (errhand != NULL) + /* Find the modules. */ + struct trans_struct *lastp = NULL; + struct trans_struct *runp; + + for (runp = trans; runp != NULL; runp = runp->next) { - /* Find the appropriate transliteration handling. */ - if (__strcasecmp (errhand, "TRANSLIT") == 0) - { - /* It's the builtin transliteration handling. We only - suport for it working on the internal encoding. */ - static const char *internal_trans_names[1] = { "INTERNAL" }; - - csnames = internal_trans_names; - ncsnames = 1; - trans_fct = __gconv_transliterate; - /* No context, init, or end function. */ - } - else if (__strcasecmp (errhand, "WORK AROUND A GCC BUG") == 0) - { - trans_init_fct = (__gconv_trans_init_fct) 1; - } + if (runp->name == NULL + || __builtin_expect (__gconv_translit_find (runp), 0) == 0) + lastp = runp; + else + /* This means we haven't found the module. Remove it. */ + (lastp == NULL ? trans : lastp->next) = runp->next; } /* Allocate room for handle. */ @@ -154,32 +210,51 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, result->__data[cnt].__outbuf = (char *) malloc (size); if (result->__data[cnt].__outbuf == NULL) - { - res = __GCONV_NOMEM; - break; - } + goto bail; + result->__data[cnt].__outbufend = result->__data[cnt].__outbuf + size; - /* Now see whether we can use the transliteration module - for this step. */ - for (n = 0; n < ncsnames; ++n) - if (__strcasecmp (steps[cnt].__from_name, csnames[n]) == 0) - { - /* Match! Now try the initializer. */ - if (trans_init_fct == NULL - || (trans_init_fct (&result->__data[cnt].__trans.__data, - steps[cnt].__to_name) - == __GCONV_OK)) - { - result->__data[cnt].__trans.__trans_fct = trans_fct; - result->__data[cnt].__trans.__trans_context_fct = - trans_context_fct; - result->__data[cnt].__trans.__trans_end_fct = - trans_end_fct; - } - break; - } + /* Now see whether we can use any of the transliteration + modules for this step. */ + for (runp = trans; runp != NULL; runp = runp->next) + for (n = 0; n < runp->ncsnames; ++n) + if (__strcasecmp (steps[cnt].__from_name, + runp->csnames[n]) == 0) + { + void *data = NULL; + + /* Match! Now try the initializer. */ + if (runp->trans_init_fct == NULL + || (runp->trans_init_fct (data, steps[cnt].__to_name) + == __GCONV_OK)) + { + /* Append at the end of the list. */ + struct __gconv_trans_data *newp; + struct __gconv_trans_data *endp; + struct __gconv_trans_data *lastp; + + newp = (struct __gconv_trans_data *) + malloc (sizeof (struct __gconv_trans_data)); + if (newp == NULL) + goto bail; + + newp->__trans_fct = runp->trans_fct; + newp->__trans_context_fct = runp->trans_context_fct; + newp->__trans_end_fct = runp->trans_end_fct; + + lastp = NULL; + for (endp = result->__data[cnt].__trans; + endp != NULL; endp = endp->__next) + lastp = endp; + + if (lastp == NULL) + result->__data[cnt].__trans = newp; + else + lastp->__next = newp; + } + break; + } } /* Now handle the last entry. */ @@ -194,34 +269,72 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, /* Now see whether we can use the transliteration module for this step. */ - for (n = 0; n < ncsnames; ++n) - if (__strcasecmp (steps[cnt].__from_name, csnames[n]) == 0) - { - /* Match! Now try the initializer. */ - if (trans_init_fct == NULL - || trans_init_fct (&result->__data[cnt].__trans.__data, - steps[cnt].__to_name) - == __GCONV_OK) - { - result->__data[cnt].__trans.__trans_fct = trans_fct; - result->__data[cnt].__trans.__trans_context_fct = - trans_context_fct; - result->__data[cnt].__trans.__trans_end_fct = - trans_end_fct; - } - break; - } + for (runp = trans; runp != NULL; runp = runp->next) + for (n = 0; n < runp->ncsnames; ++n) + if (__strcasecmp (steps[cnt].__from_name, runp->csnames[n]) == 0) + { + void *data = NULL; + + /* Match! Now try the initializer. */ + if (runp->trans_init_fct == NULL + || (runp->trans_init_fct (data, steps[cnt].__to_name) + == __GCONV_OK)) + { + /* Append at the end of the list. */ + struct __gconv_trans_data *newp; + struct __gconv_trans_data *endp; + struct __gconv_trans_data *lastp; + + newp = (struct __gconv_trans_data *) + malloc (sizeof (struct __gconv_trans_data)); + if (newp == NULL) + goto bail; + + newp->__trans_fct = runp->trans_fct; + newp->__trans_context_fct = runp->trans_context_fct; + newp->__trans_end_fct = runp->trans_end_fct; + + lastp = NULL; + for (endp = result->__data[cnt].__trans; + endp != NULL; endp = endp->__next) + lastp = endp; + + if (lastp == NULL) + result->__data[cnt].__trans = newp; + else + lastp->__next = newp; + } + break; + } } if (res != __GCONV_OK) { /* Something went wrong. Free all the resources. */ - int serrno = errno; + int serrno; + bail: + serrno = errno; if (result != NULL) { while (cnt-- > 0) - free (result->__data[cnt].__outbuf); + { + struct __gconv_trans_data *transp; + + transp = result->__data[cnt].__trans; + while (transp != NULL) + { + struct __gconv_trans_data *curp = transp; + transp = transp->__next; + + if (__builtin_expect (curp->__trans_end_fct != NULL, 0)) + curp->__trans_end_fct (curp->__data); + + free (curp); + } + + free (result->__data[cnt].__outbuf); + } free (result); result = NULL; diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c index 390574582f..019aac2a3f 100644 --- a/iconv/gconv_simple.c +++ b/iconv/gconv_simple.c @@ -797,25 +797,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step, /* XXX unaligned. */ \ if (__builtin_expect (*((uint32_t *) inptr), 0) > 0x7f) \ { \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is no correct ANSI_X3.4-1968 character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ + STANDARD_ERR_HANDLER (4); \ } \ else \ /* It's an one byte sequence. */ \ @@ -1186,24 +1168,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step, { \ if (__builtin_expect (*((uint32_t *) inptr), 0) >= 0x10000) \ { \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ + STANDARD_ERR_HANDLER (4); \ } \ else \ *((uint16_t *) outptr)++ = *((uint32_t *) inptr)++; \ @@ -1253,25 +1218,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step, uint32_t val = *((uint32_t *) inptr); \ if (__builtin_expect (val, 0) >= 0x10000) \ { \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ *((uint16_t *) outptr)++ = bswap_16 (val); \ inptr += 4; \ diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c index 269917b531..4d6e7766fd 100644 --- a/iconv/gconv_trans.c +++ b/iconv/gconv_trans.c @@ -18,9 +18,13 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <assert.h> #include <dlfcn.h> +#include <search.h> #include <stdint.h> +#include <string.h> +#include <bits/libc-lock.h> #include "gconv_int.h" #include "../locale/localeinfo.h" @@ -28,6 +32,7 @@ int __gconv_transliterate (struct __gconv_step *step, struct __gconv_step_data *step_data, + void *trans_data __attribute__ ((unused)), const unsigned char *inbufstart, const unsigned char **inbufp, const unsigned char *inbufend, @@ -218,3 +223,178 @@ __gconv_transliterate (struct __gconv_step *step, /* Haven't found a match. */ return __GCONV_ILLEGAL_INPUT; } + + +/* Structure to represent results of found (or not) transliteration + modules. */ +struct known_trans +{ + /* This structure must remain the first member. */ + struct trans_struct info; + + const char *fname; + void *handle; + int open_count; +}; + + +/* Tree with results of previous calls to __gconv_translit_find. */ +static void *search_tree; + +/* We modify global data. */ +__libc_lock_define_initialized (static, lock); + + +/* Compare two transliteration entries. */ +static int +trans_compare (const void *p1, const void *p2) +{ + struct known_trans *s1 = (struct known_trans *) p1; + struct known_trans *s2 = (struct known_trans *) p2; + + return strcmp (s1->info.name, s2->info.name); +} + + +/* Open (maybe reopen) the module named in the struct. Get the function + and data structure pointers we need. */ +static int +open_translit (struct known_trans *trans) +{ + __gconv_trans_query_fct queryfct; + + trans->handle = __libc_dlopen (trans->fname); + if (trans->handle == NULL) + /* Not available. */ + return 1; + + /* Find the required symbol. */ + queryfct = __libc_dlsym (trans->handle, "gconv_trans_context"); + if (queryfct == NULL) + { + /* We cannot live with that. */ + close_and_out: + __libc_dlclose (trans->handle); + trans->handle = NULL; + return 1; + } + + /* Get the context. */ + if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames) + != 0) + goto close_and_out; + + /* Of course we also have to have the actual function. */ + trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans"); + if (trans->info.trans_fct == NULL) + goto close_and_out; + + /* Now the optional functions. */ + trans->info.trans_init_fct = + __libc_dlsym (trans->handle, "gconv_trans_init"); + trans->info.trans_context_fct = + __libc_dlsym (trans->handle, "gconv_trans_context"); + trans->info.trans_end_fct = + __libc_dlsym (trans->handle, "gconv_trans_end"); + + trans->open_count = 1; + + return 0; +} + + +int +internal_function +__gconv_translit_find (struct trans_struct *trans) +{ + struct known_trans **found; + const struct path_elem *runp; + int res = 1; + + /* We have to have a name. */ + assert (trans->name != NULL); + + /* Acquire the lock. */ + __libc_lock_lock (lock); + + /* See whether we know this module already. */ + found = __tfind (trans, &search_tree, trans_compare); + if (found != NULL) + { + /* Is this module available? */ + if ((*found)->handle != NULL) + { + /* Maybe we have to reopen the file. */ + if ((*found)->handle != (void *) -1) + /* The object is not unloaded. */ + res = 0; + else if (open_translit (*found) == 0) + { + /* Copy the data. */ + *trans = (*found)->info; + res = 0; + } + } + } + else + { + size_t name_len = strlen (trans->name) + 1; + int need_so = 0; + struct known_trans *newp; + + /* We have to continue looking for the module. */ + if (__gconv_path_elem == NULL) + __gconv_get_path (); + + /* See whether we have to append .so. */ + if (name_len <= 3 || memcmp (&trans->name[name_len - 3], ".so", 3) != 0) + need_so = 1; + + /* Create a new entry. */ + newp = (struct known_trans *) malloc (sizeof (struct known_trans) + + (__gconv_max_path_elem_len + + name_len + 3) + + name_len); + if (newp != NULL) + { + char *cp; + + /* Clear the struct. */ + memset (newp, '\0', sizeof (struct known_trans)); + + /* Store a copy of the module name. */ + newp->info.name = (char *) (newp + 1); + cp = __mempcpy ((char *) newp->info.name, trans->name, name_len); + + newp->fname = cp; + + /* Seach in all the directories. */ + for (runp = __gconv_path_elem; runp->name != NULL; ++runp) + { + cp = __mempcpy (__stpcpy ((char *) newp->fname, runp->name), + trans->name, name_len); + if (need_so) + memcpy (cp, ".so", sizeof (".so")); + + if (open_translit (newp) == 0) + { + /* We found a module. */ + res = 0; + break; + } + } + + /* In any case we'll add the entry to our search tree. */ + if (__tsearch (newp, &search_tree, trans_compare) == NULL) + { + /* Yickes, this should not happen. Unload the object. */ + res = 1; + /* XXX unload here. */ + } + } + } + + __libc_lock_unlock (lock); + + return res; +} diff --git a/iconv/loop.c b/iconv/loop.c index ebbc1362b3..04ae50b974 100644 --- a/iconv/loop.c +++ b/iconv/loop.c @@ -173,6 +173,38 @@ #define ignore_errors_p() (flags & __GCONV_IGNORE_ERRORS) +/* Error handling with transliteration/transcription function use and + ignoring of errors. Note that we cannot use the do while (0) trick + since `break' and `continue' must reach certain points. */ +#define STANDARD_ERR_HANDLER(Incr) \ + { \ + struct __gconv_trans_data *trans; \ + \ + result = __GCONV_ILLEGAL_INPUT; \ + /* First try the transliteration methods. */ \ + for (trans = step_data->__trans; trans != NULL; trans = trans->__next) \ + { \ + result = DL_CALL_FCT (trans->__trans_fct, \ + (step, step_data, trans->__data, *inptrp, \ + &inptr, inend, &outptr, irreversible)); \ + if (result != __GCONV_ILLEGAL_INPUT) \ + break; \ + } \ + /* If any of them recognized the input stop. */ \ + if (result != __GCONV_ILLEGAL_INPUT) \ + break; \ + \ + /* Next see whether we have to ignore the error. If not, stop. */ \ + if (! ignore_errors_p ()) \ + break; \ + \ + /* When we come here it means we ignore the character. */ \ + ++*irreversible; \ + inptr += Incr; \ + continue; \ + } + + /* The function returns the status, as defined in gconv.h. */ static inline int FCTNAME (LOOPFCT) (struct __gconv_step *step, diff --git a/iconv/skeleton.c b/iconv/skeleton.c index 8dbebb81ac..854cc70bee 100644 --- a/iconv/skeleton.c +++ b/iconv/skeleton.c @@ -379,6 +379,8 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, do { + struct __gconv_trans_data *trans; + /* Remember the start value for this round. */ inptr = *inptrp; /* The outbuf buffer is empty. */ @@ -429,10 +431,10 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, /* Give the transliteration module the chance to store the original text and the result in case it needs a context. */ - if (data->__trans.__trans_context_fct != NULL) - DL_CALL_FCT (data->__trans.__trans_context_fct, - (data->__trans.__data, inptr, *inptrp, - outstart, outbuf)); + for (trans = data->__trans; trans != NULL; trans = trans->__next) + if (trans->__trans_context_fct != NULL) + DL_CALL_FCT (trans->__trans_context_fct, + (trans->__data, inptr, *inptrp, outstart, outbuf)); /* We finished one use of the loops. */ ++data->__invocation_counter; diff --git a/iconvdata/8bit-gap.c b/iconvdata/8bit-gap.c index a4a32d3eae..7caa5427d5 100644 --- a/iconvdata/8bit-gap.c +++ b/iconvdata/8bit-gap.c @@ -83,75 +83,17 @@ struct gap unsigned char res; \ \ if (__builtin_expect (ch, 0) >= 0xffff) \ + rp = NULL; \ + else \ + while (ch > rp->end) \ + ++rp; \ + if (__builtin_expect (rp == NULL, 0) \ + || __builtin_expect (ch < rp->start, 0) \ + || (res = from_ucs4[ch + rp->idx], \ + __builtin_expect (res, '\1') == '\0' && ch != 0)) \ { \ /* This is an illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - \ - ++*irreversible; \ - inptr += 4; \ - continue; \ - } \ - while (ch > rp->end) \ - ++rp; \ - if (__builtin_expect (ch < rp->start, 0)) \ - { \ - /* This is an illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ - } \ - \ - res = from_ucs4[ch + rp->idx]; \ - if (__builtin_expect (res, '\1') == '\0' && ch != 0) \ - { \ - /* This is an illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ \ *outptr++ = res; \ diff --git a/iconvdata/8bit-generic.c b/iconvdata/8bit-generic.c index 02d972e21c..bc05ccd8db 100644 --- a/iconvdata/8bit-generic.c +++ b/iconvdata/8bit-generic.c @@ -68,30 +68,11 @@ || (__builtin_expect (from_ucs4[ch], '\1') == '\0' && ch != 0)) \ { \ /* This is an illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - } \ - else \ - { \ - *outptr++ = from_ucs4[ch]; \ - inptr += 4; \ + STANDARD_ERR_HANDLER (4); \ } \ + \ + *outptr++ = from_ucs4[ch]; \ + inptr += 4; \ } #define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/ansi_x3.110.c b/iconvdata/ansi_x3.110.c index 6ec09c3c5c..d55af6fba7 100644 --- a/iconvdata/ansi_x3.110.c +++ b/iconvdata/ansi_x3.110.c @@ -497,25 +497,7 @@ static const char from_ucs4[][2] = if (tmp[0] == '\0') \ { \ /* Illegal characters. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ tmp[1] = '\0'; \ cp = tmp; \ @@ -555,25 +537,7 @@ static const char from_ucs4[][2] = else \ { \ /* Illegal characters. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ } \ else \ @@ -583,25 +547,7 @@ static const char from_ucs4[][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal characters. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ } \ \ diff --git a/iconvdata/big5.c b/iconvdata/big5.c index 947a92a341..1ba1b3f28f 100644 --- a/iconvdata/big5.c +++ b/iconvdata/big5.c @@ -8585,25 +8585,7 @@ static const char from_ucs4_tab13[][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ else \ { \ diff --git a/iconvdata/big5hkscs.c b/iconvdata/big5hkscs.c index 64923d42af..bf38e15a5a 100644 --- a/iconvdata/big5hkscs.c +++ b/iconvdata/big5hkscs.c @@ -12742,25 +12742,7 @@ static const char from_ucs4_tab14[][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ else \ { \ diff --git a/iconvdata/euc-cn.c b/iconvdata/euc-cn.c index 18e73fda6c..58f47eda3f 100644 --- a/iconvdata/euc-cn.c +++ b/iconvdata/euc-cn.c @@ -141,25 +141,7 @@ if (__builtin_expect (found, 0) == __UNKNOWN_10646_CHAR) \ { \ /* Illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ \ /* It's a GB 2312 character, adjust it for EUC-CN. */ \ diff --git a/iconvdata/euc-jp.c b/iconvdata/euc-jp.c index 3e21d55f12..fc0794d700 100644 --- a/iconvdata/euc-jp.c +++ b/iconvdata/euc-jp.c @@ -218,26 +218,7 @@ else \ { \ /* Illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, \ - &inptr, inend, &outptr, \ - irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ } \ } \ diff --git a/iconvdata/euc-kr.c b/iconvdata/euc-kr.c index c32b9b3537..abb40c8908 100644 --- a/iconvdata/euc-kr.c +++ b/iconvdata/euc-kr.c @@ -146,25 +146,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ \ *outptr++ = cp[0]; \ diff --git a/iconvdata/euc-tw.c b/iconvdata/euc-tw.c index b4cf21ba97..ed7a197d7c 100644 --- a/iconvdata/euc-tw.c +++ b/iconvdata/euc-tw.c @@ -193,25 +193,7 @@ if (__builtin_expect (found, 0) == __UNKNOWN_10646_CHAR) \ { \ /* Illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ \ /* It's a CNS 11643 character, adjust it for EUC-TW. */ \ diff --git a/iconvdata/gbgbk.c b/iconvdata/gbgbk.c index 0afcd72311..02e25f31e3 100644 --- a/iconvdata/gbgbk.c +++ b/iconvdata/gbgbk.c @@ -102,31 +102,12 @@ && __builtin_expect (ch, 0xa1a1) <= 0xa8c0)) \ { \ /* One of the characters we cannot map. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 2; \ - ++*irreversible; \ - } \ - } \ - else \ - { \ - /* Copy the two bytes. */ \ - *outptr++ = *inptr++; \ - *outptr++ = *inptr++; \ + STANDARD_ERR_HANDLER (2); \ } \ + \ + /* Copy the two bytes. */ \ + *outptr++ = *inptr++; \ + *outptr++ = *inptr++; \ } \ } #define LOOP_NEED_FLAGS diff --git a/iconvdata/gbk.c b/iconvdata/gbk.c index 4505b65c1a..c3010f30d7 100644 --- a/iconvdata/gbk.c +++ b/iconvdata/gbk.c @@ -13452,25 +13452,7 @@ static const char __gbk_from_ucs4_tab12[][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ /* See whether there is enough room for the second byte we write. */ \ else if (cp[1] != '\0' && __builtin_expect (outptr + 1 >= outend, 0)) \ diff --git a/iconvdata/iso-2022-cn.c b/iconvdata/iso-2022-cn.c index f2170698dd..6ffa18dc78 100644 --- a/iconvdata/iso-2022-cn.c +++ b/iconvdata/iso-2022-cn.c @@ -324,26 +324,7 @@ enum else \ { \ /* Even this does not work. Error. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, \ - &inptr, inend, &outptr, \ - irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ } \ } \ diff --git a/iconvdata/iso-2022-jp.c b/iconvdata/iso-2022-jp.c index ab42bcc75c..ecfdae4e47 100644 --- a/iconvdata/iso-2022-jp.c +++ b/iconvdata/iso-2022-jp.c @@ -703,26 +703,7 @@ gconv_end (struct __gconv_step *data) else if (__builtin_expect (var, iso2022jp2) == iso2022jp) \ { \ /* We have no other choice. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, \ - &inptr, inend, &outptr, \ - irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ else \ { \ @@ -888,28 +869,7 @@ gconv_end (struct __gconv_step *data) } \ else \ { \ - if (step_data->__trans.__trans_fct \ - != NULL) \ - { \ - result = DL_CALL_FCT \ - (step_data->__trans.__trans_fct,\ - (step, step_data, *inptrp, \ - &inptr, inend, &outptr, \ - irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ } \ } \ diff --git a/iconvdata/iso-2022-kr.c b/iconvdata/iso-2022-kr.c index 52031ca177..56e17a2f96 100644 --- a/iconvdata/iso-2022-kr.c +++ b/iconvdata/iso-2022-kr.c @@ -255,25 +255,7 @@ enum if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR) \ { \ /* Illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ else \ { \ diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c index 66f89589cc..99dc0251b0 100644 --- a/iconvdata/iso646.c +++ b/iconvdata/iso646.c @@ -885,29 +885,10 @@ gconv_end (struct __gconv_step *data) \ if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT) \ { \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* Exit the loop with an error. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ - else \ - *outptr++ = (unsigned char) ch; \ + \ + *outptr++ = (unsigned char) ch; \ inptr += 4; \ } #define LOOP_NEED_FLAGS diff --git a/iconvdata/iso8859-1.c b/iconvdata/iso8859-1.c index a6134816db..bedc425ec3 100644 --- a/iconvdata/iso8859-1.c +++ b/iconvdata/iso8859-1.c @@ -49,25 +49,7 @@ if (__builtin_expect (ch, 0) > 0xff) \ { \ /* We have an illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ else \ *outptr++ = (unsigned char) ch; \ diff --git a/iconvdata/iso_6937-2.c b/iconvdata/iso_6937-2.c index cde210844d..dda8acd53f 100644 --- a/iconvdata/iso_6937-2.c +++ b/iconvdata/iso_6937-2.c @@ -565,50 +565,17 @@ static const char from_ucs4[][2] = default: \ /* Illegal characters. */ \ cp = NULL; \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + break; \ + } \ + if (cp == NULL) \ + { \ + STANDARD_ERR_HANDLER (4); \ } \ } \ else if (__builtin_expect (from_ucs4[ch][0], '\1') == '\0' && ch != 0) \ { \ /* Illegal characters. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ else \ cp = from_ucs4[ch]; \ diff --git a/iconvdata/iso_6937.c b/iconvdata/iso_6937.c index e767291adf..d51f321d33 100644 --- a/iconvdata/iso_6937.c +++ b/iconvdata/iso_6937.c @@ -542,50 +542,13 @@ static const char from_ucs4[][2] = if (__builtin_expect (fail, 0)) \ { \ /* Illegal characters. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ } \ else if (__builtin_expect (from_ucs4[ch][0], '\1') == '\0' && ch != 0) \ { \ /* Illegal characters. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ else \ cp = from_ucs4[ch]; \ diff --git a/iconvdata/johab.c b/iconvdata/johab.c index d2947dcd89..46649c5923 100644 --- a/iconvdata/johab.c +++ b/iconvdata/johab.c @@ -396,26 +396,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) } \ if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR) \ { \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ \ outptr[0] -= 0x4a; \ @@ -441,26 +422,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) } \ if (__builtin_expect (written, 1) == __UNKNOWN_10646_CHAR) \ { \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ \ outptr[0] -= 0x4a; \ diff --git a/iconvdata/sjis.c b/iconvdata/sjis.c index aa51259355..08dce1c64b 100644 --- a/iconvdata/sjis.c +++ b/iconvdata/sjis.c @@ -4466,29 +4466,8 @@ static const char from_ucs4_extra[0x100][2] = && __builtin_expect (ch, 0xff01) <= 0xffef) \ cp = from_ucs4_extra[ch - 0xff00]; \ else \ - { \ - /* Illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ - } \ + /* Illegal character. */ \ + cp = ""; \ } \ else \ cp = from_ucs4_lat1[ch]; \ @@ -4496,26 +4475,7 @@ static const char from_ucs4_extra[0x100][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ else \ { \ diff --git a/iconvdata/t.61.c b/iconvdata/t.61.c index 3c1a69e4ab..611eca8b39 100644 --- a/iconvdata/t.61.c +++ b/iconvdata/t.61.c @@ -469,26 +469,7 @@ static const char from_ucs4[][2] = || __builtin_expect (ch, 0x2d8) == 0x02dc) \ { \ /* Illegal characters. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ else \ { \ @@ -506,26 +487,7 @@ static const char from_ucs4[][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal. */ \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ } \ \ diff --git a/iconvdata/uhc.c b/iconvdata/uhc.c index 5526e9b5ba..38ae65ba2e 100644 --- a/iconvdata/uhc.c +++ b/iconvdata/uhc.c @@ -3221,26 +3221,7 @@ static const char uhc_hangul_from_ucs[11172][2] = } \ if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR) \ { \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ \ *outptr++ |= 0x80; \ @@ -3261,26 +3242,7 @@ static const char uhc_hangul_from_ucs[11172][2] = } \ if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR) \ { \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - inptr += 4; \ - ++*irreversible; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ \ *outptr++ |= 0x80; \ diff --git a/iconvdata/unicode.c b/iconvdata/unicode.c index 9caa95df0f..d927cdf667 100644 --- a/iconvdata/unicode.c +++ b/iconvdata/unicode.c @@ -152,26 +152,7 @@ gconv_end (struct __gconv_step *data) \ if (__builtin_expect (c, 0) >= 0x10000) \ { \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, inend, \ - &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ else \ { \ diff --git a/iconvdata/utf-16.c b/iconvdata/utf-16.c index fd7bba72bf..4b7fefaf28 100644 --- a/iconvdata/utf-16.c +++ b/iconvdata/utf-16.c @@ -202,26 +202,7 @@ gconv_end (struct __gconv_step *data) { \ if (__builtin_expect (c, 0) >= 0x110000) \ { \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ \ /* Generate a surrogate character. */ \ @@ -245,26 +226,7 @@ gconv_end (struct __gconv_step *data) { \ if (__builtin_expect (c, 0) >= 0x110000) \ { \ - if (step_data->__trans.__trans_fct != NULL) \ - { \ - result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ - (step, step_data, *inptrp, &inptr, \ - inend, &outptr, irreversible)); \ - if (result != __GCONV_OK) \ - break; \ - } \ - else if (! ignore_errors_p ()) \ - { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - else \ - { \ - ++*irreversible; \ - inptr += 4; \ - } \ - continue; \ + STANDARD_ERR_HANDLER (4); \ } \ \ /* Generate a surrogate character. */ \ diff --git a/libio/iofwide.c b/libio/iofwide.c index 8ad2129062..12649fd9c7 100644 --- a/libio/iofwide.c +++ b/libio/iofwide.c @@ -124,9 +124,9 @@ _IO_fwide (fp, mode) cc->__cd_in.__cd.__data[0].__internal_use = 1; cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST; cc->__cd_in.__cd.__data[0].__statep = &fp->_wide_data->_IO_state; + /* XXX For now no transliteration. */ - memset (&cc->__cd_in.__cd.__data[0].__trans, '\0', - sizeof (struct __gconv_trans_data)); + cc->__cd_in.__cd.__data[0].__trans = NULL; cc->__cd_out.__cd.__nsteps = 1; /* Only one step allowed. */ cc->__cd_out.__cd.__steps = fcts.tomb; @@ -135,9 +135,9 @@ _IO_fwide (fp, mode) cc->__cd_out.__cd.__data[0].__internal_use = 1; cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST; cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state; + /* XXX For now no transliteration. */ - memset (&cc->__cd_out.__cd.__data[0].__trans, '\0', - sizeof (struct __gconv_trans_data)); + cc->__cd_out.__cd.__data[0].__trans = NULL; } #else # error "somehow determine this from LC_CTYPE" diff --git a/locale/loadlocale.c b/locale/loadlocale.c index 36ce5f4076..54336c4c49 100644 --- a/locale/loadlocale.c +++ b/locale/loadlocale.c @@ -234,8 +234,6 @@ _nl_unload_locale (struct locale_data *locale) #endif free ((void *) locale->filedata); - if (locale->options != NULL) - free (locale->options); - + free (locale->options); free (locale); } diff --git a/localedata/Makefile b/localedata/Makefile index 6f20ff96fa..765717ee40 100644 --- a/localedata/Makefile +++ b/localedata/Makefile @@ -75,6 +75,13 @@ $(inst_i18ndir)/charmaps/%: charmaps/% $(+force); $(do-install) $(inst_i18ndir)/locales/%: locales/% $(+force); $(do-install) $(inst_i18ndir)/repertoiremaps/%: repertoiremaps/% $(+force); $(do-install) +# gcc does not know all the format specifiers we are using here. +CFLAGS-tst-mbswcs1.c = -Wno-format +CFLAGS-tst-mbswcs2.c = -Wno-format +CFLAGS-tst-mbswcs3.c = -Wno-format +CFLAGS-tst-mbswcs4.c = -Wno-format +CFLAGS-tst-mbswcs5.c = -Wno-format +CFLAGS-tst-trans.c = -Wno-format ifeq (no,$(cross-compiling)) ifeq (yes,$(build-shared)) diff --git a/wcsmbs/btowc.c b/wcsmbs/btowc.c index cf0ec0825c..14d076c670 100644 --- a/wcsmbs/btowc.c +++ b/wcsmbs/btowc.c @@ -49,7 +49,7 @@ __btowc (c) data.__internal_use = 1; data.__flags = __GCONV_IS_LAST; data.__statep = &data.__state; - memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data)); + data.__trans = NULL; /* Make sure we start in the initial state. */ memset (&data.__state, '\0', sizeof (mbstate_t)); diff --git a/wcsmbs/mbrtowc.c b/wcsmbs/mbrtowc.c index 6f5417980b..d78a38bd43 100644 --- a/wcsmbs/mbrtowc.c +++ b/wcsmbs/mbrtowc.c @@ -49,7 +49,7 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) data.__internal_use = 1; data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; - memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data)); + data.__trans = NULL; /* A first special case is if S is NULL. This means put PS in the initial state. */ diff --git a/wcsmbs/mbsnrtowcs.c b/wcsmbs/mbsnrtowcs.c index 0410232187..d8c0cdc786 100644 --- a/wcsmbs/mbsnrtowcs.c +++ b/wcsmbs/mbsnrtowcs.c @@ -57,7 +57,7 @@ __mbsnrtowcs (dst, src, nmc, len, ps) data.__internal_use = 1; data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; - memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data)); + data.__trans = NULL; if (nmc == 0) return 0; diff --git a/wcsmbs/mbsrtowcs.c b/wcsmbs/mbsrtowcs.c index 73a24a7608..9f9351810e 100644 --- a/wcsmbs/mbsrtowcs.c +++ b/wcsmbs/mbsrtowcs.c @@ -53,7 +53,7 @@ __mbsrtowcs (dst, src, len, ps) data.__internal_use = 1; data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; - memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data)); + data.__trans = NULL; /* Make sure we use the correct function. */ update_conversion_ptrs (); diff --git a/wcsmbs/wcrtomb.c b/wcsmbs/wcrtomb.c index f7100d4fc7..ec75e579a4 100644 --- a/wcsmbs/wcrtomb.c +++ b/wcsmbs/wcrtomb.c @@ -49,7 +49,7 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps) data.__internal_use = 1; data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; - memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data)); + data.__trans = NULL; /* A first special case is if S is NULL. This means put PS in the initial state. */ diff --git a/wcsmbs/wcsnrtombs.c b/wcsmbs/wcsnrtombs.c index f7b4363779..129d0990fe 100644 --- a/wcsmbs/wcsnrtombs.c +++ b/wcsmbs/wcsnrtombs.c @@ -55,7 +55,7 @@ __wcsnrtombs (dst, src, nwc, len, ps) data.__internal_use = 1; data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; - memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data)); + data.__trans = NULL; if (nwc == 0) return 0; diff --git a/wcsmbs/wcsrtombs.c b/wcsmbs/wcsrtombs.c index 3c731aaa54..22dc76c3cb 100644 --- a/wcsmbs/wcsrtombs.c +++ b/wcsmbs/wcsrtombs.c @@ -51,7 +51,7 @@ __wcsrtombs (dst, src, len, ps) data.__internal_use = 1; data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; - memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data)); + data.__trans = NULL; /* Make sure we use the correct function. */ update_conversion_ptrs (); diff --git a/wcsmbs/wctob.c b/wcsmbs/wctob.c index cee739c251..0ee17ce443 100644 --- a/wcsmbs/wctob.c +++ b/wcsmbs/wctob.c @@ -43,7 +43,7 @@ wctob (c) data.__internal_use = 1; data.__flags = __GCONV_IS_LAST; data.__statep = &data.__state; - memset (&data.__trans, '\0', sizeof (struct __gconv_trans_data)); + data.__trans = NULL; /* Make sure we start in the initial state. */ memset (&data.__state, '\0', sizeof (mbstate_t)); |