[前][次][番号順一覧][スレッド一覧]

ruby-changes:45112

From: nobu <ko1@a...>
Date: Mon, 26 Dec 2016 08:57:01 +0900 (JST)
Subject: [ruby-changes:45112] nobu:r57185 (trunk): string.c: CRLF in paragraph mode

nobu	2016-12-26 08:56:55 +0900 (Mon, 26 Dec 2016)

  New Revision: 57185

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57185

  Log:
    string.c: CRLF in paragraph mode
    
    * string.c (rb_str_enumerate_lines): allow CRLF to separate
      paragraphs.

  Modified files:
    trunk/string.c
    trunk/test/ruby/test_string.rb
Index: test/ruby/test_string.rb
===================================================================
--- test/ruby/test_string.rb	(revision 57184)
+++ test/ruby/test_string.rb	(revision 57185)
@@ -785,6 +785,11 @@ CODE https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L785
     assert_equal(S("hello\n\n"), res[0])
     assert_equal(S("world"),     res[1])
 
+    res=[]
+    S("hello\r\n\r\nworld").each_line(S('')) {|x| res << x}
+    assert_equal(S("hello\r\n\r\n"), res[0])
+    assert_equal(S("world"),         res[1])
+
     $/ = "!"
 
     res=[]
@@ -828,6 +833,11 @@ CODE https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L833
     assert_equal(S("world"),   res[1])
 
     res = []
+    S("hello\r\n\r\nworld").each_line(S(''), chomp: true) {|x| res << x}
+    assert_equal(S("hello\r\n"), res[0])
+    assert_equal(S("world"),     res[1])
+
+    res = []
     S("hello!world").each_line(S('!'), chomp: true) {|x| res << x}
     assert_equal(S("hello"), res[0])
     assert_equal(S("world"), res[1])
Index: string.c
===================================================================
--- string.c	(revision 57184)
+++ string.c	(revision 57185)
@@ -7424,7 +7424,6 @@ rb_str_enumerate_lines(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/string.c#L7424
     VALUE line, rs, orig = str, opts = Qnil, chomp = Qfalse;
     const char *ptr, *pend, *subptr, *subend, *rsptr, *hit, *adjusted;
     long pos, len, rslen;
-    int paragraph_mode = 0;
     int rsnewline = 0;
 
     VALUE MAYBE_UNUSED(ary);
@@ -7469,6 +7468,7 @@ rb_str_enumerate_lines(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/string.c#L7468
 	}
     }
 
+    if (!RSTRING_LEN(str)) goto end;
     str = rb_str_new_frozen(str);
     ptr = subptr = RSTRING_PTR(str);
     pend = RSTRING_END(str);
@@ -7482,10 +7482,39 @@ rb_str_enumerate_lines(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/string.c#L7482
 	enc = rb_enc_check(str, rs);
 
     if (rslen == 0) {
-	rsptr = "\n\n";
-	rslen = 2;
-	paragraph_mode = 1;
-	rsnewline = 1;
+	/* paragraph mode */
+	int n;
+	const char *eol = NULL;
+	subend = subptr;
+	while (subend < pend) {
+	    do {
+		if (rb_enc_ascget(subend, pend, &n, enc) != '\r')
+		    n = 0;
+		rslen = n + rb_enc_mbclen(subend + n, pend, enc);
+		if (rb_enc_is_newline(subend + n, pend, enc)) {
+		    if (eol == subend) break;
+		    subend += rslen;
+		    if (subptr) eol = subend;
+		}
+		else {
+		    if (!subptr) subptr = subend;
+		    subend += rslen;
+		}
+		rslen = 0;
+	    } while (subend < pend);
+	    if (!subptr) break;
+	    line = rb_str_subseq(str, subptr - ptr,
+				 subend - subptr + (chomp ? 0 : rslen));
+	    if (wantarray) {
+		rb_ary_push(ary, line);
+	    }
+	    else {
+		rb_yield(line);
+		str_mod_check(str, ptr, len);
+	    }
+	    subptr = eol = NULL;
+	}
+	goto end;
     }
     else {
 	rsptr = RSTRING_PTR(rs);
@@ -7495,7 +7524,7 @@ rb_str_enumerate_lines(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/string.c#L7524
 	}
     }
 
-    if ((rs == rb_default_rs || paragraph_mode) && !rb_enc_asciicompat(enc)) {
+    if ((rs == rb_default_rs) && !rb_enc_asciicompat(enc)) {
 	rs = rb_str_new(rsptr, rslen);
 	rs = rb_str_encode(rs, rb_enc_from_encoding(enc), 0, Qnil);
 	rsptr = RSTRING_PTR(rs);
@@ -7512,16 +7541,6 @@ rb_str_enumerate_lines(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/string.c#L7541
 	    continue;
 	}
 	subend = hit += rslen;
-	if (paragraph_mode) {
-	    while (hit < pend) {
-		int n;
-		if (rb_enc_ascget(hit, pend, &n, enc) != '\r')
-		    n = 0;
-		if (!rb_enc_is_newline(hit + n, pend, enc)) break;
-		hit += n;
-		hit += rb_enc_mbclen(hit, pend, enc);
-	    }
-	}
 	if (chomp) {
 	    if (rsnewline) {
 		subend = chomp_newline(subptr, subend, enc);
@@ -7542,7 +7561,7 @@ rb_str_enumerate_lines(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/string.c#L7561
     }
 
     if (subptr != pend) {
-	if (chomp && paragraph_mode) {
+	if (chomp) {
 	    pend = chomp_newline(subptr, pend, enc);
 	}
 	line = rb_str_subseq(str, subptr - ptr, pend - subptr);
@@ -7553,6 +7572,7 @@ rb_str_enumerate_lines(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/string.c#L7572
 	RB_GC_GUARD(str);
     }
 
+  end:
     if (wantarray)
 	return ary;
     else

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]