[#30220] schedule for Ruby 1.8.6 — "Akinori MUSHA" <knu@...>

 ruby-core を読んでいない人もいると思うので、ここでもアナウンス

20 messages 2007/01/30

[ruby-dev:30085] Re: IO#lineno always returns 0

From: "Nobuyoshi Nakada" <nobu@...>
Date: 2007-01-05 08:49:10 UTC
List: ruby-dev #30085
なかだです。

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はできる。
    中田 伸悦

In This Thread