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
This commit is contained in:
Georg Baum 2007-01-02 20:57:34 +00:00
parent bcbd895143
commit 9c162a9bc6

View File

@ -41,7 +41,7 @@ public:
explicit iconv_codecvt_facet(string const & encoding = "UTF-8", explicit iconv_codecvt_facet(string const & encoding = "UTF-8",
std::ios_base::openmode inout = std::ios_base::in | std::ios_base::out, std::ios_base::openmode inout = std::ios_base::in | std::ios_base::out,
size_t refs = 0) size_t refs = 0)
: base(refs), utf8_(encoding == "UTF-8") : base(refs), encoding_(encoding)
{ {
if (inout & std::ios_base::in) { if (inout & std::ios_base::in) {
in_cd_ = iconv_open(ucs4_codeset, encoding.c_str()); in_cd_ = iconv_open(ucs4_codeset, encoding.c_str());
@ -89,8 +89,38 @@ protected:
size_t outbytesleft = (to_end - to) * sizeof(extern_type); size_t outbytesleft = (to_end - to) * sizeof(extern_type);
from_next = from; from_next = from;
to_next = to; to_next = to;
return do_iconv(out_cd_, reinterpret_cast<char const **>(&from_next), result const retval = do_iconv(out_cd_,
reinterpret_cast<char const **>(&from_next),
&inbytesleft, &to_next, &outbytesleft); &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<unsigned char const *>(i);
fprintf(stderr, " 0x%02x", c);
}
fputc('\n', stderr);
fflush(stderr);
}
return retval;
} }
virtual result do_unshift(state_type &, extern_type * to, virtual result do_unshift(state_type &, extern_type * to,
extern_type *, extern_type *& to_next) const extern_type *, extern_type *& to_next) const
@ -109,9 +139,40 @@ protected:
size_t outbytesleft = (to_end - to) * sizeof(intern_type); size_t outbytesleft = (to_end - to) * sizeof(intern_type);
from_next = from; from_next = from;
to_next = to; to_next = to;
return do_iconv(in_cd_, &from_next, &inbytesleft, result const retval = do_iconv(in_cd_, &from_next, &inbytesleft,
reinterpret_cast<char **>(&to_next), reinterpret_cast<char **>(&to_next),
&outbytesleft); &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<unsigned char const *>(i);
fprintf(stderr, " 0x%02x", c);
}
unsigned int const c =
*reinterpret_cast<unsigned char const *>(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<unsigned char const *>(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() virtual int do_encoding() const throw()
{ {
@ -151,7 +212,7 @@ protected:
// RFC 3629. // RFC 3629.
// All other encodings encode one UCS4 code point in one byte // All other encodings encode one UCS4 code point in one byte
// (and can therefore only encode a subset of UCS4) // (and can therefore only encode a subset of UCS4)
return utf8_ ? 4 : 1; return encoding_ == "UTF-8" ? 4 : 1;
} }
private: private:
/// Do the actual conversion. The interface is equivalent to that of /// 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, inline base::result do_iconv(iconv_t cd, char const ** from,
size_t * inbytesleft, char ** to, size_t * outbytesleft) const 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<char ICONV_CONST **>(from), size_t converted = iconv(cd, const_cast<char ICONV_CONST **>(from),
inbytesleft, to, outbytesleft); inbytesleft, to, outbytesleft);
if (converted == (size_t)(-1)) { if (converted == (size_t)(-1)) {
@ -169,9 +230,6 @@ private:
return base::partial; return base::partial;
case EILSEQ: case EILSEQ:
default: default:
fprintf(stderr, "Error %d returned from iconv: %s\n",
errno, strerror(errno));
fflush(stderr);
return base::error; return base::error;
} }
} }
@ -181,8 +239,8 @@ private:
} }
iconv_t in_cd_; iconv_t in_cd_;
iconv_t out_cd_; iconv_t out_cd_;
/// Is the narrow encoding UTF8? /// The narrow encoding
bool utf8_; std::string encoding_;
}; };
} // namespace anon } // namespace anon