mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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]
This commit is contained in:
parent
cdbb9b8555
commit
423b41cba7
Notes:
git
2022-07-22 00:03:03 +09:00
2 changed files with 18 additions and 8 deletions
9
string.c
9
string.c
|
|
@ -8967,6 +8967,7 @@ rb_str_enumerate_lines(int argc, VALUE *argv, VALUE str, VALUE ary)
|
||||||
const char *eol = NULL;
|
const char *eol = NULL;
|
||||||
subend = subptr;
|
subend = subptr;
|
||||||
while (subend < pend) {
|
while (subend < pend) {
|
||||||
|
long chomp_rslen = 0;
|
||||||
do {
|
do {
|
||||||
if (rb_enc_ascget(subend, pend, &n, enc) != '\r')
|
if (rb_enc_ascget(subend, pend, &n, enc) != '\r')
|
||||||
n = 0;
|
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 (rb_enc_is_newline(subend + n, pend, enc)) {
|
||||||
if (eol == subend) break;
|
if (eol == subend) break;
|
||||||
subend += rslen;
|
subend += rslen;
|
||||||
if (subptr) eol = subend;
|
if (subptr) {
|
||||||
|
eol = subend;
|
||||||
|
chomp_rslen = -rslen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!subptr) subptr = subend;
|
if (!subptr) subptr = subend;
|
||||||
|
|
@ -8983,8 +8987,9 @@ rb_str_enumerate_lines(int argc, VALUE *argv, VALUE str, VALUE ary)
|
||||||
rslen = 0;
|
rslen = 0;
|
||||||
} while (subend < pend);
|
} while (subend < pend);
|
||||||
if (!subptr) break;
|
if (!subptr) break;
|
||||||
|
if (rslen == 0) chomp_rslen = 0;
|
||||||
line = rb_str_subseq(str, subptr - ptr,
|
line = rb_str_subseq(str, subptr - ptr,
|
||||||
subend - subptr + (chomp ? 0 : rslen));
|
subend - subptr + (chomp ? chomp_rslen : rslen));
|
||||||
if (ENUM_ELEM(ary, line)) {
|
if (ENUM_ELEM(ary, line)) {
|
||||||
str_mod_check(str, ptr, len);
|
str_mod_check(str, ptr, len);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1121,13 +1121,18 @@ CODE
|
||||||
assert_equal(S("world"), res[1])
|
assert_equal(S("world"), res[1])
|
||||||
|
|
||||||
res = []
|
res = []
|
||||||
S("hello\n\n\nworld").each_line(S(''), chomp: true) {|x| res << x}
|
S("hello\n\n\nworld\n").each_line(S(''), chomp: true) {|x| res << x}
|
||||||
assert_equal(S("hello\n"), res[0])
|
assert_equal(S("hello"), res[0])
|
||||||
assert_equal(S("world"), res[1])
|
assert_equal(S("world\n"), res[1])
|
||||||
|
|
||||||
res = []
|
res = []
|
||||||
S("hello\r\n\r\nworld").each_line(S(''), chomp: true) {|x| res << x}
|
S("hello\r\n\r\nworld\r\n").each_line(S(''), chomp: true) {|x| res << x}
|
||||||
assert_equal(S("hello\r\n"), res[0])
|
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])
|
assert_equal(S("world"), res[1])
|
||||||
|
|
||||||
res = []
|
res = []
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue