summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--cmake/FindRuby.cmake25
-rw-r--r--configure.in30
-rw-r--r--src/plugins/scripts/ruby/CMakeLists.txt2
-rw-r--r--src/plugins/scripts/ruby/weechat-ruby.c226
5 files changed, 206 insertions, 80 deletions
diff --git a/ChangeLog b/ChangeLog
index db908a9bd..94c876084 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,7 @@
WeeChat ChangeLog
=================
FlashCode <flashcode@flashtux.org>
-v0.3.1-dev, 2009-11-24
+v0.3.1-dev, 2009-11-29
Version 0.3.1 (under dev!)
@@ -35,6 +35,7 @@ Version 0.3.1 (under dev!)
* irc: improve error management on socket error (recv/send)
* irc: improve mask used by command /kickban
* xfer: add missing charset decoding/encoding for IRC DCC chat (bug #27482)
+* ruby: support of Ruby >= 1.9.1 (patch #6989)
* gui: fix message "Day changed to", sometimes displayed at wrong time
(bug #26959)
* gui: fix bug with URL selection in some terminals (caused by horizontal lines)
diff --git a/cmake/FindRuby.cmake b/cmake/FindRuby.cmake
index 6f8da1c27..2e25e36dd 100644
--- a/cmake/FindRuby.cmake
+++ b/cmake/FindRuby.cmake
@@ -35,11 +35,16 @@ FIND_PROGRAM(RUBY_EXECUTABLE
IF(RUBY_EXECUTABLE)
EXECUTE_PROCESS(
- COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "puts Config::CONFIG['archdir']"
+ COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "puts Config::CONFIG['rubyhdrdir'] || Config::CONFIG['archdir']"
OUTPUT_VARIABLE RUBY_ARCH_DIR
)
EXECUTE_PROCESS(
+ COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "puts Config::CONFIG['arch']"
+ OUTPUT_VARIABLE RUBY_ARCH
+ )
+
+ EXECUTE_PROCESS(
COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "puts Config::CONFIG['libdir']"
OUTPUT_VARIABLE RUBY_POSSIBLE_LIB_PATH
)
@@ -48,17 +53,27 @@ IF(RUBY_EXECUTABLE)
COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "puts Config::CONFIG['rubylibdir']"
OUTPUT_VARIABLE RUBY_RUBY_LIB_PATH
)
+
+ EXECUTE_PROCESS(
+ COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "puts Config::CONFIG['ruby_version']"
+ OUTPUT_VARIABLE RUBY_VERSION
+ )
# remove the new lines from the output by replacing them with empty strings
STRING(REPLACE "\n" "" RUBY_ARCH_DIR "${RUBY_ARCH_DIR}")
STRING(REPLACE "\n" "" RUBY_POSSIBLE_LIB_PATH "${RUBY_POSSIBLE_LIB_PATH}")
STRING(REPLACE "\n" "" RUBY_RUBY_LIB_PATH "${RUBY_RUBY_LIB_PATH}")
+ STRING(REPLACE "\n" "" RUBY_ARCH "${RUBY_ARCH}")
+ STRING(REPLACE "\n" "" RUBY_VERSION "${RUBY_VERSION}")
FIND_PATH(RUBY_INCLUDE_PATH
NAMES ruby.h
PATHS ${RUBY_ARCH_DIR}
)
+ SET(RUBY_ARCH
+ "${RUBY_INCLUDE_PATH}/${RUBY_ARCH}")
+
FIND_LIBRARY(RUBY_LIBRARY
NAMES ruby ruby1.6 ruby16 ruby1.8 ruby18 ruby1.9 ruby19
PATHS ${RUBY_POSSIBLE_LIB_PATH} ${RUBY_RUBY_LIB_PATH}
@@ -67,11 +82,15 @@ IF(RUBY_EXECUTABLE)
IF(RUBY_LIBRARY AND RUBY_INCLUDE_PATH)
SET(RUBY_FOUND TRUE)
ENDIF(RUBY_LIBRARY AND RUBY_INCLUDE_PATH)
-
+
+ IF(${RUBY_VERSION} STREQUAL "1.9.0")
+ SET(RUBY_FOUND FALSE)
+ ENDIF(${RUBY_VERSION} STREQUAL "1.9.0")
+
MARK_AS_ADVANCED(
RUBY_EXECUTABLE
RUBY_LIBRARY
+ RUBY_ARCH
RUBY_INCLUDE_PATH
)
-
ENDIF(RUBY_EXECUTABLE)
diff --git a/configure.in b/configure.in
index 253c71572..b8b0f2d05 100644
--- a/configure.in
+++ b/configure.in
@@ -529,20 +529,32 @@ if test "x$enable_ruby" = "xyes" ; then
not_found="$not_found ruby"
else
RUBY_VERSION=`$RUBY -rrbconfig -e "puts Config::CONFIG[['ruby_version']]"`
- RUBY_INCLUDE=`$RUBY -rrbconfig -e "puts Config::CONFIG[['archdir']]"`
- AC_MSG_CHECKING(for Ruby header files)
- if test -r "$RUBY_INCLUDE/ruby.h"; then
- RUBY_CFLAGS="-I$RUBY_INCLUDE"
- else
+ if test "$RUBY_VERSION" = "1.9.0"; then
AC_MSG_WARN([
-*** Ruby header files couldn't be found on your system.
-*** Try to install them with your software package manager.
+*** Ruby header files have been found, but they're of the version 1.9.0.
+*** Ruby 1.9.0 is an unstable release and should not be used in production.
+*** Please install Ruby >=1.8.6 or 1.9.1.
*** WeeChat will be built without Ruby support.])
enable_ruby="no"
not_found="$not_found ruby"
+ else
+ RUBY_INCLUDE=`$RUBY -rrbconfig -e "puts Config::CONFIG[['rubyhdrdir']] || Config::CONFIG[['archdir']]"`
+ RUBY_ARCH=`$RUBY -rrbconfig -e 'print Config::CONFIG[["arch"]]'`
+ AC_MSG_CHECKING(for Ruby header files)
+ if test -d "$RUBY_INCLUDE/"; then
+ M_RUBY_VERSION=`$RUBY -rrbconfig -e "puts Config::CONFIG[['ruby_version']].gsub(/\./, '')[[0,2]]"`
+ RUBY_CFLAGS="-I$RUBY_INCLUDE/ -I$RUBY_INCLUDE/$RUBY_ARCH -DRUBY_VERSION=$M_RUBY_VERSION"
+ else
+ AC_MSG_WARN([
+*** Ruby header files couldn't be found on your system.
+*** Try to install them with your software package manager.
+*** WeeChat will be built without Ruby support.])
+ enable_ruby="no"
+ not_found="$not_found ruby"
+ fi
+ AC_MSG_RESULT(found)
+ RUBY_LFLAGS=`$RUBY -rrbconfig -e "puts Config::CONFIG[['LIBRUBYARG_SHARED']]"`
fi
- AC_MSG_RESULT(found)
- RUBY_LFLAGS=`$RUBY -rrbconfig -e "puts Config::CONFIG[['LIBRUBYARG_SHARED']]"`
fi
else
not_asked="$not_asked ruby"
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;
}