diff options
41 files changed, 1284 insertions, 376 deletions
@@ -1,6 +1,58 @@ 2000-06-05 Ulrich Drepper <drepper@redhat.com> - * iconvdata/ksc5601.h (ksc5601_to_ucs4): Undo *s in all cases of + * iconv/gconv.h (__GCONV_IS_LAST, __GCONV_IGNORE_ERRORS): Define. + (struct __gconv_step_data): Rename __is_last to __flags. + * iconv/gconv_close.c: Change all uses of __is_last. + * iconv/skeleton.c: Likewise. + * iconvdata/iso-2022-cn.c: Likewise. + * iconvdata/iso-2022-jp.c: Likewise. + * iconvdata/iso-2022-kr.c: Likewise. + * iconv/gconv_open.c: Likewise. Avoid unneeded initializations. + Recognize IGNORE error handling, set flag, and remove from name. + * iconv/loop.c (ignore_errors_p): Define. + Add flags parameter to both functions. + * iconv/skeleton.c: Pass flags to all conversion functions. + * iconv/gconv_simple.c: Add flags parameter to all functions. + Don't return error for invald error if ignore flag is set. + (ucs4_internal_loop_single): Add missing pointer increment. + (internal_ucs4le_loop_single): Likewise. + * iconv/iconv_prog.c: Implement handling of -c parameter. + * iconvdata/8bit-gap.c: Don't return error for invald error if + ignore flag is set. + * 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/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/fileops.c: Likewise. + * libio/iofwide.c: Likewise. + * 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. + + * iconvdata/ksc5601.h (ksc5601_to_ucs4): Undo *s change in all cases of an error. 2000-06-04 Ulrich Drepper <drepper@redhat.com> diff --git a/iconv/gconv.h b/iconv/gconv.h index 804d8daca2..1821844952 100644 --- a/iconv/gconv.h +++ b/iconv/gconv.h @@ -50,6 +50,14 @@ enum }; +/* Flags the `__gconv_open' function can set. */ +enum +{ + __GCONV_IS_LAST = 0x0001, + __GCONV_IGNORE_ERRORS = 0x0002 +}; + + /* Forward declarations. */ struct __gconv_step; struct __gconv_step_data; @@ -103,7 +111,7 @@ struct __gconv_step_data buffer. */ /* Is this the last module in the chain. */ - int __is_last; + int __flags; /* Counter for number of invocations of the module function for this descriptor. */ diff --git a/iconv/gconv_close.c b/iconv/gconv_close.c index a22123b1c9..79dcb0b3a1 100644 --- a/iconv/gconv_close.c +++ b/iconv/gconv_close.c @@ -1,5 +1,5 @@ /* Release any resource associated with given conversion descriptor. - Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -38,10 +38,10 @@ __gconv_close (__gconv_t cd) drunp = cd->__data; do { - if (!drunp->__is_last && drunp->__outbuf != NULL) + if (!(drunp->__flags & __GCONV_IS_LAST) && drunp->__outbuf != NULL) free (drunp->__outbuf); } - while (!(drunp++)->__is_last); + while (!((drunp++)->__flags & __GCONV_IS_LAST)); /* Free the data allocated for the descriptor. */ free (cd); diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c index 147f5b0e06..da00b1abbd 100644 --- a/iconv/gconv_open.c +++ b/iconv/gconv_open.c @@ -35,6 +35,22 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, __gconv_t result = NULL; size_t cnt = 0; int res; + int conv_flags = 0; + const char *runp; + + /* 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) + { + /* Found it. This means we should ignore conversion errors. */ + char *newtoset = (char *) alloca (runp - toset + 1); + + newtoset[runp - toset] = '\0'; + toset = memcpy (newtoset, toset, runp - toset); + + flags = __GCONV_IGNORE_ERRORS; + } res = __gconv_find_transform (toset, fromset, &steps, &nsteps, flags); if (res == __GCONV_OK) @@ -61,15 +77,19 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, { size_t size; + /* Would have to be done if we would not clear the whole + array above. */ /* If this is the last step we must not allocate an output buffer. */ - result->__data[cnt].__is_last = 0; + result->__data[cnt].__flags = conv_flags; +#if 0 /* Reset the counter. */ result->__data[cnt].__invocation_counter = 0; /* It's a regular use. */ result->__data[cnt].__internal_use = 0; +#endif /* We use the `mbstate_t' member in DATA. */ result->__data[cnt].__statep = &result->__data[cnt].__state; @@ -88,9 +108,13 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, } /* Now handle the last entry. */ - result->__data[cnt].__is_last = 1; + result->__data[cnt].__flags = conv_flags | __GCONV_IS_LAST; + /* Would have to be done if we would not clear the whole + array above. */ +#if 0 result->__data[cnt].__invocation_counter = 0; result->__data[cnt].__internal_use = 0; +#endif result->__data[cnt].__statep = &result->__data[cnt].__state; } diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c index 4010a6b326..7189ad3787 100644 --- a/iconv/gconv_simple.c +++ b/iconv/gconv_simple.c @@ -64,7 +64,7 @@ static const unsigned char encoding_byte[] = static inline int internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, void *data, size_t *converted) + mbstate_t *state, int flags, void *data, size_t *converted) { const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; @@ -104,7 +104,8 @@ static inline int internal_ucs4_loop_unaligned (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, void *data, size_t *converted) + mbstate_t *state, int flags, void *data, + size_t *converted) { const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; @@ -150,7 +151,8 @@ static inline int internal_ucs4_loop_single (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, void *data, size_t *converted) + mbstate_t *state, int flags, void *data, + size_t *converted) { size_t cnt = state->__count & 7; @@ -171,6 +173,8 @@ internal_ucs4_loop_single (const unsigned char **inptrp, (*outptrp)[1] = state->__value.__wchb[2]; (*outptrp)[2] = state->__value.__wchb[1]; (*outptrp)[3] = state->__value.__wchb[0]; + + *outptrp += 4; #elif __BYTE_ORDER == __BIG_ENDIAN /* XXX unaligned */ *(*((uint32_t **) outptrp)++) = state->__value.__wch; @@ -202,7 +206,7 @@ internal_ucs4_loop_single (const unsigned char **inptrp, static inline int ucs4_internal_loop (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, void *data, size_t *converted) + mbstate_t *state, int flags, void *data, size_t *converted) { const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; @@ -222,6 +226,13 @@ ucs4_internal_loop (const unsigned char **inptrp, const unsigned char *inend, if (inval > 0x7fffffff) { + if (flags & __GCONV_IGNORE_ERRORS) + { + /* Just ignore this character. */ + ++*converted; + continue; + } + *inptrp = inptr; *outptrp = outptr; return __GCONV_ILLEGAL_INPUT; @@ -249,7 +260,8 @@ static inline int ucs4_internal_loop_unaligned (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, void *data, size_t *converted) + mbstate_t *state, int flags, void *data, + size_t *converted) { const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; @@ -262,6 +274,13 @@ ucs4_internal_loop_unaligned (const unsigned char **inptrp, if (inptr[0] > 0x80) { /* The value is too large. */ + if (flags & __GCONV_IGNORE_ERRORS) + { + /* Just ignore this character. */ + ++*converted; + continue; + } + *inptrp = inptr; *outptrp = outptr; return __GCONV_ILLEGAL_INPUT; @@ -312,7 +331,8 @@ static inline int ucs4_internal_loop_single (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, void *data, size_t *converted) + mbstate_t *state, int flags, void *data, + size_t *converted) { size_t cnt = state->__count & 7; @@ -329,21 +349,28 @@ ucs4_internal_loop_single (const unsigned char **inptrp, } if (((unsigned char *) state->__value.__wchb)[0] > 0x80) - /* The value is too large. */ - return __GCONV_ILLEGAL_INPUT; - + { + /* The value is too large. */ + if (!(flags & __GCONV_IGNORE_ERRORS)) + return __GCONV_ILLEGAL_INPUT; + } + else + { #if __BYTE_ORDER == __LITTLE_ENDIAN - (*outptrp)[0] = state->__value.__wchb[3]; - (*outptrp)[1] = state->__value.__wchb[2]; - (*outptrp)[2] = state->__value.__wchb[1]; - (*outptrp)[3] = state->__value.__wchb[0]; + (*outptrp)[0] = state->__value.__wchb[3]; + (*outptrp)[1] = state->__value.__wchb[2]; + (*outptrp)[2] = state->__value.__wchb[1]; + (*outptrp)[3] = state->__value.__wchb[0]; #elif __BYTE_ORDER == __BIG_ENDIAN - (*outptrp)[0] = state->__value.__wchb[0]; - (*outptrp)[1] = state->__value.__wchb[1]; - (*outptrp)[2] = state->__value.__wchb[2]; - (*outptrp)[3] = state->__value.__wchb[3]; + (*outptrp)[0] = state->__value.__wchb[0]; + (*outptrp)[1] = state->__value.__wchb[1]; + (*outptrp)[2] = state->__value.__wchb[2]; + (*outptrp)[3] = state->__value.__wchb[3]; #endif + *outptrp += 4; + } + /* Clear the state buffer. */ state->__count &= ~7; @@ -367,7 +394,8 @@ ucs4_internal_loop_single (const unsigned char **inptrp, static inline int internal_ucs4le_loop (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, void *data, size_t *converted) + mbstate_t *state, int flags, void *data, + size_t *converted) { const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; @@ -407,7 +435,7 @@ static inline int internal_ucs4le_loop_unaligned (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, void *data, + mbstate_t *state, int flags, void *data, size_t *converted) { const unsigned char *inptr = *inptrp; @@ -454,7 +482,8 @@ static inline int internal_ucs4le_loop_single (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, void *data, size_t *converted) + mbstate_t *state, int flags, void *data, + size_t *converted) { size_t cnt = state->__count & 7; @@ -475,6 +504,8 @@ internal_ucs4le_loop_single (const unsigned char **inptrp, (*outptrp)[1] = state->__value.__wchb[2]; (*outptrp)[2] = state->__value.__wchb[1]; (*outptrp)[3] = state->__value.__wchb[0]; + + *outptrp += 4; #else /* XXX unaligned */ *(*((uint32_t **) outptrp)++) = state->__value.__wch; @@ -503,7 +534,8 @@ internal_ucs4le_loop_single (const unsigned char **inptrp, static inline int ucs4le_internal_loop (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, void *data, size_t *converted) + mbstate_t *state, int flags, void *data, + size_t *converted) { const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; @@ -522,7 +554,16 @@ ucs4le_internal_loop (const unsigned char **inptrp, const unsigned char *inend, #endif if (inval > 0x7fffffff) - return __GCONV_ILLEGAL_INPUT; + { + if (flags & __GCONV_IGNORE_ERRORS) + { + /* Just ignore this character. */ + ++*converted; + continue; + } + + return __GCONV_ILLEGAL_INPUT; + } *((uint32_t *) outptr)++ = bswap_32 (*(uint32_t *) inptr); } @@ -546,7 +587,7 @@ static inline int ucs4le_internal_loop_unaligned (const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, - mbstate_t *state, void *data, + mbstate_t *state, int flags, void *data, size_t *converted) { const unsigned char *inptr = *inptrp; @@ -560,12 +601,18 @@ ucs4le_internal_loop_unaligned (const unsigned char **inptrp, if (inptr[3] > 0x80) |
