summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-string-ext/src
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems/mruby-string-ext/src')
-rw-r--r--mrbgems/mruby-string-ext/src/string.c127
1 files changed, 122 insertions, 5 deletions
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c
index ac3e82a45..ddceb03ff 100644
--- a/mrbgems/mruby-string-ext/src/string.c
+++ b/mrbgems/mruby-string-ext/src/string.c
@@ -44,12 +44,13 @@ mrb_str_byteslice(mrb_state *mrb, mrb_value str)
{
mrb_value a1;
mrb_int len;
- mrb_int argc;
- argc = mrb_get_args(mrb, "o|i", &a1, &len);
- if (argc == 2) {
+ if (mrb_get_argc(mrb) == 2) {
+ mrb_int pos;
+ mrb_get_args(mrb, "ii", &pos, &len);
return mrb_str_substr(mrb, str, mrb_fixnum(a1), len);
}
+ mrb_get_args(mrb, "o|i", &a1, &len);
switch (mrb_type(a1)) {
case MRB_TT_RANGE:
{
@@ -652,6 +653,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)
{
@@ -675,8 +788,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());
}