1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-25 20:36:38 +02:00

Support of Ruby >= 1.9.1 (patch #6989)

This commit is contained in:
Sebastien Helleu
2009-11-29 16:41:08 +01:00
parent 352217c444
commit b279a99566
5 changed files with 206 additions and 80 deletions
+1 -1
View File
@@ -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)
+160 -66
View File
@@ -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;
}