0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.1.0232: Ruby error does not include backtrace

Problem:    Ruby error does not include backtrace.
Solution:   Add an error backtrace. (Masataka Pocke Kuwabara, closes #3267)
This commit is contained in:
Bram Moolenaar
2018-08-01 18:42:13 +02:00
parent a5bc38b8c1
commit f711cb2f12
2 changed files with 56 additions and 4 deletions

View File

@@ -93,6 +93,11 @@
# define RUBY20_OR_LATER 1
#endif
#if (defined(RUBY_VERSION) && RUBY_VERSION >= 21) \
|| (defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 21)
# define RUBY21_OR_LATER 1
#endif
#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19
/* Ruby 1.9 defines a number of static functions which use rb_num2long and
* rb_int2big */
@@ -238,11 +243,21 @@ static void ruby_vim_init(void);
# define rb_eRuntimeError (*dll_rb_eRuntimeError)
# define rb_eStandardError (*dll_rb_eStandardError)
# define rb_eval_string_protect dll_rb_eval_string_protect
# ifdef RUBY21_OR_LATER
# define rb_funcallv dll_rb_funcallv
# else
# define rb_funcall2 dll_rb_funcall2
# endif
# define rb_global_variable dll_rb_global_variable
# define rb_hash_aset dll_rb_hash_aset
# define rb_hash_new dll_rb_hash_new
# define rb_inspect dll_rb_inspect
# define rb_int2inum dll_rb_int2inum
# ifdef RUBY19_OR_LATER
# define rb_intern2 dll_rb_intern2
# else
# define rb_intern dll_rb_intern
# endif
# if VIM_SIZEOF_INT < VIM_SIZEOF_LONG /* 64 bits only */
# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER <= 18
# define rb_fix2int dll_rb_fix2int
@@ -367,11 +382,21 @@ static VALUE *dll_rb_eIndexError;
static VALUE *dll_rb_eRuntimeError;
static VALUE *dll_rb_eStandardError;
static VALUE (*dll_rb_eval_string_protect) (const char*, int*);
# ifdef RUBY21_OR_LATER
static VALUE (*dll_rb_funcallv) (VALUE, ID, int, const VALUE*);
# else
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_new) (void);
static VALUE (*dll_rb_inspect) (VALUE);
static VALUE (*dll_rb_int2inum) (long);
# ifdef RUBY19_OR_LATER
static ID (*dll_rb_intern2) (const char*, long);
# else
static ID (*dll_rb_intern) (const char*);
# endif
# if VIM_SIZEOF_INT < VIM_SIZEOF_LONG /* 64 bits only */
static long (*dll_rb_fix2int) (VALUE);
static long (*dll_rb_num2int) (VALUE);
@@ -561,11 +586,21 @@ static struct
{"rb_eRuntimeError", (RUBY_PROC*)&dll_rb_eRuntimeError},
{"rb_eStandardError", (RUBY_PROC*)&dll_rb_eStandardError},
{"rb_eval_string_protect", (RUBY_PROC*)&dll_rb_eval_string_protect},
# ifdef RUBY21_OR_LATER
{"rb_funcallv", (RUBY_PROC*)&dll_rb_funcallv},
# else
{"rb_funcall2", (RUBY_PROC*)&dll_rb_funcall2},
# endif
{"rb_global_variable", (RUBY_PROC*)&dll_rb_global_variable},
{"rb_hash_aset", (RUBY_PROC*)&dll_rb_hash_aset},
{"rb_hash_new", (RUBY_PROC*)&dll_rb_hash_new},
{"rb_inspect", (RUBY_PROC*)&dll_rb_inspect},
{"rb_int2inum", (RUBY_PROC*)&dll_rb_int2inum},
# ifdef RUBY19_OR_LATER
{"rb_intern2", (RUBY_PROC*)&dll_rb_intern2},
# else
{"rb_intern", (RUBY_PROC*)&dll_rb_intern},
# endif
# if VIM_SIZEOF_INT < VIM_SIZEOF_LONG /* 64 bits only */
{"rb_fix2int", (RUBY_PROC*)&dll_rb_fix2int},
{"rb_num2int", (RUBY_PROC*)&dll_rb_num2int},
@@ -926,9 +961,13 @@ static void error_print(int state)
RUBYEXTERN VALUE ruby_errinfo;
#endif
#endif
VALUE error;
VALUE eclass;
VALUE einfo;
VALUE bt;
int attr;
char buff[BUFSIZ];
long i;
#define TAG_RETURN 0x1
#define TAG_BREAK 0x2
@@ -960,12 +999,12 @@ static void error_print(int state)
case TAG_RAISE:
case TAG_FATAL:
#ifdef RUBY19_OR_LATER
eclass = CLASS_OF(rb_errinfo());
einfo = rb_obj_as_string(rb_errinfo());
error = rb_errinfo();
#else
eclass = CLASS_OF(ruby_errinfo);
einfo = rb_obj_as_string(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"));
@@ -982,6 +1021,17 @@ static void error_print(int state)
if (p) *p = '\0';
EMSG(buff);
}
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((char_u *)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((char_u *)RSTRING_PTR(RARRAY_PTR(bt)[i]), attr);
# endif
break;
default:
vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state);