From 4d03cbb9e180bfb6dee78d60a38ff7850a5d8718 Mon Sep 17 00:00:00 2001
From: Dominik Honnef <dominikho@gmx.net>
Date: Sat, 21 Nov 2009 19:19:39 +0100
Subject: [PATCH] nicer formatting of ruby exceptions

---
 src/plugins/scripts/ruby/weechat-ruby.c |   75 +++++++++++++++++++++++-------
 1 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/src/plugins/scripts/ruby/weechat-ruby.c b/src/plugins/scripts/ruby/weechat-ruby.c
index f6860c4..e1b1f45 100644
--- a/src/plugins/scripts/ruby/weechat-ruby.c
+++ b/src/plugins/scripts/ruby/weechat-ruby.c
@@ -38,6 +38,19 @@
 #ifndef StringValuePtr
 #define StringValuePtr(s) STR2CSTR(s)
 #endif
+#ifndef RARRAY_LEN
+#define RARRAY_LEN(s) RARRAY(s)->len
+#endif
+#ifndef RARRAY_PTR
+#define RARRAY_PTR(s) RARRAY(s)->ptr
+#endif
+#ifndef RSTRING_LEN
+#define RSTRING_LEN(s) RSTRING(s)->len
+#endif
+#ifndef RSTRING_PTR
+#define RSTRING_PTR(s) RSTRING(s)->ptr
+#endif
+
 
 #if defined(RUBY_VERSION) && RUBY_VERSION >= 19
 #define rb_errinfo                      dll_rb_errinfo
@@ -54,7 +67,7 @@ RUBYEXTERN VALUE ruby_errinfo;
 #if defined(RUBY_VERSION) && RUBY_VERSION >= 19
 static VALUE (*dll_rb_errinfo) (void);
 #else
- static VALUE *dll_ruby_errinfo;
+static VALUE *dll_ruby_errinfo;
 #endif
 
 WEECHAT_PLUGIN_NAME(RUBY_PLUGIN_NAME);
@@ -142,6 +155,41 @@ rb_protect_funcall (VALUE recv, ID mid, int *state, int argc, ...)
     return rb_protect(protect_funcall0, (VALUE) &arg, state);
 }
 
+int weechat_ruby_print_exception(VALUE err) {
+  VALUE err_msg, err_class, backtrace;
+  int i;
+  char* line;
+  char* cline;
+
+  backtrace = rb_funcall(err, rb_intern("backtrace"), 0);
+  err_msg = rb_funcall(err, rb_intern("message"), 0);
+  err_class = rb_funcall(rb_funcall(err, rb_intern("class"), 0), rb_intern("name"), 0);
+
+  for (i = 0; i < RARRAY_LEN(backtrace); i++) {
+    line = STR2CSTR(RARRAY_PTR(backtrace)[i]);
+    if(i == 0) {
+      cline = (char *)calloc(strlen(line) + 2 + strlen(STR2CSTR(err_msg)) + 3 + strlen(STR2CSTR(err_class)) + 1, sizeof(char));
+      strcat(cline, line);
+      strcat(cline, ": ");
+      strcat(cline, STR2CSTR(err_msg));
+      strcat(cline, " (");
+      strcat(cline, STR2CSTR(err_class));
+      strcat(cline, ")");
+    }
+    else {
+      cline = (char *)calloc(strlen(line) + strlen("     from ") + 1, sizeof(char));
+      strcat(cline, "     from ");
+      strcat(cline, line);
+    }
+    weechat_printf (NULL,
+                    weechat_gettext ("%s%s: error: %s"),
+                    weechat_prefix ("error"), RUBY_PLUGIN_NAME,
+                    cline);
+    free(cline);
+  }
+  return 0;
+}
+
 /*
  * weechat_ruby_exec: execute a Ruby script
  */
@@ -267,11 +315,8 @@ weechat_ruby_exec (struct t_plugin_script *script,
                         weechat_gettext ("%s%s: unable to run function \"%s\""),
                         weechat_prefix ("error"), RUBY_PLUGIN_NAME, function);
 
-	err = rb_inspect(rb_gv_get("$!"));
-	weechat_printf (NULL,
-                        weechat_gettext ("%s%s: error: \"%s\""),
-                        weechat_prefix ("error"), RUBY_PLUGIN_NAME,
-                        STR2CSTR(err));
+      err = rb_gv_get("$!");
+      weechat_ruby_print_exception(err);
 
 	return NULL;
     }
@@ -417,11 +462,8 @@ weechat_ruby_load (const char *filename)
 
     if (ruby_retcode == Qnil)
     {
-	err = rb_inspect(rb_gv_get("$!"));
-	weechat_printf (NULL,
-                        weechat_gettext ("%s%s: error: \"%s\""),
-                        weechat_prefix ("error"), RUBY_PLUGIN_NAME,
-                        STR2CSTR(err));
+      err = rb_gv_get("$!");
+      weechat_ruby_print_exception(err);
 	return 0;
     }
 
@@ -480,11 +522,8 @@ weechat_ruby_load (const char *filename)
                                          "\"weechat_init\" in file \"%s\""),
                         weechat_prefix ("error"), RUBY_PLUGIN_NAME, filename);
 
-	err = rb_inspect(rb_gv_get("$!"));
-	weechat_printf (NULL,
-                        weechat_gettext ("%s%s: error: \"%s\""),
-                        weechat_prefix ("error"), RUBY_PLUGIN_NAME,
-                        STR2CSTR(err));
+      err = rb_gv_get("$!");
+      weechat_ruby_print_exception(err);
 
 	if (ruby_current_script != NULL)
         {
@@ -890,9 +929,9 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
     /* init stdout/stderr buffer */
     ruby_buffer_output[0] = '\0';
 
-    #if defined(RUBY_VERSION) && RUBY_VERSION >= 19
+#if defined(RUBY_VERSION) && RUBY_VERSION >= 19
       RUBY_INIT_STACK;
-    #endif
+#endif
 
     ruby_init ();
     ruby_init_loadpath ();
-- 
1.6.5.3

