summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/scripts/ruby/CMakeLists.txt2
-rw-r--r--src/plugins/scripts/ruby/weechat-ruby.c226
2 files changed, 161 insertions, 67 deletions
diff --git a/src/plugins/scripts/ruby/CMakeLists.txt b/src/plugins/scripts/ruby/CMakeLists.txt
index cf977a254..98d948322 100644
--- a/src/plugins/scripts/ruby/CMakeLists.txt
+++ b/src/plugins/scripts/ruby/CMakeLists.txt
@@ -20,7 +20,7 @@ weechat-ruby-api.h)
SET_TARGET_PROPERTIES(ruby PROPERTIES PREFIX "")
IF(RUBY_FOUND)
- INCLUDE_DIRECTORIES(${RUBY_INCLUDE_PATH})
+ INCLUDE_DIRECTORIES(${RUBY_INCLUDE_PATH} ${RUBY_ARCH})
TARGET_LINK_LIBRARIES(ruby ${RUBY_LIBRARY} weechat_scripts)
ENDIF(RUBY_FOUND)
diff --git a/src/plugins/scripts/ruby/weechat-ruby.c b/src/plugins/scripts/ruby/weechat-ruby.c
index b59b8b213..5cda87a08 100644
--- a/src/plugins/scripts/ruby/weechat-ruby.c
+++ b/src/plugins/scripts/ruby/weechat-ruby.c
@@ -22,6 +22,10 @@
#undef _
#include <ruby.h>
+#if defined(RUBY_VERSION) && RUBY_VERSION >=19
+#include <ruby/encoding.h>
+#endif
+
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -31,6 +35,35 @@
#include "weechat-ruby.h"
#include "weechat-ruby-api.h"
+#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
+#define ruby_errinfo dll_rb_errinfo
+#else
+#define ruby_errinfo (*dll_ruby_errinfo)
+#endif
+
+#if defined(RUBY_VERSION) && RUBY_VERSION >= 19
+static VALUE (*dll_rb_errinfo) (void);
+#else
+static VALUE *dll_ruby_errinfo;
+#endif
+
WEECHAT_PLUGIN_NAME(RUBY_PLUGIN_NAME);
WEECHAT_PLUGIN_DESCRIPTION("Ruby plugin for WeeChat");
@@ -80,12 +113,12 @@ typedef struct protect_call_arg {
*/
static VALUE
-protect_funcall0(VALUE arg)
+protect_funcall0 (VALUE arg)
{
- return rb_funcall2(((protect_call_arg_t *) arg)->recv,
- ((protect_call_arg_t *) arg)->mid,
- ((protect_call_arg_t *) arg)->argc,
- ((protect_call_arg_t *) arg)->argv);
+ return rb_funcall2 (((protect_call_arg_t *)arg)->recv,
+ ((protect_call_arg_t *)arg)->mid,
+ ((protect_call_arg_t *)arg)->argc,
+ ((protect_call_arg_t *)arg)->argv);
}
/*
@@ -118,7 +151,85 @@ rb_protect_funcall (VALUE recv, ID mid, int *state, int argc, ...)
}
/*
- * weechat_ruby_exec: execute a Ruby script
+ * weechat_ruby_print_exception: display ruby exception
+ */
+
+int
+weechat_ruby_print_exception (VALUE err)
+{
+ VALUE backtrace;
+ int i;
+ int ruby_error;
+ char* line;
+ char* cline;
+ char* err_msg;
+ char* err_class;
+
+ backtrace = rb_protect_funcall (err, rb_intern("backtrace"),
+ &ruby_error, 0);
+ err_msg = STR2CSTR(rb_protect_funcall(err, rb_intern("message"),
+ &ruby_error, 0));
+ err_class = STR2CSTR(rb_protect_funcall(rb_protect_funcall(err,
+ rb_intern("class"),
+ &ruby_error, 0),
+ rb_intern("name"), &ruby_error, 0));
+
+ if (strcmp (err_class, "SyntaxError") == 0)
+ {
+ weechat_printf (NULL,
+ weechat_gettext ("%s%s: error: %s"),
+ weechat_prefix ("error"), RUBY_PLUGIN_NAME,
+ STR2CSTR(rb_inspect(err)));
+ }
+ else
+ {
+ for (i = 0; i < RARRAY_LEN(backtrace); i++)
+ {
+ line = STR2CSTR(RARRAY_PTR(backtrace)[i]);
+ cline = NULL;
+ if (i == 0)
+ {
+ cline = (char *)calloc (strlen (line) + 2 + strlen (err_msg) +
+ 3 + strlen (err_class) + 1,
+ sizeof (char));
+ if (cline)
+ {
+ strcat (cline, line);
+ strcat (cline, ": ");
+ strcat (cline, err_msg);
+ strcat (cline, " (");
+ strcat (cline, err_class);
+ strcat (cline, ")");
+ }
+ }
+ else
+ {
+ cline = (char *)calloc(strlen (line) + strlen (" from ") + 1,
+ sizeof (char));
+ if (cline)
+ {
+ strcat (cline, " from ");
+ strcat (cline, line);
+ }
+ }
+ if (cline)
+ {
+ weechat_printf (NULL,
+ weechat_gettext ("%s%s: error: %s"),
+ weechat_prefix ("error"), RUBY_PLUGIN_NAME,
+ cline);
+ }
+
+ if (cline)
+ free (cline);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * weechat_ruby_exec: call a ruby command
*/
void *
@@ -242,11 +353,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;
}
@@ -392,18 +500,13 @@ 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;
}
if (NUM2INT(ruby_retcode) != 0)
{
- VALUE ruby_eval_error;
-
switch (NUM2INT(ruby_retcode))
{
case 1:
@@ -432,14 +535,7 @@ weechat_ruby_load (const char *filename)
if (NUM2INT(ruby_retcode) == 1 || NUM2INT(ruby_retcode) == 2)
{
- ruby_eval_error = rb_iv_get(curModule, "@load_eval_file_error");
- if (ruby_eval_error)
- {
- weechat_printf (NULL,
- weechat_gettext ("%s%s: error: %s"),
- weechat_prefix ("error"), RUBY_PLUGIN_NAME,
- STR2CSTR(ruby_eval_error));
- }
+ weechat_ruby_print_exception(rb_iv_get(curModule, "@load_eval_file_error"));
}
return 0;
@@ -455,11 +551,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)
{
@@ -821,42 +914,39 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
"$stderr = WeechatOutputs\n"
"\n"
"class Module\n"
- " @load_eval_file_error = ''\n"
"\n"
" def load_eval_file (file)\n"
" lines = ''\n"
- " begin\n"
- " f = File.open(file, 'r')\n"
- " lines = f.readlines.join\n"
- " rescue => e\n"
- " @load_eval_file_error = e\n"
- " return 1\n"
- " end\n"
- "\n"
- " begin\n"
- " module_eval(lines)\n"
- " rescue => e\n"
- " @load_eval_file_error = e\n"
- " return 2\n"
- " end\n"
- "\n"
- " has_init = false\n"
- "\n"
- " instance_methods.each do |meth|\n"
- " if meth == 'weechat_init'\n"
- " has_init = true\n"
- " end\n"
- " module_eval('module_function :' + meth)\n"
- " end\n"
- "\n"
- " unless has_init\n"
- " return 3\n"
- " end\n"
- "\n"
- " return 0\n"
- " end\n"
- "end\n"
- };
+ " begin\n"
+ " lines = File.read(file)\n"
+ " rescue => e\n"
+ " return 1\n"
+ " end\n"
+ "\n"
+ " begin\n"
+ " module_eval(lines)\n"
+ " rescue Exception => e\n"
+ " @load_eval_file_error = e\n"
+ " return 2\n"
+ " end\n"
+ "\n"
+ " has_init = false\n"
+ "\n"
+ " instance_methods.each do |meth|\n"
+ " if meth.to_s == 'weechat_init'\n"
+ " has_init = true\n"
+ " end\n"
+ " module_eval('module_function :' + meth)\n"
+ " end\n"
+ "\n"
+ " unless has_init\n"
+ " return 3\n"
+ " end\n"
+ "\n"
+ " return 0\n"
+ " end\n"
+ "end\n"
+ };
weechat_ruby_plugin = plugin;
@@ -865,6 +955,10 @@ 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
+ RUBY_INIT_STACK;
+#endif
+
ruby_init ();
ruby_init_loadpath ();
ruby_script ("__weechat_plugin__");
@@ -886,7 +980,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
rb_eval_string_protect(weechat_ruby_code, &ruby_error);
if (ruby_error)
{
- VALUE ruby_error_info = rb_inspect(ruby_errinfo);
+ VALUE ruby_error_info = rb_inspect((VALUE)ruby_errinfo);
weechat_printf (NULL,
weechat_gettext ("%s%s: unable to eval WeeChat ruby "
"internal code"),
@@ -934,7 +1028,7 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
/* unload all scripts */
weechat_ruby_unload_all ();
- ruby_finalize();
+ ruby_cleanup (0);
return WEECHAT_RC_OK;
}