diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-03-26 22:51:09 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-03-26 22:51:09 +0100 |
commit | e99be0e6d28fad96efd2b2be23fa38e7559e80e1 (patch) | |
tree | ba47feb515238f5e77526bce8320d2ed33f1a1e5 /src/if_ruby.c | |
parent | 75bf3d22f42684beecd977f3185e98045b5c33d9 (diff) | |
download | vim-git-e99be0e6d28fad96efd2b2be23fa38e7559e80e1.tar.gz |
patch 8.1.1056: no eval function for Rubyv8.1.1056
Problem: No eval function for Ruby.
Solution: Add rubyeval(). (Ozaki Kiichi, closes #4152)
Diffstat (limited to 'src/if_ruby.c')
-rw-r--r-- | src/if_ruby.c | 422 |
1 files changed, 309 insertions, 113 deletions
diff --git a/src/if_ruby.c b/src/if_ruby.c index 543ee8ac2..63294f4e5 100644 --- a/src/if_ruby.c +++ b/src/if_ruby.c @@ -205,6 +205,7 @@ static int ensure_ruby_initialized(void); static void error_print(int); static void ruby_io_init(void); static void ruby_vim_init(void); +static int ruby_convert_to_vim_value(VALUE val, typval_T *rettv); #if defined(RUBY19_OR_LATER) || defined(RUBY_INIT_STACK) # if defined(__ia64) && !defined(ruby_init_stack) @@ -259,6 +260,7 @@ static void ruby_vim_init(void); # endif # define rb_global_variable dll_rb_global_variable # define rb_hash_aset dll_rb_hash_aset +# define rb_hash_foreach dll_rb_hash_foreach # define rb_hash_new dll_rb_hash_new # define rb_inspect dll_rb_inspect # define rb_int2inum dll_rb_int2inum @@ -275,6 +277,7 @@ static void ruby_vim_init(void); # endif # define rb_num2uint dll_rb_num2uint # endif +# define rb_num2dbl dll_rb_num2dbl # define rb_lastline_get dll_rb_lastline_get # define rb_lastline_set dll_rb_lastline_set # define rb_protect dll_rb_protect @@ -409,6 +412,7 @@ static VALUE (*dll_rb_funcall2) (VALUE, ID, int, const VALUE*); # endif static void (*dll_rb_global_variable) (VALUE*); static VALUE (*dll_rb_hash_aset) (VALUE, VALUE, VALUE); +static VALUE (*dll_rb_hash_foreach) (VALUE, int (*)(VALUE, VALUE, VALUE), VALUE); static VALUE (*dll_rb_hash_new) (void); static VALUE (*dll_rb_inspect) (VALUE); static VALUE (*dll_rb_int2inum) (long); @@ -418,6 +422,7 @@ static long (*dll_rb_fix2int) (VALUE); static long (*dll_rb_num2int) (VALUE); static unsigned long (*dll_rb_num2uint) (VALUE); # endif +static double (*dll_rb_num2dbl) (VALUE); static VALUE (*dll_rb_lastline_get) (void); static void (*dll_rb_lastline_set) (VALUE); static VALUE (*dll_rb_protect) (VALUE (*)(VALUE), VALUE, int*); @@ -501,42 +506,50 @@ static void (*dll_rb_gc_writebarrier_unprotect)(VALUE obj); # if defined(RUBY19_OR_LATER) && !defined(PROTO) # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 22 -long rb_num2long_stub(VALUE x) + long +rb_num2long_stub(VALUE x) # else -SIGNED_VALUE rb_num2long_stub(VALUE x) + SIGNED_VALUE +rb_num2long_stub(VALUE x) # endif { return dll_rb_num2long(x); } # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 26 -VALUE rb_int2big_stub(intptr_t x) + VALUE +rb_int2big_stub(intptr_t x) # else -VALUE rb_int2big_stub(SIGNED_VALUE x) + VALUE +rb_int2big_stub(SIGNED_VALUE x) # endif { return dll_rb_int2big(x); } # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19 \ && VIM_SIZEOF_INT < VIM_SIZEOF_LONG -long rb_fix2int_stub(VALUE x) + long +rb_fix2int_stub(VALUE x) { return dll_rb_fix2int(x); } -long rb_num2int_stub(VALUE x) + long +rb_num2int_stub(VALUE x) { return dll_rb_num2int(x); } # endif # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 20 -VALUE + VALUE rb_float_new_in_heap(double d) { return dll_rb_float_new(d); } # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 22 -unsigned long rb_num2ulong(VALUE x) + unsigned long +rb_num2ulong(VALUE x) # else -VALUE rb_num2ulong(VALUE x) + VALUE +rb_num2ulong(VALUE x) # endif { return (long)RSHIFT((SIGNED_VALUE)(x),1); @@ -547,12 +560,14 @@ VALUE rb_num2ulong(VALUE x) /* Do not generate a prototype here, VALUE isn't always defined. */ # if defined(USE_RGENGC) && USE_RGENGC && !defined(PROTO) # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER == 21 -void rb_gc_writebarrier_unprotect_promoted_stub(VALUE obj) + void +rb_gc_writebarrier_unprotect_promoted_stub(VALUE obj) { dll_rb_gc_writebarrier_unprotect_promoted(obj); } # else -void rb_gc_writebarrier_unprotect_stub(VALUE obj) + void +rb_gc_writebarrier_unprotect_stub(VALUE obj) { dll_rb_gc_writebarrier_unprotect(obj); } @@ -560,7 +575,8 @@ void rb_gc_writebarrier_unprotect_stub(VALUE obj) # endif # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 26 -void rb_ary_detransient_stub(VALUE x) + void +rb_ary_detransient_stub(VALUE x) { dll_rb_ary_detransient(x); } @@ -629,6 +645,7 @@ static struct # endif {"rb_global_variable", (RUBY_PROC*)&dll_rb_global_variable}, {"rb_hash_aset", (RUBY_PROC*)&dll_rb_hash_aset}, + {"rb_hash_foreach", (RUBY_PROC*)&dll_rb_hash_foreach}, {"rb_hash_new", (RUBY_PROC*)&dll_rb_hash_new}, {"rb_inspect", (RUBY_PROC*)&dll_rb_inspect}, {"rb_int2inum", (RUBY_PROC*)&dll_rb_int2inum}, @@ -638,6 +655,7 @@ static struct {"rb_num2int", (RUBY_PROC*)&dll_rb_num2int}, {"rb_num2uint", (RUBY_PROC*)&dll_rb_num2uint}, # endif + {"rb_num2dbl", (RUBY_PROC*)&dll_rb_num2dbl}, {"rb_lastline_get", (RUBY_PROC*)&dll_rb_lastline_get}, {"rb_lastline_set", (RUBY_PROC*)&dll_rb_lastline_set}, {"rb_protect", (RUBY_PROC*)&dll_rb_protect}, @@ -789,7 +807,8 @@ ruby_end(void) #endif } -void ex_ruby(exarg_T *eap) + void +ex_ruby(exarg_T *eap) { int state; char *script = NULL; @@ -860,7 +879,8 @@ eval_enc_string_protect(const char *str, int *state) return rb_eval_string_protect(str, state); } -void ex_rubydo(exarg_T *eap) + void +ex_rubydo(exarg_T *eap) { int state; linenr_T i; @@ -906,13 +926,15 @@ void ex_rubydo(exarg_T *eap) } } -static VALUE rb_load_wrap(VALUE file_to_load) + static VALUE +rb_load_wrap(VALUE file_to_load) { rb_load(file_to_load, 0); return Qnil; } -void ex_rubyfile(exarg_T *eap) + void +ex_rubyfile(exarg_T *eap) { int state; @@ -925,7 +947,8 @@ void ex_rubyfile(exarg_T *eap) } } -void ruby_buffer_free(buf_T *buf) + void +ruby_buffer_free(buf_T *buf) { if (buf->b_ruby_ref) { @@ -934,7 +957,8 @@ void ruby_buffer_free(buf_T *buf) } } -void ruby_window_free(win_T *win) + void +ruby_window_free(win_T *win) { if (win->w_ruby_ref) { @@ -943,7 +967,8 @@ void ruby_window_free(win_T *win) } } -static int ensure_ruby_initialized(void) + static int +ensure_ruby_initialized(void) { if (!ruby_initialized) { @@ -993,7 +1018,8 @@ static int ensure_ruby_initialized(void) return ruby_initialized; } -static void error_print(int state) + static void +error_print(int state) { #if !defined(DYNAMIC_RUBY) && !defined(RUBY19_OR_LATER) RUBYEXTERN VALUE ruby_errinfo; @@ -1018,66 +1044,67 @@ static void error_print(int state) switch (state) { - case TAG_RETURN: - emsg(_("E267: unexpected return")); - break; - case TAG_NEXT: - emsg(_("E268: unexpected next")); - break; - case TAG_BREAK: - emsg(_("E269: unexpected break")); - break; - case TAG_REDO: - emsg(_("E270: unexpected redo")); - break; - case TAG_RETRY: - emsg(_("E271: retry outside of rescue clause")); - break; - case TAG_RAISE: - case TAG_FATAL: + case TAG_RETURN: + emsg(_("E267: unexpected return")); + break; + case TAG_NEXT: + emsg(_("E268: unexpected next")); + break; + case TAG_BREAK: + emsg(_("E269: unexpected break")); + break; + case TAG_REDO: + emsg(_("E270: unexpected redo")); + break; + case TAG_RETRY: + emsg(_("E271: retry outside of rescue clause")); + break; + case TAG_RAISE: + case TAG_FATAL: #ifdef RUBY19_OR_LATER - error = rb_errinfo(); + error = rb_errinfo(); #else - error = ruby_errinfo; + error = ruby_errinfo; #endif - eclass = CLASS_OF(error); - einfo = rb_obj_as_string(error); - if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) - { - emsg(_("E272: unhandled exception")); - } - else - { - VALUE epath; - char *p; - - epath = rb_class_path(eclass); - vim_snprintf(buff, BUFSIZ, "%s: %s", - RSTRING_PTR(epath), RSTRING_PTR(einfo)); - p = strchr(buff, '\n'); - if (p) *p = '\0'; - emsg(buff); - } + eclass = CLASS_OF(error); + einfo = rb_obj_as_string(error); + if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) + { + emsg(_("E272: unhandled exception")); + } + else + { + VALUE epath; + char *p; + + epath = rb_class_path(eclass); + vim_snprintf(buff, BUFSIZ, "%s: %s", + RSTRING_PTR(epath), RSTRING_PTR(einfo)); + p = strchr(buff, '\n'); + if (p) *p = '\0'; + emsg(buff); + } - attr = syn_name2attr((char_u *)"Error"); + attr = syn_name2attr((char_u *)"Error"); # ifdef RUBY21_OR_LATER - bt = rb_funcallv(error, rb_intern("backtrace"), 0, 0); - for (i = 0; i < RARRAY_LEN(bt); i++) - msg_attr(RSTRING_PTR(RARRAY_AREF(bt, i)), attr); + bt = rb_funcallv(error, rb_intern("backtrace"), 0, 0); + for (i = 0; i < RARRAY_LEN(bt); i++) + msg_attr(RSTRING_PTR(RARRAY_AREF(bt, i)), attr); # else - bt = rb_funcall2(error, rb_intern("backtrace"), 0, 0); - for (i = 0; i < RARRAY_LEN(bt); i++) - msg_attr(RSTRING_PTR(RARRAY_PTR(bt)[i]), attr); + bt = rb_funcall2(error, rb_intern("backtrace"), 0, 0); + for (i = 0; i < RARRAY_LEN(bt); i++) + msg_attr(RSTRING_PTR(RARRAY_PTR(bt)[i]), attr); # endif - break; - default: - vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state); - emsg(buff); - break; + break; + default: + vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state); + emsg(buff); + break; } } -static VALUE vim_message(VALUE self UNUSED, VALUE str) + static VALUE +vim_message(VALUE self UNUSED, VALUE str) { char *buff, *p; @@ -1098,21 +1125,24 @@ static VALUE vim_message(VALUE self UNUSED, VALUE str) return Qnil; } -static VALUE vim_set_option(VALUE self UNUSED, VALUE str) + static VALUE +vim_set_option(VALUE self UNUSED, VALUE str) { do_set((char_u *)StringValuePtr(str), 0); update_screen(NOT_VALID); return Qnil; } -static VALUE vim_command(VALUE self UNUSED, VALUE str) + static VALUE +vim_command(VALUE self UNUSED, VALUE str) { do_cmdline_cmd((char_u *)StringValuePtr(str)); return Qnil; } #ifdef FEAT_EVAL -static VALUE vim_to_ruby(typval_T *tv) + static VALUE +vim_to_ruby(typval_T *tv) { VALUE result = Qnil; @@ -1188,7 +1218,8 @@ static VALUE vim_to_ruby(typval_T *tv) } #endif -static VALUE vim_evaluate(VALUE self UNUSED, VALUE str) + static VALUE +vim_evaluate(VALUE self UNUSED, VALUE str) { #ifdef FEAT_EVAL typval_T *tv; @@ -1221,13 +1252,15 @@ static const rb_data_type_t buffer_type = { # endif }; -static size_t buffer_dsize(const void *buf UNUSED) + static size_t +buffer_dsize(const void *buf UNUSED) { return sizeof(buf_T); } #endif -static VALUE buffer_new(buf_T *buf) + static VALUE +buffer_new(buf_T *buf) { if (buf->b_ruby_ref) { @@ -1246,7 +1279,8 @@ static VALUE buffer_new(buf_T *buf) } } -static buf_T *get_buf(VALUE obj) + static buf_T * +get_buf(VALUE obj) { buf_T *buf; @@ -1260,7 +1294,8 @@ static buf_T *get_buf(VALUE obj) return buf; } -static VALUE vim_blob(VALUE self UNUSED, VALUE str) + static VALUE +vim_blob(VALUE self UNUSED, VALUE str) { VALUE result = rb_str_new("0z", 2); char buf[4]; @@ -1273,12 +1308,14 @@ static VALUE vim_blob(VALUE self UNUSED, VALUE str) return result; } -static VALUE buffer_s_current(void) + static VALUE +buffer_s_current(void) { return buffer_new(curbuf); } -static VALUE buffer_s_count(void) + static VALUE +buffer_s_count(void) { buf_T *b; int n = 0; @@ -1294,7 +1331,8 @@ static VALUE buffer_s_count(void) return INT2NUM(n); } -static VALUE buffer_s_aref(VALUE self UNUSED, VALUE num) + static VALUE +buffer_s_aref(VALUE self UNUSED, VALUE num) { buf_T *b; int n = NUM2INT(num); @@ -1314,35 +1352,40 @@ static VALUE buffer_s_aref(VALUE self UNUSED, VALUE num) return Qnil; } -static VALUE buffer_name(VALUE self) + static VALUE +buffer_name(VALUE self) { buf_T *buf = get_buf(self); return buf->b_ffname ? rb_str_new2((char *)buf->b_ffname) : Qnil; } -static VALUE buffer_number(VALUE self) + static VALUE +buffer_number(VALUE self) { buf_T *buf = get_buf(self); return INT2NUM(buf->b_fnum); } -static VALUE buffer_count(VALUE self) + static VALUE +buffer_count(VALUE self) { buf_T *buf = get_buf(self); return INT2NUM(buf->b_ml.ml_line_count); } -static VALUE get_buffer_line(buf_T *buf, linenr_T n) + static VALUE +get_buffer_line(buf_T *buf, linenr_T n) { if (n <= 0 || n > buf->b_ml.ml_line_count) rb_raise(rb_eIndexError, "line number %ld out of range", (long)n); return vim_str2rb_enc_str((char *)ml_get_buf(buf, n, FALSE)); } -static VALUE buffer_aref(VALUE self, VALUE num) + static VALUE +buffer_aref(VALUE self, VALUE num) { buf_T *buf = get_buf(self); @@ -1351,7 +1394,8 @@ static VALUE buffer_aref(VALUE self, VALUE num) return Qnil; /* For stop warning */ } -static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str) + static VALUE +set_buffer_line(buf_T *buf, linenr_T n, VALUE str) { char *line = StringValuePtr(str); aco_save_T aco; @@ -1383,7 +1427,8 @@ static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str) return str; } -static VALUE buffer_aset(VALUE self, VALUE num, VALUE str) + static VALUE +buffer_aset(VALUE self, VALUE num, VALUE str) { buf_T *buf = get_buf(self); @@ -1392,7 +1437,8 @@ static VALUE buffer_aset(VALUE self, VALUE num, VALUE str) return str; } -static VALUE buffer_delete(VALUE self, VALUE num) + static VALUE +buffer_delete(VALUE self, VALUE num) { buf_T *buf = get_buf(self); long n = NUM2LONG(num); @@ -1427,7 +1473,8 @@ static VALUE buffer_delete(VALUE self, VALUE num) return Qnil; } -static VALUE buffer_append(VALUE self, VALUE num, VALUE str) + static VALUE +buffer_append(VALUE self, VALUE num, VALUE str) { buf_T *buf = get_buf(self); char *line = StringValuePtr(str); @@ -1479,13 +1526,15 @@ static const rb_data_type_t window_type = { # endif }; -static size_t window_dsize(const void *win UNUSED) + static size_t +window_dsize(const void *win UNUSED) { return sizeof(win_T); } #endif -static VALUE window_new(win_T *win) + static VALUE +window_new(win_T *win) { if (win->w_ruby_ref) { @@ -1504,7 +1553,8 @@ static VALUE window_new(win_T *win) } } -static win_T *get_win(VALUE obj) + static win_T * +get_win(VALUE obj) { win_T *win; @@ -1518,7 +1568,8 @@ static win_T *get_win(VALUE obj) return win; } -static VALUE window_s_current(void) + static VALUE +window_s_current(void) { return window_new(curwin); } @@ -1527,24 +1578,26 @@ static VALUE window_s_current(void) * Added line manipulation functions * SegPhault - 03/07/05 */ -static VALUE line_s_current(void) + static VALUE +line_s_current(void) { return get_buffer_line(curbuf, curwin->w_cursor.lnum); } -static VALUE set_current_line(VALUE self UNUSED, VALUE str) + static VALUE +set_current_line(VALUE self UNUSED, VALUE str) { return set_buffer_line(curbuf, curwin->w_cursor.lnum, str); } -static VALUE current_line_number(void) + static VALUE +current_line_number(void) { return INT2FIX((int)curwin->w_cursor.lnum); } - - -static VALUE window_s_count(void) + static VALUE +window_s_count(void) { win_T *w; int n = 0; @@ -1554,7 +1607,8 @@ static VALUE window_s_count(void) return INT2NUM(n); } -static VALUE window_s_aref(VALUE self UNUSED, VALUE num) + static VALUE +window_s_aref(VALUE self UNUSED, VALUE num) { win_T *w; int n = NUM2INT(num); @@ -1565,21 +1619,24 @@ static VALUE window_s_aref(VALUE self UNUSED, VALUE num) return Qnil; } -static VALUE window_buffer(VALUE self) + static VALUE +window_buffer(VALUE self) { win_T *win = get_win(self); return buffer_new(win->w_buffer); } -static VALUE window_height(VALUE self) + static VALUE +window_height(VALUE self) { win_T *win = get_win(self); return INT2NUM(win->w_height); } -static VALUE window_set_height(VALUE self, VALUE height) + static VALUE +window_set_height(VALUE self, VALUE height) { win_T *win = get_win(self); win_T *savewin = curwin; @@ -1590,12 +1647,14 @@ static VALUE window_set_height(VALUE self, VALUE height) return height; } -static VALUE window_width(VALUE self UNUSED) + static VALUE +window_width(VALUE self UNUSED) { return INT2NUM(get_win(self)->w_width); } -static VALUE window_set_width(VALUE self UNUSED, VALUE width) + static VALUE +window_set_width(VALUE self UNUSED, VALUE width) { win_T *win = get_win(self); win_T *savewin = curwin; @@ -1606,14 +1665,16 @@ static VALUE window_set_width(VALUE self UNUSED, VALUE width) return width; } -static VALUE window_cursor(VALUE self) + static VALUE +window_cursor(VALUE self) { win_T *win = get_win(self); return rb_assoc_new(INT2NUM(win->w_cursor.lnum), INT2NUM(win->w_cursor.col)); } -static VALUE window_set_cursor(VALUE self, VALUE pos) + static VALUE +window_set_cursor(VALUE self, VALUE pos) { VALUE lnum, col; win_T *win = get_win(self); @@ -1631,12 +1692,14 @@ static VALUE window_set_cursor(VALUE self, VALUE pos) return Qnil; } -static VALUE f_nop(VALUE self UNUSED) + static VALUE +f_nop(VALUE self UNUSED) { return Qnil; } -static VALUE f_p(int argc, VALUE *argv, VALUE self UNUSED) + static VALUE +f_p(int argc, VALUE *argv, VALUE self UNUSED) { int i; VALUE str = rb_str_new("", 0); @@ -1656,7 +1719,8 @@ static VALUE f_p(int argc, VALUE *argv, VALUE self UNUSED) return ret; } -static void ruby_io_init(void) + static void +ruby_io_init(void) { #ifndef DYNAMIC_RUBY RUBYEXTERN VALUE rb_stdout; @@ -1672,7 +1736,8 @@ static void ruby_io_init(void) rb_define_global_function("p", f_p, -1); } -static void ruby_vim_init(void) + static void +ruby_vim_init(void) { objtbl = rb_hash_new(); rb_global_variable(&objtbl); @@ -1736,8 +1801,139 @@ static void ruby_vim_init(void) rb_define_virtual_variable("$curwin", window_s_current, 0); } -void vim_ruby_init(void *stack_start) + void +vim_ruby_init(void *stack_start) { /* should get machine stack start address early in main function */ ruby_stack_start = stack_start; } + + static int +convert_hash2dict(VALUE key, VALUE val, VALUE arg) +{ + dict_T *d = (dict_T *)arg; + dictitem_T *di; + + di = dictitem_alloc((char_u *)RSTRING_PTR(RSTRING(rb_obj_as_string(key)))); + if (di == NULL || ruby_convert_to_vim_value(val, &di->di_tv) != OK + || dict_add(d, di) != OK) + { + d->dv_hashtab.ht_error = TRUE; + return ST_STOP; + } + return ST_CONTINUE; +} + + static int +ruby_convert_to_vim_value(VALUE val, typval_T *rettv) +{ + switch (TYPE(val)) + { + case T_NIL: + rettv->v_type = VAR_SPECIAL; + rettv->vval.v_number = VVAL_NULL; + break; + case T_TRUE: + rettv->v_type = VAR_SPECIAL; + rettv->vval.v_number = VVAL_TRUE; + break; + case T_FALSE: + rettv->v_type = VAR_SPECIAL; + rettv->vval.v_number = VVAL_FALSE; + break; + case T_BIGNUM: + case T_FIXNUM: + rettv->v_type = VAR_NUMBER; + rettv->vval.v_number = (varnumber_T)NUM2LONG(val); + break; +#ifdef FEAT_FLOAT + case T_FLOAT: + rettv->v_type = VAR_FLOAT; + rettv->vval.v_float = (float_T)NUM2DBL(val); + break; +#endif + default: + val = rb_obj_as_string(val); + // FALLTHROUGH + case T_STRING: + { + VALUE str = (VALUE)RSTRING(val); + + rettv->v_type = VAR_STRING; + rettv->vval.v_string = vim_strnsave((char_u *)RSTRING_PTR(str), + (int)RSTRING_LEN(str)); + } + break; + case T_ARRAY: + { + list_T *l; + long i; + typval_T v; + + l = list_alloc(); + if (l == NULL) + return FAIL; + + for (i = 0; i < RARRAY_LEN(val); ++i) + { + if (ruby_convert_to_vim_value((VALUE)RARRAY_PTR(val)[i], + &v) != OK) + { + list_unref(l); + return FAIL; + } + list_append_tv(l, &v); + clear_tv(&v); + } + + rettv->v_type = VAR_LIST; + rettv->vval.v_list = l; + ++l->lv_refcount; + } + break; + case T_HASH: + { + dict_T *d; + + d = dict_alloc(); + if (d == NULL) + return FAIL; + + rb_hash_foreach(val, convert_hash2dict, (VALUE)d); + if (d->dv_hashtab.ht_error) + { + dict_unref(d); + return FAIL; + } + + rettv->v_type = VAR_DICT; + rettv->vval.v_dict = d; + ++d->dv_refcount; + } + break; + } + return OK; +} + + void +do_rubyeval(char_u *str, typval_T *rettv) +{ + int retval = FAIL; + + if (ensure_ruby_initialized()) + { + int state; + VALUE obj; + + obj = rb_eval_string_protect((const char *)str, &state); + if (state) + error_print(state); + else + retval = ruby_convert_to_vim_value(obj, rettv); + } + if (retval == FAIL) + { + rettv->v_type = VAR_NUMBER; + rettv->vval.v_number = 0; + } +} |