[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]