diff options
47 files changed, 1352 insertions, 571 deletions
@@ -1,3 +1,68 @@ +2000-06-12 Ulrich Drepper <drepper@redhat.com> + + * Rules (%.out): Define GCONV_PATH in the environment. + * assert/Depend: New file. + * iconvdata/Depend: New file. + * intl/Depend: New file. + * timezone/Makefile (build-testdata): Add GCONV_PATH to environment. + * intl/tst-gettext.sh: Likewise. + * iconv/Makefile (routines): Add gconv_trans. + * iconv/gconv_trans.c: New file. + * iconv/gconv.h (struct __gconv_trans_data): New type. + (__gconv_fct): New parameter with starting position in output buffer. + (__gconv_trans_fct, __gconv_trans_context_fct, __gconv_trans_query_fct, + __gconv_trans_init_fct, __gconv_trans_end_fct): New types. + (struct __gconv_step): Add new member __trans. + * iconv/gconv_int.h: Pretty print prototypes. + (gconv_transliterate): New prototype. + (__BUILTIN_TRANS): Update for new conversion function interface. + * iconv/gconv.c (__gconv): Pass new parameter to conversion function. + * iconv/gconv_open.c (__gconv_open): Recognize error handling suffix + in names, find appropriate function, and install in the conversion + steps it can be used. + * iconv/skeleton.c: Add additional parameter for beginning of output + buffer. Change calls of downstream functions. + * iconv/loop.c: Change loop function interface completely. Pass in + step and step_data structure. Remove optimization for BODY with + NEED_LENGTH_TEST == 0. + * iconv/gconv_simple.c: Update interfaces of functions. Insert + appropriate error handling code to use transliteration steps. Remove + optimization for BODY with NEED_LENGTH_TEST == 0. + * 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: Adjust to new interface of gconv functions. Use + DL_CALL_FCT. + * 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. + 2000-04-11 Geoff Keating <geoffk@cygnus.com> * sysdeps/powerpc/dl-machine.c: Include dl-machine.h after the diff --git a/iconv/Makefile b/iconv/Makefile index 14076e6f6e..6af661c964 100644 --- a/iconv/Makefile +++ b/iconv/Makefile @@ -26,7 +26,7 @@ include ../Makeconfig headers = iconv.h gconv.h routines = iconv_open iconv iconv_close \ gconv_open gconv gconv_close gconv_db gconv_conf \ - gconv_builtin gconv_simple + gconv_builtin gconv_simple gconv_trans ifeq ($(elf),yes) routines += gconv_dl else diff --git a/iconv/gconv.c b/iconv/gconv.c index 06e212b2cb..19f95622a2 100644 --- a/iconv/gconv.c +++ b/iconv/gconv.c @@ -46,8 +46,8 @@ __gconv (__gconv_t cd, const unsigned char **inbuf, if (inbuf == NULL || *inbuf == NULL) /* We just flush. */ result = DL_CALL_FCT (cd->__steps->__fct, - (cd->__steps, cd->__data, NULL, NULL, - irreversible, 1, 0)); + (cd->__steps, cd->__data, NULL, NULL, + cd->__data[0].__outbuf, irreversible, 1, 0)); else { const unsigned char *last_start; @@ -58,8 +58,8 @@ __gconv (__gconv_t cd, const unsigned char **inbuf, { last_start = *inbuf; result = DL_CALL_FCT (cd->__steps->__fct, - (cd->__steps, cd->__data, inbuf, inbufend, - irreversible, 0, 0)); + (cd->__steps, cd->__data, inbuf, inbufend, + cd->__data[0].__outbuf, irreversible, 0, 0)); } while (result == __GCONV_EMPTY_INPUT && last_start != *inbuf && *inbuf + cd->__steps->__min_needed_from <= inbufend); diff --git a/iconv/gconv.h b/iconv/gconv.h index 1821844952..5717ddbea0 100644 --- a/iconv/gconv.h +++ b/iconv/gconv.h @@ -62,18 +62,52 @@ enum struct __gconv_step; struct __gconv_step_data; struct __gconv_loaded_object; +struct __gconv_trans_data; /* Type of a conversion function. */ typedef int (*__gconv_fct) (struct __gconv_step *, struct __gconv_step_data *, __const unsigned char **, __const unsigned char *, - size_t *, int, int); + unsigned char *, size_t *, int, int); /* Constructor and destructor for local data for conversion step. */ typedef int (*__gconv_init_fct) (struct __gconv_step *); 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, + __const unsigned char *, + __const unsigned char **, + __const unsigned char *, unsigned char *, + 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, + __const unsigned char *, + __const unsigned char *, + __const unsigned char *, + 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 *); + +/* Constructor and destructor for local data for transliteration. */ +typedef int (*__gconv_trans_init_fct) (void **, const char *); +typedef void (*__gconv_trans_end_fct) (void *); + +struct __gconv_trans_data +{ + /* Transliteration/Transscription function. */ + __gconv_trans_fct __trans_fct; + __gconv_trans_context_fct __trans_context_fct; + __gconv_trans_end_fct __trans_end_fct; + void *__data; +}; + + /* Description of a conversion step. */ struct __gconv_step { @@ -124,6 +158,9 @@ struct __gconv_step_data __mbstate_t *__statep; __mbstate_t __state; /* This element must not be used directly by any module; always use STATEP! */ + + /* Transliteration information. */ + struct __gconv_trans_data __trans; }; diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h index 01cebe72c4..87287d7b26 100644 --- a/iconv/gconv_int.h +++ b/iconv/gconv_int.h @@ -129,8 +129,8 @@ extern struct gconv_module *__gconv_modules_db; /* Return in *HANDLE decriptor for transformation from FROMSET to TOSET. */ -extern int __gconv_open (const char *__toset, const char *__fromset, - __gconv_t *__handle, int flags) +extern int __gconv_open (const char *toset, const char *fromset, + __gconv_t *handle, int flags) internal_function; /* Free resources associated with transformation descriptor CD. */ @@ -141,55 +141,65 @@ extern int __gconv_close (__gconv_t cd) according to rules described by CD and place up to *OUTBYTESLEFT bytes in buffer starting at *OUTBUF. Return number of non-identical conversions in *IRREVERSIBLE if this pointer is not null. */ -extern int __gconv (__gconv_t __cd, const unsigned char **__inbuf, - const unsigned char *inbufend, unsigned char **__outbuf, +extern int __gconv (__gconv_t cd, const unsigned char **inbuf, + const unsigned char *inbufend, unsigned char **outbuf, unsigned char *outbufend, size_t *irreversible) internal_function; /* Return in *HANDLE a pointer to an array with *NSTEPS elements describing the single steps necessary for transformation from FROMSET to TOSET. */ -extern int __gconv_find_transform (const char *__toset, const char *__fromset, - struct __gconv_step **__handle, - size_t *__nsteps, int flags) +extern int __gconv_find_transform (const char *toset, const char *fromset, + struct __gconv_step **handle, + size_t *nsteps, int flags) internal_function; /* Read all the configuration data and cache it. */ extern void __gconv_read_conf (void); /* Comparison function to search alias. */ -extern int __gconv_alias_compare (const void *__p1, const void *__p2); +extern int __gconv_alias_compare (const void *p1, const void *p2); /* Clear reference to transformation step implementations which might cause the code to be unloaded. */ -extern int __gconv_close_transform (struct __gconv_step *__steps, - size_t __nsteps) +extern int __gconv_close_transform (struct __gconv_step *steps, + size_t nsteps) internal_function; /* Load shared object named by NAME. If already loaded increment reference count. */ -extern struct __gconv_loaded_object *__gconv_find_shlib (const char *__name) +extern struct __gconv_loaded_object *__gconv_find_shlib (const char *name) internal_function; /* Release shared object. If no further reference is available unload the object. */ -extern int __gconv_release_shlib (struct __gconv_loaded_object *__handle) +extern int __gconv_release_shlib (struct __gconv_loaded_object *handle) internal_function; /* Fill STEP with information about builtin module with NAME. */ -extern void __gconv_get_builtin_trans (const char *__name, - struct __gconv_step *__step) +extern void __gconv_get_builtin_trans (const char *name, + struct __gconv_step *step) internal_function; +/* Transliteration using the locale's data. */ +extern int gconv_transliterate (struct __gconv_step *step, + struct __gconv_step_data *step_data, + __const unsigned char *inbufstart, + __const unsigned char **inbufp, + __const unsigned char *inbufend, + unsigned char *outbufstart, + unsigned char **outbufp, + unsigned char *outbufend, + size_t *irreversible); /* Builtin transformations. */ #ifdef _LIBC # define __BUILTIN_TRANS(Name) \ - extern int Name (struct __gconv_step *__step, \ - struct __gconv_step_data *__data, \ - const unsigned char **__inbuf, \ - const unsigned char *__inbufend, size_t *__written, \ - int __do_flush, int __consume_incomplete) + extern int Name (struct __gconv_step *step, \ + struct __gconv_step_data *data, \ + const unsigned char **inbuf, \ + const unsigned char *inbufend, unsigned char *outbufstart, \ + size_t *irreversible, int do_flush, int consume_incomplete) __BUILTIN_TRANS (__gconv_transform_ascii_internal); __BUILTIN_TRANS (__gconv_transform_internal_ascii); diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c index da00b1abbd..984ca9dc5d 100644 --- a/iconv/gconv_open.c +++ b/iconv/gconv_open.c @@ -36,25 +36,65 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, size_t cnt = 0; int res; int conv_flags = 0; - const char *runp; + const char *errhand; - /* Find out whether "IGNORE" is part of the options in the `toset' - name. If yes, remove the string and remember this in the flag. */ - runp = __strchrnul (__strchrnul (toset, '/'), '/'); - if (strcmp (runp, "IGNORE") == 0) + /* Find out whether any error handling method is specified. */ + errhand = strchr (toset, '/'); + if (errhand != NULL) + errhand = strchr (errhand + 1, '/'); + if (__builtin_expect (errhand != NULL, 1)) { - /* Found it. This means we should ignore conversion errors. */ - char *newtoset = (char *) alloca (runp - toset + 1); + if (errhand[1] == '\0') + errhand = NULL; + else + { + /* Make copy without the error handling description. */ + char *newtoset = (char *) alloca (errhand - toset + 1); - newtoset[runp - toset] = '\0'; - toset = memcpy (newtoset, toset, runp - toset); + newtoset[errhand - toset] = '\0'; + toset = memcpy (newtoset, toset, errhand - toset); - flags = __GCONV_IGNORE_ERRORS; + flags = __GCONV_IGNORE_ERRORS; + + if (strcasecmp (errhand, "IGNORE") == 0) + { + /* Found it. This means we should ignore conversion errors. */ + flags = __GCONV_IGNORE_ERRORS; + errhand = NULL; + } + } } 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 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; + } + } + /* Allocate room for handle. */ result = (__gconv_t) malloc (sizeof (struct __gconv_info) + (nsteps @@ -63,6 +103,8 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, res = __GCONV_NOMEM; else { + size_t n; + /* Remember the list of steps. */ result->__steps = steps; result->__nsteps = nsteps; @@ -105,6 +147,26 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, } 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 handle the last entry. */ @@ -116,6 +178,26 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, result->__data[cnt].__internal_use = 0; #endif result->__data[cnt].__statep = &result->__data[cnt].__state; + + /* 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; + } } if (res != __GCONV_OK) diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c index 4b7004caa6..188fc04c0e 100644 --- a/iconv/gconv_simple.c +++ b/iconv/gconv_simple.c @@ -19,6 +19,7 @@ Boston, MA 02111-1307, USA. */ #include <byteswap.h> +#include <dlfcn.h> #include <endian.h> #include <errno.h> #include <gconv.h> @@ -62,9 +63,10 @@ static const unsigned char encoding_byte[] = static inline int -internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, +internal_ucs4_loop (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { const unsigned char *inptr = *inptrp; @@ -102,10 +104,11 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, #ifndef _STRING_ARCH_unaligned static inline int -internal_ucs4_loop_unaligned (const unsigned char **inptrp, +internal_ucs4_loop_unaligned (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { const unsigned char *inptr = *inptrp; @@ -149,12 +152,14 @@ internal_ucs4_loop_unaligned (const unsigned char **inptrp, static inline int -internal_ucs4_loop_single (const unsigned char **inptrp, +internal_ucs4_loop_single (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { + mbstate_t *state = step_data->__statep; size_t cnt = state->__count & 7; while (*inptrp < inend && cnt < 4) @@ -205,11 +210,13 @@ internal_ucs4_loop_single (const unsigned char **inptrp, static inline int -ucs4_internal_loop (const unsigned char **inptrp, const unsigned char *inend, +ucs4_internal_loop (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { + int flags = step_data->__flags; const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; size_t n_convert = MIN (inend - inptr, outend - outptr) / 4; @@ -228,6 +235,10 @@ ucs4_internal_loop (const unsigned char **inptrp, const unsigned char *inend, if (__builtin_expect (inval, 0) > 0x7fffffff) { + /* The value is too large. We don't try transliteration here since + this is not an error because of the lack of possibilities to + represent the result. This is a genuine bug in the input since + UCS4 does not allow such values. */ if (flags & __GCONV_IGNORE_ERRORS) { /* Just ignore this character. */ @@ -259,23 +270,28 @@ ucs4_internal_loop (const unsigned char **inptrp, const unsigned char *inend, #ifndef _STRING_ARCH_unaligned static inline int -ucs4_internal_loop_unaligned (const unsigned char **inptrp, +ucs4_internal_loop_unaligned (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { + int flags = step_data->__flags; const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; size_t n_convert = MIN (inend - inptr, outend - outptr) / 4; int result; size_t cnt; - for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4) + for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4) { if (__builtin_expect (inptr[0], 0) > 0x80) { - /* The value is too large. */ + /* The value is too large. We don't try transliteration here since + this is not an error because of the lack of possibilities to + represent the result. This is a genuine bug in the input since + UCS4 does not allow such values. */ if (flags & __GCONV_IGNORE_ERRORS) { /* Just ignore this character. */ @@ -299,6 +315,7 @@ ucs4_internal_loop_unaligned (const unsigned char **inptrp, outptr[2] = inptr[2]; outptr[3] = inptr[3]; # endif + outptr += 4; } *inptrp = inptr; @@ -318,12 +335,15 @@ ucs4_internal_loop_unaligned (const unsigned char **inptrp, static inline int -ucs4_internal_loop_single (const unsigned char **inptrp, +ucs4_internal_loop_single (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { + mbstate_t *state = step_data->__statep; + int flags = step_data->__flags; size_t cnt = state->__count & 7; while (*inptrp < inend && cnt < 4) @@ -341,7 +361,10 @@ ucs4_internal_loop_single (const unsigned char **inptrp, if (__builtin_expect (((unsigned char *) state->__value.__wchb)[0], 0) > 0x80) { - /* The value is too large. */ + /* The value is too large. We don't try transliteration here since + this is not an error because of the lack of possibilities to + represent the result. This is a genuine bug in the input since + UCS4 does not allow such values. */ if (!(flags & __GCONV_IGNORE_ERRORS)) { *inptrp -= cnt - (state->__count & 7); @@ -386,9 +409,10 @@ ucs4_internal_loop_single (const unsigned char **inptrp, static inline int -internal_ucs4le_loop (const unsigned char **inptrp, const unsigned char *inend, +internal_ucs4le_loop (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { const unsigned char *inptr = *inptrp; @@ -426,10 +450,11 @@ internal_ucs4le_loop (const unsigned char **inptrp, const unsigned char *inend, #ifndef _STRING_ARCH_unaligned static inline int -internal_ucs4le_loop_unaligned (const unsigned char **inptrp, +internal_ucs4le_loop_unaligned (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { const unsigned char *inptr = *inptrp; @@ -473,12 +498,14 @@ internal_ucs4le_loop_unaligned (const unsigned char **inptrp, static inline int -internal_ucs4le_loop_single (const unsigned char **inptrp, +internal_ucs4le_loop_single (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { + mbstate_t *state = step_data->__statep; size_t cnt = state->__count & 7; while (*inptrp < inend && cnt < 4) @@ -526,11 +553,13 @@ internal_ucs4le_loop_single (const unsigned char **inptrp, static inline int -ucs4le_internal_loop (const unsigned char **inptrp, const unsigned char *inend, +ucs4le_internal_loop (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { + int flags = step_data->__flags; const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; size_t n_convert = MIN (inend - inptr, outend - outptr) / 4; @@ -549,6 +578,10 @@ ucs4le_internal_loop (const unsigned char **inptrp, const unsigned char *inend, if (__builtin_expect (inval, 0) > 0x7fffffff) { + /* The value is too large. We don't try transliteration here since + this is not an error because of the lack of possibilities to + represent the result. This is a genuine bug in the input since + UCS4 does not allow such values. */ if (flags & __GCONV_IGNORE_ERRORS) { /* Just ignore this character. */ @@ -578,12 +611,14 @@ ucs4le_internal_loop (const unsigned char **inptrp, const unsigned char *inend, #ifndef _STRING_ARCH_unaligned static inline int -ucs4le_internal_loop_unaligned (const unsigned char **inptrp, +ucs4le_internal_loop_unaligned (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { + int flags = step_data->__flags; const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; size_t n_convert = MIN (inend - inptr, outend - outptr) / 4; @@ -594,7 +629,10 @@ ucs4le_internal_loop_unaligned (const unsigned char **inptrp, { if (__builtin_expect (inptr[3], 0) > 0x80) { - /* The value is too large. */ + /* The value is too large. We don't try transliteration here since + this is not an error because of the lack of possibilities to + represent the result. This is a genuine bug in the input since + UCS4 does not allow such values. */ if (flags & __GCONV_IGNORE_ERRORS) { /* Just ignore this character. */ @@ -639,12 +677,15 @@ ucs4le_internal_loop_unaligned (const unsigned char **inptrp, static inline int -ucs4le_internal_loop_single (const unsigned char **inptrp, +ucs4le_internal_loop_single (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible) { + mbstate_t *state = step_data->__statep; + int flags = step_data->__flags; size_t cnt = state->__count & 7; while (*inptrp < inend && cnt < 4) @@ -662,7 +703,10 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, if (__builtin_expect (((unsigned char *) state->__value.__wchb)[3], 0) > 0x80) { - /* The value is too large. */ + /* The value is too large. We don't try transliteration here since + this is not an error because of the lack of possibilities to + represent the result. This is a genuine bug in the input since + UCS4 does not allow such values. */ if (!(flags & __GCONV_IGNORE_ERRORS)) return __GCONV_ILLEGAL_INPUT; } @@ -710,6 +754,10 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, { \ if (__builtin_expect (*inptr, 0) > '\x7f') \ { \ + /* The value is too large. We don't try transliteration here since \ + this is not an error because of the lack of possibilities to \ + represent the result. This is a genuine bug in the input since \ + ASCII does not allow such values. */ \ if (! ignore_errors_p ()) \ { \ /* This is no correct ANSI_X3.4-1968 character. */ \ @@ -718,13 +766,14 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, } \ \ ++*irreversible; \ - ++inptr; \ + ++inptr; \ } \ else \ /* It's an one byte sequence. */ \ /* XXX unaligned. */ \ *((uint32_t *) outptr)++ = *inptr++; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> #include <iconv/skeleton.c> @@ -740,6 +789,13 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, #define FUNCTION_NAME __gconv_transform_internal_ascii #define ONE_DIRECTION 1 +extern int FUNCTION_NAME (struct __gconv_step *step, + struct __gconv_step_data *data, + const unsigned char **inptrp, + const unsigned char *inend, + unsigned char *outbufstart, size_t *irreversible, + int do_flush, int consume_incomplete); + #define MIN_NEEDED_INPUT MIN_NEEDED_FROM #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO #define LOOPFCT FROM_LOOP @@ -748,20 +804,31 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, /* XXX unaligned. */ \ if (__builtin_expect (*((uint32_t *) inptr), 0) > 0x7f) \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, 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; \ } \ - \ - ++*irreversible; \ - inptr += 4; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ } \ else \ /* It's an one byte sequence. */ \ *outptr++ = *((uint32_t *) inptr)++; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> #include <iconv/skeleton.c> @@ -916,7 +983,7 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, continue; \ } \ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + cnt > inend, 0)) \ + if (__builtin_expect (inptr + cnt > inend, 0)) \ { \ /* We don't have enough input. But before we report that check \ that all the bytes are correct. */ \ @@ -979,6 +1046,7 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, /* Now adjust the pointers and store the result. */ \ *((uint32_t *) outptr)++ = ch; \ } +#define LOOP_NEED_FLAGS #define STORE_REST \ { \ @@ -1125,18 +1193,29 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, { \ if (__builtin_expect (*((uint32_t *) inptr), 0) >= 0x10000) \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ } \ else \ *((uint16_t *) outptr)++ = *((uint32_t *) inptr)++; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> #include <iconv/skeleton.c> @@ -1181,17 +1260,29 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, uint32_t val = *((uint32_t *) inptr); \ if (__builtin_expect (val, 0) >= 0x10000) \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ + continue; \ } \ *((uint16_t *) outptr)++ = bswap_16 (val); \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> #include <iconv/skeleton.c> diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c new file mode 100644 index 0000000000..11c542e744 --- /dev/null +++ b/iconv/gconv_trans.c @@ -0,0 +1,50 @@ +/* Transliteration using the locale's data. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stdint.h> + +#include "gconv_int.h" +#include "../locale/localeinfo.h" + + +int +gconv_transliterate (struct __gconv_step *step, + struct __gconv_step_data *step_data, + __const unsigned char *inbufstart, + __const unsigned char **inbufp, + __const unsigned char *inbufend, + unsigned char *outbufstart, + unsigned char **outbufp, unsigned char *outbufend, + size_t *irreversible) +{ + /* Find out about the locale's transliteration. */ + uint_fast32_t size = _NL_CURRENT_WORD (LC_CTYPE, + _NL_CTYPE_TRANSLIT_HASH_SIZE); + uint_fast32_t layers = _NL_CURRENT_WORD (LC_CTYPE, + _NL_CTYPE_TRANSLIT_HASH_LAYERS); + + /* If there is no transliteration information in the locale don't do + anything and return the error. */ + if (size == 0) + return __GCONV_ILLEGAL_INPUT; + + /* XXX For now we don't do anything. */ + return __GCONV_ILLEGAL_INPUT; +} diff --git a/iconv/loop.c b/iconv/loop.c index c01e52040e..ebbc1362b3 100644 --- a/iconv/loop.c +++ b/iconv/loop.c @@ -175,88 +175,57 @@ /* The function returns the status, as defined in gconv.h. */ static inline int -FCTNAME (LOOPFCT) (const unsigned char **inptrp, const unsigned char *inend, +FCTNAME (LOOPFCT) (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible EXTRA_LOOP_DECLS) { - int result = __GCONV_OK; +#ifdef LOOP_NEED_STATE + mbstate_t *state = step_data->__statep; +#endif +#ifdef LOOP_NEED_FLAGS + int flags = step_data->__flags; +#endif +#ifdef LOOP_NEED_DATA + void *data = step->__data; +#endif + int result = __GCONV_EMPTY_INPUT; const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; - /* We run one loop where we avoid checks for underflow/overflow of the - buffers to speed up the conversion a bit. */ - size_t min_in_rounds = (inend - inptr) / MAX_NEEDED_INPUT; - size_t min_out_rounds = (outend - outptr) / MAX_NEEDED_OUTPUT; - size_t min_rounds = MIN (min_in_rounds, min_out_rounds); - #ifdef INIT_PARAMS INIT_PARAMS; #endif -#undef NEED_LENGTH_TEST -#define NEED_LENGTH_TEST 0 - while (min_rounds-- > 0) + while (inptr != inend) { - /* Here comes the body the user provides. It can stop with RESULT - set to GCONV_INCOMPLETE_INPUT (if the size of the input characters - vary in size), GCONV_ILLEGAL_INPUT, or GCONV_FULL_OUTPUT (if the - output characters vary in size. */ - BODY - } - - if (result == __GCONV_OK) - { -#if MIN_NEEDED_INPUT == MAX_NEEDED_INPUT \ - && MIN_NEEDED_OUTPUT == MAX_NEEDED_OUTPUT - /* We don't need to start another loop since we were able to determine - the maximal number of characters to copy in advance. What remains - to be determined is the status. */ - if (inptr == inend) - /* No more input. */ - result = __GCONV_EMPTY_INPUT; - else if ((MIN_NEEDED_OUTPUT != 1 && outptr + MIN_NEEDED_OUTPUT > outend) - || (MIN_NEEDED_OUTPUT == 1 && outptr >= outend)) - /* Overflow in the output buffer. */ - result = __GCONV_FULL_OUTPUT; - else - /* We have something left in the input buffer. */ - result = __GCONV_INCOMPLETE_INPUT; -#else - result = __GCONV_EMPTY_INPUT; - -# undef NEED_LENGTH_TEST -# define NEED_LENGTH_TEST 1 - while (inptr != inend) + /* `if' cases for MIN_NEEDED_OUTPUT ==/!= 1 is made to help the + compiler generating better code. It will optimized away + since MIN_NEEDED_OUTPUT is always a constant. */ + if ((MIN_NEEDED_OUTPUT != 1 + && __builtin_expect (outptr + MIN_NEEDED_OUTPUT > outend, 0)) + || (MIN_NEEDED_OUTPUT == 1 + && __builtin_expect (outptr >= outend, 0))) + { + /* Overflow in the output buffer. */ + result = __GCONV_FULL_OUTPUT; + break; + } + if (MIN_NEEDED_INPUT > 1 + && __builtin_expect (inptr + MIN_NEEDED_INPUT > inend, 0)) { - /* `if' cases for MIN_NEEDED_OUTPUT ==/!= 1 is made to help the - compiler generating better code. It will optimized away - since MIN_NEEDED_OUTPUT is always a constant. */ - if ((MIN_NEEDED_OUTPUT != 1 - && __builtin_expect (outptr + MIN_NEEDED_OUTPUT > outend, 0)) - || (MIN_NEEDED_OUTPUT == 1 - && __builtin_expect (outptr >= outend, 0))) - { - /* Overflow in the output buffer. */ - result = __GCONV_FULL_OUTPUT; - break; - } - if (MIN_NEEDED_INPUT > 1 - && __builtin_expect (inptr + MIN_NEEDED_INPUT > inend, 0)) - { - /* We don't have enough input for another complete input - character. */ - result = __GCONV_INCOMPLETE_INPUT; - break; - } - - /* Here comes the body the user provides. It can stop with - RESULT set to GCONV_INCOMPLETE_INPUT (if the size of the - input characters vary in size), GCONV_ILLEGAL_INPUT, or - GCONV_FULL_OUTPUT (if the output characters vary in size). */ - BODY + /* We don't have enough input for another complete input + character. */ + result = __GCONV_INCOMPLETE_INPUT; + break; } -#endif /* Input and output charset are not both fixed width. */ + + /* Here comes the body the user provides. It can stop with + RESULT set to GCONV_INCOMPLETE_INPUT (if the size of the + input characters vary in size), GCONV_ILLEGAL_INPUT, or + GCONV_FULL_OUTPUT (if the output characters vary in size). */ + BODY } /* Update the pointers pointed to by the parameters. */ @@ -291,11 +260,19 @@ FCTNAME (LOOPFCT) (const unsigned char **inptrp, const unsigned char *inend, # define SINGLE(fct) SINGLE2 (fct) # define SINGLE2(fct) fct##_single static inline int -SINGLE(LOOPFCT) (const unsigned char **inptrp, const unsigned char *inend, +SINGLE(LOOPFCT) (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, int flags, void *data, size_t *irreversible - EXTRA_LOOP_DECLS) + size_t *irreversible EXTRA_LOOP_DECLS) { + mbstate_t *state = step_data->__statep; +#ifdef LOOP_NEED_FLAGS + int flags = step_data->__flags; +#endif +#ifdef LOOP_NEED_DATA + void *data = step->__data; +#endif int result = __GCONV_OK; unsigned char bytebuf[MAX_NEEDED_INPUT]; const unsigned char *inptr = *inptrp; @@ -347,8 +324,7 @@ SINGLE(LOOPFCT) (const unsigned char **inptrp, const unsigned char *inend, inptr = bytebuf; inend = &bytebuf[inlen]; -#undef NEED_LENGTH_TEST -#define NEED_LENGTH_TEST 1 + do { BODY @@ -410,9 +386,12 @@ SINGLE(LOOPFCT) (const unsigned char **inptrp, const unsigned char *inend, #undef EXTRA_LOOP_DECLS #undef INIT_PARAMS #undef UPDATE_PARAMS +#undef UNPACK_BYTES +#undef LOOP_NEED_STATE +#undef LOOP_NEED_FLAGS +#undef LOOP_NEED_DATA #undef get16 #undef get32 #undef put16 #undef put32 #undef unaligned -#undef UNPACK_BYTES diff --git a/iconv/skeleton.c b/iconv/skeleton.c index 9b7b4a1125..dca2c7f7a6 100644 --- a/iconv/skeleton.c +++ b/iconv/skeleton.c @@ -271,7 +271,8 @@ gconv_init (struct __gconv_step *step) int FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, const unsigned char **inptrp, const unsigned char *inend, - size_t *irreversible, int do_flush, int consume_incomplete) + unsigned char *outbufstart, size_t *irreversible, int do_flush, + int consume_incomplete) { struct __gconv_step *next_step = step + 1; struct __gconv_step_data *next_data = data + 1; @@ -295,13 +296,14 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, successfully emitted the escape sequence. */ if (status == __GCONV_OK && ! (data->__flags & __GCONV_IS_LAST)) status = DL_CALL_FCT (fct, (next_step, next_data, NULL, NULL, - irreversible, 1, consume_incomplete)); + next_data->__outbuf, irreversible, 1, + consume_incomplete)); } else { /* We preserve the initial values of the pointer variables. */ const unsigned char *inptr = *inptrp; - unsigned char *outbuf = data->__outbuf; + unsigned char *outbuf = outbufstart; unsigned char *outend = data->__outbufend; unsigned char *outstart; /* This variable is used to count the number of characters we @@ -333,19 +335,16 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, # if MAX_NEEDED_FROM > 1 if (MAX_NEEDED_TO == 1 || FROM_DIRECTION) - status = SINGLE(FROM_LOOP) (inptrp, inend, &outbuf, outend, - data->__statep, data->__flags, - step->__data, &lirreversible + status = SINGLE(FROM_LOOP) (step, data, inptrp, inend, &outbuf, + outend, &lirreversible EXTRA_LOOP_ARGS); # endif # if MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1 && !ONE_DIRECTION else # endif # if MAX_NEEDED_TO > 1 && !ONE_DIRECTION - status = SINGLE(TO_LOOP) (inptrp, inend, &outbuf, outend, - data->__statep, data->__flags, - step->__data, &lirreversible - EXTRA_LOOP_ARGS); + status = SINGLE(TO_LOOP) (step, data, inptrp, inend, &outbuf, + outend, &lirreversible EXTRA_LOOP_ARGS); # endif if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK) @@ -386,16 +385,12 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, { if (FROM_DIRECTION) /* Run the conversion loop. */ - status = FROM_LOOP (inptrp, inend, &outbuf, outend, - data->__statep, data->__flags, - step->__data, &lirreversible - EXTRA_LOOP_ARGS); + status = FROM_LOOP (step, data, inptrp, inend, &outbuf, outend, + &lirreversible EXTRA_LOOP_ARGS); else /* Run the conversion loop. */ - status = TO_LOOP (inptrp, inend, &outbuf, outend, - data->__statep, data->__flags, - step->__data, &lirreversible - EXTRA_LOOP_ARGS); + status = TO_LOOP (step, data, inptrp, inend, &outbuf, outend, + &lirreversible EXTRA_LOOP_ARGS); } #if !defined _STRING_ARCH_unaligned \ && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \ @@ -404,18 +399,14 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, { if (FROM_DIRECTION) /* Run the conversion loop. */ - status = GEN_unaligned (FROM_LOOP) (inptrp, inend, &outbuf, - outend, data->__statep, - data->__flags, - step->__data, + status = GEN_unaligned (FROM_LOOP) (step, data, inptrp, inend, + &outbuf, outend, &lirreversible EXTRA_LOOP_ARGS); else /* Run the conversion loop. */ - status = GEN_unaligned (TO_LOOP) (inptrp, inend, &outbuf, - outend, data->__statep, - data->__flags, - step->__data, + status = GEN_unaligned (TO_LOOP) (step, data, inptrp, inend, + &outbuf, outend, &lirreversible EXTRA_LOOP_ARGS); } @@ -445,7 +436,8 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, int result; result = DL_CALL_FCT (fct, (next_step, next_data, &outerr, - outbuf, irreversible, 0, + outbuf, next_data->__outbuf, + irreversible, 0, consume_incomplete)); if (result != __GCONV_EMPTY_INPUT) @@ -471,22 +463,20 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, /* XXX Handle unaligned access here as well. */ if (FROM_DIRECTION) /* Run the conversion loop. */ - nstatus = FROM_LOOP ((const unsigned char **) inptrp, + nstatus = FROM_LOOP (step, data, + (const unsigned char **) inptrp, (const unsigned char *) inend, (unsigned char **) &outbuf, (unsigned char *) outerr, - data->__statep, data->__flags, - step->__data, &lirreversible - EXTRA_LOOP_ARGS); + &lirreversible EXTRA_LOOP_ARGS); else /* Run the conversion loop. */ - nstatus = TO_LOOP ((const unsigned char **) inptrp, + nstatus = TO_LOOP (step, data, + (const unsigned char **) inptrp, (const unsigned char *) inend, (unsigned char **) &outbuf, (unsigned char *) outerr, - data->__statep, data->__flags, - step->__data, &lirreversible - EXTRA_LOOP_ARGS); + &lirreversible EXTRA_LOOP_ARGS); /* We must run out of output buffer space in this rerun. */ diff --git a/iconvdata/8bit-gap.c b/iconvdata/8bit-gap.c index 2d66f8b666..23a63fd9e4 100644 --- a/iconvdata/8bit-gap.c +++ b/iconvdata/8bit-gap.c @@ -19,6 +19,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <stdint.h> struct gap @@ -67,6 +68,7 @@ struct gap \ ++inptr; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -83,7 +85,15 @@ struct gap if (__builtin_expect (ch, 0) >= 0xffff) \ { \ /* This is an illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ @@ -98,14 +108,24 @@ struct gap if (__builtin_expect (ch < rp->start, 0)) \ { \ /* This is an illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ - inptr += 4; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ continue; \ } \ \ @@ -113,20 +133,31 @@ struct gap if (__builtin_expect (res, '\1') == '\0' && ch != 0) \ { \ /* This is an illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ - inptr += 4; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ continue; \ } \ \ *outptr++ = res; \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/8bit-generic.c b/iconvdata/8bit-generic.c index 97ca193194..62160c6efa 100644 --- a/iconvdata/8bit-generic.c +++ b/iconvdata/8bit-generic.c @@ -18,6 +18,8 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> + #define FROM_LOOP from_generic #define TO_LOOP to_generic #define DEFINE_INIT 1 @@ -50,6 +52,7 @@ outptr += 4; \ ++inptr; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -65,19 +68,32 @@ || (__builtin_expect (from_ucs4[ch], '\1') == '\0' && ch != 0)) \ { \ /* This is an illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ } \ else \ - *outptr++ = from_ucs4[ch]; \ - \ - inptr += 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 2dd082d3b9..f403773d9d 100644 --- a/iconvdata/ansi_x3.110.c +++ b/iconvdata/ansi_x3.110.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gconv.h> #include <stdint.h> #include <string.h> @@ -407,7 +408,7 @@ static const char from_ucs4[][2] = is also available. */ \ uint32_t ch2; \ \ - if (NEED_LENGTH_TEST && inptr + 1 >= inend) \ + if (inptr + 1 >= inend) \ { \ /* The second character is not available. */ \ result = __GCONV_INCOMPLETE_INPUT; \ @@ -458,6 +459,7 @@ static const char from_ucs4[][2] = \ inptr += incr; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -495,14 +497,25 @@ static const char from_ucs4[][2] = if (tmp[0] == '\0') \ { \ /* Illegal characters. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ - inptr += 4; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ continue; \ } \ tmp[1] = '\0'; \ @@ -543,14 +556,25 @@ static const char from_ucs4[][2] = else \ { \ /* Illegal characters. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ - inptr += 4; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ continue; \ } \ } \ @@ -561,14 +585,25 @@ static const char from_ucs4[][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal characters. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ - inptr += 4; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ continue; \ } \ } \ @@ -577,7 +612,7 @@ static const char from_ucs4[][2] = /* Now test for a possible second byte and write this if possible. */ \ if (cp[1] != '\0') \ { \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr >= outend, 0)) \ + if (__builtin_expect (outptr >= outend, 0)) \ { \ /* The result does not fit into the buffer. */ \ --outptr; \ @@ -590,6 +625,7 @@ static const char from_ucs4[][2] = \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/big5.c b/iconvdata/big5.c index a52f850f73..2e039376d0 100644 --- a/iconvdata/big5.c +++ b/iconvdata/big5.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gconv.h> #include <stdint.h> #include <stdlib.h> @@ -8438,7 +8439,7 @@ static const char from_ucs4_tab13[][2] = uint32_t ch2; \ int idx; \ \ - if (NEED_LENGTH_TEST && inptr + 1 >= inend) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. */ \ result = __GCONV_INCOMPLETE_INPUT; \ @@ -8493,6 +8494,7 @@ static const char from_ucs4_tab13[][2] = put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -8583,18 +8585,30 @@ static const char from_ucs4_tab13[][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ + continue; \ } \ else \ { \ /* See whether there is enough room for the second byte we write. */ \ - if (NEED_LENGTH_TEST && __builtin_expect (cp[1], '\1') != '\0' \ + if (__builtin_expect (cp[1], '\1') != '\0' \ && __builtin_expect (outptr + 1 >= outend, 0)) \ { \ /* We have not enough room. */ \ @@ -8609,6 +8623,7 @@ static const char from_ucs4_tab13[][2] = \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/big5hkscs.c b/iconvdata/big5hkscs.c index 1ca22d65a6..b5fe9663e5 100644 --- a/iconvdata/big5hkscs.c +++ b/iconvdata/big5hkscs.c @@ -19,6 +19,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gconv.h> #include <stdint.h> #include <stdlib.h> @@ -12592,7 +12593,7 @@ static const char from_ucs4_tab14[][2] = uint32_t ch2; \ int idx; \ \ - if (NEED_LENGTH_TEST && inptr + 1 >= inend) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. */ \ result = __GCONV_INCOMPLETE_INPUT; \ @@ -12647,6 +12648,7 @@ static const char from_ucs4_tab14[][2] = put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -12740,18 +12742,30 @@ static const char from_ucs4_tab14[][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ + continue; \ } \ else \ { \ /* See whether there is enough room for the second byte we write. */ \ - if (NEED_LENGTH_TEST && __builtin_expect (cp[1], '\1') != '\0' \ + if (__builtin_expect (cp[1], '\1') != '\0' \ && __builtin_expect (outptr + 1 >= outend, 0)) \ { \ /* We have not enough room. */ \ @@ -12766,6 +12780,7 @@ static const char from_ucs4_tab14[][2] = \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/euc-cn.c b/iconvdata/euc-cn.c index 2c2b36e433..c7a02c2cd4 100644 --- a/iconvdata/euc-cn.c +++ b/iconvdata/euc-cn.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gb2312.h> #include <stdint.h> @@ -64,7 +65,7 @@ next character is also available. */ \ const unsigned char *endp; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 1 >= inend, 0)) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. Store \ the intermediate result. */ \ @@ -114,6 +115,7 @@ put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -133,22 +135,31 @@ { \ size_t found; \ \ - found = ucs4_to_gb2312 (ch, outptr, \ - (NEED_LENGTH_TEST \ - ? outend - outptr : MAX_NEEDED_OUTPUT)); \ - if (!NEED_LENGTH_TEST || __builtin_expect (found, 1) != 0) \ + found = ucs4_to_gb2312 (ch, outptr, outend - outptr); \ + if (__builtin_expect (found, 1) != 0) \ { \ if (__builtin_expect (found, 0) == __UNKNOWN_10646_CHAR) \ { \ /* Illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ \ @@ -165,6 +176,7 @@ } \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/euc-jp.c b/iconvdata/euc-jp.c index 93622e778e..6cf89e3aa6 100644 --- a/iconvdata/euc-jp.c +++ b/iconvdata/euc-jp.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <stdint.h> #include <gconv.h> #include <jis0201.h> @@ -66,7 +67,7 @@ character is also available. */ \ int ch2; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 1 >= inend, 0)) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. Store the \ intermediate result. */ \ @@ -106,21 +107,17 @@ /* This is code set 3: JIS X 0212-1990. */ \ endp = inptr + 1; \ \ - ch = jisx0212_to_ucs4 (&endp, \ - NEED_LENGTH_TEST ? inend - endp : 2, \ - 0x80); \ + ch = jisx0212_to_ucs4 (&endp, inend - endp, 0x80); \ } \ else \ { \ /* This is code set 1: JIS X 0208. */ \ endp = inptr; \ \ - ch = jisx0208_to_ucs4 (&endp, \ - NEED_LENGTH_TEST ? inend - inptr : 2, \ - 0x80); \ + ch = jisx0208_to_ucs4 (&endp, inend - inptr, 0x80); \ } \ \ - if (NEED_LENGTH_TEST && __builtin_expect (ch, 1) == 0) \ + if (__builtin_expect (ch, 1) == 0) \ { \ /* Not enough input available. */ \ result = __GCONV_INCOMPLETE_INPUT; \ @@ -147,6 +144,7 @@ put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -174,7 +172,7 @@ size_t found; \ \ /* See whether we have room for at least two characters. */ \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr + 1 >= outend, 0)) \ + if (__builtin_expect (outptr + 1 >= outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -202,8 +200,7 @@ { \ /* No JIS 0208 character. */ \ found = ucs4_to_jisx0212 (ch, outptr + 1, \ - (NEED_LENGTH_TEST \ - ? outend - outptr - 1 : 2)); \ + outend - outptr - 1); \ \ if (__builtin_expect (found, 1) == 0) \ { \ @@ -221,14 +218,26 @@ else \ { \ /* Illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, \ + &inptr, inend, *outptrp, \ + &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ } \ @@ -237,6 +246,7 @@ \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/euc-kr.c b/iconvdata/euc-kr.c index f067fbc548..88794f2f02 100644 --- a/iconvdata/euc-kr.c +++ b/iconvdata/euc-kr.c @@ -19,6 +19,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <stdint.h> #include <ksc5601.h> @@ -98,9 +99,8 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) { \ /* Two-byte character. First test whether the next character \ is also available. */ \ - ch = ksc5601_to_ucs4 (&inptr, \ - NEED_LENGTH_TEST ? inptr - inend : 2, 0x80); \ - if (NEED_LENGTH_TEST && __builtin_expect (ch, 1) == 0) \ + ch = ksc5601_to_ucs4 (&inptr, inptr - inend, 0x80); \ + if (__builtin_expect (ch, 1) == 0) \ { \ /* The second character is not available. */ \ result = __GCONV_INCOMPLETE_INPUT; \ @@ -125,6 +125,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -145,14 +146,24 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ \ @@ -160,7 +171,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) /* Now test for a possible second byte and write this if possible. */ \ if (cp[1] != '\0') \ { \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr >= outend, 0)) \ + if (__builtin_expect (outptr >= outend, 0)) \ { \ /* The result does not fit into the buffer. */ \ --outptr; \ @@ -172,6 +183,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/euc-tw.c b/iconvdata/euc-tw.c index a508c848ef..ee88d4e2a7 100644 --- a/iconvdata/euc-tw.c +++ b/iconvdata/euc-tw.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <stdint.h> #include <cns11643l1.h> #include <cns11643.h> @@ -48,8 +49,15 @@ else if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*irreversible; \ + continue; \ } \ else \ { \ @@ -57,7 +65,7 @@ character is also available. */ \ uint32_t ch2; \ \ - if (NEED_LENGTH_TEST && inptr + (ch == 0x8e ? 3 : 1) >= inend) \ + if (inptr + (ch == 0x8e ? 3 : 1) >= inend) \ { \ /* The second character is not available. Store the \ intermediate result. */ \ @@ -70,9 +78,16 @@ /* All second bytes of a multibyte character must be >= 0xa1. */ \ if (ch2 < 0xa1 || ch2 == 0xff) \ { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + /* This is illegal. */ \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*irreversible; \ + continue; \ } \ \ if (ch == 0x8e) \ @@ -80,16 +95,22 @@ /* This is code set 2: CNS 11643, planes 1 to 16. */ \ const char *endp = inptr + 1; \ \ - ch = cns11643_to_ucs4 (&endp, \ - NEED_LENGTH_TEST ? inend - inptr - 1 : 3, \ - 0x80); \ + ch = cns11643_to_ucs4 (&endp, inend - inptr - 1, 0x80); \ /* Please note that we need not test for the missing input \ characters here anymore. */ \ if (ch == __UNKNOWN_10646_CHAR) \ { \ /* Illegal input. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*irreversible; \ + continue; \ } \ \ inptr += 4; \ @@ -99,16 +120,22 @@ /* This is code set 1: CNS 11643, plane 1. */ \ const unsigned char *endp = inptr; \ \ - ch = cns11643l1_to_ucs4 (&endp, \ - NEED_LENGTH_TEST ? inend - inptr : 2, \ - 0x80); \ + ch = cns11643l1_to_ucs4 (&endp, inend - inptr, 0x80); \ /* Please note that we need not test for the missing input \ characters here anymore. */ \ if (ch == __UNKNOWN_10646_CHAR) \ { \ /* Illegal input. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*irreversible; \ + continue; \ } \ \ inptr += 2; \ @@ -118,6 +145,7 @@ put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -138,15 +166,14 @@ /* Try the JIS character sets. */ \ size_t found; \ \ - found = ucs4_to_cns11643l1 (ch, outptr, \ - NEED_LENGTH_TEST ? outend - outptr : 2); \ - if (NEED_LENGTH_TEST && found == 0) \ + found = ucs4_to_cns11643l1 (ch, outptr, outend - outptr); \ + if (__builtin_expect (found, 1) == 0) \ { \ /* We ran out of space. */ \ result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ - if (found != __UNKNOWN_10646_CHAR) \ + if (__builtin_expect (found, 1) != __UNKNOWN_10646_CHAR) \ { \ /* It's a CNS 11643, plane 1 character, adjust it for EUC-TW. */ \ *outptr++ += 0x80; \ @@ -156,20 +183,36 @@ { \ /* No CNS 11643, plane 1 character. */ \ \ - found = ucs4_to_cns11643 (ch, outptr + 1, \ - (NEED_LENGTH_TEST \ - ? outend - outptr - 1 : 3)); \ - if (NEED_LENGTH_TEST && found == 0) \ + found = ucs4_to_cns11643 (ch, outptr + 1, outend - outptr - 1); \ + if (__builtin_expect (found, 1) == 0) \ { \ /* We ran out of space. */ \ result = __GCONV_INCOMPLETE_INPUT; \ break; \ } \ - if (found == __UNKNOWN_10646_CHAR) \ + if (__builtin_expect (found, 0) == __UNKNOWN_10646_CHAR) \ { \ - /* No legal input. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + /* Illegal character. */ \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ + continue; \ } \ \ /* It's a CNS 11643 character, adjust it for EUC-TW. */ \ @@ -182,6 +225,7 @@ \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/gbgbk.c b/iconvdata/gbgbk.c index 0fbbfc81e4..c6f2e4e0c2 100644 --- a/iconvdata/gbgbk.c +++ b/iconvdata/gbgbk.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gconv.h> #include <stdint.h> @@ -71,7 +72,7 @@ UCS4 -> GB2312 -> GBK -> UCS4 \ \ might not produce identical text. */ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 1 >= inend, 0)) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. Store \ the intermediate result. */ \ @@ -79,7 +80,7 @@ break; \ } \ \ - if (NEED_LENGTH_TEST && __builtin_expect (outend - outptr < 2, 0)) \ + if (__builtin_expect (outend - outptr < 2, 0)) \ { \ /* We ran out of space. */ \ result = __GCONV_FULL_OUTPUT; \ @@ -101,14 +102,25 @@ && __builtin_expect (ch, 0xa1a1) <= 0xa8c0)) \ { \ /* One of the characters we cannot map. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 2; \ - ++*irreversible; \ + else \ + { \ + inptr += 2; \ + ++*irreversible; \ + } \ } \ else \ { \ @@ -118,6 +130,7 @@ } \ } \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -136,7 +149,7 @@ \ if (ch > 0x7f) \ { \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 1 >= inend, 0)) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. Store \ the intermediate result. */ \ @@ -144,7 +157,7 @@ break; \ } \ \ - if (NEED_LENGTH_TEST && __builtin_expect (outend - outptr < 2, 0)) \ + if (__builtin_expect (outend - outptr < 2, 0)) \ { \ /* We ran out of space. */ \ result = __GCONV_FULL_OUTPUT; \ diff --git a/iconvdata/gbk.c b/iconvdata/gbk.c index 952f76ab73..f82059195e 100644 --- a/iconvdata/gbk.c +++ b/iconvdata/gbk.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gconv.h> #include <stdint.h> #include <stdlib.h> @@ -13109,7 +13110,7 @@ static const char __gbk_from_ucs4_tab12[][2] = #define MIN_NEEDED_TO 4 -/* First define the conversion function from ISO 8859-1 to UCS4. */ +/* First define the conversion function from GBK to UCS4. */ #define MIN_NEEDED_INPUT MIN_NEEDED_FROM #define MAX_NEEDED_INPUT MAX_NEEDED_FROM #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO @@ -13142,7 +13143,7 @@ static const char __gbk_from_ucs4_tab12[][2] = uint32_t ch2; \ int idx; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 1 >= inend, 0)) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. Store \ the intermediate result. */ \ @@ -13194,6 +13195,7 @@ static const char __gbk_from_ucs4_tab12[][2] = put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -13450,17 +13452,29 @@ static const char __gbk_from_ucs4_tab12[][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ + continue; \ } \ /* See whether there is enough room for the second byte we write. */ \ - else if (NEED_LENGTH_TEST && cp[1] != '\0' \ - && __builtin_expect (outptr + 1 >= outend, 0)) \ + else if (cp[1] != '\0' && __builtin_expect (outptr + 1 >= outend, 0)) \ { \ /* We have not enough room. */ \ result = __GCONV_FULL_OUTPUT; \ @@ -13476,6 +13490,7 @@ static const char __gbk_from_ucs4_tab12[][2] = \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/iso-2022-cn.c b/iconvdata/iso-2022-cn.c index 38b138b928..af7f92d3ac 100644 --- a/iconvdata/iso-2022-cn.c +++ b/iconvdata/iso-2022-cn.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gconv.h> #include <stdint.h> #include <string.h> @@ -140,16 +141,15 @@ enum line; we can simply ignore them \ - the initial byte of the SS2 sequence. \ */ \ - if (NEED_LENGTH_TEST \ - && (__builtin_expect (inptr + 1 > inend, 0) \ - || (inptr[1] == '$' \ - && (__builtin_expect (inptr + 2 > inend, 0) \ - || (inptr[2] == ')' \ - && __builtin_expect (inptr + 3 > inend, 0)) \ - || (inptr[2] == '*' \ - && __builtin_expect (inptr + 3 > inend, 0)))) \ - || (inptr[1] == SS2_1 \ - && __builtin_expect (inptr + 3 > inend, 0)))) \ + if (__builtin_expect (inptr + 1 > inend, 0) \ + || (inptr[1] == '$' \ + && (__builtin_expect (inptr + 2 > inend, 0) \ + || (inptr[2] == ')' \ + && __builtin_expect (inptr + 3 > inend, 0)) \ + || (inptr[2] == '*' \ + && __builtin_expect (inptr + 3 > inend, 0)))) \ + || (inptr[1] == SS2_1 \ + && __builtin_expect (inptr + 3 > inend, 0))) \ { \ result = __GCONV_EMPTY_INPUT; \ break; \ @@ -216,16 +216,14 @@ enum { \ /* That's pretty easy, we have a dedicated functions for this. */ \ if (set == GB2312_set) \ - ch = gb2312_to_ucs4 (&inptr, \ - NEED_LENGTH_TEST ? inend - inptr : 2, 0); \ + ch = gb2312_to_ucs4 (&inptr, inend - inptr, 0); \ else \ { \ assert (set == CNS11643_1_set); \ - ch = cns11643l1_to_ucs4 (&inptr, \ - NEED_LENGTH_TEST ? inend - inptr : 2, 0);\ + ch = cns11643l1_to_ucs4 (&inptr, inend - inptr, 0); \ } \ \ - if (NEED_LENGTH_TEST && __builtin_expect (ch, 1) == 0) \ + if (__builtin_expect (ch, 1) == 0) \ { \ result = __GCONV_EMPTY_INPUT; \ break; \ @@ -248,6 +246,7 @@ enum put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , int *setp #define INIT_PARAMS int set = *setp & CURRENT_SEL_MASK; \ int ann = *setp & CURRENT_ANN_MASK @@ -272,7 +271,7 @@ enum { \ *outptr++ = SI; \ set = ASCII_set; \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr == outend, 0)) \ + if (__builtin_expect (outptr == outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -325,14 +324,26 @@ enum else \ { \ /* Even this does not work. Error. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, \ + &inptr, inend, *outptrp, \ + &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ } \ @@ -348,8 +359,7 @@ enum { \ const char *escseq; \ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 4 > outend, 0)) \ + if (__builtin_expect (outptr + 4 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -404,8 +414,7 @@ enum break; \ } \ } \ - else if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 2 > outend, 0)) \ + else if (__builtin_expect (outptr + 2 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -418,6 +427,7 @@ enum /* Now that we wrote the output increment the input pointer. */ \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , int *setp #define INIT_PARAMS int set = *setp & CURRENT_SEL_MASK; \ int ann = *setp & CURRENT_ANN_MASK diff --git a/iconvdata/iso-2022-jp.c b/iconvdata/iso-2022-jp.c index 9b22ddd6b3..c6a43d121d 100644 --- a/iconvdata/iso-2022-jp.c +++ b/iconvdata/iso-2022-jp.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gconv.h> #include <stdint.h> #include <stdlib.h> @@ -444,26 +445,22 @@ gconv_end (struct __gconv_step *data) JIS X 0208. Therefore I'm using the tables for JIS X \ 0208-1990. If somebody has problems with this please \ provide the appropriate tables. */ \ - ch = jisx0208_to_ucs4 (&inptr, \ - NEED_LENGTH_TEST ? inend - inptr : 2, 0); \ + ch = jisx0208_to_ucs4 (&inptr, inend - inptr, 0); \ else if (set == JISX0212_set) \ /* Use the JIS X 0212 table. */ \ - ch = jisx0212_to_ucs4 (&inptr, \ - NEED_LENGTH_TEST ? inend - inptr : 2, 0); \ + ch = jisx0212_to_ucs4 (&inptr, inend - inptr, 0); \ else if (set == GB2312_set) \ /* Use the GB 2312 table. */ \ - ch = gb2312_to_ucs4 (&inptr, \ - NEED_LENGTH_TEST ? inend - inptr : 2, 0); \ + ch = gb2312_to_ucs4 (&inptr, inend - inptr, 0); \ else \ { \ assert (set == KSC5601_set); \ \ /* Use the KSC 5601 table. */ \ - ch = ksc5601_to_ucs4 (&inptr, \ - NEED_LENGTH_TEST ? inend - inptr : 2, 0); \ + ch = ksc5601_to_ucs4 (&inptr, inend - inptr, 0); \ } \ \ - if (NEED_LENGTH_TEST && __builtin_expect (ch, 1) == 0) \ + if (__builtin_expect (ch, 1) == 0) \ { \ result = __GCONV_EMPTY_INPUT; \ break; \ @@ -485,6 +482,7 @@ gconv_end (struct __gconv_step *data) put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , enum variant var, int *setp #define INIT_PARAMS int set = *setp & CURRENT_SEL_MASK; \ int set2 = *setp & CURRENT_ASSIGN_MASK @@ -554,26 +552,19 @@ gconv_end (struct __gconv_step *data) else \ { \ if (set == JISX0208_1978_set || set == JISX0208_1983_set) \ - written = ucs4_to_jisx0208 (ch, outptr, \ - (NEED_LENGTH_TEST \ - ? outend - outptr : 2)); \ + written = ucs4_to_jisx0208 (ch, outptr, outend - outptr); \ else if (set == JISX0212_set) \ - written = ucs4_to_jisx0212 (ch, outptr, \ - (NEED_LENGTH_TEST \ - ? outend - outptr : 2)); \ + written = ucs4_to_jisx0212 (ch, outptr, outend - outptr); \ else if (set == GB2312_set) \ - written = ucs4_to_gb2312 (ch, outptr, (NEED_LENGTH_TEST \ - ? outend - outptr : 2)); \ + written = ucs4_to_gb2312 (ch, outptr, outend - outptr); \ else \ { \ assert (set == KSC5601_set); \ \ - written = ucs4_to_ksc5601 (ch, outptr, \ - (NEED_LENGTH_TEST \ - ? outend - outptr : 2)); \ + written = ucs4_to_ksc5601 (ch, outptr, outend - outptr); \ } \ \ - if (NEED_LENGTH_TEST && __builtin_expect (written, 1) == 0) \ + if (__builtin_expect (written, 1) == 0) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -631,7 +622,7 @@ gconv_end (struct __gconv_step *data) { \ /* We must encode using ASCII. First write out the \ escape sequence. */ \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr + 3 > outend, 0))\ + if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -642,7 +633,7 @@ gconv_end (struct __gconv_step *data) *outptr++ = 'B'; \ set = ASCII_set; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr + 1 > outend, 0))\ + if (__builtin_expect (outptr + 1 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -666,8 +657,7 @@ gconv_end (struct __gconv_step *data) if (written != __UNKNOWN_10646_CHAR && buf[0] < 0x80) \ { \ /* We use JIS X 0201. */ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 3 > outend, 0)) \ + if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -678,8 +668,7 @@ gconv_end (struct __gconv_step *data) *outptr++ = 'J'; \ set = JISX0201_Roman_set; \ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 1 > outend, 0)) \ + if (__builtin_expect (outptr + 1 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -692,8 +681,7 @@ gconv_end (struct __gconv_step *data) if (written != __UNKNOWN_10646_CHAR) \ { \ /* We use JIS X 0208. */ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 3 > outend, 0)) \ + if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -704,8 +692,7 @@ gconv_end (struct __gconv_step *data) *outptr++ = 'B'; \ set = JISX0208_1983_set; \ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 2 > outend, 0)) \ + if (__builtin_expect (outptr + 2 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -716,13 +703,27 @@ gconv_end (struct __gconv_step *data) else if (__builtin_expect (var, iso2022jp2) == iso2022jp) \ { \ /* We have no other choice. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, \ + &inptr, inend, *outptrp, \ + &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ + continue; \ } \ else \ { \ @@ -730,8 +731,7 @@ gconv_end (struct __gconv_step *data) if (written != __UNKNOWN_10646_CHAR) \ { \ /* We use JIS X 0212. */ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 4 > outend, 0)) \ + if (__builtin_expect (outptr + 4 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -742,8 +742,7 @@ gconv_end (struct __gconv_step *data) *outptr++ = 'D'; \ set = JISX0212_set; \ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 2 > outend, 0)) \ + if (__builtin_expect (outptr + 2 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -758,8 +757,7 @@ gconv_end (struct __gconv_step *data) && buf[0] >= 0x80) \ { \ /* We use JIS X 0201. */ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 3 > outend, 0)) \ + if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -770,8 +768,7 @@ gconv_end (struct __gconv_step *data) *outptr++ = 'I'; \ set = JISX0201_Kana_set; \ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 1 > outend, 0)) \ + if (__builtin_expect (outptr + 1 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -781,8 +778,7 @@ gconv_end (struct __gconv_step *data) else if (ch != 0xa5 && ch >= 0x80 && ch <= 0xff) \ { \ /* ISO 8859-1 upper half. */ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 3 > outend, 0)) \ + if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -793,8 +789,7 @@ gconv_end (struct __gconv_step *data) *outptr++ = 'A'; \ set2 = ISO88591_set; \ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 3 > outend, 0)) \ + if (__builtin_expect (outptr + 3 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -809,9 +804,7 @@ gconv_end (struct __gconv_step *data) if (written != __UNKNOWN_10646_CHAR) \ { \ /* We use GB 2312. */ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 3 > outend, \ - 0)) \ + if (__builtin_expect (outptr + 3 > outend, 0))\ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -822,9 +815,7 @@ gconv_end (struct __gconv_step *data) *outptr++ = 'A'; \ set = GB2312_set; \ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 2 > outend, \ - 0)) \ + if (__builtin_expect (outptr + 2 > outend, 0))\ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -838,9 +829,8 @@ gconv_end (struct __gconv_step *data) if (written != __UNKNOWN_10646_CHAR) \ { \ /* We use KSC 5601. */ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 4 \ - > outend, 0)) \ + if (__builtin_expect (outptr + 4 > outend,\ + 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -851,9 +841,8 @@ gconv_end (struct __gconv_step *data) *outptr++ = 'C'; \ set = KSC5601_set; \ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 2 \ - > outend, 0)) \ + if (__builtin_expect (outptr + 2 > outend,\ + 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -877,9 +866,8 @@ gconv_end (struct __gconv_step *data) if (__builtin_expect (gch, 1) != 0) \ { \ /* We use ISO 8859-7 greek. */ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 3 \ - > outend, 0))\ + if (__builtin_expect (outptr + 3 \ + > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -889,9 +877,8 @@ gconv_end (struct __gconv_step *data) *outptr++ = 'F'; \ set2 = ISO88597_set; \ \ - if (NEED_LENGTH_TEST \ - && __builtin_expect (outptr + 3 \ - > outend, 0))\ + if (__builtin_expect (outptr + 3 \ + > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -902,13 +889,29 @@ gconv_end (struct __gconv_step *data) } \ else \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct \ + != NULL) \ + { \ + result = DL_CALL_FCT \ + (step_data->__trans.__trans_fct,\ + (step, step_data, *inptrp, \ + &inptr, inend, *outptrp, \ + &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ + continue; \ } \ } \ } \ @@ -922,6 +925,7 @@ gconv_end (struct __gconv_step *data) /* Now that we wrote the output increment the input pointer. */ \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , enum variant var, int *setp #define INIT_PARAMS int set = *setp & CURRENT_SEL_MASK; \ int set2 = *setp & CURRENT_ASSIGN_MASK diff --git a/iconvdata/iso-2022-kr.c b/iconvdata/iso-2022-kr.c index 99208c9522..4601e22e68 100644 --- a/iconvdata/iso-2022-kr.c +++ b/iconvdata/iso-2022-kr.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gconv.h> #include <stdint.h> #include <string.h> @@ -141,10 +142,9 @@ enum switching is done using the SI and SO bytes. But we have to \ recognize `Esc $ ) C' since this is a kind of flag for this \ encoding. We simply ignore it. */ \ - if ((NEED_LENGTH_TEST && __builtin_expect (inptr + 1 > inend, 0)) \ + if (__builtin_expect (inptr + 1 > inend, 0) \ || (inptr[1] == '$' \ - && ((NEED_LENGTH_TEST \ - && __builtin_expect (inptr + 2 > inend, 0)) \ + && (__builtin_expect (inptr + 2 > inend, 0) \ || (inptr[2] == ')' \ && __builtin_expect (inptr + 3 > inend, 0))))) \ \ @@ -184,10 +184,9 @@ enum assert (set == KSC5601_set); \ \ /* Use the KSC 5601 table. */ \ - ch = ksc5601_to_ucs4 (&inptr, \ - NEED_LENGTH_TEST ? inend - inptr : 2, 0); \ + ch = ksc5601_to_ucs4 (&inptr, inend - inptr, 0); \ \ - if (NEED_LENGTH_TEST && __builtin_expect (ch, 1) == 0) \ + if (__builtin_expect (ch, 1) == 0) \ { \ result = __GCONV_EMPTY_INPUT; \ break; \ @@ -210,6 +209,7 @@ enum put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , int *setp #define INIT_PARAMS int set = *setp #define UPDATE_PARAMS *setp = set @@ -236,7 +236,7 @@ enum { \ *outptr++ = SI; \ set = ASCII_set; \ - if (NEED_LENGTH_TEST && outptr == outend) \ + if (__builtin_expect (outptr == outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -255,13 +255,26 @@ enum if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR) \ { \ /* Illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ + continue; \ } \ else \ { \ @@ -274,7 +287,7 @@ enum set = KSC5601_set; \ } \ \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr + 2 > outend, 0))\ + if (__builtin_expect (outptr + 2 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -288,6 +301,7 @@ enum /* Now that we wrote the output increment the input pointer. */ \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , int *setp #define INIT_PARAMS int set = *setp #define UPDATE_PARAMS *setp = set diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c index cdc77fc651..f39f1b4d6d 100644 --- a/iconvdata/iso646.c +++ b/iconvdata/iso646.c @@ -31,6 +31,7 @@ allows one to easily provide a tuned implementation in case this proofs to be necessary. */ +#include <dlfcn.h> #include <gconv.h> #include <stdint.h> #include <stdlib.h> @@ -422,6 +423,7 @@ gconv_end (struct __gconv_step *data) } \ ++inptr; \ } +#define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , enum variant var #include <iconv/loop.c> @@ -883,19 +885,32 @@ gconv_end (struct __gconv_step *data) \ if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT) \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* Exit the loop with an error. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ + continue; \ } \ else \ *outptr++ = (unsigned char) ch; \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS , enum variant var #include <iconv/loop.c> diff --git a/iconvdata/iso8859-1.c b/iconvdata/iso8859-1.c index 7a5be60373..fb1fabc4f6 100644 --- a/iconvdata/iso8859-1.c +++ b/iconvdata/iso8859-1.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <stdint.h> /* Definitions used in the body of the `gconv' function. */ @@ -48,18 +49,31 @@ if (__builtin_expect (ch, 0) > 0xff) \ { \ /* We have an illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ + continue; \ } \ else \ *outptr++ = (unsigned char) ch; \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/iso_6937-2.c b/iconvdata/iso_6937-2.c index 6895879744..4f5a8689b8 100644 --- a/iconvdata/iso_6937-2.c +++ b/iconvdata/iso_6937-2.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <stdint.h> /* Data taken from the WG15 tables. */ @@ -405,7 +406,7 @@ static const char from_ucs4[][2] = is also available. */ \ int ch2; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 1 >= inend, 0)) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. Store the \ intermediate result. */ \ @@ -474,6 +475,7 @@ static const char from_ucs4[][2] = put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -491,7 +493,6 @@ static const char from_ucs4[][2] = if (__builtin_expect (ch, 0) \ >= sizeof (from_ucs4) / sizeof (from_ucs4[0])) \ { \ - int fail = 0; \ switch (ch) \ { \ case 0x2c7: \ @@ -562,36 +563,52 @@ static const char from_ucs4[][2] = cp = "\xd5"; \ break; \ default: \ - cp = NULL; \ - fail = 1; \ - } \ - \ - if (__builtin_expect (fail, 0)) \ - { \ /* Illegal characters. */ \ - if (! ignore_errors_p ()) \ + cp = NULL; \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ } \ else if (__builtin_expect (from_ucs4[ch][0], '\1') == '\0' && ch != 0) \ { \ /* Illegal characters. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ - inptr += 4; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ else \ @@ -601,7 +618,7 @@ static const char from_ucs4[][2] = /* Now test for a possible second byte and write this if possible. */ \ if (cp[1] != '\0') \ { \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr >= outend, 0)) \ + if (__builtin_expect (outptr >= outend, 0)) \ { \ /* The result does not fit into the buffer. */ \ --outptr; \ @@ -613,6 +630,7 @@ static const char from_ucs4[][2] = \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/iso_6937.c b/iconvdata/iso_6937.c index d27b923689..b7ab0841eb 100644 --- a/iconvdata/iso_6937.c +++ b/iconvdata/iso_6937.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <stdint.h> /* Data taken from the WG15 tables. */ @@ -397,7 +398,7 @@ static const char from_ucs4[][2] = is also available. */ \ int ch2; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 1 >= inend, 0)) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. Store the \ intermediate result. */ \ @@ -466,6 +467,7 @@ static const char from_ucs4[][2] = put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -540,29 +542,50 @@ static const char from_ucs4[][2] = if (__builtin_expect (fail, 0)) \ { \ /* Illegal characters. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ } \ else if (__builtin_expect (from_ucs4[ch][0], '\1') == '\0' && ch != 0) \ { \ /* Illegal characters. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ - inptr += 4; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ else \ @@ -572,7 +595,7 @@ static const char from_ucs4[][2] = /* Now test for a possible second byte and write this if possible. */ \ if (cp[1] != '\0') \ { \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr >= outend, 0)) \ + if (__builtin_expect (outptr >= outend, 0)) \ { \ /* The result does not fit into the buffer. */ \ --outptr; \ @@ -584,6 +607,7 @@ static const char from_ucs4[][2] = \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/johab.c b/iconvdata/johab.c index 50b974686b..7253ff6cb8 100644 --- a/iconvdata/johab.c +++ b/iconvdata/johab.c @@ -19,6 +19,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <stdint.h> #include <ksc5601.h> @@ -203,7 +204,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) uint32_t ch2; \ uint_fast32_t idx; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 1 >= inend, 0)) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. Store the \ intermediate result. */ \ @@ -319,6 +320,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -350,7 +352,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) { \ if (ch >= 0xac00 && ch <= 0xd7a3) \ { \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr + 2 > outend, 0))\ + if (__builtin_expect (outptr + 2 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -371,7 +373,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) { \ ch = jamo_from_ucs_table[ch - 0x3131]; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr + 2 > outend, 0))\ + if (__builtin_expect (outptr + 2 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -386,25 +388,34 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) size_t written; \ uint32_t temp; \ \ - written = ucs4_to_ksc5601_hanja (ch, outptr, \ - (NEED_LENGTH_TEST \ - ? outend - outptr : 2)); \ - if (NEED_LENGTH_TEST && __builtin_expect (written, 1) == 0) \ + written = ucs4_to_ksc5601_hanja (ch, outptr, outend - outptr); \ + if (__builtin_expect (written, 1) == 0) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ } \ if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR) \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ \ @@ -423,25 +434,34 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) { \ size_t written; \ \ - written = ucs4_to_ksc5601_sym (ch, outptr, \ - (NEED_LENGTH_TEST \ - ? outend - outptr : 2)); \ - if (NEED_LENGTH_TEST && __builtin_expect (written, 1) == 0) \ + written = ucs4_to_ksc5601_sym (ch, outptr, outend - outptr); \ + if (__builtin_expect (written, 1) == 0) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ } \ if (__builtin_expect (written, 1) == __UNKNOWN_10646_CHAR) \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ \ @@ -460,6 +480,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/sjis.c b/iconvdata/sjis.c index 0f38362fb3..2641b24743 100644 --- a/iconvdata/sjis.c +++ b/iconvdata/sjis.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <stdint.h> #include <wchar.h> @@ -4377,7 +4378,7 @@ static const char from_ucs4_extra[0x100][2] = uint32_t ch2; \ uint_fast32_t idx; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 1 >= inend, 0)) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. Store \ the intermediate result. */ \ @@ -4441,6 +4442,7 @@ static const char from_ucs4_extra[0x100][2] = put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -4466,15 +4468,26 @@ static const char from_ucs4_extra[0x100][2] = else \ { \ /* Illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ } \ @@ -4484,14 +4497,26 @@ static const char from_ucs4_extra[0x100][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ + continue; \ } \ else \ { \ @@ -4499,7 +4524,7 @@ static const char from_ucs4_extra[0x100][2] = /* Now test for a possible second byte and write this if possible. */\ if (cp[1] != '\0') \ { \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr >= outend, 0)) \ + if (__builtin_expect (outptr >= outend, 0)) \ { \ /* The result does not fit into the buffer. */ \ result = __GCONV_FULL_OUTPUT; \ @@ -4511,6 +4536,7 @@ static const char from_ucs4_extra[0x100][2] = \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/t.61.c b/iconvdata/t.61.c index 74fbf8aca7..991cce1626 100644 --- a/iconvdata/t.61.c +++ b/iconvdata/t.61.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gconv.h> #include <stdint.h> #include <string.h> @@ -390,7 +391,7 @@ static const char from_ucs4[][2] = is also available. */ \ uint32_t ch2; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 1 >= inend, 0)) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. */ \ result = __GCONV_INCOMPLETE_INPUT; \ @@ -441,6 +442,7 @@ static const char from_ucs4[][2] = } \ inptr += increment; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -467,15 +469,26 @@ static const char from_ucs4[][2] = || __builtin_expect (ch, 0x2d8) == 0x02dc) \ { \ /* Illegal characters. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ else \ @@ -494,15 +507,26 @@ static const char from_ucs4[][2] = if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0) \ { \ /* Illegal. */ \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ } \ @@ -511,7 +535,7 @@ static const char from_ucs4[][2] = /* Now test for a possible second byte and write this if possible. */ \ if (cp[1] != '\0') \ { \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr >= outend, 0)) \ + if (__builtin_expect (outptr >= outend, 0)) \ { \ /* The result does not fit into the buffer. */ \ --outptr; \ @@ -524,6 +548,7 @@ static const char from_ucs4[][2] = \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/uhc.c b/iconvdata/uhc.c index d62f93bf29..232e5c8416 100644 --- a/iconvdata/uhc.c +++ b/iconvdata/uhc.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <stdint.h> #include <ksc5601.h> @@ -3085,7 +3086,7 @@ static const char uhc_hangul_from_ucs[11172][2] = is also available. */ \ uint32_t ch2; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 1 >= inend, 0)) \ + if (__builtin_expect (inptr + 1 >= inend, 0)) \ { \ /* The second character is not available. Store \ the intermediate result. */ \ @@ -3180,6 +3181,7 @@ static const char uhc_hangul_from_ucs[11172][2] = put32 (outptr, ch); \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> @@ -3199,7 +3201,7 @@ static const char uhc_hangul_from_ucs[11172][2] = { \ const char *s = uhc_hangul_from_ucs[ch - 0xac00]; \ \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr + 2 > outend, 0)) \ + if (__builtin_expect (outptr + 2 > outend, 0)) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ @@ -3210,26 +3212,35 @@ static const char uhc_hangul_from_ucs[11172][2] = } \ else if ((ch >= 0x4e00 && ch <= 0x9fa5) || (ch >= 0xf900 && ch <= 0xfa0b))\ { \ - size_t written = ucs4_to_ksc5601_hanja (ch, outptr, \ - (NEED_LENGTH_TEST \ - ? outend - outptr : 2)); \ + size_t written = ucs4_to_ksc5601_hanja (ch, outptr, outend - outptr); \ \ - if (NEED_LENGTH_TEST && __builtin_expect (written, 1) == 0) \ + if (__builtin_expect (written, 1) == 0) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ } \ if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR) \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ \ @@ -3242,26 +3253,35 @@ static const char uhc_hangul_from_ucs[11172][2] = */ \ else \ { \ - size_t written = ucs4_to_ksc5601_sym (ch, outptr, \ - (NEED_LENGTH_TEST \ - ? outend - outptr : 2)); \ + size_t written = ucs4_to_ksc5601_sym (ch, outptr, outend - outptr); \ \ - if (NEED_LENGTH_TEST && __builtin_expect (written, 1) == 0) \ + if (__builtin_expect (written, 1) == 0) \ { \ result = __GCONV_FULL_OUTPUT; \ break; \ } \ if (__builtin_expect (written, 0) == __UNKNOWN_10646_CHAR) \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - inptr += 4; \ - ++*irreversible; \ + else \ + { \ + inptr += 4; \ + ++*irreversible; \ + } \ continue; \ } \ \ @@ -3271,6 +3291,7 @@ static const char uhc_hangul_from_ucs[11172][2] = \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #include <iconv/loop.c> diff --git a/iconvdata/unicode.c b/iconvdata/unicode.c index 5309fc267f..438658edb9 100644 --- a/iconvdata/unicode.c +++ b/iconvdata/unicode.c @@ -19,6 +19,7 @@ Boston, MA 02111-1307, USA. */ #include <byteswap.h> +#include <dlfcn.h> #include <gconv.h> #include <stddef.h> #include <stdint.h> @@ -70,7 +71,7 @@ outbuf += 2; \ } \ swap = ((struct unicode_data *) step->__data)->swap; -#define EXTRA_LOOP_ARGS , data, swap +#define EXTRA_LOOP_ARGS , swap /* Direction of the transformation. */ @@ -151,14 +152,26 @@ gconv_end (struct __gconv_step *data) \ if (__builtin_expect (c, 0) >= 0x10000) \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, inend, \ + *outptrp, &outptr, outend, irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ + continue; \ } \ else \ { \ @@ -168,8 +181,9 @@ gconv_end (struct __gconv_step *data) \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS \ - , struct __gconv_step_data *step_data, int swap + , int swap #include <iconv/loop.c> @@ -190,7 +204,7 @@ gconv_end (struct __gconv_step *data) outptr += 4; \ } #define EXTRA_LOOP_DECLS \ - , struct __gconv_step_data *step_data, int swap + , int swap #include <iconv/loop.c> diff --git a/iconvdata/utf-16.c b/iconvdata/utf-16.c index d24b55b2bc..bbb546ef9a 100644 --- a/iconvdata/utf-16.c +++ b/iconvdata/utf-16.c @@ -19,6 +19,7 @@ Boston, MA 02111-1307, USA. */ #include <byteswap.h> +#include <dlfcn.h> #include <gconv.h> #include <stddef.h> #include <stdint.h> @@ -72,7 +73,7 @@ put16u (outbuf, BOM); \ outbuf += 2; \ } -#define EXTRA_LOOP_ARGS , var, data, swap +#define EXTRA_LOOP_ARGS , var, swap /* Direction of the transformation. */ @@ -201,20 +202,31 @@ gconv_end (struct __gconv_step *data) { \ if (__builtin_expect (c, 0) >= 0x110000) \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ - inptr += 4; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ continue; \ } \ \ /* Generate a surrogate character. */ \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr + 4 > outend, 0))\ + if (__builtin_expect (outptr + 4 > outend, 0)) \ { \ /* Overflow in the output buffer. */ \ result = __GCONV_FULL_OUTPUT; \ @@ -234,20 +246,31 @@ gconv_end (struct __gconv_step *data) { \ if (__builtin_expect (c, 0) >= 0x110000) \ { \ - if (! ignore_errors_p ()) \ + if (step_data->__trans.__trans_fct != NULL) \ + { \ + result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ + (step, step_data, *inptrp, &inptr, \ + inend, *outptrp, &outptr, outend, \ + irreversible)); \ + if (result != __GCONV_OK) \ + break; \ + } \ + else if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ - \ - ++*irreversible; \ - inptr += 4; \ + else \ + { \ + ++*irreversible; \ + inptr += 4; \ + } \ continue; \ } \ \ /* Generate a surrogate character. */ \ - if (NEED_LENGTH_TEST && __builtin_expect (outptr + 4 > outend, 0))\ + if (__builtin_expect (outptr + 4 > outend, 0)) \ { \ /* Overflow in the output buffer. */ \ result = __GCONV_FULL_OUTPUT; \ @@ -264,8 +287,9 @@ gconv_end (struct __gconv_step *data) outptr += 2; \ inptr += 4; \ } +#define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS \ - , enum variant var, struct __gconv_step_data *step_data, int swap + , enum variant var, int swap #include <iconv/loop.c> @@ -294,7 +318,7 @@ gconv_end (struct __gconv_step *data) \ /* It's a surrogate character. At least the first word says \ it is. */ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 4 > inend, 0)) \ + if (__builtin_expect (inptr + 4 > inend, 0)) \ { \ /* We don't have enough input for another complete input \ character. */ \ @@ -337,7 +361,7 @@ gconv_end (struct __gconv_step *data) \ /* It's a surrogate character. At least the first word says \ it is. */ \ - if (NEED_LENGTH_TEST && __builtin_expect (inptr + 4 > inend, 0)) \ + if (__builtin_expect (inptr + 4 > inend, 0)) \ { \ /* We don't have enough input for another complete input \ character. */ \ @@ -368,8 +392,9 @@ gconv_end (struct __gconv_step *data) } \ outptr += 4; \ } +#define LOOP_NEED_FLAGS #define EXTRA_LOOP_DECLS \ - , enum variant var, struct __gconv_step_data *step_data, int swap + , enum variant var, int swap #include <iconv/loop.c> diff --git a/intl/tst-gettext.sh b/intl/tst-gettext.sh index db3653ad73..9d2151f6b6 100755 --- a/intl/tst-gettext.sh +++ b/intl/tst-gettext.sh @@ -21,6 +21,9 @@ common_objpfx=$1 objpfx=$2 +GCONV_PATH=${common_objpfx}iconvdata +export GCONV_PATH + # Generate the test data. test -d ${objpfx}domaindir || mkdir ${objpfx}domaindir # Create the locale directories. diff --git a/libio/iofwide.c b/libio/iofwide.c index d1a0f1ef13..5ca0a84f0d 100644 --- a/libio/iofwide.c +++ b/libio/iofwide.c @@ -25,6 +25,7 @@ #include <libioP.h> #ifdef _LIBC +# include <dlfcn.h> # include <wchar.h> #endif #include <stdlib.h> @@ -165,15 +166,17 @@ do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, #ifdef _LIBC struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; int status; - size_t written; + size_t dummy; const unsigned char *from_start_copy = (unsigned char *) from_start; codecvt->__cd_out.__cd.__data[0].__outbuf = to_start; codecvt->__cd_out.__cd.__data[0].__outbufend = to_end; codecvt->__cd_out.__cd.__data[0].__statep = statep; - status = (*gs->__fct) (gs, codecvt->__cd_out.__cd.__data, &from_start_copy, - (const unsigned char *) from_end, &written, 0, 0); + status = DL_CALL_FCT (gs->__fct, + (gs, codecvt->__cd_out.__cd.__data, &from_start_copy, + (const unsigned char *) from_end, to_start, + &dummy, 0, 0)); *from_stop = (wchar_t *) from_start_copy; *to_stop = codecvt->__cd_out.__cd.__data[0].__outbuf; @@ -212,14 +215,15 @@ do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep, #ifdef _LIBC struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; int status; - size_t written; + size_t dummy; codecvt->__cd_out.__cd.__data[0].__outbuf = to_start; codecvt->__cd_out.__cd.__data[0].__outbufend = to_end; codecvt->__cd_out.__cd.__data[0].__statep = statep; - status = (*gs->__fct) (gs, codecvt->__cd_out.__cd.__data, NULL, NULL, - &written, 1, 0); + status = DL_CALL_FCT (gs->__fct, + (gs, codecvt->__cd_out.__cd.__data, NULL, NULL, + to_start, &dummy, 1, 0)); *to_stop = codecvt->__cd_out.__cd.__data[0].__outbuf; @@ -258,15 +262,16 @@ do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, #ifdef _LIBC struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps; int status; - size_t written; + size_t dummy; const unsigned char *from_start_copy = (unsigned char *) from_start; codecvt->__cd_in.__cd.__data[0].__outbuf = (char *) to_start; codecvt->__cd_in.__cd.__data[0].__outbufend = (char *) to_end; codecvt->__cd_in.__cd.__data[0].__statep = statep; - status = (*gs->__fct) (gs, codecvt->__cd_in.__cd.__data, &from_start_copy, - from_end, &written, 0, 0); + status = DL_CALL_FCT (gs->__fct, + (gs, codecvt->__cd_in.__cd.__data, &from_start_copy, + from_end, (char *) to_start, &dummy, 0, 0)); *from_stop = from_start_copy; *to_stop = (wchar_t *) codecvt->__cd_in.__cd.__data[0].__outbuf; @@ -335,14 +340,15 @@ do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, wchar_t to_buf[max]; struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps; int status; - size_t written; + size_t dummy; codecvt->__cd_in.__cd.__data[0].__outbuf = (char *) to_buf; codecvt->__cd_in.__cd.__data[0].__outbufend = (char *) &to_buf[max]; codecvt->__cd_in.__cd.__data[0].__statep = statep; - status = (*gs->__fct) (gs, codecvt->__cd_in.__cd.__data, &cp, from_end, - &written, 0, 0); + status = DL_CALL_FCT (gs->__fct, + (gs, codecvt->__cd_in.__cd.__data, &cp, from_end, + (char *) to_buf, &dummy, 0, 0)); result = cp - (const unsigned char *) from_start; #else diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index c4236bd748..3066c0d1e2 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,5 +1,7 @@ 2000-06-12 Ulrich Drepper <drepper@redhat.com> + * Makefile (tests): Add joinrace. + * Examples/ex6.c: Test return value of pthread_join. 2000-06-11 Geoff Keating <geoffk@cygnus.com> diff --git a/linuxthreads/Makefile b/linuxthreads/Makefile index afbe51c618..6e9f8141bd 100644 --- a/linuxthreads/Makefile +++ b/linuxthreads/Makefile @@ -38,7 +38,7 @@ libpthread-routines := attr cancel condvar join manager mutex ptfork \ oldsemaphore events getcpuclockid pspinlock vpath %.c Examples -tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 +tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 joinrace include ../Rules @@ -68,3 +68,4 @@ $(objpfx)ex5: $(libpthread) $(objpfx)ex6: $(libpthread) $(objpfx)ex7: $(libpthread) $(objpfx)ex8: $(libpthread) +$(objpfx)joinrace: $(libpthread) diff --git a/timezone/Makefile b/timezone/Makefile index 45a9ea64c0..93478d4948 100644 --- a/timezone/Makefile +++ b/timezone/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1998, 1999 Free Software Foundation, Inc. +# Copyright (C) 1998, 1999, 2000 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 @@ -174,7 +174,8 @@ CFLAGS-scheck.c = -Wno-strict-prototypes -DNOID # leapseconds. testdata = $(objpfx)testdata define build-testdata -$(built-program-cmd) -d $(testdata) -y ./yearistype $< +GCONV_PATH=${common-objpfx}iconvdata \ + $(built-program-cmd) -d $(testdata) -y ./yearistype $< endef $(objpfx)test-tz.out: $(addprefix $(testdata)/, America/New_York Etc/UTC UTC) diff --git a/wcsmbs/btowc.c b/wcsmbs/btowc.c index 0978f097f1..1271a01ed6 100644 --- a/wcsmbs/btowc.c +++ b/wcsmbs/btowc.c @@ -17,6 +17,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gconv.h> #include <stdio.h> #include <string.h> @@ -58,9 +59,9 @@ __btowc (c) /* Create the input string. */ inbuf[0] = c; - status = (*__wcsmbs_gconv_fcts.towc->__fct) (__wcsmbs_gconv_fcts.towc, &data, - &inptr, inptr + 1, &dummy, - 0, 1); + status = DL_CALL_FCT (__wcsmbs_gconv_fcts.towc->__fct, + (__wcsmbs_gconv_fcts.towc, &data, &inptr, inptr + 1, + data.__outbuf, &dummy, 0, 1)); /* The conversion failed. */ if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT && status != __GCONV_EMPTY_INPUT) diff --git a/wcsmbs/mbrtowc.c b/wcsmbs/mbrtowc.c index 6ecbdc5b5c..9809ed51a2 100644 --- a/wcsmbs/mbrtowc.c +++ b/wcsmbs/mbrtowc.c @@ -17,6 +17,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <errno.h> #include <gconv.h> #include <wchar.h> @@ -69,9 +70,9 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) /* Do a normal conversion. */ inbuf = (const unsigned char *) s; - status = (*__wcsmbs_gconv_fcts.towc->__fct) (__wcsmbs_gconv_fcts.towc, - &data, &inbuf, inbuf + n, - &dummy, 0, 1); + status = DL_CALL_FCT (__wcsmbs_gconv_fcts.towc->__fct, + (__wcsmbs_gconv_fcts.towc, &data, &inbuf, inbuf + n, + data.__outbuf, &dummy, 0, 1)); /* There must not be any problems with the conversion but illegal input characters. The output buffer must be large enough, otherwise the diff --git a/wcsmbs/mbsnrtowcs.c b/wcsmbs/mbsnrtowcs.c index 540afd0800..238458d25d 100644 --- a/wcsmbs/mbsnrtowcs.c +++ b/wcsmbs/mbsnrtowcs.c @@ -17,6 +17,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <errno.h> #include <gconv.h> #include <string.h> @@ -49,7 +50,7 @@ __mbsnrtowcs (dst, src, nmc, len, ps) size_t result; int status; struct __gconv_step *towc; - size_t non_reversible; + size_t dummy; /* Tell where we want the result. */ data.__invocation_counter = 0; @@ -79,8 +80,9 @@ __mbsnrtowcs (dst, src, nmc, len, ps) { data.__outbuf = (unsigned char *) buf; - status = (*towc->__fct) (__wcsmbs_gconv_fcts.towc, &data, &inbuf, - srcend, &non_reversible, 0, 1); + status = DL_CALL_FCT (towc->__fct, + (towc, &data, &inbuf, srcend, data.__outbuf, + &dummy, 0, 1)); result += (wchar_t *) data.__outbuf - buf; } @@ -99,9 +101,9 @@ __mbsnrtowcs (dst, src, nmc, len, ps) data.__outbuf = (unsigned char *) dst; data.__outbufend = data.__outbuf + len * sizeof (wchar_t); - status = (*towc->__fct) (__wcsmbs_gconv_fcts.towc, &data, - (const unsigned char **) src, srcend, - &non_reversible, 0, 1); + status = DL_CALL_FCT (towc->__fct, + (towc, &data, (const unsigned char **) src, srcend, + data.__outbuf, &dummy, 0, 1)); result = (wchar_t *) data.__outbuf - dst; diff --git a/wcsmbs/mbsrtowcs.c b/wcsmbs/mbsrtowcs.c index aaafe3bf1e..3c1f86a196 100644 --- a/wcsmbs/mbsrtowcs.c +++ b/wcsmbs/mbsrtowcs.c @@ -17,6 +17,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <errno.h> #include <gconv.h> #include <stdlib.h> @@ -76,8 +77,9 @@ __mbsrtowcs (dst, src, len, ps) { data.__outbuf = (char *) buf; - status = (*towc->__fct) (__wcsmbs_gconv_fcts.towc, &data, &inbuf, - srcend, &non_reversible, 0, 1); + status = DL_CALL_FCT (towc->__fct, + (towc, &data, &inbuf, srcend, data.__outbuf, + &non_reversible, 0, 1)); result += (wchar_t *) data.__outbuf - buf; } @@ -105,9 +107,9 @@ __mbsrtowcs (dst, src, len, ps) data.__outbuf = (unsigned char *) dst; data.__outbufend = data.__outbuf + len * sizeof (wchar_t); - status = (*towc->__fct) (__wcsmbs_gconv_fcts.towc, &data, - (const unsigned char **) src, srcend, - &non_reversible, 0, 1); + status = DL_CALL_FCT (towc->__fct, + (towc, &data, (const unsigned char **) src, srcend, + data.__outbuf, &non_reversible, 0, 1)); result = (wchar_t *) data.__outbuf - dst; diff --git a/wcsmbs/wcrtomb.c b/wcsmbs/wcrtomb.c index 5af383178c..f0bc824584 100644 --- a/wcsmbs/wcrtomb.c +++ b/wcsmbs/wcrtomb.c @@ -17,6 +17,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <errno.h> #include <gconv.h> #include <stdlib.h> @@ -71,9 +72,9 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps) by a NUL byte. */ if (wc == L'\0') { - status = (*__wcsmbs_gconv_fcts.tomb->__fct) (__wcsmbs_gconv_fcts.tomb, - &data, NULL, NULL, - &dummy, 1, 1); + status = DL_CALL_FCT (__wcsmbs_gconv_fcts.tomb->__fct, + (__wcsmbs_gconv_fcts.tomb, &data, NULL, NULL, + data.__outbuf, &dummy, 1, 1)); if (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT) *data.__outbuf++ = '\0'; @@ -83,10 +84,10 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps) /* Do a normal conversion. */ const unsigned char *inbuf = (const unsigned char *) &wc; - status = (*__wcsmbs_gconv_fcts.tomb->__fct) (__wcsmbs_gconv_fcts.tomb, - &data, &inbuf, - inbuf + sizeof (wchar_t), - &dummy, 0, 1); + status = DL_CALL_FCT (__wcsmbs_gconv_fcts.tomb->__fct, + (__wcsmbs_gconv_fcts.tomb, &data, &inbuf, + inbuf + sizeof (wchar_t), data.__outbuf, &dummy, + 0, 1)); } /* There must not be any problems with the conversion but illegal input diff --git a/wcsmbs/wcsnrtombs.c b/wcsmbs/wcsnrtombs.c index 7005bdcf12..dae2216ae5 100644 --- a/wcsmbs/wcsnrtombs.c +++ b/wcsmbs/wcsnrtombs.c @@ -17,6 +17,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <errno.h> #include <gconv.h> #include <wchar.h> @@ -79,10 +80,10 @@ __wcsnrtombs (dst, src, nwc, len, ps) { data.__outbuf = buf; - status = (*tomb->__fct) (__wcsmbs_gconv_fcts.tomb, &data, - (const unsigned char **) &inbuf, - (const unsigned char *) srcend, &dummy, - 0, 1); + status = DL_CALL_FCT (tomb->__fct, + (tomb, &data, (const unsigned char **) &inbuf, + (const unsigned char *) srcend, data.__outbuf, + &dummy, 0, 1)); /* Count the number of bytes. */ result += data.__outbuf - buf; @@ -104,9 +105,10 @@ __wcsnrtombs (dst, src, nwc, len, ps) data.__outbuf = dst; data.__outbufend = dst + len; - status = (*tomb->__fct) (__wcsmbs_gconv_fcts.tomb, &data, - (const unsigned char **) src, - (const unsigned char *) srcend, &dummy, 0, 1); + status = DL_CALL_FCT (tomb->__fct, + (tomb, &data, (const unsigned char **) src, + (const unsigned char *) srcend, data.__outbuf, + &dummy, 0, 1)); /* Count the number of bytes. */ result = data.__outbuf - (unsigned char *) dst; diff --git a/wcsmbs/wcsrtombs.c b/wcsmbs/wcsrtombs.c index 875ef16f75..03ef013c7c 100644 --- a/wcsmbs/wcsrtombs.c +++ b/wcsmbs/wcsrtombs.c @@ -17,6 +17,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <errno.h> #include <stdlib.h> #include <gconv.h> @@ -76,10 +77,10 @@ __wcsrtombs (dst, src, len, ps) { data.__outbuf = buf; - status = (*tomb->__fct) (__wcsmbs_gconv_fcts.tomb, &data, - (const unsigned char **) &inbuf, - (const unsigned char *) srcend, &dummy, - 0, 1); + status = DL_CALL_FCT (tomb->__fct, + (tomb, &data, (const unsigned char **) &inbuf, + (const unsigned char *) srcend, data.__outbuf, + &dummy, 0, 1)); /* Count the number of bytes. */ result += data.__outbuf - buf; @@ -105,9 +106,10 @@ __wcsrtombs (dst, src, len, ps) data.__outbuf = dst; data.__outbufend = dst + len; - status = (*tomb->__fct) (__wcsmbs_gconv_fcts.tomb, &data, - (const unsigned char **) src, - (const unsigned char *) srcend, &dummy, 0, 1); + status = DL_CALL_FCT (tomb->__fct, + (tomb, &data, (const unsigned char **) src, + (const unsigned char *) srcend, data.__outbuf, + &dummy, 0, 1)); /* Count the number of bytes. */ result = data.__outbuf - (unsigned char *) dst; diff --git a/wcsmbs/wctob.c b/wcsmbs/wctob.c index 8c6372558e..fc4c38331d 100644 --- a/wcsmbs/wctob.c +++ b/wcsmbs/wctob.c @@ -17,6 +17,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <gconv.h> #include <stdio.h> #include <string.h> @@ -52,10 +53,12 @@ wctob (c) /* Create the input string. */ inbuf[0] = c; - status = (*__wcsmbs_gconv_fcts.tomb->__fct) (__wcsmbs_gconv_fcts.tomb, &data, - (const unsigned char **) &inptr, - (const unsigned char *) &inbuf[1], - &dummy, 0, 1); + status = DL_CALL_FCT (__wcsmbs_gconv_fcts.tomb->__fct, + (__wcsmbs_gconv_fcts.tomb, &data, + (const unsigned char **) &inptr, + (const unsigned char *) &inbuf[1], + data.__outbuf, &dummy, 0, 1)); + /* The conversion failed or the output is too long. */ if ((status != __GCONV_OK && status != __GCONV_FULL_OUTPUT && status != __GCONV_EMPTY_INPUT) |