summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2022-05-26 13:25:22 -0700
committerJeremy Evans <code@jeremyevans.net>2022-07-21 08:02:32 -0700
commit423b41cba77719b4f62aa530593ad36a990f7c74 (patch)
tree546b853d2bd8396719d426262436c0e4215b9a5b /string.c
parentcdbb9b8555b4ddcc4c557f25ad785cae6209478d (diff)
downloadruby-423b41cba77719b4f62aa530593ad36a990f7c74.tar.gz
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]
Diffstat (limited to 'string.c')
-rw-r--r--string.c9
1 files changed, 7 insertions, 2 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)
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)
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)
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);
}