From c7018ea9627efd9c6fe4ef6b6f459fefef01fc52 Mon Sep 17 00:00:00 2001 From: Christopher Aue Date: Fri, 28 Jul 2017 21:07:20 +0200 Subject: Added mrb_str_index to the mrb API --- include/mruby/string.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/mruby/string.h b/include/mruby/string.h index b18093218..8b75a2275 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -84,6 +84,12 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); void mrb_gc_free_str(mrb_state*, struct RString*); MRB_API void mrb_str_modify(mrb_state*, struct RString*); + +/* + * Finds the index of a substring in a string + */ +MRB_API mrb_int mrb_str_index(mrb_state*, mrb_value, const char*, mrb_int, mrb_int); + /* * Appends self to other. Returns self as a concatnated string. * -- cgit v1.2.3 From f937af5745cbc6edead0ad3911bf16e08f66a96f Mon Sep 17 00:00:00 2001 From: Christopher Aue Date: Fri, 28 Jul 2017 22:46:26 +0200 Subject: Extended Module#const_get to support class paths --- include/mruby/string.h | 1 + src/class.c | 36 +++++++++++++++++++++++++++++++++--- test/t/module.rb | 8 +++++++- 3 files changed, 41 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/mruby/string.h b/include/mruby/string.h index 8b75a2275..c3fbb063d 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -89,6 +89,7 @@ MRB_API void mrb_str_modify(mrb_state*, struct RString*); * Finds the index of a substring in a string */ MRB_API mrb_int mrb_str_index(mrb_state*, mrb_value, const char*, mrb_int, mrb_int); +#define mrb_str_index_lit(mrb, str, lit, off) mrb_str_index(mrb, str, lit, mrb_strlen_lit(lit), off); /* * Appends self to other. Returns self as a concatnated string. diff --git a/src/class.c b/src/class.c index 56f64fd4e..57f64dcc5 100644 --- a/src/class.c +++ b/src/class.c @@ -2160,14 +2160,44 @@ mrb_mod_const_defined(mrb_state *mrb, mrb_value mod) return const_defined(mrb, mod, id, inherit); } +static mrb_value +mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id) +{ + check_const_name_sym(mrb, id); + return mrb_const_get(mrb, mod, id); +} + static mrb_value mrb_mod_const_get(mrb_state *mrb, mrb_value mod) { + mrb_value path; mrb_sym id; + char *ptr; + mrb_int off, end, len; - mrb_get_args(mrb, "n", &id); - check_const_name_sym(mrb, id); - return mrb_const_get(mrb, mod, id); + mrb_get_args(mrb, "o", &path); + + if (mrb_symbol_p(path)) { + /* const get with symbol */ + id = mrb_symbol(path); + return mrb_const_get_sym(mrb, mod, id); + } + + /* const get with class path string */ + path = mrb_string_type(mrb, path); + ptr = RSTRING_PTR(path); + len = RSTRING_LEN(path); + off = 0; + + while (off < len) { + end = mrb_str_index_lit(mrb, path, "::", off); + end = (end == -1) ? len : end; + id = mrb_intern(mrb, ptr+off, end-off); + mod = mrb_const_get_sym(mrb, mod, id); + off = (end == len) ? end : end+2; + } + + return mod; } static mrb_value diff --git a/test/t/module.rb b/test/t/module.rb index 419b0bfd5..04fa8d102 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -268,6 +268,12 @@ assert('Module#const_get', '15.2.2.4.21') do end assert_equal 42, Test4ConstGet.const_get(:Const4Test4ConstGet) + assert_equal 42, Test4ConstGet.const_get("Const4Test4ConstGet") + assert_equal 42, Object.const_get("Test4ConstGet::Const4Test4ConstGet") + + assert_raise(TypeError){ Test4ConstGet.const_get(123) } + assert_raise(NameError){ Test4ConstGet.const_get(:I_DO_NOT_EXIST) } + assert_raise(NameError){ Test4ConstGet.const_get("I_DO_NOT_EXIST::ME_NEITHER") } end assert('Module#const_missing', '15.2.2.4.22') do @@ -280,7 +286,7 @@ assert('Module#const_missing', '15.2.2.4.22') do assert_equal 42, Test4ConstMissing.const_get(:ConstDoesntExist) end -assert('Module#const_get', '15.2.2.4.23') do +assert('Module#const_set', '15.2.2.4.23') do module Test4ConstSet Const4Test4ConstSet = 42 end -- cgit v1.2.3