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

ruby-changes:72625

From: Jeremy <ko1@a...>
Date: Fri, 22 Jul 2022 00:02:51 +0900 (JST)
Subject: [ruby-changes:72625] 423b41cba7 (master): Make String#each_line work correctly with paragraph separator and chomp

https://git.ruby-lang.org/ruby.git/commit/?id=423b41cba7

From 423b41cba77719b4f62aa530593ad36a990f7c74 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Thu, 26 May 2022 13:25:22 -0700
Subject: Make String#each_line work correctly with paragraph separator and
 chomp

Previously, it was including one newline when chomp was used,
which is inconsistent with IO#each_line behavior. This makes
behavior consistent with IO#each_line, chomping all paragraph
separators (multiple consecutive newlines), but not single
newlines.

Partially Fixes [Bug #18768]
---
 string.c                 |  9 +++++++--
 test/ruby/test_string.rb | 17 +++++++++++------
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/string.c b/string.c
index c726adb2c3..72f6dbd67c 100644
--- a/string.c
+++ b/string.c
@@ -8967,6 +8967,7 @@ rb_str_enumerate_lines(int argc, VALUE *argv, VALUE str, VALUE ary) https://github.com/ruby/ruby/blob/trunk/string.c#L8967
 	const char *eol = NULL;
 	subend = subptr;
 	while (subend < pend) {
+            long chomp_rslen = 0;
 	    do {
 		if (rb_enc_ascget(subend, pend, &n, enc) != '\r')
 		    n = 0;
@@ -8974,7 +8975,10 @@ rb_str_enumerate_lines(int argc, VALUE *argv, VALUE str, VALUE ary) https://github.com/ruby/ruby/blob/trunk/string.c#L8975
 		if (rb_enc_is_newline(subend + n, pend, enc)) {
 		    if (eol == subend) break;
 		    subend += rslen;
-		    if (subptr) eol = subend;
+                    if (subptr) {
+                        eol = subend;
+                        chomp_rslen = -rslen;
+                    }
 		}
 		else {
 		    if (!subptr) subptr = subend;
@@ -8983,8 +8987,9 @@ rb_str_enumerate_lines(int argc, VALUE *argv, VALUE str, VALUE ary) https://github.com/ruby/ruby/blob/trunk/string.c#L8987
 		rslen = 0;
 	    } while (subend < pend);
 	    if (!subptr) break;
+            if (rslen == 0) chomp_rslen = 0;
 	    line = rb_str_subseq(str, subptr - ptr,
-				 subend - subptr + (chomp ? 0 : rslen));
+                                 subend - subptr + (chomp ? chomp_rslen : rslen));
 	    if (ENUM_ELEM(ary, line)) {
 		str_mod_check(str, ptr, len);
 	    }
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index d96e8dff22..d37924dec1 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -1121,14 +1121,19 @@ CODE https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L1121
     assert_equal(S("world"), res[1])
 
     res = []
-    S("hello\n\n\nworld").each_line(S(''), chomp: true) {|x| res << x}
-    assert_equal(S("hello\n"), res[0])
-    assert_equal(S("world"),   res[1])
+    S("hello\n\n\nworld\n").each_line(S(''), chomp: true) {|x| res << x}
+    assert_equal(S("hello"), res[0])
+    assert_equal(S("world\n"), 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])
+    S("hello\r\n\r\nworld\r\n").each_line(S(''), chomp: true) {|x| res << x}
+    assert_equal(S("hello"), res[0])
+    assert_equal(S("world\r\n"), res[1])
+
+    res = []
+    S("hello\r\n\n\nworld").each_line(S(''), chomp: true) {|x| res << x}
+    assert_equal(S("hello"), res[0])
+    assert_equal(S("world"), res[1])
 
     res = []
     S("hello!world").each_line(S('!'), chomp: true) {|x| res << x}
-- 
cgit v1.2.1


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

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