diff options
| author | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-12-12 01:38:10 +0000 |
|---|---|---|
| committer | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-12-12 01:38:10 +0000 |
| commit | 2d1f9589a302bf6e28f4929a1a0a1e46af2a55f8 (patch) | |
| tree | 0b62ddc2f572ce42be0b6c205799d426377b9049 /libcpp | |
| parent | 6349d0b0c066399932730df41a844850740c91a9 (diff) | |
| download | ppe42-gcc-2d1f9589a302bf6e28f4929a1a0a1e46af2a55f8.tar.gz ppe42-gcc-2d1f9589a302bf6e28f4929a1a0a1e46af2a55f8.zip | |
* charset.c (convert_using_iconv): Close out any shift states,
returning to the initial state.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130785 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp')
| -rw-r--r-- | libcpp/ChangeLog | 5 | ||||
| -rw-r--r-- | libcpp/charset.c | 25 |
2 files changed, 26 insertions, 4 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 1cc5d7f57f1..217294af563 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,8 @@ +2007-12-11 DJ Delorie <dj@redhat.com> + + * charset.c (convert_using_iconv): Close out any shift states, + returning to the initial state. + 2007-12-06 Tom Tromey <tromey@redhat.com> PR c/29172: diff --git a/libcpp/charset.c b/libcpp/charset.c index d1323601bd1..5db8fc13430 100644 --- a/libcpp/charset.c +++ b/libcpp/charset.c @@ -548,6 +548,15 @@ convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED, /* And this one uses the system iconv primitive. It's a little different, since iconv's interface is a little different. */ #if HAVE_ICONV + +#define CONVERT_ICONV_GROW_BUFFER \ + do { \ + outbytesleft += OUTBUF_BLOCK_SIZE; \ + to->asize += OUTBUF_BLOCK_SIZE; \ + to->text = XRESIZEVEC (uchar, to->text, to->asize); \ + outbuf = (char *)to->text + to->asize - outbytesleft; \ + } while (0) + static bool convert_using_iconv (iconv_t cd, const uchar *from, size_t flen, struct _cpp_strbuf *to) @@ -570,16 +579,24 @@ convert_using_iconv (iconv_t cd, const uchar *from, size_t flen, iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); if (__builtin_expect (inbytesleft == 0, 1)) { + /* Close out any shift states, returning to the initial state. */ + if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1) + { + if (errno != E2BIG) + return false; + + CONVERT_ICONV_GROW_BUFFER; + if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1) + return false; + } + to->len = to->asize - outbytesleft; return true; } if (errno != E2BIG) return false; - outbytesleft += OUTBUF_BLOCK_SIZE; - to->asize += OUTBUF_BLOCK_SIZE; - to->text = XRESIZEVEC (uchar, to->text, to->asize); - outbuf = (char *)to->text + to->asize - outbytesleft; + CONVERT_ICONV_GROW_BUFFER; } } #else |

