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

ruby-changes:39204

From: normal <ko1@a...>
Date: Sat, 18 Jul 2015 03:03:13 +0900 (JST)
Subject: [ruby-changes:39204] normal:r51285 (trunk): io.c (argf_read_nonblock): support `exception: false'

normal	2015-07-18 03:02:53 +0900 (Sat, 18 Jul 2015)

  New Revision: 51285

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

  Log:
    io.c (argf_read_nonblock): support `exception: false'
    
    This is a preparation for [ruby-core:69892]
    ("io.c: avoid kwarg parsing in C API")
    since I noticed ARGF.read_nonblock did not properly catch up to
    the `exception: false' change.
    
    * io.c (argf_read_nonblock): support `exception: false'
      (io_nonblock_eof): new function
      (io_read_nonblock): use io_nonblock_eof
      (argf_getpartial): accept kwargs hash for `exception: false'
    * test/ruby/test_argf.rb (test_read_nonblock): new test
      [ruby-core:70000] [Feature #11358]
    * NEWS: add item for ARGF.read_nonblock

  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/io.c
    trunk/test/ruby/test_argf.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 51284)
+++ ChangeLog	(revision 51285)
@@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Jul 18 02:53:06 2015  Eric Wong  <e@8...>
+
+	* io.c (argf_read_nonblock): support `exception: false'
+	  (io_nonblock_eof): new function
+	  (io_read_nonblock): use io_nonblock_eof
+	  (argf_getpartial): accept kwargs hash for `exception: false'
+	* test/ruby/test_argf.rb (test_read_nonblock): new test
+	* NEWS: add item for ARGF.read_nonblock
+	  [ruby-core:70000] [Feature #11358]
+
 Fri Jul 17 23:51:31 2015  Nobuyoshi Nakada  <nobu@r...>
 
 	* vm_eval.c (rb_eval_cmd): $SAFE=4 has been deprecated.
Index: io.c
===================================================================
--- io.c	(revision 51284)
+++ io.c	(revision 51285)
@@ -2619,6 +2619,15 @@ io_readpartial(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/io.c#L2619
     return ret;
 }
 
+static VALUE
+io_nonblock_eof(VALUE opts)
+{
+    if (!no_exception_p(opts)) {
+        rb_eof_error();
+    }
+    return Qnil;
+}
+
 /*
  *  call-seq:
  *     ios.read_nonblock(maxlen)              -> string
@@ -2680,10 +2689,7 @@ io_read_nonblock(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/io.c#L2689
     ret = io_getpartial(argc, argv, io, opts, 1);
 
     if (NIL_P(ret)) {
-	if (no_exception_p(opts))
-	    return Qnil;
-	else
-	    rb_eof_error();
+	return io_nonblock_eof(opts);
     }
     return ret;
 }
@@ -11139,7 +11145,8 @@ argf_forward_call(VALUE arg) https://github.com/ruby/ruby/blob/trunk/io.c#L11145
     return Qnil;
 }
 
-static VALUE argf_getpartial(int argc, VALUE *argv, VALUE argf, int nonblock);
+static VALUE argf_getpartial(int argc, VALUE *argv, VALUE argf, VALUE opts,
+                             int nonblock);
 
 /*
  *  call-seq:
@@ -11164,7 +11171,7 @@ static VALUE argf_getpartial(int argc, V https://github.com/ruby/ruby/blob/trunk/io.c#L11171
 static VALUE
 argf_readpartial(int argc, VALUE *argv, VALUE argf)
 {
-    return argf_getpartial(argc, argv, argf, 0);
+    return argf_getpartial(argc, argv, argf, Qnil, 0);
 }
 
 /*
@@ -11178,11 +11185,18 @@ argf_readpartial(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/io.c#L11185
 static VALUE
 argf_read_nonblock(int argc, VALUE *argv, VALUE argf)
 {
-    return argf_getpartial(argc, argv, argf, 1);
+    VALUE opts;
+
+    rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);
+
+    if (!NIL_P(opts))
+        argc--;
+
+    return argf_getpartial(argc, argv, argf, opts, 1);
 }
 
 static VALUE
-argf_getpartial(int argc, VALUE *argv, VALUE argf, int nonblock)
+argf_getpartial(int argc, VALUE *argv, VALUE argf, VALUE opts, int nonblock)
 {
     VALUE tmp, str, length;
 
@@ -11205,16 +11219,17 @@ argf_getpartial(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/io.c#L11219
 			 RUBY_METHOD_FUNC(0), Qnil, rb_eEOFError, (VALUE)0);
     }
     else {
-        tmp = io_getpartial(argc, argv, ARGF.current_file, Qnil, nonblock);
+        tmp = io_getpartial(argc, argv, ARGF.current_file, opts, nonblock);
     }
     if (NIL_P(tmp)) {
         if (ARGF.next_p == -1) {
-            rb_eof_error();
+	    return io_nonblock_eof(opts);
         }
         argf_close(argf);
         ARGF.next_p = 1;
-        if (RARRAY_LEN(ARGF.argv) == 0)
-            rb_eof_error();
+        if (RARRAY_LEN(ARGF.argv) == 0) {
+	    return io_nonblock_eof(opts);
+	}
         if (NIL_P(str))
             str = rb_str_new(NULL, 0);
         return str;
Index: NEWS
===================================================================
--- NEWS	(revision 51284)
+++ NEWS	(revision 51285)
@@ -35,6 +35,11 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L35
     true when the receiver is positive and negative respectively.
     [Feature #11151]
 
+* ARGF
+
+  * ARGF.read_nonblock supports `exception: false' like IO#read_nonblock.
+    [Feature #11358]
+
 * IO
 
   * new mode flag File::SHARE_DELETE is available.
Index: test/ruby/test_argf.rb
===================================================================
--- test/ruby/test_argf.rb	(revision 51284)
+++ test/ruby/test_argf.rb	(revision 51285)
@@ -856,4 +856,47 @@ class TestArgf < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_argf.rb#L856
       assert_equal([49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10], Marshal.load(f.read))
     end
   end
+
+  def test_read_nonblock
+    ruby('-e', <<-SRC) do |f|
+      $stdout.sync = true
+      :wait_readable == ARGF.read_nonblock(1, "", exception: false) or
+        abort "did not return :wait_readable"
+
+      begin
+        ARGF.read_nonblock(1)
+        abort 'fail to raise IO::WaitReadable'
+      rescue IO::WaitReadable
+      end
+      puts 'starting select'
+
+      IO.select([ARGF]) == [[ARGF], [], []] or
+        abort 'did not awaken for readability (before byte)'
+
+      buf = ''
+      buf.object_id == ARGF.read_nonblock(1, buf).object_id or
+        abort "read destination buffer failed"
+      print buf
+
+      IO.select([ARGF]) == [[ARGF], [], []] or
+        abort 'did not awaken for readability (before EOF)'
+
+      ARGF.read_nonblock(1, buf, exception: false) == nil or
+        abort "EOF should return nil if exception: false"
+
+      begin
+        ARGF.read_nonblock(1, buf)
+        abort 'fail to raise IO::WaitReadable'
+      rescue EOFError
+        puts 'done with eof'
+      end
+    SRC
+      f.sync = true
+      assert_equal "starting select\n", f.gets
+      f.write('.') # wake up from IO.select
+      assert_equal '.', f.read(1)
+      f.close_write
+      assert_equal "done with eof\n", f.gets
+    end
+  end
 end

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

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