diff options
| -rw-r--r-- | include/mruby/string.h | 4 | ||||
| -rw-r--r-- | lib/mruby-core-ext.rb | 40 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-symbol-ext/src/symbol.c | 7 | ||||
| -rw-r--r-- | mrbgems/mruby-symbol-ext/test/symbol.rb | 15 | ||||
| -rw-r--r-- | src/string.c | 63 | ||||
| -rw-r--r-- | src/symbol.c | 1 |
8 files changed, 76 insertions, 58 deletions
diff --git a/include/mruby/string.h b/include/mruby/string.h index 3fe8295ff..6fe0556b0 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -439,6 +439,10 @@ void mrb_regexp_check(mrb_state *mrb, mrb_value obj); #define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len) #define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2) +#ifdef MRB_UTF8_STRING +mrb_int mrb_utf8_len(const char *str, mrb_int byte_len); +#endif + MRB_END_DECL #endif /* MRUBY_STRING_H */ diff --git a/lib/mruby-core-ext.rb b/lib/mruby-core-ext.rb index 4c6d3ca76..08e6f6148 100644 --- a/lib/mruby-core-ext.rb +++ b/lib/mruby-core-ext.rb @@ -18,18 +18,20 @@ class String end # Compatible with 1.9 on 1.8 - def %(params) - if params.is_a?(Hash) - str = self.clone - params.each do |k, v| - str.gsub!("%{#{k}}") { v } - end - str - else - if params.is_a?(Array) - sprintf(self, *params) + unless (sprintf("%{a}", :a => 1) rescue false) + def %(params) + if params.is_a?(Hash) + str = self.clone + params.each do |k, v| + str.gsub!("%{#{k}}") { v } + end + str else - sprintf(self, params) + if params.is_a?(Array) + sprintf(self, *params) + else + sprintf(self, params) + end end end end @@ -37,17 +39,21 @@ end class Symbol # Compatible with 1.9 on 1.8 - def to_proc - proc { |obj, *args| obj.send(self, *args) } + unless method_defined?(:to_proc) + def to_proc + proc { |obj, *args| obj.send(self, *args) } + end end end module Enumerable # Compatible with 1.9 on 1.8 - def each_with_object(memo) - return to_enum :each_with_object, memo unless block_given? - each { |obj| yield obj, memo } - memo + unless method_defined?(:each_with_object) + def each_with_object(memo) + return to_enum :each_with_object, memo unless block_given? + each { |obj| yield obj, memo } + memo + end end end diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c index 0a864567d..2fc661cdf 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c @@ -495,7 +495,7 @@ dbgcmd_quit(mrb_state *mrb, mrdb_state *mrdb) if (mrdb->dbg->xm == DBG_QUIT) { struct RClass *exc; - exc = mrb_define_class(mrb, "DebuggerExit", mrb_class_get(mrb, "Exception")); + exc = mrb_define_class(mrb, "DebuggerExit", mrb->eException_class); mrb_raise(mrb, exc, "Exit mrdb."); } return DBGST_PROMPT; diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c index cb4c738fc..233c86cef 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c @@ -19,7 +19,7 @@ dbgcmd_run(mrb_state *mrb, mrdb_state *mrdb) if (dbg->xphase == DBG_PHASE_RUNNING){ struct RClass *exc; puts("Start it from the beginning."); - exc = mrb_define_class(mrb, "DebuggerRestart", mrb_class_get(mrb, "Exception")); + exc = mrb_define_class(mrb, "DebuggerRestart", mrb->eException_class); mrb_raise(mrb, exc, "Restart mrdb."); } } diff --git a/mrbgems/mruby-symbol-ext/src/symbol.c b/mrbgems/mruby-symbol-ext/src/symbol.c index a992dbfce..215226502 100644 --- a/mrbgems/mruby-symbol-ext/src/symbol.c +++ b/mrbgems/mruby-symbol-ext/src/symbol.c @@ -1,6 +1,7 @@ #include <mruby.h> #include <mruby/khash.h> #include <mruby/array.h> +#include <mruby/string.h> typedef struct symbol_name { size_t len; @@ -45,7 +46,13 @@ static mrb_value mrb_sym_length(mrb_state *mrb, mrb_value self) { mrb_int len; +#ifdef MRB_UTF8_STRING + mrb_int byte_len; + const char *name = mrb_sym2name_len(mrb, mrb_symbol(self), &byte_len); + len = mrb_utf8_len(name, byte_len); +#else mrb_sym2name_len(mrb, mrb_symbol(self), &len); +#endif return mrb_fixnum_value(len); } diff --git a/mrbgems/mruby-symbol-ext/test/symbol.rb b/mrbgems/mruby-symbol-ext/test/symbol.rb index 63c1bd826..2c7a62b0c 100644 --- a/mrbgems/mruby-symbol-ext/test/symbol.rb +++ b/mrbgems/mruby-symbol-ext/test/symbol.rb @@ -7,9 +7,18 @@ assert('Symbol.all_symbols') do assert_equal foo, symbols end -assert("Symbol#length") do - assert_equal 5, :hello.size - assert_equal 5, :mruby.length +%w[size length].each do |n| + assert("Symbol##{n}") do + assert_equal 5, :hello.__send__(n) + assert_equal 4, :"aA\0b".__send__(n) + if "あ".size == 1 # enable MRB_UTF8_STRING? + assert_equal 8, :"こんにちは世界!".__send__(n) + assert_equal 4, :"aあ\0b".__send__(n) + else + assert_equal 22, :"こんにちは世界!".__send__(n) + assert_equal 6, :"aあ\0b".__send__(n) + end + end end assert("Symbol#capitalize") do diff --git a/src/string.c b/src/string.c index 52b869eca..d26d6f4c9 100644 --- a/src/string.c +++ b/src/string.c @@ -156,13 +156,6 @@ mrb_str_new(mrb_state *mrb, const char *p, size_t len) return mrb_obj_value(str_new(mrb, p, len)); } -/* - * call-seq: (Caution! NULL string) - * String.new(str="") => new_str - * - * Returns a new string object containing a copy of <i>str</i>. - */ - MRB_API mrb_value mrb_str_new_cstr(mrb_state *mrb, const char *p) { @@ -238,27 +231,36 @@ utf8len(const char* p, const char* e) return len; } -static mrb_int -utf8_strlen(mrb_value str, mrb_int len) +mrb_int +mrb_utf8_len(const char *str, mrb_int byte_len) { mrb_int total = 0; - char* p = RSTRING_PTR(str); - char* e = p; - if (RSTRING(str)->flags & MRB_STR_NO_UTF) { - return RSTRING_LEN(str); - } - e += len < 0 ? RSTRING_LEN(str) : len; - while (p<e) { + const char *p = str; + const char *e = p + byte_len; + + while (p < e) { p += utf8len(p, e); total++; } - if (RSTRING_LEN(str) == total) { - RSTRING(str)->flags |= MRB_STR_NO_UTF; - } return total; } -#define RSTRING_CHAR_LEN(s) utf8_strlen(s, -1) +static mrb_int +utf8_strlen(mrb_value str) +{ + mrb_int byte_len = RSTRING_LEN(str); + + if (RSTRING(str)->flags & MRB_STR_NO_UTF) { + return byte_len; + } + else { + mrb_int utf8_len = mrb_utf8_len(RSTRING_PTR(str), byte_len); + if (byte_len == utf8_len) RSTRING(str)->flags |= MRB_STR_NO_UTF; + return utf8_len; + } +} + +#define RSTRING_CHAR_LEN(s) utf8_strlen(s) /* map character index to byte offset index */ static mrb_int @@ -739,12 +741,6 @@ mrb_str_to_cstr(mrb_state *mrb, mrb_value str0) return RSTR_PTR(s); } -/* - * call-seq: (Caution! String("abcd") change) - * String("abcdefg") = String("abcd") + String("efg") - * - * Returns a new string object containing a copy of <i>str</i>. - */ MRB_API void mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other) { @@ -752,12 +748,6 @@ mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other) mrb_str_cat_str(mrb, self, other); } -/* - * call-seq: (Caution! String("abcd") remain) - * String("abcdefg") = String("abcd") + String("efg") - * - * Returns a new string object containing a copy of <i>str</i>. - */ MRB_API mrb_value mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b) { @@ -775,10 +765,13 @@ mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b) /* 15.2.10.5.2 */ /* - * call-seq: (Caution! String("abcd") remain) for stack_argument - * String("abcdefg") = String("abcd") + String("efg") + * call-seq: + * str + other_str -> new_str * - * Returns a new string object containing a copy of <i>str</i>. + * Concatenation---Returns a new <code>String</code> containing + * <i>other_str</i> concatenated to <i>str</i>. + * + * "Hello from " + self.to_s #=> "Hello from main" */ static mrb_value mrb_str_plus_m(mrb_state *mrb, mrb_value self) diff --git a/src/symbol.c b/src/symbol.c index 6b4c7200c..bed918241 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -143,7 +143,6 @@ mrb_check_intern_str(mrb_state *mrb, mrb_value str) return mrb_check_intern(mrb, RSTRING_PTR(str), RSTRING_LEN(str)); } -/* lenp must be a pointer to a size_t variable */ MRB_API const char* mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp) { |
