From 9c162a9bc66e5c25c80168663862db01cba648fb Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Tue, 2 Jan 2007 20:57:34 +0000 Subject: [PATCH] Implement more detailed iconv error messages for better tracking of bugs like 3043 * src/support/docstream.C (iconv_codecvt_facet::do_out): Output the to be converted string and the partially converted result in hex notation if an error occurs (iconv_codecvt_facet::do_in): ditto (iconv_codecvt_facet::do_iconv): remove now obsolete error message git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16469 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/support/docstream.C | 78 +++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/src/support/docstream.C b/src/support/docstream.C index cec4956156..9f0b70187c 100644 --- a/src/support/docstream.C +++ b/src/support/docstream.C @@ -41,7 +41,7 @@ public: explicit iconv_codecvt_facet(string const & encoding = "UTF-8", std::ios_base::openmode inout = std::ios_base::in | std::ios_base::out, size_t refs = 0) - : base(refs), utf8_(encoding == "UTF-8") + : base(refs), encoding_(encoding) { if (inout & std::ios_base::in) { in_cd_ = iconv_open(ucs4_codeset, encoding.c_str()); @@ -89,8 +89,38 @@ protected: size_t outbytesleft = (to_end - to) * sizeof(extern_type); from_next = from; to_next = to; - return do_iconv(out_cd_, reinterpret_cast(&from_next), + result const retval = do_iconv(out_cd_, + reinterpret_cast(&from_next), &inbytesleft, &to_next, &outbytesleft); + if (retval == base::error) { + fprintf(stderr, + "Error %d returned from iconv when converting from %s to %s: %s\n", + errno, ucs4_codeset, encoding_.c_str(), + strerror(errno)); + fputs("Converted input:", stderr); + for (intern_type const * i = from; i < from_next; ++i) { + unsigned int const c = *i; + fprintf(stderr, " 0x%04x", c); + } + unsigned int const c = *from_next; + fprintf(stderr, "\nStopped at: 0x%04x\n", c); + fputs("Unconverted input:", stderr); + for (intern_type const * i = from_next + 1; i < from_end; ++i) { + unsigned int const c = *i; + fprintf(stderr, " 0x%04x", c); + } + fputs("\nConverted output:", stderr); + for (extern_type const * i = to; i < to_next; ++i) { + // extern_type may be signed, avoid output of + // something like 0xffffffc2 + unsigned int const c = + *reinterpret_cast(i); + fprintf(stderr, " 0x%02x", c); + } + fputc('\n', stderr); + fflush(stderr); + } + return retval; } virtual result do_unshift(state_type &, extern_type * to, extern_type *, extern_type *& to_next) const @@ -109,9 +139,40 @@ protected: size_t outbytesleft = (to_end - to) * sizeof(intern_type); from_next = from; to_next = to; - return do_iconv(in_cd_, &from_next, &inbytesleft, + result const retval = do_iconv(in_cd_, &from_next, &inbytesleft, reinterpret_cast(&to_next), &outbytesleft); + if (retval == base::error) { + fprintf(stderr, + "Error %d returned from iconv when converting from %s to %s: %s\n", + errno, encoding_.c_str(), ucs4_codeset, + strerror(errno)); + fputs("Converted input:", stderr); + for (extern_type const * i = from; i < from_next; ++i) { + // extern_type may be signed, avoid output of + // something like 0xffffffc2 + unsigned int const c = + *reinterpret_cast(i); + fprintf(stderr, " 0x%02x", c); + } + unsigned int const c = + *reinterpret_cast(from_next); + fprintf(stderr, "\nStopped at: 0x%02x\n", c); + fputs("Unconverted input:", stderr); + for (extern_type const * i = from_next + 1; i < from_end; ++i) { + unsigned int const c = + *reinterpret_cast(i); + fprintf(stderr, " 0x%02x", c); + } + fputs("\nConverted output:", stderr); + for (intern_type const * i = to; i < to_next; ++i) { + unsigned int const c = *i; + fprintf(stderr, " 0x%02x", c); + } + fputc('\n', stderr); + fflush(stderr); + } + return retval; } virtual int do_encoding() const throw() { @@ -151,7 +212,7 @@ protected: // RFC 3629. // All other encodings encode one UCS4 code point in one byte // (and can therefore only encode a subset of UCS4) - return utf8_ ? 4 : 1; + return encoding_ == "UTF-8" ? 4 : 1; } private: /// Do the actual conversion. The interface is equivalent to that of @@ -159,7 +220,7 @@ private: inline base::result do_iconv(iconv_t cd, char const ** from, size_t * inbytesleft, char ** to, size_t * outbytesleft) const { - char const * to_start = *to; + char const * const to_start = *to; size_t converted = iconv(cd, const_cast(from), inbytesleft, to, outbytesleft); if (converted == (size_t)(-1)) { @@ -169,9 +230,6 @@ private: return base::partial; case EILSEQ: default: - fprintf(stderr, "Error %d returned from iconv: %s\n", - errno, strerror(errno)); - fflush(stderr); return base::error; } } @@ -181,8 +239,8 @@ private: } iconv_t in_cd_; iconv_t out_cd_; - /// Is the narrow encoding UTF8? - bool utf8_; + /// The narrow encoding + std::string encoding_; }; } // namespace anon -- 2.39.5