summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-24 09:40:31 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-24 09:40:31 +0000
commitfb2e6dbe840ba348461292f41a33303952790c2c (patch)
tree765e064f24cabc75e34e456e8d4f443fd1dff9b1
parentffff30fc87f019bec2e2cd37312508e95918d9a8 (diff)
downloadruby-fb2e6dbe840ba348461292f41a33303952790c2c.tar.gz
ruby-fb2e6dbe840ba348461292f41a33303952790c2c.tar.xz
ruby-fb2e6dbe840ba348461292f41a33303952790c2c.zip
* io.c (rb_io_s_pipe): accept optional hash.
(rb_io_set_encoding): ditto. (rb_io_extract_modeenc): use rb_econv_opts to initialize ecopts. (rb_file_open_generic): ditto. (rb_file_open_internal): ditto. (io_encoding_set): new argument: opt. (argf_set_encoding): copy fptr->encs.opts to argf_ecopts. * transcode.c (rb_econv_opts): accept Qnil for initialization. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@18817 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog13
-rw-r--r--io.c26
-rw-r--r--test/ruby/test_io_m17n.rb38
-rw-r--r--transcode.c5
4 files changed, 70 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index de7356fab..9167854e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Sun Aug 24 18:37:42 2008 Tanaka Akira <akr@fsij.org>
+
+ * io.c (rb_io_s_pipe): accept optional hash.
+ (rb_io_set_encoding): ditto.
+ (rb_io_extract_modeenc): use rb_econv_opts to initialize
+ ecopts.
+ (rb_file_open_generic): ditto.
+ (rb_file_open_internal): ditto.
+ (io_encoding_set): new argument: opt.
+ (argf_set_encoding): copy fptr->encs.opts to argf_ecopts.
+
+ * transcode.c (rb_econv_opts): accept Qnil for initialization.
+
Sun Aug 24 18:10:08 2008 Tanaka Akira <akr@fsij.org>
* include/ruby/io.h (rb_io_enc_t): add opts field.
diff --git a/io.c b/io.c
index 2fafce363..9319e2934 100644
--- a/io.c
+++ b/io.c
@@ -3876,7 +3876,7 @@ rb_io_extract_modeenc(VALUE *mode_p, VALUE opthash,
}
if (NIL_P(opthash)) {
- ecopts.flags = 0;
+ rb_econv_opts(Qnil, &ecopts);
}
else {
VALUE v;
@@ -4016,7 +4016,7 @@ rb_file_open_generic(VALUE io, VALUE filename, int modenum, int flags, convconfi
else {
fptr->encs.enc = NULL;
fptr->encs.enc2 = NULL;
- fptr->encs.opts.flags = 0;
+ rb_econv_opts(Qnil, &fptr->encs.opts);
}
fptr->pathv = rb_str_new_frozen(filename);
fptr->fd = rb_sysopen(RSTRING_PTR(fptr->pathv), modenum, perm);
@@ -4038,7 +4038,7 @@ rb_file_open_internal(VALUE io, VALUE filename, const char *mode)
else {
convconfig.enc = NULL;
convconfig.enc2 = NULL;
- convconfig.opts.flags = 0;
+ rb_econv_opts(Qnil, &convconfig.opts);
}
flags = rb_io_mode_flags(mode);
@@ -6627,31 +6627,32 @@ io_new_instance(VALUE args)
}
static void
-io_encoding_set(rb_io_t *fptr, int argc, VALUE v1, VALUE v2)
+io_encoding_set(rb_io_t *fptr, int argc, VALUE v1, VALUE v2, VALUE opt)
{
if (NIL_P(v2)) argc = 1;
if (argc == 2) {
fptr->encs.enc2 = rb_to_encoding(v1);
fptr->encs.enc = rb_to_encoding(v2);
- fptr->encs.opts.flags = 0; /* xxx */
+ rb_econv_opts(opt, &fptr->encs.opts);
clear_codeconv(fptr);
}
else if (argc == 1) {
if (NIL_P(v1)) {
fptr->encs.enc = NULL;
fptr->encs.enc2 = NULL;
- fptr->encs.opts.flags = 0;
+ rb_econv_opts(Qnil, &fptr->encs.opts);
clear_codeconv(fptr);
}
else {
VALUE tmp = rb_check_string_type(v1);
if (!NIL_P(tmp)) {
mode_enc(fptr, StringValueCStr(tmp));
+ rb_econv_opts(opt, &fptr->encs.opts);
}
else {
fptr->encs.enc = rb_to_encoding(v1);
fptr->encs.enc2 = NULL;
- fptr->encs.opts.flags = 0;
+ rb_econv_opts(Qnil, &fptr->encs.opts);
clear_codeconv(fptr);
}
}
@@ -6716,8 +6717,10 @@ rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
#else
int pipes[2], state;
VALUE r, w, args[3], v1, v2;
+ VALUE opt;
rb_io_t *fptr;
+ opt = pop_last_hash(&argc, &argv);
rb_scan_args(argc, argv, "02", &v1, &v2);
if (rb_pipe(pipes) == -1)
rb_sys_fail(0);
@@ -6732,7 +6735,7 @@ rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
rb_jump_tag(state);
}
GetOpenFile(r, fptr);
- io_encoding_set(fptr, argc, v1, v2);
+ io_encoding_set(fptr, argc, v1, v2, opt);
args[1] = INT2NUM(pipes[1]);
args[2] = INT2FIX(O_WRONLY);
w = rb_protect(io_new_instance, (VALUE)args, &state);
@@ -7531,11 +7534,12 @@ static VALUE
rb_io_set_encoding(int argc, VALUE *argv, VALUE io)
{
rb_io_t *fptr;
- VALUE v1, v2;
+ VALUE v1, v2, opt;
+ opt = pop_last_hash(&argc, &argv);
rb_scan_args(argc, argv, "11", &v1, &v2);
GetOpenFile(io, fptr);
- io_encoding_set(fptr, argc, v1, v2);
+ io_encoding_set(fptr, argc, v1, v2, opt);
return io;
}
@@ -7569,7 +7573,7 @@ argf_set_encoding(int argc, VALUE *argv, VALUE argf)
GetOpenFile(current_file, fptr);
argf_enc = fptr->encs.enc;
argf_enc2 = fptr->encs.enc2;
- argf_ecopts.flags = 0; /* xxx */
+ argf_ecopts = fptr->encs.opts;
return argf;
}
diff --git a/test/ruby/test_io_m17n.rb b/test/ruby/test_io_m17n.rb
index 93b6de034..c2254545f 100644
--- a/test/ruby/test_io_m17n.rb
+++ b/test/ruby/test_io_m17n.rb
@@ -219,6 +219,26 @@ EOT
}
end
+ def test_s_pipe_invalid
+ r, w = IO.pipe("utf-8", "euc-jp", :invalid=>:replace)
+ w << "\x80"
+ w.close
+ assert_equal("?", r.read)
+ ensure
+ r.close if r && !r.closed?
+ w.close if w && !w.closed?
+ end
+
+ def test_s_pipe_undef
+ r, w = IO.pipe("utf-8:euc-jp", :undef=>:replace)
+ w << "\ufffd"
+ w.close
+ assert_equal("?", r.read)
+ ensure
+ r.close if r && !r.closed?
+ w.close if w && !w.closed?
+ end
+
def test_stdin
assert_equal(Encoding.default_external, STDIN.external_encoding)
assert_equal(nil, STDIN.internal_encoding)
@@ -716,6 +736,24 @@ EOT
}
end
+ def test_set_encoding_invalid
+ with_pipe {|r, w|
+ w << "\x80"
+ w.close
+ r.set_encoding("utf-8:euc-jp", :invalid=>:replace)
+ assert_equal("?", r.read)
+ }
+ end
+
+ def test_set_encoding_undef
+ with_pipe {|r, w|
+ w << "\ufffd"
+ w.close
+ r.set_encoding("utf-8", "euc-jp", :undef=>:replace)
+ assert_equal("?", r.read)
+ }
+ end
+
def test_write_conversion_fixenc
with_pipe {|r, w|
w.set_encoding("iso-2022-jp:utf-8")
diff --git a/transcode.c b/transcode.c
index 34a61c336..15755a07c 100644
--- a/transcode.c
+++ b/transcode.c
@@ -1709,7 +1709,10 @@ econv_opts(VALUE opt)
void
rb_econv_opts(VALUE hash, rb_econv_option_t *opts)
{
- opts->flags = econv_opts(hash);
+ if (NIL_P(hash))
+ opts->flags = 0;
+ else
+ opts->flags = econv_opts(hash);
}
static int