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/