From: Nobuyoshi Nakada Date: 2007-01-05T17:49:10+09:00 Subject: [ruby-dev:30085] Re: IO#lineno always returns 0 なかだです。 At Fri, 5 Jan 2007 14:15:47 +0900, Nobuyoshi Nakada wrote in [ruby-dev:30081]: > ちょうど一行の長さと同じlimitを指定したときにlinenoが進んでいません。 > Index: io.c > =================================================================== > --- io.c (revision 11475) > +++ io.c (working copy) 正月早々うっかりコンパイルがとおらないパッチを出してしまいました。 ついでに、IO#readlinesやIO#each_lineで毎回rsやlimitをチェックしている のが気になったので、分離してみました。 Index: io.c =================================================================== --- io.c (revision 11479) +++ io.c (working copy) @@ -1637,13 +1637,17 @@ rb_io_getline_fast(OpenFile *fptr, unsig { VALUE str = Qnil; - int c; + int c, nolimit = 0; for (;;) { c = appendline(fptr, delim, &str, &limit); - if (c == EOF || c == delim || limit == 0) break; + if (c == EOF || c == delim) break; + if (limit == 0) { + nolimit = 1; + break; + } } if (!NIL_P(str)) { - if (limit != 0) { + if (!nolimit) { fptr->lineno++; lineno = INT2FIX(fptr->lineno); @@ -1663,10 +1667,8 @@ rscheck(const char *rsptr, long rslen, V } -static VALUE -rb_io_getline(int argc, VALUE *argv, VALUE io) +static void +getline_args(int argc, VALUE *argv, VALUE *rsp, long *limit) { - VALUE rs, lim, str = Qnil; - OpenFile *fptr; - long limit; + VALUE lim, rs; if (argc == 0) { @@ -1688,5 +1690,14 @@ rb_io_getline(int argc, VALUE *argv, VAL } } - limit = NIL_P(lim) ? 0 : NUM2LONG(lim); + *rsp = rs; + *limit = NIL_P(lim) ? -1L : NUM2LONG(lim); +} + +static VALUE +rb_io_getline_1(VALUE rs, long limit, VALUE io) +{ + VALUE str = Qnil; + OpenFile *fptr; + int nolimit = 0; GetOpenFile(io, fptr); @@ -1696,5 +1707,5 @@ rb_io_getline(int argc, VALUE *argv, VAL if (RSTRING_LEN(str) == 0) return Qnil; } - else if (!NIL_P(lim) && limit == 0) { + else if (limit == 0) { return rb_str_new(0,0); } @@ -1730,5 +1741,8 @@ rb_io_getline(int argc, VALUE *argv, VAL rsptr, rslen) == 0) break; } - if (limit == 0) break; + if (limit == 0) { + nolimit = 1; + break; + } } @@ -1741,5 +1755,5 @@ rb_io_getline(int argc, VALUE *argv, VAL if (!NIL_P(str)) { - if (limit != 0) { + if (!nolimit) { fptr->lineno++; lineno = INT2FIX(fptr->lineno); @@ -1751,4 +1765,14 @@ rb_io_getline(int argc, VALUE *argv, VAL } +static VALUE +rb_io_getline(int argc, VALUE *argv, VALUE io) +{ + VALUE rs; + long limit; + + getline_args(argc, argv, &rs, &limit); + return rb_io_getline_1(rs, limit, io); +} + VALUE rb_io_gets(VALUE io) @@ -1913,8 +1937,10 @@ static VALUE rb_io_readlines(int argc, VALUE *argv, VALUE io) { - VALUE line, ary; + VALUE line, ary, rs; + long limit; + getline_args(argc, argv, &rs, &limit); ary = rb_ary_new(); - while (!NIL_P(line = rb_io_getline(argc, argv, io))) { + while (!NIL_P(line = rb_io_getline_1(rs, limit, io))) { rb_ary_push(ary, line); } @@ -1949,8 +1975,10 @@ static VALUE rb_io_each_line(int argc, VALUE *argv, VALUE io) { - VALUE str; + VALUE str, rs; + long limit; RETURN_ENUMERATOR(io, argc, argv); - while (!NIL_P(str = rb_io_getline(argc, argv, io))) { + getline_args(argc, argv, &rs, &limit); + while (!NIL_P(str = rb_io_getline_1(rs, limit, io))) { rb_yield(str); } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦