ruby-changes:27944
From: nobu <ko1@a...>
Date: Fri, 29 Mar 2013 16:51:22 +0900 (JST)
Subject: [ruby-changes:27944] nobu:r39996 (trunk): io.c: get rid of IOError when skipped while iteration
nobu 2013-03-29 16:51:08 +0900 (Fri, 29 Mar 2013) New Revision: 39996 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=39996 Log: io.c: get rid of IOError when skipped while iteration * io.c (argf_close): deal with init flag. * io.c (argf_block_call_i, argf_block_call): forward next file if skipped while iteration, to get rid of IOError. [ruby-list:49185] Modified files: trunk/ChangeLog trunk/io.c trunk/test/ruby/test_argf.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 39995) +++ ChangeLog (revision 39996) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Mar 29 16:51:04 2013 Nobuyoshi Nakada <nobu@r...> + + * io.c (argf_close): deal with init flag. + + * io.c (argf_block_call_i, argf_block_call): forward next file if + skipped while iteration, to get rid of IOError. [ruby-list:49185] + Fri Mar 29 11:09:48 2013 Nobuyoshi Nakada <nobu@r...> * lib/mkmf.rb (configuration): not include all CFLAGS in CXXFLAGS, to Index: io.c =================================================================== --- io.c (revision 39995) +++ io.c (revision 39996) @@ -7573,13 +7573,15 @@ argf_forward(int argc, VALUE *argv, VALU https://github.com/ruby/ruby/blob/trunk/io.c#L7573 } while (0) static void -argf_close(VALUE file) +argf_close(VALUE argf) { + VALUE file = ARGF.current_file; if (file == rb_stdin) return; if (RB_TYPE_P(file, T_FILE)) { rb_io_set_write_io(file, Qnil); } rb_funcall3(file, rb_intern("close"), 0, 0); + ARGF.init_p = -1; } static int @@ -7612,6 +7614,7 @@ argf_next_argv(VALUE argf) https://github.com/ruby/ruby/blob/trunk/io.c#L7614 else if (ARGF.next_p == -1 && RARRAY_LEN(ARGF.argv) > 0) { ARGF.next_p = 1; } + ARGF.init_p = 1; } if (ARGF.next_p == 1) { @@ -7766,7 +7769,7 @@ argf_getline(int argc, VALUE *argv, VALU https://github.com/ruby/ruby/blob/trunk/io.c#L7769 line = rb_io_getline(argc, argv, ARGF.current_file); } if (NIL_P(line) && ARGF.next_p != -1) { - argf_close(ARGF.current_file); + argf_close(argf); ARGF.next_p = 1; goto retry; } @@ -7992,7 +7995,7 @@ argf_readlines(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/io.c#L7995 } else { lines = rb_io_readlines(argc, argv, ARGF.current_file); - argf_close(ARGF.current_file); + argf_close(argf); } ARGF.next_p = 1; rb_ary_concat(ary, lines); @@ -10645,7 +10648,7 @@ argf_read(int argc, VALUE *argv, VALUE a https://github.com/ruby/ruby/blob/trunk/io.c#L10648 else if (!NIL_P(tmp)) rb_str_append(str, tmp); if (NIL_P(tmp) || NIL_P(length)) { if (ARGF.next_p != -1) { - argf_close(ARGF.current_file); + argf_close(argf); ARGF.next_p = 1; goto retry; } @@ -10757,7 +10760,7 @@ argf_getpartial(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/io.c#L10760 if (ARGF.next_p == -1) { rb_eof_error(); } - argf_close(ARGF.current_file); + argf_close(argf); ARGF.next_p = 1; if (RARRAY_LEN(ARGF.argv) == 0) rb_eof_error(); @@ -10805,7 +10808,7 @@ argf_getc(VALUE argf) https://github.com/ruby/ruby/blob/trunk/io.c#L10808 ch = rb_io_getc(ARGF.current_file); } if (NIL_P(ch) && ARGF.next_p != -1) { - argf_close(ARGF.current_file); + argf_close(argf); ARGF.next_p = 1; goto retry; } @@ -10845,7 +10848,7 @@ argf_getbyte(VALUE argf) https://github.com/ruby/ruby/blob/trunk/io.c#L10848 ch = rb_io_getbyte(ARGF.current_file); } if (NIL_P(ch) && ARGF.next_p != -1) { - argf_close(ARGF.current_file); + argf_close(argf); ARGF.next_p = 1; goto retry; } @@ -10885,7 +10888,7 @@ argf_readchar(VALUE argf) https://github.com/ruby/ruby/blob/trunk/io.c#L10888 ch = rb_io_getc(ARGF.current_file); } if (NIL_P(ch) && ARGF.next_p != -1) { - argf_close(ARGF.current_file); + argf_close(argf); ARGF.next_p = 1; goto retry; } @@ -10926,6 +10929,23 @@ argf_readbyte(VALUE argf) https://github.com/ruby/ruby/blob/trunk/io.c#L10929 #define FOREACH_ARGF() for (; next_argv(); ARGF.next_p = 1) +static VALUE +argf_block_call_i(VALUE i, VALUE argf, int argc, VALUE *argv) +{ + const VALUE current = ARGF.current_file; + rb_yield_values2(argc, argv); + if (ARGF.init_p == -1 || current != ARGF.current_file) { + rb_iter_break(); + } + return Qnil; +} + +static void +argf_block_call(ID mid, int argc, VALUE *argv, VALUE argf) +{ + rb_block_call(ARGF.current_file, mid, argc, argv, argf_block_call_i, argf); +} + /* * call-seq: * ARGF.each(sep=$/) {|line| block } -> ARGF @@ -10963,7 +10983,7 @@ argf_each_line(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/io.c#L10983 { RETURN_ENUMERATOR(argf, argc, argv); FOREACH_ARGF() { - rb_block_call(ARGF.current_file, rb_intern("each_line"), argc, argv, 0, 0); + argf_block_call(rb_intern("each_line"), argc, argv, argf); } return argf; } @@ -11010,7 +11030,7 @@ argf_each_byte(VALUE argf) https://github.com/ruby/ruby/blob/trunk/io.c#L11030 { RETURN_ENUMERATOR(argf, 0, 0); FOREACH_ARGF() { - rb_block_call(ARGF.current_file, rb_intern("each_byte"), 0, 0, 0, 0); + argf_block_call(rb_intern("each_byte"), 0, 0, argf); } return argf; } @@ -11049,7 +11069,7 @@ argf_each_char(VALUE argf) https://github.com/ruby/ruby/blob/trunk/io.c#L11069 { RETURN_ENUMERATOR(argf, 0, 0); FOREACH_ARGF() { - rb_block_call(ARGF.current_file, rb_intern("each_char"), 0, 0, 0, 0); + argf_block_call(rb_intern("each_char"), 0, 0, argf); } return argf; } @@ -11088,7 +11108,7 @@ argf_each_codepoint(VALUE argf) https://github.com/ruby/ruby/blob/trunk/io.c#L11108 { RETURN_ENUMERATOR(argf, 0, 0); FOREACH_ARGF() { - rb_block_call(ARGF.current_file, rb_intern("each_codepoint"), 0, 0, 0, 0); + argf_block_call(rb_intern("each_codepoint"), 0, 0, argf); } return argf; } @@ -11224,7 +11244,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/io.c#L11244 argf_skip(VALUE argf) { if (ARGF.init_p && ARGF.next_p == 0) { - argf_close(ARGF.current_file); + argf_close(argf); ARGF.next_p = 1; } return argf; @@ -11252,7 +11272,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/io.c#L11272 argf_close_m(VALUE argf) { next_argv(); - argf_close(ARGF.current_file); + argf_close(argf); if (ARGF.next_p != -1) { ARGF.next_p = 1; } Index: test/ruby/test_argf.rb =================================================================== --- test/ruby/test_argf.rb (revision 39995) +++ test/ruby/test_argf.rb (revision 39996) @@ -683,6 +683,44 @@ class TestArgf < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_argf.rb#L683 end end + def test_skip_in_each_line + ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f| + ARGF.each_line {|l| print l; ARGF.skip} + SRC + assert_equal("1\n3\n5\n", f.read, '[ruby-list:49185]') + end + end + + def test_skip_in_each_byte + ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f| + ARGF.each_byte {|l| print l; ARGF.skip} + SRC + assert_equal("135".unpack("C*").join(""), f.read, '[ruby-list:49185]') + end + end + + def test_skip_in_each_char + [[@t1, "\u{3042}"], [@t2, "\u{3044}"], [@t3, "\u{3046}"]].each do |f, s| + File.write(f.path, s, mode: "w:utf-8") + end + ruby('-Eutf-8', '-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f| + ARGF.each_char {|l| print l; ARGF.skip} + SRC + assert_equal("\u{3042 3044 3046}", f.read, '[ruby-list:49185]') + end + end + + def test_skip_in_each_codepoint + [[@t1, "\u{3042}"], [@t2, "\u{3044}"], [@t3, "\u{3046}"]].each do |f, s| + File.write(f.path, s, mode: "w:utf-8") + end + ruby('-Eutf-8', '-Eutf-8', '-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f| + ARGF.each_codepoint {|l| printf "%x:", l; ARGF.skip} + SRC + assert_equal("3042:3044:3046:", f.read, '[ruby-list:49185]') + end + end + def test_close ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f| ARGF.close -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/