diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-02-04 21:11:06 +0900 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-02-04 21:11:06 +0900 |
| commit | db2545cb3c61f55702be2abe8836b5190effa9c5 (patch) | |
| tree | 4b3cfd9dbed6bfb7eac0e92b524d5dd02cd284ab /src | |
| parent | 5fd9f68b2735d6c104c9945e374ff28309af7a39 (diff) | |
| parent | 69fd1a592560d321061790c94f93532db93dccb9 (diff) | |
| download | mruby-db2545cb3c61f55702be2abe8836b5190effa9c5.tar.gz mruby-db2545cb3c61f55702be2abe8836b5190effa9c5.zip | |
Merge pull request #4260 from shuujii/fix-symbol-size-with-mrb_utf8_string
Fix `Symbol#size` for multi-byte characters with `MRB_UTF8_STRING`
Diffstat (limited to 'src')
| -rw-r--r-- | src/string.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/src/string.c b/src/string.c index 52b869eca..148e2fee2 100644 --- a/src/string.c +++ b/src/string.c @@ -238,27 +238,36 @@ utf8len(const char* p, const char* e) return len; } -static mrb_int -utf8_strlen(mrb_value str, mrb_int len) +mrb_int +mrb_utf8_len(const char *str, mrb_int byte_len) { mrb_int total = 0; - char* p = RSTRING_PTR(str); - char* e = p; - if (RSTRING(str)->flags & MRB_STR_NO_UTF) { - return RSTRING_LEN(str); - } - e += len < 0 ? RSTRING_LEN(str) : len; - while (p<e) { + const char *p = str; + const char *e = p + byte_len; + + while (p < e) { p += utf8len(p, e); total++; } - if (RSTRING_LEN(str) == total) { - RSTRING(str)->flags |= MRB_STR_NO_UTF; - } return total; } -#define RSTRING_CHAR_LEN(s) utf8_strlen(s, -1) +static mrb_int +utf8_strlen(mrb_value str) +{ + mrb_int byte_len = RSTRING_LEN(str); + + if (RSTRING(str)->flags & MRB_STR_NO_UTF) { + return byte_len; + } + else { + mrb_int utf8_len = mrb_utf8_len(RSTRING_PTR(str), byte_len); + if (byte_len == utf8_len) RSTRING(str)->flags |= MRB_STR_NO_UTF; + return utf8_len; + } +} + +#define RSTRING_CHAR_LEN(s) utf8_strlen(s) /* map character index to byte offset index */ static mrb_int |
