ruby-changes:25019
From: nobu <ko1@a...>
Date: Wed, 3 Oct 2012 11:43:34 +0900 (JST)
Subject: [ruby-changes:25019] nobu:r37071 (trunk): io.c: improved IO#reopen
nobu 2012-10-03 11:43:19 +0900 (Wed, 03 Oct 2012) New Revision: 37071 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37071 Log: io.c: improved IO#reopen * io.c (rb_io_reopen): improvement to accept optional arguments. a patch by Glass_saga (Masaki Matsushita) in [ruby-core:47806]. [Feature #7103] Modified files: trunk/ChangeLog trunk/io.c trunk/test/ruby/test_io.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 37070) +++ ChangeLog (revision 37071) @@ -1,3 +1,9 @@ +Wed Oct 3 11:43:15 2012 Nobuyoshi Nakada <nobu@r...> + + * io.c (rb_io_reopen): improvement to accept optional arguments. + a patch by Glass_saga (Masaki Matsushita) in [ruby-core:47806]. + [Feature #7103] + Wed Oct 3 04:36:11 2012 Eric Hodel <drbrain@s...> * ext/openssl/ossl_x509store.c (ossl_x509store_add_file): Added Index: io.c =================================================================== --- io.c (revision 37070) +++ io.c (revision 37071) @@ -4792,23 +4792,6 @@ rb_io_ext_int_to_encs(ext_enc, int_enc, enc_p, enc2_p); } -static void -mode_enc(rb_io_t *fptr, const char *estr) -{ - clear_codeconv(fptr); - - parse_mode_enc(estr, &fptr->encs.enc, &fptr->encs.enc2, NULL); -} - -static void -rb_io_mode_enc(rb_io_t *fptr, const char *modestr) -{ - const char *p = strchr(modestr, ':'); - if (p) { - mode_enc(fptr, p+1); - } -} - int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p) { @@ -6344,12 +6327,12 @@ static VALUE rb_io_reopen(int argc, VALUE *argv, VALUE file) { - VALUE fname, nmode; + VALUE fname, nmode, opt; int oflags; rb_io_t *fptr; rb_secure(4); - if (rb_scan_args(argc, argv, "11", &fname, &nmode) == 1) { + if (rb_scan_args(argc, argv, "11:", &fname, &nmode, &opt) == 1) { VALUE tmp = rb_io_check_io(fname); if (!NIL_P(tmp)) { return io_reopen(file, tmp); @@ -6364,18 +6347,11 @@ MEMZERO(fptr, rb_io_t, 1); } - if (!NIL_P(nmode)) { - VALUE intmode = rb_check_to_int(nmode); + if (!NIL_P(nmode) || !NIL_P(opt)) { int fmode; + convconfig_t convconfig; - if (!NIL_P(intmode)) { - oflags = NUM2INT(intmode); - fmode = rb_io_oflags_fmode(oflags); - } - else { - fmode = rb_io_modestr_fmode(StringValueCStr(nmode)); - } - + rb_io_extract_modeenc(&nmode, 0, opt, &oflags, &fmode, &convconfig); if (IS_PREP_STDIO(fptr) && ((fptr->mode & FMODE_READWRITE) & (fmode & FMODE_READWRITE)) != (fptr->mode & FMODE_READWRITE)) { @@ -6385,15 +6361,13 @@ rb_io_fmode_modestr(fmode)); } fptr->mode = fmode; - if (NIL_P(intmode)) { - rb_io_mode_enc(fptr, StringValueCStr(nmode)); - } - fptr->encs.ecflags = 0; - fptr->encs.ecopts = Qnil; + fptr->encs = convconfig; } + else { + oflags = rb_io_fmode_oflags(fptr->mode); + } fptr->pathv = rb_str_new_frozen(fname); - oflags = rb_io_fmode_oflags(fptr->mode); if (fptr->fd < 0) { fptr->fd = rb_sysopen(fptr->pathv, oflags, 0666); fptr->stdio_file = 0; Index: test/ruby/test_io.rb =================================================================== --- test/ruby/test_io.rb (revision 37070) +++ test/ruby/test_io.rb (revision 37071) @@ -1732,6 +1732,74 @@ } end + def test_reopen_opt + feature7103 = '[ruby-core:47806]' + make_tempfile {|t| + open(__FILE__) do |f| + assert_nothing_raised(feature7103) { + f.reopen(t.path, "r", binmode: true) + } + assert_equal("foo\n", f.gets) + end + + open(__FILE__) do |f| + assert_nothing_raised(feature7103) { + f.reopen(t.path, autoclose: false) + } + assert_equal("foo\n", f.gets) + end + } + end + + def make_tempfile_for_encoding + t = make_tempfile + open(t.path, "rb+:utf-8") {|f| f.puts "\u7d05\u7389bar\n"} + if block_given? + yield t + else + t + end + ensure + t.close(true) if t and block_given? + end + + def test_reopen_encoding + make_tempfile_for_encoding {|t| + open(__FILE__) {|f| + f.reopen(t.path, "r:utf-8") + s = f.gets + assert_equal(Encoding::UTF_8, s.encoding) + assert_equal("\u7d05\u7389bar\n", s) + } + + open(__FILE__) {|f| + f.reopen(t.path, "r:UTF-8:EUC-JP") + s = f.gets + assert_equal(Encoding::EUC_JP, s.encoding) + assert_equal("\xB9\xC8\xB6\xCCbar\n".force_encoding(Encoding::EUC_JP), s) + } + } + end + + def test_reopen_opt_encoding + feature7103 = '[ruby-core:47806]' + make_tempfile_for_encoding {|t| + open(__FILE__) {|f| + assert_nothing_raised(feature7103) {f.reopen(t.path, encoding: "ASCII-8BIT")} + s = f.gets + assert_equal(Encoding::ASCII_8BIT, s.encoding) + assert_equal("\xe7\xb4\x85\xe7\x8e\x89bar\n", s) + } + + open(__FILE__) {|f| + assert_nothing_raised(feature7103) {f.reopen(t.path, encoding: "UTF-8:EUC-JP")} + s = f.gets + assert_equal(Encoding::EUC_JP, s.encoding) + assert_equal("\xB9\xC8\xB6\xCCbar\n".force_encoding(Encoding::EUC_JP), s) + } + } + end + def test_foreach a = [] IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/