summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-string-ext
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems/mruby-string-ext')
-rw-r--r--mrbgems/mruby-string-ext/mrblib/string.rb93
-rw-r--r--mrbgems/mruby-string-ext/src/string.c66
-rw-r--r--mrbgems/mruby-string-ext/test/string.rb32
3 files changed, 181 insertions, 10 deletions
diff --git a/mrbgems/mruby-string-ext/mrblib/string.rb b/mrbgems/mruby-string-ext/mrblib/string.rb
index 45c631b94..1cfb7e2f5 100644
--- a/mrbgems/mruby-string-ext/mrblib/string.rb
+++ b/mrbgems/mruby-string-ext/mrblib/string.rb
@@ -1,4 +1,28 @@
class String
+
+ ##
+ # call-seq:
+ # string.clear -> string
+ #
+ # Makes string empty.
+ #
+ # a = "abcde"
+ # a.clear #=> ""
+ #
+ def clear
+ self.replace("")
+ end
+
+ ##
+ # call-seq:
+ # str.lstrip -> new_str
+ #
+ # Returns a copy of <i>str</i> with leading whitespace removed. See also
+ # <code>String#rstrip</code> and <code>String#strip</code>.
+ #
+ # " hello ".lstrip #=> "hello "
+ # "hello".lstrip #=> "hello"
+ #
def lstrip
a = 0
z = self.size - 1
@@ -6,6 +30,16 @@ class String
(z >= 0) ? self[a..z] : ""
end
+ ##
+ # call-seq:
+ # str.rstrip -> new_str
+ #
+ # Returns a copy of <i>str</i> with trailing whitespace removed. See also
+ # <code>String#lstrip</code> and <code>String#strip</code>.
+ #
+ # " hello ".rstrip #=> " hello"
+ # "hello".rstrip #=> "hello"
+ #
def rstrip
a = 0
z = self.size - 1
@@ -13,6 +47,15 @@ class String
(z >= 0) ? self[a..z] : ""
end
+ ##
+ # call-seq:
+ # str.strip -> new_str
+ #
+ # Returns a copy of <i>str</i> with leading and trailing whitespace removed.
+ #
+ # " hello ".strip #=> "hello"
+ # "\tgoodbye\r\n".strip #=> "goodbye"
+ #
def strip
a = 0
z = self.size - 1
@@ -21,31 +64,61 @@ class String
(z >= 0) ? self[a..z] : ""
end
+ ##
+ # call-seq:
+ # str.lstrip! -> self or nil
+ #
+ # Removes leading whitespace from <i>str</i>, returning <code>nil</code> if no
+ # change was made. See also <code>String#rstrip!</code> and
+ # <code>String#strip!</code>.
+ #
+ # " hello ".lstrip #=> "hello "
+ # "hello".lstrip! #=> nil
+ #
def lstrip!
s = self.lstrip
(s == self) ? nil : self.replace(s)
end
+ ##
+ # call-seq:
+ # str.rstrip! -> self or nil
+ #
+ # Removes trailing whitespace from <i>str</i>, returning <code>nil</code> if
+ # no change was made. See also <code>String#lstrip!</code> and
+ # <code>String#strip!</code>.
+ #
+ # " hello ".rstrip #=> " hello"
+ # "hello".rstrip! #=> nil
+ #
def rstrip!
s = self.rstrip
(s == self) ? nil : self.replace(s)
end
+ ##
+ # call-seq:
+ # str.strip! -> str or nil
+ #
+ # Removes leading and trailing whitespace from <i>str</i>. Returns
+ # <code>nil</code> if <i>str</i> was not altered.
+ #
def strip!
s = self.strip
(s == self) ? nil : self.replace(s)
end
-# call-seq:
-# str.casecmp(other_str) -> -1, 0, +1 or nil
-#
-# Case-insensitive version of <code>String#<=></code>.
-#
-# "abcdef".casecmp("abcde") #=> 1
-# "aBcDeF".casecmp("abcdef") #=> 0
-# "abcdef".casecmp("abcdefg") #=> -1
-# "abcdef".casecmp("ABCDEF") #=> 0
-#
+ ##
+ # call-seq:
+ # str.casecmp(other_str) -> -1, 0, +1 or nil
+ #
+ # Case-insensitive version of <code>String#<=></code>.
+ #
+ # "abcdef".casecmp("abcde") #=> 1
+ # "aBcDeF".casecmp("abcdef") #=> 0
+ # "abcdef".casecmp("abcdefg") #=> -1
+ # "abcdef".casecmp("ABCDEF") #=> 0
+ #
def casecmp(str)
self.downcase <=> str.to_str.downcase
rescue NoMethodError
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c
index 2c0a406ad..f04f12c4b 100644
--- a/mrbgems/mruby-string-ext/src/string.c
+++ b/mrbgems/mruby-string-ext/src/string.c
@@ -1,6 +1,8 @@
#include <ctype.h>
#include <string.h>
#include "mruby.h"
+#include "mruby/array.h"
+#include "mruby/class.h"
#include "mruby/string.h"
static mrb_value
@@ -175,6 +177,68 @@ mrb_str_oct(mrb_state *mrb, mrb_value self)
return mrb_str_to_inum(mrb, self, 8, FALSE);
}
+/*
+ * call-seq:
+ * string.chr -> string
+ *
+ * Returns a one-character string at the beginning of the string.
+ *
+ * a = "abcde"
+ * a.chr #=> "a"
+ */
+static mrb_value
+mrb_str_chr(mrb_state *mrb, mrb_value self)
+{
+ return mrb_str_substr(mrb, self, 0, 1);
+}
+
+/*
+ * call-seq:
+ * string.lines -> array of string
+ *
+ * Returns strings per line;
+ *
+ * a = "abc\ndef"
+ * a.lines #=> ["abc\n", "def"]
+ */
+static mrb_value
+mrb_str_lines(mrb_state *mrb, mrb_value self)
+{
+ mrb_value result;
+ mrb_value blk;
+ int ai;
+ mrb_int len;
+ mrb_value arg;
+ char *p = RSTRING_PTR(self), *t;
+ char *e = p + RSTRING_LEN(self);
+
+ mrb_get_args(mrb, "&", &blk);
+
+ result = mrb_ary_new(mrb);
+
+ if (!mrb_nil_p(blk)) {
+ while (p < e) {
+ t = p;
+ while (p < e && *p != '\n') p++;
+ if (*p == '\n') p++;
+ len = (mrb_int) (p - t);
+ arg = mrb_str_new(mrb, t, len);
+ mrb_yield_argv(mrb, blk, 1, &arg);
+ }
+ return self;
+ }
+ while (p < e) {
+ ai = mrb_gc_arena_save(mrb);
+ t = p;
+ while (p < e && *p != '\n') p++;
+ if (*p == '\n') p++;
+ len = (mrb_int) (p - t);
+ mrb_ary_push(mrb, result, mrb_str_new(mrb, t, len));
+ mrb_gc_arena_restore(mrb, ai);
+ }
+ return result;
+}
+
void
mrb_mruby_string_ext_gem_init(mrb_state* mrb)
{
@@ -190,6 +254,8 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
mrb_define_method(mrb, s, "end_with?", mrb_str_end_with, MRB_ARGS_REST());
mrb_define_method(mrb, s, "hex", mrb_str_hex, 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, "lines", mrb_str_lines, MRB_ARGS_NONE());
}
void
diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb
index 01712a607..72c919b35 100644
--- a/mrbgems/mruby-string-ext/test/string.rb
+++ b/mrbgems/mruby-string-ext/test/string.rb
@@ -161,3 +161,35 @@ assert('String#oct') do
assert_equal 8, "010".oct
assert_equal (-8), "-10".oct
end
+
+assert('String#chr') do
+ assert_equal "a", "abcde".chr
+end
+
+assert('String#lines') do
+ assert_equal ["Hel\n", "lo\n", "World!"], "Hel\nlo\nWorld!".lines
+ assert_equal ["Hel\n", "lo\n", "World!\n"], "Hel\nlo\nWorld!\n".lines
+ assert_equal ["\n", "\n", "\n"], "\n\n\n".lines
+ assert_equal [], "".lines
+end
+
+assert('String#clear') do
+ # embed string
+ s = "foo"
+ assert_equal("", s.clear)
+ assert_equal("", s)
+
+ # not embed string and not shared string
+ s = "foo" * 100
+ a = s
+ assert_equal("", s.clear)
+ assert_equal("", s)
+ assert_equal("", a)
+
+ # shared string
+ s = "foo" * 100
+ a = s[10, 90] # create shared string
+ assert_equal("", s.clear) # clear
+ assert_equal("", s) # s is cleared
+ assert_not_equal("", a) # a should not be affected
+end