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

ruby-changes:8467

From: usa <ko1@a...>
Date: Tue, 28 Oct 2008 21:18:13 +0900 (JST)
Subject: [ruby-changes:8467] Ruby:r19999 (ruby_1_9_1): merge from trunk (r19984, r19985, r19991-r19998)

usa	2008-10-28 21:17:54 +0900 (Tue, 28 Oct 2008)

  New Revision: 19999

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=19999

  Log:
    merge from trunk (r19984, r19985, r19991-r19998)
    * io.c (extract_binmode): new function to extract binmode/textmode
      options from hash.
    
    * io.c (rb_io_extract_modeenc): use above function.
    
    * io.c (rb_io_s_pipe): recognize binmode/textmode options.
    
    * io.c (make_readconv): now can specify the size of cbuf.
    
    * io.c (read_all, appendline, io_getc, rb_io_ungetc): follow above
      change.
    
    * win32/win32.c (rb_w32_pipe_exec): internal fds should be always
      binmode.
    
    * test/ruby/test_file.rb (test_each_char_extended_file,
      test_getbyte_extended_file): add tests.
    
    * test/ruby/test_file.rb (test_*_extended_file): test in default/text/
      binary mode.
    
    * test/ruby/test_file.rb (test_para_gets_extended_file): output file
      should be binmode.
    
    * test/ruby/test_io.rb (test_copy_stream, test_copy_stream_socket): skip
      some tests if there isn't IO#nonblock=.
    
    * test/ruby/test_io.rb (test_close_on_exec): skip if there isn't
      IO#close_on_exec=.
    
    * test/ruby/test_io.rb (test_bytes, test_readbyte): depend on binmode.
    
    * test/ruby/test_io.rb (test_sysopen): should specify the mode of
      IO::for_fd if F_GETFL is not available.
    
    * test/ruby/test_io_m17n.rb (test_getc_invalid3): should set binmode if 
      enc is not compatible with ASCII.
    
    * test/ruby/test_require.rb (test_require_too_long_filename): too long
      commandline may be rejected by OS.

  Modified files:
    branches/ruby_1_9_1/ChangeLog
    branches/ruby_1_9_1/io.c
    branches/ruby_1_9_1/test/ruby/test_file.rb
    branches/ruby_1_9_1/test/ruby/test_io.rb
    branches/ruby_1_9_1/test/ruby/test_io_m17n.rb
    branches/ruby_1_9_1/test/ruby/test_require.rb
    branches/ruby_1_9_1/win32/win32.c

Index: ruby_1_9_1/ChangeLog
===================================================================
--- ruby_1_9_1/ChangeLog	(revision 19998)
+++ ruby_1_9_1/ChangeLog	(revision 19999)
@@ -1,3 +1,20 @@
+Tue Oct 28 21:11:58 2008  NAKAMURA Usaku  <usa@r...>
+
+	* io.c (extract_binmode): new function to extract binmode/textmode
+	  options from hash.
+
+	* io.c (rb_io_extract_modeenc): use above function.
+
+	* io.c (rb_io_s_pipe): recognize binmode/textmode options.
+
+	* io.c (make_readconv): now can specify the size of cbuf.
+
+	* io.c (read_all, appendline, io_getc, rb_io_ungetc): follow above
+	  change.
+
+	* win32/win32.c (rb_w32_pipe_exec): internal fds should be always
+	  binmode.
+
 Tue Oct 28 17:22:35 2008  Yuki Sonoda (Yugui)  <yugui@y...>
 
 	* tool/make-snapshot.rb: merged back from trunk.
Index: ruby_1_9_1/io.c
===================================================================
--- ruby_1_9_1/io.c	(revision 19998)
+++ ruby_1_9_1/io.c	(revision 19999)
@@ -1430,7 +1430,7 @@
 }
 
 static void
-make_readconv(rb_io_t *fptr)
+make_readconv(rb_io_t *fptr, int size)
 {
     if (!fptr->readconv) {
         int ecflags;
@@ -1452,7 +1452,7 @@
             rb_exc_raise(rb_econv_open_exc(sname, dname, ecflags));
         fptr->cbuf_off = 0;
         fptr->cbuf_len = 0;
-        fptr->cbuf_capa = 1024;
+        fptr->cbuf_capa = size < 1024 ? 1024 : size;
         fptr->cbuf = ALLOC_N(char, fptr->cbuf_capa);
     }
 }
@@ -1558,7 +1558,7 @@
     if (NEED_READCONV(fptr)) {
         if (NIL_P(str)) str = rb_str_new(NULL, 0);
         else rb_str_set_len(str, 0);
-        make_readconv(fptr);
+        make_readconv(fptr, 0);
         while (1) {
             if (fptr->cbuf_len) {
                 io_shift_cbuf(fptr, fptr->cbuf_len, &str);
@@ -1940,7 +1940,7 @@
     long limit = *lp;
 
     if (NEED_READCONV(fptr)) {
-        make_readconv(fptr);
+        make_readconv(fptr, 0);
         while (1) {
             const char *p, *e;
             int searchlen;
@@ -2473,7 +2473,7 @@
     if (NEED_READCONV(fptr)) {
         VALUE str = Qnil;
 
-        make_readconv(fptr);
+        make_readconv(fptr, 0);
 
         while (1) {
             if (fptr->cbuf_len) {
@@ -2825,8 +2825,8 @@
 	SafeStringValue(c);
     }
     if (NEED_READCONV(fptr)) {
-        make_readconv(fptr);
         len = RSTRING_LEN(c);
+        make_readconv(fptr, len);
         if (fptr->cbuf_capa - fptr->cbuf_len < len)
             rb_raise(rb_eIOError, "ungetc failed");
         if (fptr->cbuf_off < len) {
@@ -3923,6 +3923,23 @@
 }
 
 static void
+extract_binmode(VALUE opthash, int *fmode)
+{
+    if (!NIL_P(opthash)) {
+	VALUE v;
+	v = rb_hash_aref(opthash, sym_textmode);
+	if (!NIL_P(v) && RTEST(v))
+            *fmode |= FMODE_TEXTMODE;
+	v = rb_hash_aref(opthash, sym_binmode);
+	if (!NIL_P(v) && RTEST(v))
+            *fmode |= FMODE_BINMODE;
+
+	if ((*fmode & FMODE_BINMODE) && (*fmode & FMODE_TEXTMODE))
+	    rb_raise(rb_eArgError, "both textmode and binmode specified");
+    }
+}
+
+static void
 rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
         int *oflags_p, int *fmode_p, convconfig_t *convconfig_p)
 {
@@ -3975,16 +3992,11 @@
     }
     else {
 	VALUE v;
-	v = rb_hash_aref(opthash, sym_textmode);
-	if (!NIL_P(v) && RTEST(v))
-            fmode |= FMODE_TEXTMODE;
-	v = rb_hash_aref(opthash, sym_binmode);
-	if (!NIL_P(v) && RTEST(v)) {
-            fmode |= FMODE_BINMODE;
+	extract_binmode(opthash, &fmode);
 #ifdef O_BINARY
+	if (fmode & FMODE_BINMODE)
             oflags |= O_BINARY;
 #endif
-        }
 	if (!has_vmode) {
 	    v = rb_hash_aref(opthash, sym_mode);
 	    if (!NIL_P(v)) {
@@ -4017,9 +4029,6 @@
         }
     }
 
-    if ((fmode & FMODE_BINMODE) && (fmode & FMODE_TEXTMODE))
-        rb_raise(rb_eArgError, "both textmode and binmode specified");
-
     validate_enc_binmode(fmode, enc, enc2);
 
     *vmode_p = vmode;
@@ -6825,7 +6834,8 @@
     int pipes[2], state;
     VALUE r, w, args[3], v1, v2;
     VALUE opt;
-    rb_io_t *fptr;
+    rb_io_t *fptr, *fptr2;
+    int fmode = 0;
 
     opt = pop_last_hash(&argc, argv);
     rb_scan_args(argc, argv, "02", &v1, &v2);
@@ -6851,8 +6861,13 @@
 	if (!NIL_P(r)) rb_io_close(r);
 	rb_jump_tag(state);
     }
-    rb_io_synchronized(RFILE(w)->fptr);
+    GetOpenFile(w, fptr2);
+    rb_io_synchronized(fptr2);
 
+    extract_binmode(opt, &fmode);
+    fptr->mode |= fmode;
+    fptr2->mode |= fmode;
+
     return rb_assoc_new(r, w);
 }
 
Index: ruby_1_9_1/win32/win32.c
===================================================================
--- ruby_1_9_1/win32/win32.c	(revision 19998)
+++ ruby_1_9_1/win32/win32.c	(revision 19999)
@@ -764,9 +764,8 @@
 	reading = TRUE;
 	writing = FALSE;
     }
-    mode &= ~(O_RDWR|O_RDONLY|O_WRONLY);
-    if (!(mode & O_BINARY))
-	mode |= O_TEXT;
+    mode &= ~(O_RDWR|O_RDONLY|O_WRONLY|O_TEXT);
+    mode |= O_BINARY;
 
     sa.nLength              = sizeof (SECURITY_ATTRIBUTES);
     sa.lpSecurityDescriptor = NULL;
Index: ruby_1_9_1/test/ruby/test_io_m17n.rb
===================================================================
--- ruby_1_9_1/test/ruby/test_io_m17n.rb	(revision 19998)
+++ ruby_1_9_1/test/ruby/test_io_m17n.rb	(revision 19999)
@@ -677,7 +677,7 @@
   end
 
   def test_getc_invalid3
-    with_pipe("utf-16le:euc-jp") {|r, w|
+    with_pipe("utf-16le:euc-jp", binmode: true) {|r, w|
       before1 = "\x42\x30".force_encoding("utf-16le")
       before2 = "\x44\x30".force_encoding("utf-16le")
       invalid = "\x00\xd8".force_encoding("utf-16le")
Index: ruby_1_9_1/test/ruby/test_require.rb
===================================================================
--- ruby_1_9_1/test/ruby/test_require.rb	(revision 19998)
+++ ruby_1_9_1/test/ruby/test_require.rb	(revision 19999)
@@ -27,11 +27,15 @@
       end
     INPUT
 
-    assert_in_out_err(["-S", "foo/" * 10000 + "foo"], "") do |r, e|
-      assert_equal([], r)
-      assert_operator(2, :<=, e.size)
-      assert_equal("openpath: pathname too long (ignored)", e.first)
-      assert_match(/\(LoadError\)/, e.last)
+    begin
+      assert_in_out_err(["-S", "foo/" * 10000 + "foo"], "") do |r, e|
+        assert_equal([], r)
+        assert_operator(2, :<=, e.size)
+        assert_equal("openpath: pathname too long (ignored)", e.first)
+        assert_match(/\(LoadError\)/, e.last)
+      end
+    rescue Errno::EINVAL
+      # too long commandline may be blocked by OS.
     end
   end
 
Index: ruby_1_9_1/test/ruby/test_file.rb
===================================================================
--- ruby_1_9_1/test/ruby/test_file.rb	(revision 19998)
+++ ruby_1_9_1/test/ruby/test_file.rb	(revision 19999)
@@ -65,42 +65,72 @@
   end
 
   def test_read_all_extended_file
-    f = Tempfile.new("test-extended-file")
-    assert_nil(f.getc)
-    open(f.path, "w") {|g| g.print "a" }
-    assert_equal("a", f.read)
+    [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+      f = Tempfile.new("test-extended-file", mode)
+      assert_nil(f.getc)
+      open(f.path, "w") {|g| g.print "a" }
+      assert_equal("a", f.read, "mode = <#{mode}>")
+    end
   end
 
   def test_gets_extended_file
-    f = Tempfile.new("test-extended-file")
-    assert_nil(f.getc)
-    open(f.path, "w") {|g| g.print "a" }
-    assert_equal("a", f.gets("a"))
+    [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+      f = Tempfile.new("test-extended-file", mode)
+      assert_nil(f.getc)
+      open(f.path, "w") {|g| g.print "a" }
+      assert_equal("a", f.gets("a"), "mode = <#{mode}>")
+    end
   end
 
   def test_gets_para_extended_file
-    f = Tempfile.new("test-extended-file")
-    assert_nil(f.getc)
-    open(f.path, "w") {|g| g.print "\na" }
-    assert_equal("a", f.gets(""))
+    [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+      f = Tempfile.new("test-extended-file", mode)
+      assert_nil(f.getc)
+      open(f.path, "wb") {|g| g.print "\na" }
+      assert_equal("a", f.gets(""), "mode = <#{mode}>")
+    end
   end
 
+  def test_each_char_extended_file
+    [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+      f = Tempfile.new("test-extended-file", mode)
+      assert_nil(f.getc)
+      open(f.path, "w") {|g| g.print "a" }
+      result = []
+      f.each_char {|b| result << b }
+      assert_equal([?a], result, "mode = <#{mode}>")
+    end
+  end
+
   def test_each_byte_extended_file
-    f = Tempfile.new("test-extended-file")
-    assert_nil(f.getc)
-    open(f.path, "w") {|g| g.print "a" }
-    result = []
-    f.each_byte {|b| result << b.chr }
-    assert_equal([?a], result)
+    [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+      f = Tempfile.new("test-extended-file", mode)
+      assert_nil(f.getc)
+      open(f.path, "w") {|g| g.print "a" }
+      result = []
+      f.each_byte {|b| result << b.chr }
+      assert_equal([?a], result, "mode = <#{mode}>")
+    end
   end
 
   def test_getc_extended_file
-    f = Tempfile.new("test-extended-file")
-    assert_nil(f.getc)
-    open(f.path, "w") {|g| g.print "a" }
-    assert_equal(?a, f.getc)
+    [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+      f = Tempfile.new("test-extended-file", mode)
+      assert_nil(f.getc)
+      open(f.path, "w") {|g| g.print "a" }
+      assert_equal(?a, f.getc, "mode = <#{mode}>")
+    end
   end
 
+  def test_getbyte_extended_file
+    [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+      f = Tempfile.new("test-extended-file", mode)
+      assert_nil(f.getc)
+      open(f.path, "w") {|g| g.print "a" }
+      assert_equal(?a, f.getbyte.chr, "mode = <#{mode}>")
+    end
+  end
+
   def test_s_chown
     assert_nothing_raised { File.chown -1, -1 }
     assert_nothing_raised { File.chown nil, nil }
Index: ruby_1_9_1/test/ruby/test_io.rb
===================================================================
--- ruby_1_9_1/test/ruby/test_io.rb	(revision 19998)
+++ ruby_1_9_1/test/ruby/test_io.rb	(revision 19999)
@@ -1,5 +1,6 @@
 require 'test/unit'
 require 'tmpdir'
+require "fcntl"
 require 'io/nonblock'
 require 'socket'
 require 'stringio'
@@ -8,6 +9,19 @@
 require_relative 'envutil'
 
 class TestIO < Test::Unit::TestCase
+  def have_close_on_exec?
+    begin
+      $stdin.close_on_exec?
+      true
+    rescue NotImplementedError
+      false
+    end
+  end
+
+  def have_nonblock?
+    IO.instance_methods.index(:"nonblock=")
+  end
+
   def test_gets_rs
     # default_rs
     r, w = IO.pipe
@@ -236,18 +250,20 @@
         assert_equal(content[1,1], r.read)
       }
 
-      with_read_pipe("abc") {|r1|
-        assert_equal("a", r1.getc)
-        with_pipe {|r2, w2|
-          w2.nonblock = true
-          s = w2.syswrite("a" * 100000)
-          t = Thread.new { sleep 0.1; r2.read }
-          ret = IO.copy_stream(r1, w2)
-          w2.close
-          assert_equal(2, ret)
-          assert_equal("a" * s + "bc", t.value)
+      if have_nonblock?
+        with_read_pipe("abc") {|r1|
+          assert_equal("a", r1.getc)
+          with_pipe {|r2, w2|
+            w2.nonblock = true
+            s = w2.syswrite("a" * 100000)
+            t = Thread.new { sleep 0.1; r2.read }
+            ret = IO.copy_stream(r1, w2)
+            w2.close
+            assert_equal(2, ret)
+            assert_equal("a" * s + "bc", t.value)
+          }
         }
-      }
+      end
 
       bigcontent = "abc" * 123456
       File.open("bigsrc", "w") {|f| f << bigcontent }
@@ -266,15 +282,19 @@
       assert_equal(bigcontent[100, 30000], File.read("bigdst"))
 
       File.open("bigsrc") {|f|
-        assert_equal(0, f.pos)
-        ret = IO.copy_stream(f, "bigdst", nil, 10)
-        assert_equal(bigcontent.bytesize-10, ret)
-        assert_equal(bigcontent[10..-1], File.read("bigdst"))
-        assert_equal(0, f.pos)
-        ret = IO.copy_stream(f, "bigdst", 40, 30)
-        assert_equal(40, ret)
-        assert_equal(bigcontent[30, 40], File.read("bigdst"))
-        assert_equal(0, f.pos)
+        begin
+          assert_equal(0, f.pos)
+          ret = IO.copy_stream(f, "bigdst", nil, 10)
+          assert_equal(bigcontent.bytesize-10, ret)
+          assert_equal(bigcontent[10..-1], File.read("bigdst"))
+          assert_equal(0, f.pos)
+          ret = IO.copy_stream(f, "bigdst", 40, 30)
+          assert_equal(40, ret)
+          assert_equal(bigcontent[30, 40], File.read("bigdst"))
+          assert_equal(0, f.pos)
+        rescue NotImplementedError
+          #skip "pread(2) is not implemtented."
+        end
       }
 
       with_pipe {|r, w|
@@ -285,19 +305,21 @@
       megacontent = "abc" * 1234567
       File.open("megasrc", "w") {|f| f << megacontent }
 
-      with_pipe {|r1, w1|
-        with_pipe {|r2, w2|
-          t1 = Thread.new { w1 << megacontent; w1.close }
-          t2 = Thread.new { r2.read }
-          r1.nonblock = true
-          w2.nonblock = true
-          ret = IO.copy_stream(r1, w2)
-          assert_equal(megacontent.bytesize, ret)
-          w2.close
-          t1.join
-          assert_equal(megacontent, t2.value)
+      if have_nonblock?
+        with_pipe {|r1, w1|
+          with_pipe {|r2, w2|
+            t1 = Thread.new { w1 << megacontent; w1.close }
+            t2 = Thread.new { r2.read }
+            r1.nonblock = true
+            w2.nonblock = true
+            ret = IO.copy_stream(r1, w2)
+            assert_equal(megacontent.bytesize, ret)
+            w2.close
+            t1.join
+            assert_equal(megacontent, t2.value)
+          }
         }
-      }
+      end
 
       with_pipe {|r1, w1|
         with_pipe {|r2, w2|
@@ -323,15 +345,19 @@
 
   def test_copy_stream_rbuf
     mkcdtmpdir {
-      with_pipe {|r, w|
-        File.open("foo", "w") {|f| f << "abcd" }
-        File.open("foo") {|f|
-          f.read(1)
-          assert_equal(3, IO.copy_stream(f, w, 10, 1))
+      begin
+        with_pipe {|r, w|
+          File.open("foo", "w") {|f| f << "abcd" }
+          File.open("foo") {|f|
+            f.read(1)
+            assert_equal(3, IO.copy_stream(f, w, 10, 1))
+          }
+          w.close
+          assert_equal("bcd", r.read)
         }
-        w.close
-        assert_equal("bcd", r.read)
-      }
+      rescue NotImplementedError
+        skip "pread(2) is not implemtented."
+      end
     }
   end
 
@@ -410,15 +436,17 @@
       megacontent = "abc" * 1234567
       File.open("megasrc", "w") {|f| f << megacontent }
 
-      with_socketpair {|s1, s2|
-        t = Thread.new { s2.read }
-        s1.nonblock = true
-        ret = IO.copy_stream("megasrc", s1)
-        assert_equal(megacontent.bytesize, ret)
-        s1.close
-        result = t.value
-        assert_equal(megacontent, result)
-      }
+      if have_nonblock?
+        with_socketpair {|s1, s2|
+          t = Thread.new { s2.read }
+          s1.nonblock = true
+          ret = IO.copy_stream("megasrc", s1)
+          assert_equal(megacontent.bytesize, ret)
+          s1.close
+          result = t.value
+          assert_equal(megacontent, result)
+        }
+      end
     }
   end
 
@@ -695,6 +723,7 @@
   end
 
   def test_write_nonblock
+    skip "IO#write_nonblock is not supported on file/pipe." if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
     pipe(proc do |w|
       w.write_nonblock(1)
       w.close
@@ -874,6 +903,7 @@
 
   def test_bytes
     pipe(proc do |w|
+      w.binmode
       w.puts "foo"
       w.puts "bar"
       w.puts "baz"
@@ -904,11 +934,13 @@
 
   def test_readbyte
     pipe(proc do |w|
+      w.binmode
       w.puts "foo"
       w.puts "bar"
       w.puts "baz"
       w.close
     end, proc do |r|
+      r.binmode
       (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
         assert_equal(c.ord, r.readbyte)
       end
@@ -931,7 +963,7 @@
   end
 
   def test_close_on_exec
-    # xxx
+    skip "IO\#close_on_exec is not implemented." unless have_close_on_exec?
     ruby do |f|
       assert_equal(false, f.close_on_exec?)
       f.close_on_exec = true
@@ -1022,7 +1054,11 @@
     
     fd = IO.sysopen(t.path, "w", 0666)
     assert_kind_of(Integer, fd)
-    f = IO.for_fd(fd)
+    if defined?(Fcntl::F_GETFL)
+      f = IO.for_fd(fd)
+    else
+      f = IO.for_fd(fd, 0666)
+    end
     f.write("FOO\n")
     f.close
     

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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