summaryrefslogtreecommitdiffhomepage
path: root/src/string.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2019-06-26 13:22:42 +0900
committerGitHub <[email protected]>2019-06-26 13:22:42 +0900
commit014f9282291a89dc9f59ba7ffa42d6d49283266f (patch)
tree17a5b9f88c98376e1194b03a8d4fa6e8ddd53856 /src/string.c
parent84779f01703c4cfb31c74b34a864d3208a175a77 (diff)
parent11e09dc5dbd6ddaabf145bbee62741f4191eca79 (diff)
downloadmruby-014f9282291a89dc9f59ba7ffa42d6d49283266f.tar.gz
mruby-014f9282291a89dc9f59ba7ffa42d6d49283266f.zip
Merge pull request #4524 from dearblue/reverse-utf8
Change to UTF-8 string reversing with in place
Diffstat (limited to 'src/string.c')
-rw-r--r--src/string.c64
1 files changed, 29 insertions, 35 deletions
diff --git a/src/string.c b/src/string.c
index 7b58705dd..b980ee760 100644
--- a/src/string.c
+++ b/src/string.c
@@ -1674,6 +1674,18 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
return mrb_obj_value(p_str);
}
+static inline void
+str_reverse(char *p, char *e)
+{
+ char c;
+
+ while (p < e) {
+ c = *p;
+ *p++ = *e;
+ *e-- = c;
+ }
+}
+
/* 15.2.10.5.30 */
/*
* call-seq:
@@ -1684,53 +1696,35 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
static mrb_value
mrb_str_reverse_bang(mrb_state *mrb, mrb_value str)
{
+ struct RString *s = mrb_str_ptr(str);
+ char *p, *e;
+
#ifdef MRB_UTF8_STRING
mrb_int utf8_len = RSTRING_CHAR_LEN(str);
- mrb_int len = RSTRING_LEN(str);
-
- if (utf8_len == len) goto bytes;
- if (utf8_len > 1) {
- char *buf;
- char *p, *e, *r;
-
- mrb_str_modify(mrb, mrb_str_ptr(str));
- len = RSTRING_LEN(str);
- buf = (char*)mrb_malloc(mrb, (size_t)len);
- p = buf;
- e = buf + len;
-
- memcpy(buf, RSTRING_PTR(str), len);
- r = RSTRING_PTR(str) + len;
+ mrb_int len = RSTR_LEN(s);
+ if (utf8_len < 2) return str;
+ if (utf8_len < len) {
+ mrb_str_modify(mrb, s);
+ p = RSTR_PTR(s);
+ e = p + RSTR_LEN(s);
while (p<e) {
mrb_int clen = utf8len(p, e);
- r -= clen;
- memcpy(r, p, clen);
+ str_reverse(p, p + clen - 1);
p += clen;
}
- mrb_free(mrb, buf);
+ goto bytes;
}
- return str;
-
- bytes:
#endif
- {
- struct RString *s = mrb_str_ptr(str);
- char *p, *e;
- char c;
+ if (RSTR_LEN(s) > 1) {
mrb_str_modify(mrb, s);
- if (RSTR_LEN(s) > 1) {
- p = RSTR_PTR(s);
- e = p + RSTR_LEN(s) - 1;
- while (p < e) {
- c = *p;
- *p++ = *e;
- *e-- = c;
- }
- }
- return str;
+ bytes:
+ p = RSTR_PTR(s);
+ e = p + RSTR_LEN(s) - 1;
+ str_reverse(p, e);
}
+ return str;
}
/* ---------------------------------- */