]> granicus.if.org Git - vim/commitdiff
patch 8.1.0232: Ruby error does not include backtrace v8.1.0232
authorBram Moolenaar <Bram@vim.org>
Wed, 1 Aug 2018 16:42:13 +0000 (18:42 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 1 Aug 2018 16:42:13 +0000 (18:42 +0200)
Problem:    Ruby error does not include backtrace.
Solution:   Add an error backtrace. (Masataka Pocke Kuwabara, closes #3267)

src/if_ruby.c
src/version.c

index 2e1f8d75aef72749b97d9f7d329a8098eaf43305..bf83c8b965ec85238c612a7a0bf2709ae613a762 100644 (file)
 # 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);
index b826410db0203fe10becb8dc8b025d4949950722..64aa76abb1f698920c8a6e29621a786d7ddfa780 100644 (file)
@@ -794,6 +794,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    232,
 /**/
     231,
 /**/