summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--build_config/ci/gcc-clang.rb6
-rw-r--r--examples/mrbgems/c_and_ruby_extension_example/src/example.c5
-rw-r--r--examples/mrbgems/c_extension_example/src/example.c5
-rw-r--r--include/mruby.h14
-rw-r--r--include/mruby/array.h2
-rw-r--r--include/mruby/hash.h2
-rw-r--r--include/mruby/string.h21
-rw-r--r--mrbgems/mruby-io/src/file.c4
-rw-r--r--mrbgems/mruby-kernel-ext/src/kernel.c43
-rw-r--r--mrbgems/mruby-sprintf/src/sprintf.c2
-rw-r--r--mrbgems/mruby-string-ext/mrblib/string.rb30
-rw-r--r--mrbgems/mruby-string-ext/src/string.c64
-rw-r--r--mrbgems/mruby-struct/src/struct.c2
-rw-r--r--mrblib/string.rb44
-rw-r--r--src/class.c2
-rw-r--r--src/error.c2
-rw-r--r--src/kernel.c1
-rw-r--r--src/object.c53
-rw-r--r--src/string.c58
-rw-r--r--src/vm.c6
20 files changed, 185 insertions, 181 deletions
diff --git a/build_config/ci/gcc-clang.rb b/build_config/ci/gcc-clang.rb
index aa4a1a87d..eb4331e65 100644
--- a/build_config/ci/gcc-clang.rb
+++ b/build_config/ci/gcc-clang.rb
@@ -6,7 +6,7 @@ MRuby::Build.new('full-debug') do |conf|
# include all core GEMs
conf.gembox 'full-core'
- conf.cc.defines += %w(MRB_GC_STRESS MRB_USE_DEBUG_HOOK)
+ conf.cc.defines += %w(MRB_GC_STRESS MRB_USE_DEBUG_HOOK MRB_UTF8_STRING)
conf.enable_test
end
@@ -18,7 +18,7 @@ MRuby::Build.new do |conf|
conf.gembox 'full-core'
conf.gem :core => 'mruby-bin-debugger'
conf.compilers.each do |c|
- c.defines += %w(MRB_GC_FIXED_ARENA)
+ c.defines += %w(MRB_GC_FIXED_ARENA MRB_UTF8_STRING)
end
conf.enable_bintest
conf.enable_test
@@ -30,7 +30,7 @@ MRuby::Build.new('cxx_abi') do |conf|
conf.gembox 'full-core'
conf.cc.flags += %w(-fpermissive)
conf.compilers.each do |c|
- c.defines += %w(MRB_GC_FIXED_ARENA)
+ c.defines += %w(MRB_GC_FIXED_ARENA MRB_UTF8_STRING)
end
conf.enable_test
diff --git a/examples/mrbgems/c_and_ruby_extension_example/src/example.c b/examples/mrbgems/c_and_ruby_extension_example/src/example.c
index 1fdb1078d..f1d7971c2 100644
--- a/examples/mrbgems/c_and_ruby_extension_example/src/example.c
+++ b/examples/mrbgems/c_and_ruby_extension_example/src/example.c
@@ -5,9 +5,8 @@
static mrb_value
mrb_c_method(mrb_state *mrb, mrb_value self)
{
- mrb_value self_str = mrb_str_to_str(mrb, self);
-
- printf("%s: A C Extension\n", mrb_str_to_cstr(mrb, self_str));
+ mrb_ensure_string_type(mrb, self);
+ printf("%s: A C Extension\n", mrb_str_to_cstr(mrb, self));
return self;
}
diff --git a/examples/mrbgems/c_extension_example/src/example.c b/examples/mrbgems/c_extension_example/src/example.c
index 727c7c698..fe872c933 100644
--- a/examples/mrbgems/c_extension_example/src/example.c
+++ b/examples/mrbgems/c_extension_example/src/example.c
@@ -5,9 +5,8 @@
static mrb_value
mrb_c_method(mrb_state *mrb, mrb_value self)
{
- mrb_value self_str = mrb_str_to_str(mrb, self);
-
- printf("%s: A C Extension\n", mrb_str_to_cstr(mrb, self_str));
+ mrb_ensure_string_type(mrb, self);
+ printf("%s: A C Extension\n", mrb_str_to_cstr(mrb, self));
return self;
}
diff --git a/include/mruby.h b/include/mruby.h
index 87c902df0..4e0f9dddc 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -1249,7 +1249,6 @@ MRB_API mrb_sym mrb_obj_to_sym(mrb_state *mrb, mrb_value name);
MRB_API mrb_bool mrb_obj_eq(mrb_state *mrb, mrb_value a, mrb_value b);
MRB_API mrb_bool mrb_obj_equal(mrb_state *mrb, mrb_value a, mrb_value b);
MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
-MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base);
#ifndef MRB_NO_FLOAT
MRB_API mrb_value mrb_to_float(mrb_state *mrb, mrb_value val);
#endif
@@ -1368,11 +1367,22 @@ MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj);
/* mrb_gc_unregister() removes the object from GC root. */
MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj);
+/* type conversion/check functions */
+MRB_API mrb_value mrb_ensure_array_type(mrb_state *mrb, mrb_value self);
+MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self);
+MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash);
+MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash);
+MRB_API mrb_value mrb_ensure_string_type(mrb_state *mrb, mrb_value str);
+MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str);
+/* obsolete: use mrb_ensure_string_type() instead */
+#define mrb_string_type(mrb, str) mrb_ensure_string_type(mrb,str)
+#define mrb_to_str(mrb, str) mrb_ensure_string_type(mrb,str)
+/* obsolete: use mrb_obj_as_string() instead */
+#define mrb_str_to_str(mrb, str) mrb_obj_as_string(mrb, str)
MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val);
#define mrb_as_int(mrb, val) mrb_integer(mrb_to_int(mrb, val))
/* string type checking (contrary to the name, it doesn't convert) */
-MRB_API mrb_value mrb_to_str(mrb_state *mrb, mrb_value val);
MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t);
MRB_INLINE void mrb_check_frozen(mrb_state *mrb, void *o)
diff --git a/include/mruby/array.h b/include/mruby/array.h
index e8a003e47..8bb652472 100644
--- a/include/mruby/array.h
+++ b/include/mruby/array.h
@@ -204,8 +204,6 @@ MRB_API void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val
* @param other The array to replace it with.
*/
MRB_API void mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other);
-MRB_API mrb_value mrb_ensure_array_type(mrb_state *mrb, mrb_value self);
-MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self);
/*
* Unshift an element into the array
diff --git a/include/mruby/hash.h b/include/mruby/hash.h
index 749ea3869..1b37a12d4 100644
--- a/include/mruby/hash.h
+++ b/include/mruby/hash.h
@@ -37,8 +37,6 @@ struct RHash {
size_t mrb_hash_memsize(mrb_value obj);
MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa);
-MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash);
-MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash);
/*
* Initializes a new hash.
diff --git a/include/mruby/string.h b/include/mruby/string.h
index 9c88a0856..b214aa7c8 100644
--- a/include/mruby/string.h
+++ b/include/mruby/string.h
@@ -324,20 +324,6 @@ MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len);
*/
MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
-/**
- * Returns a Ruby string type.
- *
- *
- * @param mrb The current mruby state.
- * @param str Ruby string.
- * @return [mrb_value] A Ruby string.
- */
-MRB_API mrb_value mrb_ensure_string_type(mrb_state *mrb, mrb_value str);
-MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str);
-/* obsolete: use mrb_ensure_string_type() instead */
-MRB_API mrb_value mrb_string_type(mrb_state *mrb, mrb_value str);
-
-
MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa);
#define mrb_str_buf_new(mrb, capa) mrb_str_new_capa(mrb, (capa))
@@ -373,13 +359,6 @@ MRB_API mrb_value mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, m
MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck);
/**
- * Returns a converted string type.
- * For type checking, non converting `mrb_to_str` is recommended.
- * obsolete: use `mrb_obj_as_string()` instead.
- */
-#define mrb_str_to_str(mrb, str) mrb_obj_as_string(mrb, str)
-
-/**
* Returns true if the strings match and false if the strings don't match.
*
* @param mrb The current mruby state.
diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c
index 6c62db662..a19858a63 100644
--- a/mrbgems/mruby-io/src/file.c
+++ b/mrbgems/mruby-io/src/file.c
@@ -116,14 +116,14 @@ static mrb_value
mrb_file_s_unlink(mrb_state *mrb, mrb_value obj)
{
const mrb_value *argv;
- mrb_value pathv;
mrb_int argc, i;
char *path;
mrb_get_args(mrb, "*", &argv, &argc);
for (i = 0; i < argc; i++) {
const char *utf8_path;
- pathv = mrb_ensure_string_type(mrb, argv[i]);
+ mrb_value pathv = argv[i];
+ mrb_ensure_string_type(mrb, pathv);
utf8_path = RSTRING_CSTR(mrb, pathv);
path = mrb_locale_from_utf8(utf8_path, -1);
if (UNLINK(path) < 0) {
diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c
index 15b4c5f72..2d93e4fef 100644
--- a/mrbgems/mruby-kernel-ext/src/kernel.c
+++ b/mrbgems/mruby-kernel-ext/src/kernel.c
@@ -3,6 +3,8 @@
#include <mruby/array.h>
#include <mruby/hash.h>
#include <mruby/range.h>
+#include <mruby/string.h>
+#include <mruby/numeric.h>
#include <mruby/presym.h>
static mrb_value
@@ -107,11 +109,43 @@ mrb_f_method(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_f_integer(mrb_state *mrb, mrb_value self)
{
- mrb_value arg;
+ mrb_value val, tmp;
mrb_int base = 0;
- mrb_get_args(mrb, "o|i", &arg, &base);
- return mrb_convert_to_integer(mrb, arg, base);
+ mrb_get_args(mrb, "o|i", &val, &base);
+ if (mrb_nil_p(val)) {
+ if (base != 0) goto arg_error;
+ mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer");
+ }
+ switch (mrb_type(val)) {
+#ifndef MRB_NO_FLOAT
+ case MRB_TT_FLOAT:
+ if (base != 0) goto arg_error;
+ return mrb_float_to_integer(mrb, val);
+#endif
+
+ case MRB_TT_INTEGER:
+ if (base != 0) goto arg_error;
+ return val;
+
+ case MRB_TT_STRING:
+ string_conv:
+ return mrb_str_to_inum(mrb, val, base, TRUE);
+
+ default:
+ break;
+ }
+ if (base != 0) {
+ tmp = mrb_obj_as_string(mrb, val);
+ if (mrb_string_p(tmp)) {
+ val = tmp;
+ goto string_conv;
+ }
+arg_error:
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
+ }
+ /* to raise TypeError */
+ return mrb_to_int(mrb, val);
}
#ifndef MRB_NO_FLOAT
@@ -202,7 +236,8 @@ mrb_f_hash(mrb_state *mrb, mrb_value self)
if (mrb_nil_p(arg) || (mrb_array_p(arg) && RARRAY_LEN(arg) == 0)) {
return mrb_hash_new(mrb);
}
- return mrb_ensure_hash_type(mrb, arg);
+ mrb_ensure_hash_type(mrb, arg);
+ return arg;
}
void
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c
index ba5ba4cda..93ddf2ad5 100644
--- a/mrbgems/mruby-sprintf/src/sprintf.c
+++ b/mrbgems/mruby-sprintf/src/sprintf.c
@@ -586,7 +586,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm
++argc;
--argv;
- mrb_to_str(mrb, fmt);
+ mrb_ensure_string_type(mrb, fmt);
p = RSTRING_PTR(fmt);
end = p + RSTRING_LEN(fmt);
blen = 0;
diff --git a/mrbgems/mruby-string-ext/mrblib/string.rb b/mrbgems/mruby-string-ext/mrblib/string.rb
index 2b3071567..d485c51ef 100644
--- a/mrbgems/mruby-string-ext/mrblib/string.rb
+++ b/mrbgems/mruby-string-ext/mrblib/string.rb
@@ -111,36 +111,6 @@ class String
(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
- #
- def casecmp(str)
- self.downcase <=> str.__to_str.downcase
- rescue NoMethodError
- nil
- end
-
- ##
- # call-seq:
- # str.casecmp?(other) -> true, false, or nil
- #
- # Returns true if str and other_str are equal after case folding,
- # false if they are not equal, and nil if other_str is not a string.
-
- def casecmp?(str)
- c = self.casecmp(str)
- return nil if c.nil?
- return c == 0
- end
-
def partition(sep)
raise TypeError, "type mismatch: #{sep.class} given" unless sep.is_a? String
n = index(sep)
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c
index f5f46c082..8fafcc089 100644
--- a/mrbgems/mruby-string-ext/src/string.c
+++ b/mrbgems/mruby-string-ext/src/string.c
@@ -195,14 +195,14 @@ static mrb_value
mrb_str_start_with(mrb_state *mrb, mrb_value self)
{
const mrb_value *argv;
- mrb_value sub;
mrb_int argc, i;
mrb_get_args(mrb, "*", &argv, &argc);
for (i = 0; i < argc; i++) {
size_t len_l, len_r;
int ai = mrb_gc_arena_save(mrb);
- sub = mrb_ensure_string_type(mrb, argv[i]);
+ mrb_value sub = argv[i];
+ mrb_ensure_string_type(mrb, sub);
mrb_gc_arena_restore(mrb, ai);
len_l = RSTRING_LEN(self);
len_r = RSTRING_LEN(sub);
@@ -225,14 +225,14 @@ static mrb_value
mrb_str_end_with(mrb_state *mrb, mrb_value self)
{
const mrb_value *argv;
- mrb_value sub;
mrb_int argc, i;
mrb_get_args(mrb, "*", &argv, &argc);
for (i = 0; i < argc; i++) {
size_t len_l, len_r;
int ai = mrb_gc_arena_save(mrb);
- sub = mrb_ensure_string_type(mrb, argv[i]);
+ mrb_value sub = argv[i];
+ mrb_ensure_string_type(mrb, sub);
mrb_gc_arena_restore(mrb, ai);
len_l = RSTRING_LEN(self);
len_r = RSTRING_LEN(sub);
@@ -1174,6 +1174,60 @@ mrb_str_del_suffix(mrb_state *mrb, mrb_value self)
return mrb_str_substr(mrb, self, 0, slen-plen);
}
+#define lesser(a,b) (((a)>(b))?(b):(a))
+
+/*
+ * 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
+ */
+static mrb_value
+mrb_str_casecmp(mrb_state *mrb, mrb_value self)
+{
+ mrb_value str;
+
+ mrb_get_args(mrb, "o", &str);
+ if (!mrb_string_p(str)) return mrb_nil_value();
+
+ struct RString *s1 = mrb_str_ptr(self);
+ struct RString *s2 = mrb_str_ptr(str);
+ mrb_int len = lesser(RSTR_LEN(s1), RSTR_LEN(s2));
+ char *p1 = RSTR_PTR(s1);
+ char *p2 = RSTR_PTR(s2);
+
+ for (mrb_int i=0; i<len; i++) {
+ int c1 = p1[i], c2 = p2[i];
+ if (ISASCII(c1) && ISUPPER(c1)) c1 = TOLOWER(c1);
+ if (ISASCII(c2) && ISUPPER(c2)) c2 = TOLOWER(c2);
+ if (c1 > c2) return mrb_fixnum_value(1);
+ if (c1 < c2) return mrb_fixnum_value(-1);
+ }
+ if (RSTR_LEN(s1) == RSTR_LEN(s2)) return mrb_fixnum_value(0);
+ if (RSTR_LEN(s1) > RSTR_LEN(s2)) return mrb_fixnum_value(1);
+ return mrb_fixnum_value(-1);
+}
+
+/*
+ * call-seq:
+ * str.casecmp?(other) -> true, false, or nil
+ *
+ * Returns true if str and other_str are equal after case folding,
+ * false if they are not equal, and nil if other is not a string.
+ */
+static mrb_value
+mrb_str_casecmp_p(mrb_state *mrb, mrb_value self)
+{
+ mrb_value c = mrb_str_casecmp(mrb, self);
+ if (mrb_nil_p(c)) return c;
+ return mrb_bool_value(mrb_fixnum(c) == 0);
+}
+
static mrb_value
mrb_str_lines(mrb_state *mrb, mrb_value self)
{
@@ -1231,6 +1285,8 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
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, s, "casecmp", mrb_str_casecmp, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, s, "casecmp?", mrb_str_casecmp_p, MRB_ARGS_REQ(1));
mrb_define_method(mrb, s, "__lines", mrb_str_lines, MRB_ARGS_NONE());
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c
index df76d7a33..e8f06b802 100644
--- a/mrbgems/mruby-struct/src/struct.c
+++ b/mrbgems/mruby-struct/src/struct.c
@@ -202,7 +202,7 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl
}
else {
/* old style: should we warn? */
- mrb_to_str(mrb, name);
+ mrb_ensure_string_type(mrb, name);
id = mrb_obj_to_sym(mrb, name);
if (!mrb_const_name_p(mrb, RSTRING_PTR(name), RSTRING_LEN(name))) {
mrb_name_error(mrb, id, "identifier %v needs to be constant", name);
diff --git a/mrblib/string.rb b/mrblib/string.rb
index 675026e73..2b3178688 100644
--- a/mrblib/string.rb
+++ b/mrblib/string.rb
@@ -42,32 +42,6 @@ class String
self
end
- # private method for gsub/sub
- def __sub_replace(pre, m, post)
- s = ""
- i = 0
- while j = index("\\", i)
- break if j == length-1
- t = case self[j+1]
- when "\\"
- "\\"
- when "`"
- pre
- when "&", "0"
- m
- when "'"
- post
- when "1", "2", "3", "4", "5", "6", "7", "8", "9"
- ""
- else
- self[j, 2]
- end
- s += self[i, j-i] + t
- i = j + 2
- end
- s + self[i, length-i]
- end
-
##
# Replace all matches of +pattern+ with +replacement+.
# Call block (if given) for each match and replace
@@ -84,9 +58,6 @@ class String
if args.length == 2 && block
block = nil
end
- if !replace.nil? || !block
- replace.__to_str
- end
offset = 0
result = []
while found = index(pattern, offset)
@@ -95,7 +66,7 @@ class String
result << if block
block.call(pattern).to_s
else
- replace.__sub_replace(self[0, found], pattern, self[offset..-1] || "")
+ self.__sub_replace(replace, pattern, found)
end
if plen == 0
result << self[offset, 1]
@@ -144,25 +115,20 @@ class String
end
pattern, replace = *args
- pattern.__to_str
if args.length == 2 && block
block = nil
end
- unless block
- replace.__to_str
- end
result = []
- this = dup
found = index(pattern)
- return this unless found
- result << this[0, found]
+ return self.dup unless found
+ result << self[0, found]
offset = found + pattern.length
result << if block
block.call(pattern).to_s
else
- replace.__sub_replace(this[0, found], pattern, this[offset..-1] || "")
+ self.__sub_replace(replace, pattern, found)
end
- result << this[offset..-1] if offset < length
+ result << self[offset..-1] if offset < length
result.join
end
diff --git a/src/class.c b/src/class.c
index 855a7715c..b683deda0 100644
--- a/src/class.c
+++ b/src/class.c
@@ -2379,7 +2379,7 @@ mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
}
/* const get with class path string */
- path = mrb_ensure_string_type(mrb, path);
+ mrb_ensure_string_type(mrb, path);
ptr = RSTRING_PTR(path);
len = RSTRING_LEN(path);
off = 0;
diff --git a/src/error.c b/src/error.c
index 0ef7bc9c1..206d1a0e8 100644
--- a/src/error.c
+++ b/src/error.c
@@ -27,7 +27,7 @@ mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len)
MRB_API mrb_value
mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str)
{
- mrb_to_str(mrb, str);
+ mrb_ensure_string_type(mrb, str);
return mrb_obj_new(mrb, c, 1, &str);
}
diff --git a/src/kernel.c b/src/kernel.c
index 812229ba7..14922b39a 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -652,7 +652,6 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */
mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */
mrb_define_method(mrb, krn, "__to_int", mrb_to_int, MRB_ARGS_NONE()); /* internal */
- mrb_define_method(mrb, krn, "__to_str", mrb_to_str, MRB_ARGS_NONE()); /* internal */
mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
}
diff --git a/src/object.c b/src/object.c
index 8fe4688ac..fd2cd3968 100644
--- a/src/object.c
+++ b/src/object.c
@@ -495,46 +495,6 @@ mrb_to_int(mrb_state *mrb, mrb_value val)
return val;
}
-MRB_API mrb_value
-mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base)
-{
- mrb_value tmp;
-
- if (mrb_nil_p(val)) {
- if (base != 0) goto arg_error;
- mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer");
- }
- switch (mrb_type(val)) {
-#ifndef MRB_NO_FLOAT
- case MRB_TT_FLOAT:
- if (base != 0) goto arg_error;
- return mrb_float_to_integer(mrb, val);
-#endif
-
- case MRB_TT_INTEGER:
- if (base != 0) goto arg_error;
- return val;
-
- case MRB_TT_STRING:
- string_conv:
- return mrb_str_to_inum(mrb, val, base, TRUE);
-
- default:
- break;
- }
- if (base != 0) {
- tmp = mrb_check_string_type(mrb, val);
- if (!mrb_nil_p(tmp)) {
- val = tmp;
- goto string_conv;
- }
-arg_error:
- mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
- }
- /* to raise TypeError */
- return mrb_to_int(mrb, val);
-}
-
#ifndef MRB_NO_FLOAT
MRB_API mrb_value
mrb_to_float(mrb_state *mrb, mrb_value val)
@@ -559,19 +519,6 @@ mrb_to_float(mrb_state *mrb, mrb_value val)
#endif
MRB_API mrb_value
-mrb_to_str(mrb_state *mrb, mrb_value val)
-{
- return mrb_ensure_string_type(mrb, val);
-}
-
-/* obsolete: use mrb_ensure_string_type() instead */
-MRB_API mrb_value
-mrb_string_type(mrb_state *mrb, mrb_value str)
-{
- return mrb_ensure_string_type(mrb, str);
-}
-
-MRB_API mrb_value
mrb_ensure_string_type(mrb_state *mrb, mrb_value str)
{
if (!mrb_string_p(str)) {
diff --git a/src/string.c b/src/string.c
index 30d1bcab3..1a8b01c66 100644
--- a/src/string.c
+++ b/src/string.c
@@ -237,7 +237,7 @@ str_modify_keep_ascii(mrb_state *mrb, struct RString *s)
static void
check_null_byte(mrb_state *mrb, mrb_value str)
{
- mrb_to_str(mrb, str);
+ mrb_ensure_string_type(mrb, str);
if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
}
@@ -1071,7 +1071,7 @@ mrb_string_value_ptr(mrb_state *mrb, mrb_value str)
MRB_API mrb_int
mrb_string_value_len(mrb_state *mrb, mrb_value ptr)
{
- mrb_to_str(mrb, ptr);
+ mrb_ensure_string_type(mrb, ptr);
return RSTRING_LEN(ptr);
}
@@ -1358,8 +1358,7 @@ mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_
{
mrb_int beg, len, charlen;
- mrb_to_str(mrb, replace);
-
+ mrb_ensure_string_type(mrb, replace);
switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) {
case STR_OUT_OF_RANGE:
default:
@@ -2400,7 +2399,7 @@ mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck)
const char *s;
mrb_int len;
- mrb_to_str(mrb, str);
+ mrb_ensure_string_type(mrb, str);
s = RSTRING_PTR(str);
len = RSTRING_LEN(str);
return mrb_str_len_to_inum(mrb, s, len, base, badcheck);
@@ -2699,7 +2698,7 @@ mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2)
MRB_API mrb_value
mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2)
{
- mrb_to_str(mrb, str2);
+ mrb_ensure_string_type(mrb, str2);
return mrb_str_cat_str(mrb, str1, str2);
}
@@ -2848,6 +2847,51 @@ mrb_str_byteslice(mrb_state *mrb, mrb_value str)
}
}
+static mrb_value
+sub_replace(mrb_state *mrb, mrb_value self)
+{
+ char *p, *match;
+ mrb_int plen, mlen;
+ mrb_int found, offset;
+ mrb_value result;
+
+ mrb_get_args(mrb, "ssi", &p, &plen, &match, &mlen, &found);
+ result = mrb_str_new(mrb, 0, 0);
+ for (mrb_int i=0; i<plen; i++) {
+ if (p[i] != '\\' || i+1==plen) {
+ mrb_str_cat(mrb, result, p+i, 1);
+ continue;
+ }
+ i++;
+ switch (p[i]) {
+ case '\\':
+ mrb_str_cat(mrb, result, "\\", 1);
+ break;
+ case '`':
+ mrb_str_cat(mrb, result, RSTRING_PTR(self), chars2bytes(self, 0, found));
+ break;
+ case '&': case '0':
+ mrb_str_cat(mrb, result, match, mlen);
+ break;
+ case '\'':
+ offset = chars2bytes(self, 0, found) + mlen;
+ if (RSTRING_LEN(self) > offset) {
+ mrb_str_cat(mrb, result, RSTRING_PTR(self)+offset, RSTRING_LEN(self)-offset);
+ }
+ break;
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+ /* ignore sub-group match (no Regexp supported) */
+ break;
+ default:
+ mrb_str_cat(mrb, result, &p[i-1], 2);
+ break;
+ }
+ }
+ return result;
+}
+
/* ---------------------------*/
void
mrb_init_string(mrb_state *mrb)
@@ -2909,4 +2953,6 @@ mrb_init_string(mrb_state *mrb)
mrb_define_method(mrb, s, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1));
mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2));
mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_ARG(1,1));
+
+ mrb_define_method(mrb, s, "__sub_replace", sub_replace, MRB_ARGS_REQ(3)); /* internal */
}
diff --git a/src/vm.c b/src/vm.c
index 50ad3b31d..a8120f5a5 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -2671,7 +2671,8 @@ RETRY_TRY_BLOCK:
int i;
int lim = a+b*2+1;
- hash = mrb_ensure_hash_type(mrb, regs[a]);
+ hash = regs[a];
+ mrb_ensure_hash_type(mrb, hash);
for (i=a+1; i<lim; i+=2) {
mrb_hash_set(mrb, hash, regs[i], regs[i+1]);
}
@@ -2679,8 +2680,9 @@ RETRY_TRY_BLOCK:
NEXT;
}
CASE(OP_HASHCAT, B) {
- mrb_value hash = mrb_ensure_hash_type(mrb, regs[a]);
+ mrb_value hash = regs[a];
+ mrb_ensure_hash_type(mrb, hash);
mrb_hash_merge(mrb, hash, regs[a+1]);
mrb_gc_arena_restore(mrb, ai);
NEXT;