1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
nobu 2013-03-29 07:51:08 +00:00
parent 2e26edb633
commit 8d7c52dbe2
3 changed files with 79 additions and 14 deletions

View file

@ -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

48
io.c
View file

@ -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;
}

View file

@ -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