diff options
author | Ulrich Drepper <drepper@redhat.com> | 2000-06-06 03:16:30 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2000-06-06 03:16:30 +0000 |
commit | 85830c4c4688b30d3d76111aa9a26745c7b141d6 (patch) | |
tree | 8b2b99b4e538983ac760fb4faa94ce0a42121fa2 | |
parent | b0f1ca68448e9049cb6d266f327ca36523f3f675 (diff) | |
download | glibc-85830c4c4688b30d3d76111aa9a26745c7b141d6.zip glibc-85830c4c4688b30d3d76111aa9a26745c7b141d6.tar.gz glibc-85830c4c4688b30d3d76111aa9a26745c7b141d6.tar.bz2 |
Update.
* 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
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 804d8da..1821844 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 a22123b..79dcb0b 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 147f5b0..da00b1a 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 4010a6b..7189ad3 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) { /* The value is too large. */ + if (flags & __GCONV_IGNORE_ERRORS) + { + /* Just ignore this character. */ + ++*converted; + continue; + } + *inptrp = inptr; *outptrp = outptr; return __GCONV_ILLEGAL_INPUT; } - # if __BYTE_ORDER == __BIG_ENDIAN outptr[3] = inptr[0]; outptr[2] = inptr[1]; @@ -577,6 +624,8 @@ ucs4le_internal_loop_unaligned (const unsigned char **inptrp, outptr[2] = inptr[2]; outptr[3] = inptr[3]; # endif + + outptr += 4; } *inptrp = inptr; @@ -599,7 +648,8 @@ static inline int ucs4le_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; @@ -616,21 +666,28 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, } if (((unsigned char *) state->__value.__wchb)[3] > 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 == __BIG_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; @@ -658,14 +715,20 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, { \ if (*inptr > '\x7f') \ { \ - /* This is no correct ANSI_X3.4-1968 character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ + if (! ignore_errors_p ()) \ + { \ + /* This is no correct ANSI_X3.4-1968 character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ \ - /* It's an one byte sequence. */ \ - /* XXX unaligned. */ \ - *((uint32_t *) outptr)++ = *inptr++; \ + ++*converted; \ + ++inptr; \ + } \ + else \ + /* It's an one byte sequence. */ \ + /* XXX unaligned. */ \ + *((uint32_t *) outptr)++ = *inptr++; \ } #include <iconv/loop.c> #include <iconv/skeleton.c> @@ -689,13 +752,20 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, { \ if (*((uint32_t *) inptr) > 0x7f) \ { \ - /* This is no correct ANSI_X3.4-1968 character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ + if (! ignore_errors_p ()) \ + { \ + /* This is no correct ANSI_X3.4-1968 character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ \ - /* It's an one byte sequence. */ \ - *outptr++ = *((uint32_t *) inptr)++; \ + ++*converted; \ + inptr += 4; \ + } \ + else \ + /* It's an one byte sequence. */ \ + /* XXX unaligned. */ \ + *outptr++ = *((uint32_t *) inptr)++; \ } #include <iconv/loop.c> #include <iconv/skeleton.c> @@ -829,9 +899,26 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, } \ else \ { \ - /* This is an illegal encoding. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + int skipped; \ + \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal encoding. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + /* Search the end of this ill-formed UTF-8 character. This \ + is the next byte with (x & 0xc0) != 0x80. */ \ + skipped = 0; \ + do \ + { \ + ++inptr; \ + ++skipped; \ + } \ + while (inptr < inend && (*inptr & 0xc0) == 0x80 && skipped < 5); \ + \ + continue; \ } \ \ if (NEED_LENGTH_TEST && inptr + cnt > inend) \ @@ -841,8 +928,23 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, for (i = 1; inptr + i < inend; ++i) \ if ((inptr[i] & 0xc0) != 0x80) \ break; \ - result = (inptr + i == inend \ - ? __GCONV_INCOMPLETE_INPUT : __GCONV_ILLEGAL_INPUT); \ + \ + if (inptr + i == inend) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + \ + /* This is an illegal character. */ \ + if (ignore_errors_p ()) \ + { \ + /* Ignore it. */ \ + inptr += i; \ + ++*converted; \ + continue; \ + } \ + \ + result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ @@ -858,13 +960,20 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, ch <<= 6; \ ch |= byte & 0x3f; \ } \ - \ + \ /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \ If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \ have been represented with fewer than cnt bytes. */ \ - if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0)) \ + if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0)) \ { \ /* This is an illegal encoding. */ \ + if (ignore_errors_p ()) \ + { \ + inptr += i; \ + ++*converted; \ + continue; \ + } \ + \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ @@ -1021,10 +1130,17 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, { \ if (*((uint32_t *) inptr) >= 0x10000) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ } \ - *((uint16_t *) outptr)++ = *((uint32_t *) inptr)++; \ + else \ + *((uint16_t *) outptr)++ = *((uint32_t *) inptr)++; \ } #include <iconv/loop.c> #include <iconv/skeleton.c> @@ -1070,8 +1186,14 @@ ucs4le_internal_loop_single (const unsigned char **inptrp, uint32_t val = *((uint32_t *) inptr); \ if (val >= 0x10000) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ } \ *((uint16_t *) outptr)++ = bswap_16 (val); \ inptr += 4; \ diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c index 1ac23e0..56a2014 100644 --- a/iconv/iconv_prog.c +++ b/iconv/iconv_prog.c @@ -97,6 +97,9 @@ static int verbose; /* Nonzero if list of all coded character sets is wanted. */ static int list; +/* If nonzero omit invalid character from output. */ +static int omit_invalid; + /* Prototypes for the functions doing the actual work. */ static int process_block (iconv_t cd, char *addr, size_t len, FILE *output); static int process_fd (iconv_t cd, int fd, FILE *output); @@ -111,6 +114,7 @@ main (int argc, char *argv[]) int remaining; FILE *output; iconv_t cd; + const char *orig_to_code; /* Set locale via LC_ALL. */ setlocale (LC_ALL, ""); @@ -138,15 +142,48 @@ main (int argc, char *argv[]) if (to_code == NULL) error (EXIT_FAILURE, 0, _("target encoding not specified using `-t'")); + /* If we have to ignore errors make sure we use the appropriate name for + the to-character-set. */ + orig_to_code = to_code; + if (omit_invalid) + { + const char *errhand = strchrnul (to_code, '/'); + int nslash = 2; + char *newp; + char *cp; + + if (*errhand == '/') + { + --nslash; + errhand = strchrnul (errhand, '/'); + + if (*errhand == '/') + { + --nslash; + ++errhand; + } + } + + newp = (char *) alloca (errhand - to_code + nslash + 6 + 1); + cp = mempcpy (newp, to_code, errhand - to_code); + while (nslash > 0) + *cp++ = '/'; + memcpy (cp, "NEEDED", sizeof ("NEEDED")); + + to_code = newp; + } + /* Let's see whether we have these coded character sets. */ cd = iconv_open (to_code, from_code); if (cd == (iconv_t) -1) { if (errno == EINVAL) - error (EXIT_FAILURE, 0, _("conversion from `%s' to `%s' not supported"), - from_code, to_code); + error (EXIT_FAILURE, 0, + _("conversion from `%s' to `%s' not supported"), + from_code, orig_to_code); else - error (EXIT_FAILURE, errno, _("failed to start conversion processing")); + error (EXIT_FAILURE, errno, + _("failed to start conversion processing")); } /* Determine output file. */ @@ -274,9 +311,8 @@ parse_opt (int key, char *arg, struct argp_state *state) about missing character or so. */ break; case 'c': - /* Omit invalid characters from output. - XXX This option will become a meaning once we have different - modes of operation for the conversion functions. */ + /* Omit invalid characters from output. */ + omit_invalid = 1; break; case OPT_VERBOSE: verbose = 1; diff --git a/iconv/loop.c b/iconv/loop.c index 9c5dbfc..9e8e32e 100644 --- a/iconv/loop.c +++ b/iconv/loop.c @@ -168,11 +168,16 @@ #endif +/* To make it easier for the writers of the modules, we define a macro + to test whether we have to ignore errors. */ +#define ignore_errors_p() (flags & __GCONV_IGNORE_ERRORS) + + /* The function returns the status, as defined in gconv.h. */ static inline int FCTNAME (LOOPFCT) (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 EXTRA_LOOP_DECLS) { int result = __GCONV_OK; @@ -285,7 +290,7 @@ FCTNAME (LOOPFCT) (const unsigned char **inptrp, const unsigned char *inend, static inline int SINGLE(LOOPFCT) (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 EXTRA_LOOP_DECLS) { int result = __GCONV_OK; diff --git a/iconv/skeleton.c b/iconv/skeleton.c index 81677cc..6069104 100644 --- a/iconv/skeleton.c +++ b/iconv/skeleton.c @@ -275,9 +275,11 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, { struct __gconv_step *next_step = step + 1; struct __gconv_step_data *next_data = data + 1; - __gconv_fct fct = data->__is_last ? NULL : next_step->__fct; + __gconv_fct fct; int status; + fct = (data->__flags & __GCONV_IS_LAST) ? NULL : next_step->__fct; + /* If the function is called with no input this means we have to reset to the initial state. The possibly partly converted input is dropped. */ @@ -291,7 +293,7 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, #endif /* Call the steps down the chain if there are any but only if we successfully emitted the escape sequence. */ - if (status == __GCONV_OK && ! data->__is_last) + if (status == __GCONV_OK && ! (data->__flags & __GCONV_IS_LAST)) status = DL_CALL_FCT (fct, (next_step, next_data, NULL, NULL, written, 1, consume_incomplete)); } @@ -332,16 +334,18 @@ 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, step->__data, - &converted EXTRA_LOOP_ARGS); + data->__statep, data->__flags, + step->__data, &converted + 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, step->__data, - &converted EXTRA_LOOP_ARGS); + data->__statep, data->__flags, + step->__data, &converted + EXTRA_LOOP_ARGS); # endif if (status != __GCONV_OK) @@ -359,10 +363,10 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, for all known and supported encodings. */ unaligned = ((FROM_DIRECTION && ((uintptr_t) inptr % MIN_NEEDED_FROM != 0 - || (data->__is_last + || ((data->__flags & __GCONV_IS_LAST) && (uintptr_t) outbuf % MIN_NEEDED_TO != 0))) || (!FROM_DIRECTION - && ((data->__is_last + && (((data->__flags & __GCONV_IS_LAST) && (uintptr_t) outbuf % MIN_NEEDED_FROM != 0) || (uintptr_t) inptr % MIN_NEEDED_TO != 0))); #endif @@ -383,13 +387,13 @@ 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, step->__data, &converted - EXTRA_LOOP_ARGS); + data->__statep, data->__flags, + step->__data, &converted EXTRA_LOOP_ARGS); else /* Run the conversion loop. */ status = TO_LOOP (inptrp, inend, &outbuf, outend, - data->__statep, step->__data, &converted - EXTRA_LOOP_ARGS); + data->__statep, data->__flags, + step->__data, &converted EXTRA_LOOP_ARGS); } #if !defined _STRING_ARCH_unaligned \ && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \ @@ -400,12 +404,14 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, /* Run the conversion loop. */ status = GEN_unaligned (FROM_LOOP) (inptrp, inend, &outbuf, outend, data->__statep, + data->__flags, step->__data, &converted EXTRA_LOOP_ARGS); else /* Run the conversion loop. */ status = GEN_unaligned (TO_LOOP) (inptrp, inend, &outbuf, outend, data->__statep, + data->__flags, step->__data, &converted EXTRA_LOOP_ARGS); } @@ -416,7 +422,7 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, /* If this is the last step leave the loop, there is nothing we can do. */ - if (data->__is_last) + if (data->__flags & __GCONV_IS_LAST) { /* Store information about how many bytes are available. */ data->__outbuf = outbuf; @@ -457,22 +463,25 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, SAVE_RESET_STATE (0); # endif + /* XXX Handle unaligned access here as well. */ if (FROM_DIRECTION) /* Run the conversion loop. */ nstatus = FROM_LOOP ((const unsigned char **) inptrp, (const unsigned char *) inend, (unsigned char **) &outbuf, (unsigned char *) outerr, - data->__statep, step->__data, - &converted EXTRA_LOOP_ARGS); + data->__statep, data->__flags, + step->__data, &converted + EXTRA_LOOP_ARGS); else /* Run the conversion loop. */ nstatus = TO_LOOP ((const unsigned char **) inptrp, (const unsigned char *) inend, (unsigned char **) &outbuf, (unsigned char *) outerr, - data->__statep, step->__data, - &converted EXTRA_LOOP_ARGS); + data->__statep, data->__flags, + step->__data, &converted + 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 b633c47..c805d5e 100644 --- a/iconvdata/8bit-gap.c +++ b/iconvdata/8bit-gap.c @@ -51,12 +51,20 @@ struct gap if (HAS_HOLES && ch == L'\0' && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + } \ + else \ + { \ + put32 (outptr, ch); \ + outptr += 4; \ } \ \ - put32 (outptr, ch); \ - outptr += 4; \ ++inptr; \ } #include <iconv/loop.c> @@ -75,24 +83,45 @@ struct gap if (ch >= 0xffff) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + inptr += 4; \ + continue; \ } \ while (ch > rp->end) \ ++rp; \ if (ch < rp->start) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + inptr += 4; \ + continue; \ } \ \ res = from_ucs4[ch + rp->idx]; \ if (ch != 0 && res == '\0') \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + inptr += 4; \ + continue; \ } \ \ *outptr++ = res; \ diff --git a/iconvdata/8bit-generic.c b/iconvdata/8bit-generic.c index 3543bdf..3b6b47a 100644 --- a/iconvdata/8bit-generic.c +++ b/iconvdata/8bit-generic.c @@ -37,8 +37,13 @@ if (HAS_HOLES && ch == L'\0' && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ } \ \ put32 (outptr, ch); \ @@ -60,11 +65,17 @@ || (ch != 0 && from_ucs4[ch] == '\0')) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ } \ + else \ + *outptr++ = from_ucs4[ch]; \ \ - *outptr++ = from_ucs4[ch]; \ inptr += 4; \ } #include <iconv/loop.c> diff --git a/iconvdata/ansi_x3.110.c b/iconvdata/ansi_x3.110.c index 1dd214b..94bd2e6 100644 --- a/iconvdata/ansi_x3.110.c +++ b/iconvdata/ansi_x3.110.c @@ -419,13 +419,20 @@ static const char from_ucs4[][2] = if (ch2 < 0x20 || ch2 >= 0x80) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - \ - ch = to_ucs4_comb[ch - 0xc1][ch2 - 0x20]; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ \ - incr = 2; \ + ++*converted; \ + incr = 1; \ + } \ + else \ + { \ + ch = to_ucs4_comb[ch - 0xc1][ch2 - 0x20]; \ + incr = 2; \ + } \ } \ else \ { \ @@ -436,13 +443,19 @@ static const char from_ucs4[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + } \ + else \ + { \ + put32 (outptr, ch); \ + outptr += 4; \ } \ \ inptr += incr; \ - put32 (outptr, ch); \ - outptr += 4; \ } #include <iconv/loop.c> @@ -480,8 +493,15 @@ static const char from_ucs4[][2] = if (tmp[0] == '\0') \ { \ /* Illegal characters. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + inptr += 4; \ + continue; \ } \ tmp[1] = '\0'; \ cp = tmp; \ @@ -504,13 +524,13 @@ static const char from_ucs4[][2] = cp = "\xd7"; \ else if (ch == 0x253c) \ cp = "\xe5"; \ - else if (ch >= 0x2571 && ch <= 0x2572) \ + else if (ch >= 0x2571 && ch <= 0x2572) \ { \ tmp[0] = 0xd8 + ch - 0x2571; \ tmp[1] = '\0'; \ cp = tmp; \ } \ - else if (ch >= 0x25e2 && ch <= 0x25e3) \ + else if (ch >= 0x25e2 && ch <= 0x25e3) \ { \ tmp[0] = 0xda + ch - 0x25e2; \ tmp[1] = '\0'; \ @@ -521,8 +541,15 @@ static const char from_ucs4[][2] = else \ { \ /* Illegal characters. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + inptr += 4; \ + continue; \ } \ } \ else \ @@ -531,9 +558,16 @@ static const char from_ucs4[][2] = \ if (cp[0] == '\0' && ch != 0) \ { \ - /* Illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + /* Illegal characters. */ \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + inptr += 4; \ + continue; \ } \ } \ \ diff --git a/iconvdata/big5.c b/iconvdata/big5.c index de15ad6..0e4ca74 100644 --- a/iconvdata/big5.c +++ b/iconvdata/big5.c @@ -8455,8 +8455,15 @@ static const char from_ucs4_tab13[][2] = else \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ \ /* Get the value from the table. */ \ @@ -8466,8 +8473,15 @@ static const char from_ucs4_tab13[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ \ inptr += 2; \ @@ -8567,21 +8581,29 @@ static const char from_ucs4_tab13[][2] = if (cp[0] == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ \ - /* See whether there is enough room for the second byte we write. */ \ - if (NEED_LENGTH_TEST && cp[1] != '\0' && outptr + 1 >= outend) \ + ++*converted; \ + } \ + else \ { \ - /* We have not enough room. */ \ - result = __GCONV_FULL_OUTPUT; \ - break; \ + /* See whether there is enough room for the second byte we write. */ \ + if (NEED_LENGTH_TEST && cp[1] != '\0' && outptr + 1 >= outend) \ + { \ + /* We have not enough room. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + \ + *outptr++ = cp[0]; \ + if (cp[1] != '\0') \ + *outptr++ = cp[1]; \ } \ \ - *outptr++ = cp[0]; \ - if (cp[1] != '\0') \ - *outptr++ = cp[1]; \ inptr += 4; \ } #include <iconv/loop.c> diff --git a/iconvdata/big5hkscs.c b/iconvdata/big5hkscs.c index 7e1999e..09974d5 100644 --- a/iconvdata/big5hkscs.c +++ b/iconvdata/big5hkscs.c @@ -12609,8 +12609,15 @@ static const char from_ucs4_tab14[][2] = else \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ \ /* Get the value from the table. */ \ @@ -12620,8 +12627,15 @@ static const char from_ucs4_tab14[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ \ inptr += 2; \ @@ -12724,21 +12738,29 @@ static const char from_ucs4_tab14[][2] = if (cp[0] == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ \ - /* See whether there is enough room for the second byte we write. */ \ - if (NEED_LENGTH_TEST && cp[1] != '\0' && outptr + 1 >= outend) \ + ++*converted; \ + } \ + else \ { \ - /* We have not enough room. */ \ - result = __GCONV_FULL_OUTPUT; \ - break; \ + /* See whether there is enough room for the second byte we write. */ \ + if (NEED_LENGTH_TEST && cp[1] != '\0' && outptr + 1 >= outend) \ + { \ + /* We have not enough room. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + \ + *outptr++ = cp[0]; \ + if (cp[1] != '\0') \ + *outptr++ = cp[1]; \ } \ \ - *outptr++ = cp[0]; \ - if (cp[1] != '\0') \ - *outptr++ = cp[1]; \ inptr += 4; \ } #include <iconv/loop.c> diff --git a/iconvdata/euc-cn.c b/iconvdata/euc-cn.c index 61601e7..3211b57 100644 --- a/iconvdata/euc-cn.c +++ b/iconvdata/euc-cn.c @@ -44,11 +44,18 @@ if (ch <= 0x7f) \ ++inptr; \ else \ - if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e && ch != 0x8f) \ + if ((ch <= 0xa0 && ch != 0x8e && ch != 0x8f) || ch > 0xfe) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ else \ { \ @@ -69,9 +76,16 @@ /* All second bytes of a multibyte character must be >= 0xa1. */ \ if (ch < 0xa1) \ { \ - /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ \ /* This is code set 1: GB 2312-80. */ \ @@ -81,8 +95,16 @@ if (ch == __UNKNOWN_10646_CHAR) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ \ inptr += 2; \ @@ -118,8 +140,15 @@ if (found == __UNKNOWN_10646_CHAR) \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ \ /* It's a GB 2312 character, adjust it for EUC-CN. */ \ diff --git a/iconvdata/euc-jp.c b/iconvdata/euc-jp.c index 2c25d7a..240d760 100644 --- a/iconvdata/euc-jp.c +++ b/iconvdata/euc-jp.c @@ -46,11 +46,18 @@ \ if (ch <= 0x7f) \ ++inptr; \ - else if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e && ch != 0x8f) \ + else if ((ch <= 0xa0 && ch != 0x8e && ch != 0x8f) || ch > 0xfe) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ else \ { \ @@ -72,8 +79,15 @@ if (ch2 < 0xa1) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ \ if (ch == 0x8e) \ @@ -114,8 +128,16 @@ if (ch == __UNKNOWN_10646_CHAR) \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ inptr = endp; \ } \ @@ -198,8 +220,15 @@ else \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ } \ } \ diff --git a/iconvdata/euc-kr.c b/iconvdata/euc-kr.c index 19516b6..d84e72c 100644 --- a/iconvdata/euc-kr.c +++ b/iconvdata/euc-kr.c @@ -81,8 +81,15 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) else if (ch <= 0xa0 || ch > 0xfe || ch == 0xc9) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ else \ { \ @@ -99,8 +106,16 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) if (ch == __UNKNOWN_10646_CHAR) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ } \ \ @@ -127,8 +142,15 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) if (cp[0] == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ \ *outptr++ = cp[0]; \ diff --git a/iconvdata/gbgbk.c b/iconvdata/gbgbk.c index 64da7a4..88617ae 100644 --- a/iconvdata/gbgbk.c +++ b/iconvdata/gbgbk.c @@ -89,28 +89,28 @@ ch = (ch << 8) | inptr[1]; \ \ /* Now determine whether the character is valid. */ \ - if (ch >= 0xa1a1 && ch <= 0xf7fe && inptr[1] >= 0xa1) \ + if (ch < 0xa1a1 || ch > 0xf7fe || inptr[1] < 0xa1 \ + /* Now test the exceptions. */ \ + || (ch >= 0xa2a1 && ch <= 0xa2aa) \ + || (ch >= 0xa6e0 && ch <= 0xa6f5) \ + || (ch >= 0xa8bb && ch <= 0xa8c0)) \ { \ - /* So far so good. Now test the exceptions. */ \ - if ((ch >= 0xa2a1 && ch <= 0xa2aa) \ - || (ch >= 0xa6e0 && ch <= 0xa6f5) \ - || (ch >= 0xa8bb && ch <= 0xa8c0)) \ + /* One of the characters we cannot map. */ \ + if (! ignore_errors_p ()) \ { \ - /* One of the exceptions. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ + \ + inptr += 2; \ + ++*converted; \ } \ else \ { \ - /* One of the characters we cannot map. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + /* Copy the two bytes. */ \ + *outptr++ = *inptr++; \ + *outptr++ = *inptr++; \ } \ - \ - /* Copy the two bytes. */ \ - *outptr++ = *inptr++; \ - *outptr++ = *inptr++; \ } \ } #include <iconv/loop.c> diff --git a/iconvdata/gbk.c b/iconvdata/gbk.c index 9956ea3..c120df0 100644 --- a/iconvdata/gbk.c +++ b/iconvdata/gbk.c @@ -13124,8 +13124,15 @@ static const char __gbk_from_ucs4_tab12[][2] = if (ch <= 0x80 || ch > 0xfe) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ else \ { \ @@ -13148,8 +13155,16 @@ static const char __gbk_from_ucs4_tab12[][2] = if (ch2 < 0x40) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ \ /* This is code set 1: GBK. */ \ @@ -13160,8 +13175,16 @@ static const char __gbk_from_ucs4_tab12[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ \ inptr += 2; \ @@ -13426,21 +13449,27 @@ static const char __gbk_from_ucs4_tab12[][2] = if (cp == NULL || (cp[0] == '\0' && ch != 0)) \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ \ + ++*converted; \ + } \ /* See whether there is enough room for the second byte we write. */ \ - if (NEED_LENGTH_TEST && cp[1] != '\0' && outptr + 1 >= outend) \ + else if (NEED_LENGTH_TEST && cp[1] != '\0' && outptr + 1 >= outend) \ { \ /* We have not enough room. */ \ result = __GCONV_FULL_OUTPUT; \ break; \ } \ - \ - *outptr++ = cp[0]; \ - if (cp[1] != '\0') \ - *outptr++ = cp[1]; \ + else \ + { \ + *outptr++ = cp[0]; \ + if (cp[1] != '\0') \ + *outptr++ = cp[1]; \ + } \ } \ \ inptr += 4; \ diff --git a/iconvdata/iso-2022-cn.c b/iconvdata/iso-2022-cn.c index 5ffbfa5..c89fc57 100644 --- a/iconvdata/iso-2022-cn.c +++ b/iconvdata/iso-2022-cn.c @@ -93,7 +93,7 @@ enum { \ /* Write out the shift sequence. */ \ *outbuf++ = SI; \ - if (data->__is_last) \ + if (data->__flags & __GCONV_IS_LAST) \ *written += 1; \ data->__outbuf = outbuf; \ data->__statep->__count = ASCII_set; \ @@ -123,8 +123,15 @@ enum /* This is a 7bit character set, disallow all 8bit characters. */ \ if (ch > 0x7f) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ \ /* Recognize escape sequences. */ \ @@ -187,9 +194,16 @@ enum ch = cns11643l2_to_ucs4 (&inptr, 2, 0); \ if (ch == __UNKNOWN_10646_CHAR) \ { \ - inptr -= 2; \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + inptr -= 2; \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + continue; \ } \ } \ else if (set == ASCII_set) \ @@ -217,8 +231,16 @@ enum } \ else if (ch == __UNKNOWN_10646_CHAR) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ } \ \ @@ -305,8 +327,15 @@ enum else \ { \ /* Even this does not work. Error. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ } \ } \ diff --git a/iconvdata/iso-2022-jp.c b/iconvdata/iso-2022-jp.c index 105fd47..51420fb 100644 --- a/iconvdata/iso-2022-jp.c +++ b/iconvdata/iso-2022-jp.c @@ -217,7 +217,7 @@ gconv_end (struct __gconv_step *data) *outbuf++ = ESC; \ *outbuf++ = '('; \ *outbuf++ = 'B'; \ - if (data->__is_last) \ + if (data->__flags & __GCONV_IS_LAST) \ *written += 3; \ data->__outbuf = outbuf; \ /* Note that this also clears the G2 designation. */ \ @@ -362,21 +362,42 @@ gconv_end (struct __gconv_step *data) /* We use the table from the ISO 8859-7 module. */ \ if (inptr[2] < 0x20 || inptr[2] > 0x80) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ ch = iso88597_to_ucs4[inptr[2] - 0x20]; \ if (ch == 0) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 3; \ + ++*converted; \ + continue; \ } \ inptr += 3; \ } \ else \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ } \ else if (set == ASCII_set || (ch < 0x21 || ch == 0x7f)) \ @@ -388,8 +409,15 @@ gconv_end (struct __gconv_step *data) ch = jisx0201_to_ucs4 (ch); \ if (ch == __UNKNOWN_10646_CHAR) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ ++inptr; \ } \ @@ -399,8 +427,15 @@ gconv_end (struct __gconv_step *data) ch = jisx0201_to_ucs4 (ch + 0x80); \ if (ch == __UNKNOWN_10646_CHAR) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ ++inptr; \ } \ @@ -437,8 +472,15 @@ gconv_end (struct __gconv_step *data) } \ else if (ch == __UNKNOWN_10646_CHAR) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ } \ \ @@ -672,8 +714,13 @@ gconv_end (struct __gconv_step *data) else if (var == iso2022jp) \ { \ /* We have no other choice. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ } \ else \ { \ @@ -839,8 +886,13 @@ gconv_end (struct __gconv_step *data) } \ else \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ } \ } \ } \ diff --git a/iconvdata/iso-2022-kr.c b/iconvdata/iso-2022-kr.c index ab03472..e6db8c4 100644 --- a/iconvdata/iso-2022-kr.c +++ b/iconvdata/iso-2022-kr.c @@ -95,7 +95,7 @@ enum { \ /* Write out the shift sequence. */ \ *outbuf++ = SI; \ - if (data->__is_last) \ + if (data->__flags & __GCONV_IS_LAST) \ *written += 1; \ data->__outbuf = outbuf; \ data->__statep->__count = ASCII_set; \ @@ -125,8 +125,15 @@ enum /* This is a 7bit character set, disallow all 8bit characters. */ \ if (ch > 0x7f) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ \ /* Recognize escape sequences. */ \ @@ -187,8 +194,16 @@ enum } \ else if (ch == __UNKNOWN_10646_CHAR) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + ++inptr; \ + continue; \ } \ } \ \ @@ -240,26 +255,34 @@ enum if (written == __UNKNOWN_10646_CHAR) \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ - assert (written == 2); \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ \ - /* We use KSC 5601. */ \ - if (set != KSC5601_set) \ - { \ - *outptr++ = SO; \ - set = KSC5601_set; \ + ++*converted; \ } \ - \ - if (NEED_LENGTH_TEST && outptr + 2 > outend) \ + else \ { \ - result = __GCONV_FULL_OUTPUT; \ - break; \ - } \ + assert (written == 2); \ + \ + /* We use KSC 5601. */ \ + if (set != KSC5601_set) \ + { \ + *outptr++ = SO; \ + set = KSC5601_set; \ + } \ + \ + if (NEED_LENGTH_TEST && outptr + 2 > outend) \ + { \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ \ - *outptr++ = buf[0]; \ - *outptr++ = buf[1]; \ + *outptr++ = buf[0]; \ + *outptr++ = buf[1]; \ + } \ } \ \ /* Now that we wrote the output increment the input pointer. */ \ diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c index c8d0a02..ba0addc 100644 --- a/iconvdata/iso646.c +++ b/iconvdata/iso646.c @@ -406,12 +406,20 @@ gconv_end (struct __gconv_step *data) when we reach the default case in the `switch' statement. */ \ if (failure == __GCONV_ILLEGAL_INPUT) \ { \ - /* Exit the loop with an error. */ \ - result = failure; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* Exit the loop with an error. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + } \ + else \ + { \ + put32 (outptr, ch); \ + outptr += 4; \ } \ - put32 (outptr, ch); \ - outptr += 4; \ ++inptr; \ } #define EXTRA_LOOP_DECLS , enum variant var @@ -875,11 +883,17 @@ gconv_end (struct __gconv_step *data) \ if (failure == __GCONV_ILLEGAL_INPUT) \ { \ - /* Exit the loop with an error. */ \ - result = failure; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* Exit the loop with an error. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ } \ - *outptr++ = (unsigned char) ch; \ + else \ + *outptr++ = (unsigned char) ch; \ inptr += 4; \ } #define EXTRA_LOOP_DECLS , enum variant var diff --git a/iconvdata/iso8859-1.c b/iconvdata/iso8859-1.c index 06eeda5..4949991 100644 --- a/iconvdata/iso8859-1.c +++ b/iconvdata/iso8859-1.c @@ -1,5 +1,5 @@ /* Conversion to and from ISO 8859-1. - 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. @@ -48,10 +48,16 @@ if (ch > 0xff) \ { \ /* We have an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ } \ - *outptr++ = (unsigned char) ch; \ + else \ + *outptr++ = (unsigned char) ch; \ inptr += 4; \ } #include <iconv/loop.c> diff --git a/iconvdata/iso_6937-2.c b/iconvdata/iso_6937-2.c index a688b7c..f58ebe4 100644 --- a/iconvdata/iso_6937-2.c +++ b/iconvdata/iso_6937-2.c @@ -418,8 +418,16 @@ static const char from_ucs4[][2] = if (ch2 < 0x20 || ch2 >= 0x80) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ \ ch = to_ucs4_comb[ch - 0xc1][ch2 - 0x20]; \ @@ -427,8 +435,16 @@ static const char from_ucs4[][2] = if (ch == 0) \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ \ inptr += 2; \ @@ -440,8 +456,16 @@ static const char from_ucs4[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ ++inptr; \ } \ @@ -543,15 +567,30 @@ static const char from_ucs4[][2] = if (fail) \ { \ /* Illegal characters. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ } \ else if (from_ucs4[ch][0] == '\0' && ch != 0) \ { \ /* Illegal characters. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + inptr += 4; \ + continue; \ } \ else \ cp = from_ucs4[ch]; \ @@ -563,6 +602,7 @@ static const char from_ucs4[][2] = if (NEED_LENGTH_TEST && outptr >= outend) \ { \ /* The result does not fit into the buffer. */ \ + --outptr; \ result = __GCONV_FULL_OUTPUT; \ break; \ } \ diff --git a/iconvdata/iso_6937.c b/iconvdata/iso_6937.c index 81e5d0c..f6581cf 100644 --- a/iconvdata/iso_6937.c +++ b/iconvdata/iso_6937.c @@ -410,8 +410,16 @@ static const char from_ucs4[][2] = if (ch2 < 0x20 || ch2 >= 0x80) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ \ ch = to_ucs4_comb[ch - 0xc1][ch2 - 0x20]; \ @@ -419,8 +427,16 @@ static const char from_ucs4[][2] = if (ch == 0) \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ \ inptr += 2; \ @@ -432,8 +448,16 @@ static const char from_ucs4[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ ++inptr; \ } \ @@ -514,15 +538,30 @@ static const char from_ucs4[][2] = if (fail) \ { \ /* Illegal characters. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ } \ else if (from_ucs4[ch][0] == '\0' && ch != 0) \ { \ /* Illegal characters. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + inptr += 4; \ + continue; \ } \ else \ cp = from_ucs4[ch]; \ @@ -534,6 +573,7 @@ static const char from_ucs4[][2] = if (NEED_LENGTH_TEST && outptr >= outend) \ { \ /* The result does not fit into the buffer. */ \ + --outptr; \ result = __GCONV_FULL_OUTPUT; \ break; \ } \ diff --git a/iconvdata/johab.c b/iconvdata/johab.c index 1822b0d..ca4d053 100644 --- a/iconvdata/johab.c +++ b/iconvdata/johab.c @@ -183,8 +183,16 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) || (ch > 0xd3 && ch < 0xd9)) \ { \ /* These are illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ else \ { \ @@ -215,8 +223,16 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) if (i == -1 || m == -1 || f == -1) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ else if (i > 0 && m > 0) \ ch = ((i - 1) * 21 + (m - 1)) * 28 + f + 0xac00; \ @@ -229,8 +245,16 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) else \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ } \ else \ @@ -238,15 +262,31 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) if (ch2 < 0x31 || (ch2 > 0x7e && ch2 < 0x91) || ch2 == 0xff) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ else if (ch == 0xda && ch2 > 0xa0 && ch2 < 0xd4) \ { \ /* This is illegal. Modern Hangul Jaso is defined \ elsewhere in Johab */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ else \ { \ @@ -267,8 +307,16 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) if (ch == 0) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ \ inptr += 2; \ @@ -354,8 +402,16 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) } \ if (written == __UNKNOWN_10646_CHAR) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ \ outptr[0] -= 0x4a; \ @@ -383,8 +439,16 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2) } \ if (written == __UNKNOWN_10646_CHAR) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ \ outptr[0] -= 0x4a; \ diff --git a/iconvdata/sjis.c b/iconvdata/sjis.c index 4ca7ce9..07f03f7 100644 --- a/iconvdata/sjis.c +++ b/iconvdata/sjis.c @@ -4354,11 +4354,19 @@ static const char from_ucs4_extra[0x100][2] = ch = halfkana_to_ucs4[ch - 0xa1]; \ ++inptr; \ } \ - else if (ch > 0xea || ch == 0xa0 || ch == 0x7f || ch == 0x80) \ + else if (ch > 0xea || ch == 0xa0 || ch <= 0x80) \ { \ /* These are illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ else \ { \ @@ -4382,8 +4390,16 @@ static const char from_ucs4_extra[0x100][2] = || (idx > 0x9ffc && idx < 0xe040) || idx > 0xeaa4) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ else \ { \ @@ -4405,8 +4421,16 @@ static const char from_ucs4_extra[0x100][2] = if (ch == 0) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ } \ \ @@ -4437,8 +4461,16 @@ static const char from_ucs4_extra[0x100][2] = else \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ } \ else \ @@ -4447,21 +4479,29 @@ static const char from_ucs4_extra[0x100][2] = if (cp[0] == '\0' && ch != 0) \ { \ /* Illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ \ - *outptr++ = cp[0]; \ - /* Now test for a possible second byte and write this if possible. */ \ - if (cp[1] != '\0') \ + ++*converted; \ + } \ + else \ { \ - if (NEED_LENGTH_TEST && outptr >= outend) \ + *outptr++ = cp[0]; \ + /* Now test for a possible second byte and write this if possible. */\ + if (cp[1] != '\0') \ { \ - /* The result does not fit into the buffer. */ \ - result = __GCONV_FULL_OUTPUT; \ - break; \ + if (NEED_LENGTH_TEST && outptr >= outend) \ + { \ + /* The result does not fit into the buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + *outptr++ = cp[1]; \ } \ - *outptr++ = cp[1]; \ } \ \ inptr += 4; \ diff --git a/iconvdata/t.61.c b/iconvdata/t.61.c index 10a52a1..1623606 100644 --- a/iconvdata/t.61.c +++ b/iconvdata/t.61.c @@ -401,8 +401,16 @@ static const char from_ucs4[][2] = if (ch2 < 0x20 || ch2 >= 0x80) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ \ ch = to_ucs4_comb[ch - 0xc1][ch2 - 0x20]; \ @@ -418,12 +426,21 @@ static const char from_ucs4[][2] = if (ch == 0 && *inptr != '\0') \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + --inptr; \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ \ - put32 (outptr, ch); \ - outptr += 4; \ + ++*converted; \ + } \ + else \ + { \ + put32 (outptr, ch); \ + outptr += 4; \ + } \ } #include <iconv/loop.c> @@ -448,8 +465,16 @@ static const char from_ucs4[][2] = else if (ch < 0x2d8 || ch > 0x2dd || ch == 0x02dc) \ { \ /* Illegal characters. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ else \ { \ @@ -467,8 +492,16 @@ static const char from_ucs4[][2] = if (cp[0] == '\0' && ch != 0) \ { \ /* Illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ } \ \ diff --git a/iconvdata/uhc.c b/iconvdata/uhc.c index e42cb2e..15faf1e 100644 --- a/iconvdata/uhc.c +++ b/iconvdata/uhc.c @@ -3066,8 +3066,16 @@ static const char uhc_hangul_from_ucs[11172][2] = else if (ch <= 0x80 || ch >= 0xfe || ch == 0xc9) \ { \ /* This is illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ else \ { \ @@ -3109,8 +3117,16 @@ static const char uhc_hangul_from_ucs[11172][2] = || (ch2 > 0x7a && ch2 < 0x81) || (ch == 0xc6 && ch2 > 0x52)) \ { \ /* This is not legal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++inptr; \ + ++*converted; \ + continue; \ } \ \ ch = uhc_extra_to_ucs[ch2 - 0x41 \ @@ -3122,8 +3138,16 @@ static const char uhc_hangul_from_ucs[11172][2] = if (ch == 0) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ \ inptr += 2; \ @@ -3134,8 +3158,16 @@ static const char uhc_hangul_from_ucs[11172][2] = if (ch == __UNKNOWN_10646_CHAR) \ { \ /* Illegal. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 2; \ + ++*converted; \ + continue; \ } \ } \ } \ @@ -3184,8 +3216,16 @@ static const char uhc_hangul_from_ucs[11172][2] = } \ if (written == __UNKNOWN_10646_CHAR) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ \ *outptr++ |= 0x80; \ @@ -3208,8 +3248,16 @@ static const char uhc_hangul_from_ucs[11172][2] = } \ if (written == __UNKNOWN_10646_CHAR) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + inptr += 4; \ + ++*converted; \ + continue; \ } \ \ *outptr++ |= 0x80; \ diff --git a/iconvdata/unicode.c b/iconvdata/unicode.c index 883e7b1..7f2aca5 100644 --- a/iconvdata/unicode.c +++ b/iconvdata/unicode.c @@ -151,13 +151,21 @@ gconv_end (struct __gconv_step *data) \ if (c >= 0x10000) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ - } \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ \ - put16 (outptr, c); \ + ++*converted; \ + } \ + else \ + { \ + put16 (outptr, c); \ + outptr += 2; \ + } \ \ - outptr += 2; \ inptr += 4; \ } #define EXTRA_LOOP_DECLS \ diff --git a/iconvdata/utf-16.c b/iconvdata/utf-16.c index a7a01a8..9ca2e0b 100644 --- a/iconvdata/utf-16.c +++ b/iconvdata/utf-16.c @@ -201,8 +201,16 @@ gconv_end (struct __gconv_step *data) { \ if (c >= 0x110000) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + inptr += 4; \ + continue; \ } \ \ /* Generate a surrogate character. */ \ @@ -226,8 +234,16 @@ gconv_end (struct __gconv_step *data) { \ if (c >= 0x110000) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + /* This is an illegal character. */ \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + inptr += 4; \ + continue; \ } \ \ /* Generate a surrogate character. */ \ @@ -291,9 +307,15 @@ gconv_end (struct __gconv_step *data) if (u2 < 0xdc00 || u2 >= 0xdfff) \ { \ /* This is no valid second word for a surrogate. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - inptr -= 2; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + inptr -= 2; \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + continue; \ } \ \ put32 (outptr, ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00)); \ @@ -327,9 +349,15 @@ gconv_end (struct __gconv_step *data) if (u2 < 0xdc00 || u2 >= 0xdfff) \ { \ /* This is no valid second word for a surrogate. */ \ - result = __GCONV_ILLEGAL_INPUT; \ - inptr -= 2; \ - break; \ + if (! ignore_errors_p ()) \ + { \ + inptr -= 2; \ + result = __GCONV_ILLEGAL_INPUT; \ + break; \ + } \ + \ + ++*converted; \ + continue; \ } \ \ put32 (outptr, ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00)); \ diff --git a/libio/fileops.c b/libio/fileops.c index cd57370..81dece0 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -299,7 +299,7 @@ _IO_new_file_fopen (fp, filename, mode, is32not64) cc->__cd_in.__cd.__data[0].__invocation_counter = 0; cc->__cd_in.__cd.__data[0].__internal_use = 1; - cc->__cd_in.__cd.__data[0].__is_last = 1; + cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST; cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state; cc->__cd_out.__cd.__nsteps = 1; /* Only one step allowed. */ @@ -307,7 +307,7 @@ _IO_new_file_fopen (fp, filename, mode, is32not64) cc->__cd_out.__cd.__data[0].__invocation_counter = 0; cc->__cd_out.__cd.__data[0].__internal_use = 1; - cc->__cd_out.__cd.__data[0].__is_last = 1; + cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST; cc->__cd_out.__cd.__data[0].__statep = &result->_wide_data->_IO_state; /* Set the mode now. */ diff --git a/libio/iofwide.c b/libio/iofwide.c index 6db8365..d1a0f1e 100644 --- a/libio/iofwide.c +++ b/libio/iofwide.c @@ -121,7 +121,7 @@ _IO_fwide (fp, mode) cc->__cd_in.__cd.__data[0].__invocation_counter = 0; cc->__cd_in.__cd.__data[0].__internal_use = 1; - cc->__cd_in.__cd.__data[0].__is_last = 1; + cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST; cc->__cd_in.__cd.__data[0].__statep = &fp->_wide_data->_IO_state; cc->__cd_out.__cd.__nsteps = 1; /* Only one step allowed. */ @@ -129,7 +129,7 @@ _IO_fwide (fp, mode) cc->__cd_out.__cd.__data[0].__invocation_counter = 0; cc->__cd_out.__cd.__data[0].__internal_use = 1; - cc->__cd_out.__cd.__data[0].__is_last = 1; + cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST; cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state; } #else diff --git a/wcsmbs/btowc.c b/wcsmbs/btowc.c index e0e4ceb..0978f09 100644 --- a/wcsmbs/btowc.c +++ b/wcsmbs/btowc.c @@ -46,7 +46,7 @@ __btowc (c) data.__outbufend = data.__outbuf + sizeof (wchar_t); data.__invocation_counter = 0; data.__internal_use = 1; - data.__is_last = 1; + data.__flags = __GCONV_IS_LAST; data.__statep = &data.__state; /* Make sure we start in the initial state. */ diff --git a/wcsmbs/mbrtowc.c b/wcsmbs/mbrtowc.c index 212b001..6ecbdc5 100644 --- a/wcsmbs/mbrtowc.c +++ b/wcsmbs/mbrtowc.c @@ -46,7 +46,7 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) /* Set information for this step. */ data.__invocation_counter = 0; data.__internal_use = 1; - data.__is_last = 1; + data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; /* A first special case is if S is NULL. This means put PS in the diff --git a/wcsmbs/mbsnrtowcs.c b/wcsmbs/mbsnrtowcs.c index 42b5879..540afd0 100644 --- a/wcsmbs/mbsnrtowcs.c +++ b/wcsmbs/mbsnrtowcs.c @@ -54,7 +54,7 @@ __mbsnrtowcs (dst, src, nmc, len, ps) /* Tell where we want the result. */ data.__invocation_counter = 0; data.__internal_use = 1; - data.__is_last = 1; + data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; if (nmc == 0) diff --git a/wcsmbs/mbsrtowcs.c b/wcsmbs/mbsrtowcs.c index facec08..aaafe3b 100644 --- a/wcsmbs/mbsrtowcs.c +++ b/wcsmbs/mbsrtowcs.c @@ -50,7 +50,7 @@ __mbsrtowcs (dst, src, len, ps) /* Tell where we want the result. */ data.__invocation_counter = 0; data.__internal_use = 1; - data.__is_last = 1; + data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; /* Make sure we use the correct function. */ diff --git a/wcsmbs/wcrtomb.c b/wcsmbs/wcrtomb.c index 7aef505..5af3831 100644 --- a/wcsmbs/wcrtomb.c +++ b/wcsmbs/wcrtomb.c @@ -46,7 +46,7 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps) /* Set information for this step. */ data.__invocation_counter = 0; data.__internal_use = 1; - data.__is_last = 1; + data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; /* A first special case is if S is NULL. This means put PS in the diff --git a/wcsmbs/wcsnrtombs.c b/wcsmbs/wcsnrtombs.c index 50c33ec..7005bdc 100644 --- a/wcsmbs/wcsnrtombs.c +++ b/wcsmbs/wcsnrtombs.c @@ -52,7 +52,7 @@ __wcsnrtombs (dst, src, nwc, len, ps) /* Tell where we want the result. */ data.__invocation_counter = 0; data.__internal_use = 1; - data.__is_last = 1; + data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; if (nwc == 0) diff --git a/wcsmbs/wcsrtombs.c b/wcsmbs/wcsrtombs.c index 28af214..875ef16 100644 --- a/wcsmbs/wcsrtombs.c +++ b/wcsmbs/wcsrtombs.c @@ -48,7 +48,7 @@ __wcsrtombs (dst, src, len, ps) /* Tell where we want the result. */ data.__invocation_counter = 0; data.__internal_use = 1; - data.__is_last = 1; + data.__flags = __GCONV_IS_LAST; data.__statep = ps ?: &state; /* Make sure we use the correct function. */ diff --git a/wcsmbs/wctob.c b/wcsmbs/wctob.c index 7e4c04f..8c63725 100644 --- a/wcsmbs/wctob.c +++ b/wcsmbs/wctob.c @@ -40,7 +40,7 @@ wctob (c) data.__outbufend = buf + MB_LEN_MAX; data.__invocation_counter = 0; data.__internal_use = 1; - data.__is_last = 1; + data.__flags = __GCONV_IS_LAST; data.__statep = &data.__state; /* Make sure we start in the initial state. */ |