mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Add String#delete_{prefix,suffix}; CRuby2.5
This commit is contained in:
@@ -650,6 +650,118 @@ mrb_str_upto(mrb_state *mrb, mrb_value beg)
|
||||
return beg;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* str.delete_prefix!(prefix) -> self or nil
|
||||
*
|
||||
* Deletes leading <code>prefix</code> from <i>str</i>, returning
|
||||
* <code>nil</code> if no change was made.
|
||||
*
|
||||
* "hello".delete_prefix!("hel") #=> "lo"
|
||||
* "hello".delete_prefix!("llo") #=> nil
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_str_del_prefix_bang(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int plen, slen;
|
||||
char *ptr, *s;
|
||||
struct RString *str = RSTRING(self);
|
||||
|
||||
mrb_get_args(mrb, "s", &ptr, &plen);
|
||||
slen = RSTR_LEN(str);
|
||||
if (plen > slen) return mrb_nil_value();
|
||||
s = RSTR_PTR(str);
|
||||
if (memcmp(s, ptr, plen) != 0) return mrb_nil_value();
|
||||
if (!MRB_FROZEN_P(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
|
||||
str->as.heap.ptr += plen;
|
||||
}
|
||||
else {
|
||||
mrb_str_modify(mrb, str);
|
||||
s = RSTR_PTR(str);
|
||||
memmove(s, s+plen, slen-plen);
|
||||
}
|
||||
RSTR_SET_LEN(str, slen-plen);
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* str.delete_prefix(prefix) -> new_str
|
||||
*
|
||||
* Returns a copy of <i>str</i> with leading <code>prefix</code> deleted.
|
||||
*
|
||||
* "hello".delete_prefix("hel") #=> "lo"
|
||||
* "hello".delete_prefix("llo") #=> "hello"
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_str_del_prefix(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int plen, slen;
|
||||
char *ptr;
|
||||
|
||||
mrb_get_args(mrb, "s", &ptr, &plen);
|
||||
slen = RSTRING_LEN(self);
|
||||
if (plen > slen) return mrb_str_dup(mrb, self);
|
||||
if (memcmp(RSTRING_PTR(self), ptr, plen) != 0)
|
||||
return mrb_str_dup(mrb, self);
|
||||
return mrb_str_substr(mrb, self, plen, slen-plen);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* str.delete_suffix!(suffix) -> self or nil
|
||||
*
|
||||
* Deletes trailing <code>suffix</code> from <i>str</i>, returning
|
||||
* <code>nil</code> if no change was made.
|
||||
*
|
||||
* "hello".delete_suffix!("llo") #=> "he"
|
||||
* "hello".delete_suffix!("hel") #=> nil
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_str_del_suffix_bang(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int plen, slen;
|
||||
char *ptr, *s;
|
||||
struct RString *str = RSTRING(self);
|
||||
|
||||
mrb_get_args(mrb, "s", &ptr, &plen);
|
||||
slen = RSTR_LEN(str);
|
||||
if (plen > slen) return mrb_nil_value();
|
||||
s = RSTR_PTR(str);
|
||||
if (memcmp(s+slen-plen, ptr, plen) != 0) return mrb_nil_value();
|
||||
if (!MRB_FROZEN_P(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
|
||||
/* no need to modify string */
|
||||
}
|
||||
else {
|
||||
mrb_str_modify(mrb, str);
|
||||
}
|
||||
RSTR_SET_LEN(str, slen-plen);
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* str.delete_suffix(suffix) -> new_str
|
||||
*
|
||||
* Returns a copy of <i>str</i> with leading <code>suffix</code> deleted.
|
||||
*
|
||||
* "hello".delete_suffix("hel") #=> "lo"
|
||||
* "hello".delete_suffix("llo") #=> "hello"
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_str_del_suffix(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int plen, slen;
|
||||
char *ptr;
|
||||
|
||||
mrb_get_args(mrb, "s", &ptr, &plen);
|
||||
slen = RSTRING_LEN(self);
|
||||
if (plen > slen) return mrb_str_dup(mrb, self);
|
||||
if (memcmp(RSTRING_PTR(self)+slen-plen, ptr, plen) != 0)
|
||||
return mrb_str_dup(mrb, self);
|
||||
return mrb_str_substr(mrb, self, 0, slen-plen);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_string_ext_gem_init(mrb_state* mrb)
|
||||
{
|
||||
@@ -673,8 +785,12 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
|
||||
mrb_define_method(mrb, s, "succ!", mrb_str_succ_bang, MRB_ARGS_NONE());
|
||||
mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next"), mrb_intern_lit(mrb, "succ"));
|
||||
mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next!"), mrb_intern_lit(mrb, "succ!"));
|
||||
mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, s, "upto", mrb_str_upto, MRB_ARGS_ANY());
|
||||
mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, s, "upto", mrb_str_upto, MRB_ARGS_ANY());
|
||||
mrb_define_method(mrb, s, "delete_prefix!", mrb_str_del_prefix_bang, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, s, "delete_prefix", mrb_str_del_prefix, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, s, "delete_suffix!", mrb_str_del_suffix_bang, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, s, "delete_suffix", mrb_str_del_suffix, MRB_ARGS_REQ(1));
|
||||
|
||||
mrb_define_method(mrb, mrb->fixnum_class, "chr", mrb_fixnum_chr, MRB_ARGS_NONE());
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# coding: utf-8
|
||||
##
|
||||
# String(Ext) Test
|
||||
|
||||
@@ -665,3 +666,17 @@ assert('String#each_codepoint(UTF-8)') do
|
||||
end
|
||||
assert_equal expect, cp
|
||||
end if UTF8STRING
|
||||
|
||||
assert('String#delete_prefix') do
|
||||
assert_equal "llo", "hello".delete_prefix("he")
|
||||
assert_equal "hello", "hello".delete_prefix("llo")
|
||||
assert_equal "llo", "hello".delete_prefix!("he")
|
||||
assert_nil "hello".delete_prefix!("llo")
|
||||
end
|
||||
|
||||
assert('String#delete_suffix') do
|
||||
assert_equal "he", "hello".delete_suffix("llo")
|
||||
assert_equal "hello", "hello".delete_suffix("he")
|
||||
assert_equal "he", "hello".delete_suffix!("llo")
|
||||
assert_nil "hello".delete_suffix!("he")
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user