diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-03-29 07:51:08 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-03-29 07:51:08 +0000 |
commit | 8d7c52dbe21f1bbd423860c7bab21a9f8ce487c2 (patch) | |
tree | ad7db745219ad3beae52cec06d7a6d4f2e36e78f | |
parent | 2e26edb633606f1e99d22817678e11c25f7d2882 (diff) | |
download | ruby-8d7c52dbe21f1bbd423860c7bab21a9f8ce487c2.tar.gz |
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]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39996 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | io.c | 48 | ||||
-rw-r--r-- | test/ruby/test_argf.rb | 38 |
3 files changed, 79 insertions, 14 deletions
@@ -1,3 +1,10 @@ +Fri Mar 29 16:51:04 2013 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * 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@ruby-lang.org> * lib/mkmf.rb (configuration): not include all CFLAGS in CXXFLAGS, to @@ -7573,13 +7573,15 @@ argf_forward(int argc, VALUE *argv, VALUE argf) } 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) 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, VALUE argf) 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, VALUE argf) } 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 argf) 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, VALUE argf, int nonblock) 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) 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) 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) 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) #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, VALUE argf) { 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) { 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) { 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) { 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 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 argf_close_m(VALUE argf) { next_argv(); - argf_close(ARGF.current_file); + argf_close(argf); if (ARGF.next_p != -1) { ARGF.next_p = 1; } diff --git a/test/ruby/test_argf.rb b/test/ruby/test_argf.rb index 1bccac0ffa..979b66765b 100644 --- a/test/ruby/test_argf.rb +++ b/test/ruby/test_argf.rb @@ -683,6 +683,44 @@ class TestArgf < Test::Unit::TestCase 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 |