Commit 2067f1f9 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge branch 'master' of github.com:mruby/mruby

parents 2ed70895 be3e36cb
...@@ -55,6 +55,10 @@ struct RString { ...@@ -55,6 +55,10 @@ struct RString {
#define RSTR_SET_SHARED_FLAG(s) ((s)->flags |= MRB_STR_SHARED) #define RSTR_SET_SHARED_FLAG(s) ((s)->flags |= MRB_STR_SHARED)
#define RSTR_UNSET_SHARED_FLAG(s) ((s)->flags &= ~MRB_STR_SHARED) #define RSTR_UNSET_SHARED_FLAG(s) ((s)->flags &= ~MRB_STR_SHARED)
#define RSTR_NOFREE_P(s) ((s)->flags & MRB_STR_NOFREE)
#define RSTR_SET_NOFREE_FLAG(s) ((s)->flags |= MRB_STR_NOFREE)
#define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE)
#define mrb_str_ptr(s) ((struct RString*)(mrb_ptr(s))) #define mrb_str_ptr(s) ((struct RString*)(mrb_ptr(s)))
#define RSTRING(s) mrb_str_ptr(s) #define RSTRING(s) mrb_str_ptr(s)
#define RSTRING_PTR(s) RSTR_PTR(RSTRING(s)) #define RSTRING_PTR(s) RSTR_PTR(RSTRING(s))
......
class String class String
##
# call-seq:
# string.clear -> string
#
# Makes string empty.
#
# a = "abcde"
# a.clear #=> ""
#
def clear
self.replace("")
end
## ##
# call-seq: # call-seq:
# str.lstrip -> new_str # str.lstrip -> new_str
......
...@@ -239,37 +239,6 @@ mrb_str_lines(mrb_state *mrb, mrb_value self) ...@@ -239,37 +239,6 @@ mrb_str_lines(mrb_state *mrb, mrb_value self)
return result; return result;
} }
/*
* call-seq:
* string.clear -> string
*
* Makes string empty.
*
* a = "abcde"
* a.clear #=> ""
*/
static mrb_value
mrb_str_clear(mrb_state *mrb, mrb_value str)
{
struct RString *s = mrb_str_ptr(str);
if (!RSTR_SHARED_P(s) && !RSTR_EMBED_P(s)) {
if (s->flags & MRB_STR_NOFREE) {
s->flags &= ~MRB_STR_NOFREE;
}
else {
mrb_free(mrb, s->as.heap.ptr);
}
s->as.heap.ptr = 0;
s->as.heap.len = 0;
}
RSTR_UNSET_SHARED_FLAG(s);
RSTR_SET_EMBED_FLAG(s);
RSTR_SET_EMBED_LEN(s, 0);
RSTRING_PTR(str)[0] = '\0';
return str;
}
void void
mrb_mruby_string_ext_gem_init(mrb_state* mrb) mrb_mruby_string_ext_gem_init(mrb_state* mrb)
{ {
...@@ -287,7 +256,6 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb) ...@@ -287,7 +256,6 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
mrb_define_method(mrb, s, "oct", mrb_str_oct, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "oct", mrb_str_oct, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "chr", mrb_str_chr, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "chr", mrb_str_chr, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "lines", mrb_str_lines, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "lines", mrb_str_lines, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "clear", mrb_str_clear, MRB_ARGS_NONE());
} }
void void
......
...@@ -106,7 +106,7 @@ mrb_str_modify(mrb_state *mrb, struct RString *s) ...@@ -106,7 +106,7 @@ mrb_str_modify(mrb_state *mrb, struct RString *s)
RSTR_UNSET_SHARED_FLAG(s); RSTR_UNSET_SHARED_FLAG(s);
return; return;
} }
if (s->flags & MRB_STR_NOFREE) { if (RSTR_NOFREE_P(s)) {
char *p = s->as.heap.ptr; char *p = s->as.heap.ptr;
s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)s->as.heap.len+1); s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)s->as.heap.len+1);
...@@ -115,7 +115,7 @@ mrb_str_modify(mrb_state *mrb, struct RString *s) ...@@ -115,7 +115,7 @@ mrb_str_modify(mrb_state *mrb, struct RString *s)
} }
RSTR_PTR(s)[s->as.heap.len] = '\0'; RSTR_PTR(s)[s->as.heap.len] = '\0';
s->as.heap.aux.capa = s->as.heap.len; s->as.heap.aux.capa = s->as.heap.len;
s->flags &= ~MRB_STR_NOFREE; RSTR_UNSET_NOFREE_FLAG(s);
return; return;
} }
} }
...@@ -302,7 +302,7 @@ mrb_gc_free_str(mrb_state *mrb, struct RString *str) ...@@ -302,7 +302,7 @@ mrb_gc_free_str(mrb_state *mrb, struct RString *str)
/* no code */; /* no code */;
else if (RSTR_SHARED_P(str)) else if (RSTR_SHARED_P(str))
str_decref(mrb, str->as.heap.aux.shared); str_decref(mrb, str->as.heap.aux.shared);
else if ((str->flags & MRB_STR_NOFREE) == 0) else if (!RSTR_NOFREE_P(str))
mrb_free(mrb, str->as.heap.ptr); mrb_free(mrb, str->as.heap.ptr);
} }
...@@ -340,10 +340,10 @@ str_make_shared(mrb_state *mrb, struct RString *s) ...@@ -340,10 +340,10 @@ str_make_shared(mrb_state *mrb, struct RString *s)
shared->nofree = FALSE; shared->nofree = FALSE;
shared->ptr = s->as.heap.ptr; shared->ptr = s->as.heap.ptr;
} }
else if (s->flags & MRB_STR_NOFREE) { else if (RSTR_NOFREE_P(s)) {
shared->nofree = TRUE; shared->nofree = TRUE;
shared->ptr = s->as.heap.ptr; shared->ptr = s->as.heap.ptr;
s->flags &= ~MRB_STR_NOFREE; RSTR_UNSET_NOFREE_FLAG(s);
} }
else { else {
shared->nofree = FALSE; shared->nofree = FALSE;
...@@ -1368,14 +1368,17 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) ...@@ -1368,14 +1368,17 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
long len; long len;
len = RSTR_LEN(s2); len = RSTR_LEN(s2);
if (RSTR_SHARED_P(s1)) {
str_decref(mrb, s1->as.heap.aux.shared);
}
else if (!RSTR_EMBED_P(s1) && !RSTR_NOFREE_P(s1)) {
mrb_free(mrb, s1->as.heap.ptr);
}
RSTR_UNSET_NOFREE_FLAG(s1);
if (RSTR_SHARED_P(s2)) { if (RSTR_SHARED_P(s2)) {
L_SHARE: L_SHARE:
if (RSTR_SHARED_P(s1)) {
str_decref(mrb, s1->as.heap.aux.shared);
}
else if (!RSTR_EMBED_P(s1) && !(s1->flags & MRB_STR_NOFREE)) {
mrb_free(mrb, s1->as.heap.ptr);
}
RSTR_UNSET_EMBED_FLAG(s1); RSTR_UNSET_EMBED_FLAG(s1);
s1->as.heap.ptr = s2->as.heap.ptr; s1->as.heap.ptr = s2->as.heap.ptr;
s1->as.heap.len = len; s1->as.heap.len = len;
...@@ -1385,6 +1388,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) ...@@ -1385,6 +1388,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
} }
else { else {
if (len <= RSTRING_EMBED_LEN_MAX) { if (len <= RSTRING_EMBED_LEN_MAX) {
RSTR_UNSET_SHARED_FLAG(s1);
RSTR_SET_EMBED_FLAG(s1); RSTR_SET_EMBED_FLAG(s1);
memcpy(s1->as.ary, RSTR_PTR(s2), len); memcpy(s1->as.ary, RSTR_PTR(s2), len);
RSTR_SET_EMBED_LEN(s1, len); RSTR_SET_EMBED_LEN(s1, len);
......
...@@ -320,6 +320,13 @@ assert('String#replace', '15.2.10.5.28') do ...@@ -320,6 +320,13 @@ assert('String#replace', '15.2.10.5.28') do
b.replace(c); b.replace(c);
c.replace(b); c.replace(b);
assert_equal c, b assert_equal c, b
# shared string
s = "foo" * 100
a = s[10, 90] # create shared string
assert_equal("", s.replace("")) # clear
assert_equal("", s) # s is cleared
assert_not_equal("", a) # a should not be affected
end end
assert('String#reverse', '15.2.10.5.29') do assert('String#reverse', '15.2.10.5.29') do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment