diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-12-23 19:55:18 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-12-23 19:55:18 +0000 |
commit | c749064f9f250d79db6ada0fe7f1f0784c183baa (patch) | |
tree | 88f3c790bc442b74069069332367147bf2b8113f /io.c | |
parent | b4f2e2ba074fb8eb689769ca4623eedcc265092c (diff) | |
download | ruby-c749064f9f250d79db6ada0fe7f1f0784c183baa.tar.gz |
* io.c (appendline): should do multibyte aware RS search.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14554 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 22 |
1 files changed, 16 insertions, 6 deletions
@@ -1647,22 +1647,32 @@ io_read(int argc, VALUE *argv, VALUE io) } static int -appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp) +appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp, int mb) { VALUE str = *strp; int c = EOF; long limit = *lp; + rb_encoding *enc = io_read_encoding(fptr); do { long pending = READ_DATA_PENDING_COUNT(fptr); if (pending > 0) { - const char *p = READ_DATA_PENDING_PTR(fptr); - const char *e; + const char *s = READ_DATA_PENDING_PTR(fptr); + const char *p, *e; long last = 0, len = (c != EOF); if (limit > 0 && pending > limit) pending = limit; + p = s; + again: e = memchr(p, delim, pending); - if (e) pending = e - p + 1; + if (e) { + if (mb && + ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,(UChar*)s,(UChar*)e) != (UChar*)e) { + p = e + 1; + goto again; + } + pending = e - s + 1; + } len += pending; if (!NIL_P(str)) { last = RSTRING_LEN(str); @@ -1742,7 +1752,7 @@ rb_io_getline_fast(rb_io_t *fptr, unsigned char delim, long limit) int c, nolimit = 0; for (;;) { - c = appendline(fptr, delim, &str, &limit); + c = appendline(fptr, delim, &str, &limit, 0); if (c == EOF || c == delim) break; if (limit == 0) { nolimit = 1; @@ -1842,7 +1852,7 @@ rb_io_getline_1(VALUE rs, long limit, VALUE io) } newline = rsptr[rslen - 1]; - while ((c = appendline(fptr, newline, &str, &limit)) != EOF) { + while ((c = appendline(fptr, newline, &str, &limit, 1)) != EOF) { if (c == newline) { if (RSTRING_LEN(str) < rslen) continue; if (!rspara) rscheck(rsptr, rslen, rs); |