From 8f9ed3c464fea371855792758b9e9d31ba99c0ec Mon Sep 17 00:00:00 2001 From: akr Date: Sun, 24 Aug 2008 02:42:37 +0000 Subject: * include/ruby/encoding.h (rb_econv_open_exc): declared. * transcode.c (rb_eNoConverter): new exception. (rb_econv_open_exc): new function. (transcode_loop): use rb_econv_open_exc. * io.c (make_writeconv): use rb_econv_open_exc. (make_readconv): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18803 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 11 +++++++++ include/ruby/encoding.h | 2 ++ io.c | 6 +++-- test/ruby/test_econv.rb | 2 +- test/ruby/test_transcode.rb | 8 +++--- transcode.c | 59 ++++++++++++++++++++++++++++++++++++++++----- 6 files changed, 75 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index a9411f6256..4605df1c1a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Sun Aug 24 11:40:38 2008 Tanaka Akira + + * include/ruby/encoding.h (rb_econv_open_exc): declared. + + * transcode.c (rb_eNoConverter): new exception. + (rb_econv_open_exc): new function. + (transcode_loop): use rb_econv_open_exc. + + * io.c (make_writeconv): use rb_econv_open_exc. + (make_readconv): ditto. + Sun Aug 24 11:26:54 2008 NARUSE, Yui * lib/cgi.rb (CGI::unescapeHTML): consider ISO-8859-1. diff --git a/include/ruby/encoding.h b/include/ruby/encoding.h index 1f0feae98e..748c8cff53 100644 --- a/include/ruby/encoding.h +++ b/include/ruby/encoding.h @@ -256,6 +256,8 @@ rb_econv_result_t rb_econv_convert(rb_econv_t *ec, int flags); void rb_econv_close(rb_econv_t *ec); +VALUE rb_econv_open_exc(const char *senc, const char *denc, int flags); + /* result: 0:success -1:failure */ int rb_econv_insert_output(rb_econv_t *ec, const unsigned char *str, size_t len, const char *str_encoding); diff --git a/io.c b/io.c index f1fbd6ec7c..15eaba9d93 100644 --- a/io.c +++ b/io.c @@ -705,6 +705,8 @@ make_writeconv(rb_io_t *fptr) if (!fptr->enc) { fptr->writeconv = rb_econv_open("", "", ecflags); + if (!fptr->writeconv) + rb_exc_raise(rb_econv_open_exc("", "", ecflags)); fptr->writeconv_stateless = Qnil; return; } @@ -723,7 +725,7 @@ make_writeconv(rb_io_t *fptr) if (senc) { fptr->writeconv = rb_econv_open(senc, denc, ecflags); if (!fptr->writeconv) - rb_raise(rb_eIOError, "code converter open failed (%s to %s)", senc, denc); + rb_exc_raise(rb_econv_open_exc(senc, denc, ecflags)); } else { fptr->writeconv = NULL; @@ -1447,7 +1449,7 @@ make_readconv(rb_io_t *fptr) } fptr->readconv = rb_econv_open(sname, dname, ecflags); if (!fptr->readconv) - rb_raise(rb_eIOError, "code converter open failed (%s to %s)", sname, dname); + rb_exc_raise(rb_econv_open_exc(sname, dname, ecflags)); fptr->crbuf_off = 0; fptr->crbuf_len = 0; fptr->crbuf_capa = 1024; diff --git a/test/ruby/test_econv.rb b/test/ruby/test_econv.rb index 025887f1c6..5ba6b7c447 100644 --- a/test/ruby/test_econv.rb +++ b/test/ruby/test_econv.rb @@ -37,7 +37,7 @@ class TestEncodingConverter < Test::Unit::TestCase name1 = "encoding-which-is-not-exist-1" name2 = "encoding-which-is-not-exist-2" - assert_raise(ArgumentError) { + assert_raise(Encoding::NoConverter) { Encoding::Converter.new(name1, name2) } diff --git a/test/ruby/test_transcode.rb b/test/ruby/test_transcode.rb index b88b4d561d..fd673a96c0 100644 --- a/test/ruby/test_transcode.rb +++ b/test/ruby/test_transcode.rb @@ -21,10 +21,10 @@ class TestTranscode < Test::Unit::TestCase def test_errors assert_raise(ArgumentError) { 'abc'.encode } assert_raise(ArgumentError) { 'abc'.encode! } - assert_raise(ArgumentError) { 'abc'.encode('foo', 'bar') } - assert_raise(ArgumentError) { 'abc'.encode!('foo', 'bar') } - assert_raise(ArgumentError) { 'abc'.force_encoding('utf-8').encode('foo') } - assert_raise(ArgumentError) { 'abc'.force_encoding('utf-8').encode!('foo') } + assert_raise(Encoding::NoConverter) { 'abc'.encode('foo', 'bar') } + assert_raise(Encoding::NoConverter) { 'abc'.encode!('foo', 'bar') } + assert_raise(Encoding::NoConverter) { 'abc'.force_encoding('utf-8').encode('foo') } + assert_raise(Encoding::NoConverter) { 'abc'.force_encoding('utf-8').encode!('foo') } assert_raise(Encoding::ConversionUndefined) { "\x80".encode('utf-8','ASCII-8BIT') } assert_raise(Encoding::InvalidByteSequence) { "\x80".encode('utf-8','US-ASCII') } assert_raise(Encoding::ConversionUndefined) { "\xA5".encode('utf-8','iso-8859-3') } diff --git a/transcode.c b/transcode.c index 61843cfe9e..ce3455df0f 100644 --- a/transcode.c +++ b/transcode.c @@ -17,6 +17,7 @@ VALUE rb_eConversionUndefined; VALUE rb_eInvalidByteSequence; +VALUE rb_eNoConverter; VALUE rb_cEncodingConverter; @@ -1388,6 +1389,47 @@ rb_econv_binmode(rb_econv_t *ec) } } +VALUE +rb_econv_open_exc(const char *senc, const char *denc, int flags) +{ + VALUE mesg, exc; + int noenc = 0; + mesg = rb_str_new_cstr("code converter open failed ("); + if (*senc == '\0' || *denc == '\0') { + if (*senc != '\0') + rb_str_cat2(mesg, senc); + else if (*denc != '\0') + rb_str_cat2(mesg, denc); + else + noenc = 1; + } + else { + rb_str_catf(mesg, "%s to %s", senc, denc); + } + if (flags & (ECONV_UNIVERSAL_NEWLINE_DECODER| + ECONV_CRLF_NEWLINE_ENCODER| + ECONV_CR_NEWLINE_ENCODER)) { + char *pre = ""; + if (!noenc) + rb_str_cat2(mesg, " with "); + if (flags & ECONV_UNIVERSAL_NEWLINE_DECODER) { + rb_str_cat2(mesg, pre); pre = ","; + rb_str_cat2(mesg, "Universal-newline"); + } + if (flags & ECONV_CRLF_NEWLINE_ENCODER) { + rb_str_cat2(mesg, pre); pre = ","; + rb_str_cat2(mesg, "CRLF-newline"); + } + if (flags & ECONV_CR_NEWLINE_ENCODER) { + rb_str_cat2(mesg, pre); pre = ","; + rb_str_cat2(mesg, "CR-newline"); + } + } + rb_str_cat2(mesg, ")"); + exc = rb_exc_new3(rb_eNoConverter, mesg); + return exc; +} + static VALUE make_econv_exception(rb_econv_t *ec) { @@ -1491,10 +1533,12 @@ transcode_loop(const unsigned char **in_pos, unsigned char **out_pos, unsigned char *out_start = *out_pos; int max_output; VALUE exc; + int ecflags; - ec = rb_econv_open(from_encoding, to_encoding, opt & (ECONV_INVALID_MASK|ECONV_UNDEF_MASK)); + ecflags = opt & (ECONV_INVALID_MASK|ECONV_UNDEF_MASK); + ec = rb_econv_open(from_encoding, to_encoding, ecflags); if (!ec) - rb_raise(rb_eArgError, "transcoding not supported (from %s to %s)", from_encoding, to_encoding); + rb_exc_raise(rb_econv_open_exc(from_encoding, to_encoding, ecflags)); last_tc = ec->last_tc; max_output = last_tc ? last_tc->transcoder->max_output : 1; @@ -1539,10 +1583,12 @@ transcode_loop(const unsigned char **in_pos, unsigned char **out_pos, const unsigned char *ptr; int max_output; VALUE exc; + int ecflags; - ec = rb_econv_open(from_encoding, to_encoding, opt & (ECONV_INVALID_MASK|ECONV_UNDEF_MASK)); + ecflags = opt & (ECONV_INVALID_MASK|ECONV_UNDEF_MASK); + ec = rb_econv_open(from_encoding, to_encoding, ecflags); if (!ec) - rb_raise(rb_eArgError, "transcoding not supported (from %s to %s)", from_encoding, to_encoding); + rb_exc_raise(rb_econv_open_exc(from_encoding, to_encoding, ecflags)); last_tc = ec->last_tc; max_output = last_tc ? last_tc->transcoder->max_output : 1; @@ -1883,7 +1929,7 @@ econv_init(int argc, VALUE *argv, VALUE self) ec = rb_econv_open(sname, dname, flags); if (!ec) { - rb_raise(rb_eArgError, "encoding convewrter not supported (from %s to %s)", sname, dname); + rb_exc_raise(rb_econv_open_exc(sname, dname, flags)); } if (*sname && *dname) { /* check "" to "universal_newline" */ @@ -2242,9 +2288,9 @@ econv_primitive_insert_output(VALUE self, VALUE string) string = rb_str_transcode(string, rb_enc_from_encoding(rb_enc_find(insert_enc))); ret = rb_econv_insert_output(ec, (const unsigned char *)RSTRING_PTR(string), RSTRING_LEN(string), insert_enc); - if (ret == -1) return Qfalse; + return Qtrue; } @@ -2311,6 +2357,7 @@ Init_transcode(void) { rb_eConversionUndefined = rb_define_class_under(rb_cEncoding, "ConversionUndefined", rb_eStandardError); rb_eInvalidByteSequence = rb_define_class_under(rb_cEncoding, "InvalidByteSequence", rb_eStandardError); + rb_eNoConverter = rb_define_class_under(rb_cEncoding, "NoConverter", rb_eStandardError); transcoder_table = st_init_strcasetable(); -- cgit v1.2.3