24 |
|
|
25 |
#include <stdlib.h> |
#include <stdlib.h> |
26 |
#include <string.h> |
#include <string.h> |
27 |
|
#include <stdarg.h> |
28 |
|
#include <sys/socket.h> |
29 |
|
#include <netinet/in.h> |
30 |
|
#include <arpa/inet.h> |
31 |
#undef _ |
#undef _ |
32 |
#include "../../weechat-plugin.h" |
#include "../../weechat-plugin.h" |
33 |
#include "../weechat-script.h" |
#include "../weechat-script.h" |
43 |
t_plugin_script *ruby_current_script = NULL; |
t_plugin_script *ruby_current_script = NULL; |
44 |
char *ruby_current_script_filename = NULL; |
char *ruby_current_script_filename = NULL; |
45 |
|
|
46 |
|
VALUE mWeechat, mWeechatOutputs; |
47 |
|
|
48 |
|
#define MOD_NAME_PREFIX "WeechatRubyModule" |
49 |
|
int modnum = 0; |
50 |
|
|
51 |
|
|
52 |
|
/* |
53 |
|
* -- this structure comes from apache mod_ruby -- |
54 |
|
*/ |
55 |
|
typedef struct protect_call_arg { |
56 |
|
VALUE recv; |
57 |
|
ID mid; |
58 |
|
int argc; |
59 |
|
VALUE *argv; |
60 |
|
} protect_call_arg_t; |
61 |
|
|
62 |
|
/* |
63 |
|
* protect_funcall0 : |
64 |
|
* |
65 |
|
* -- this function comes from apache mod_ruby -- |
66 |
|
*/ |
67 |
|
|
68 |
|
static VALUE |
69 |
|
protect_funcall0(VALUE arg) |
70 |
|
{ |
71 |
|
return rb_funcall2(((protect_call_arg_t *) arg)->recv, |
72 |
|
((protect_call_arg_t *) arg)->mid, |
73 |
|
((protect_call_arg_t *) arg)->argc, |
74 |
|
((protect_call_arg_t *) arg)->argv); |
75 |
|
} |
76 |
|
|
77 |
|
/* |
78 |
|
* rb_protect_funcall : |
79 |
|
* |
80 |
|
* -- this function comes from apache mod_ruby -- |
81 |
|
*/ |
82 |
|
|
83 |
|
VALUE |
84 |
|
rb_protect_funcall(VALUE recv, ID mid, int *state, int argc, ...) |
85 |
|
{ |
86 |
|
va_list ap; |
87 |
|
VALUE *argv; |
88 |
|
struct protect_call_arg arg; |
89 |
|
|
90 |
|
if (argc > 0) |
91 |
|
{ |
92 |
|
int i; |
93 |
|
argv = ALLOCA_N(VALUE, argc); |
94 |
|
va_start(ap, argc); |
95 |
|
for (i = 0; i < argc; i++) |
96 |
|
argv[i] = va_arg(ap, VALUE); |
97 |
|
va_end(ap); |
98 |
|
} |
99 |
|
else |
100 |
|
argv = 0; |
101 |
|
arg.recv = recv; |
102 |
|
arg.mid = mid; |
103 |
|
arg.argc = argc; |
104 |
|
arg.argv = argv; |
105 |
|
return rb_protect(protect_funcall0, (VALUE) &arg, state); |
106 |
|
} |
107 |
|
|
108 |
/* |
/* |
109 |
* weechat_ruby_exec: execute a Ruby script |
* weechat_ruby_exec: execute a Ruby script |
116 |
{ |
{ |
117 |
/* make gcc happy */ |
/* make gcc happy */ |
118 |
(void) plugin; |
(void) plugin; |
119 |
(void) script; |
|
120 |
(void) function; |
VALUE ruby_retcode; |
121 |
(void) server; |
int ruby_error; |
|
(void) arguments; |
|
122 |
|
|
123 |
/* TODO: exec Ruby script */ |
ruby_current_script = script; |
124 |
return PLUGIN_RC_OK; |
|
125 |
|
ruby_retcode = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), |
126 |
|
&ruby_error, 2, |
127 |
|
rb_str_new2((server == NULL) ? "" : server), |
128 |
|
rb_str_new2((arguments == NULL) ? "" : arguments)); |
129 |
|
ruby_current_script = NULL; |
130 |
|
|
131 |
|
if (ruby_error) |
132 |
|
{ |
133 |
|
VALUE ruby_error_info = rb_inspect(ruby_errinfo); |
134 |
|
rb_backtrace(); |
135 |
|
ruby_plugin->printf_server (ruby_plugin, |
136 |
|
"Ruby error: unable to run function \"%s\"", |
137 |
|
function); |
138 |
|
ruby_plugin->printf_server (ruby_plugin, |
139 |
|
"Ruby error: %s", STR2CSTR(ruby_error_info)); |
140 |
|
return PLUGIN_RC_KO; |
141 |
|
} |
142 |
|
|
143 |
|
return NUM2INT(ruby_retcode); |
144 |
} |
} |
145 |
|
|
146 |
/* |
/* |
232 |
*/ |
*/ |
233 |
|
|
234 |
static VALUE |
static VALUE |
235 |
weechat_ruby_print (VALUE class, VALUE message, VALUE channel_name, |
weechat_ruby_print (int argc, VALUE *argv, VALUE class) |
|
VALUE server_name) |
|
236 |
{ |
{ |
237 |
|
VALUE message, channel_name, server_name; |
238 |
char *c_message, *c_channel_name, *c_server_name; |
char *c_message, *c_channel_name, *c_server_name; |
239 |
|
|
240 |
/* make gcc happy */ |
/* make gcc happy */ |
248 |
return INT2FIX (0); |
return INT2FIX (0); |
249 |
} |
} |
250 |
|
|
251 |
|
message = Qnil; |
252 |
|
channel_name = Qnil; |
253 |
|
server_name = Qnil; |
254 |
c_message = NULL; |
c_message = NULL; |
255 |
c_channel_name = NULL; |
c_channel_name = NULL; |
256 |
c_server_name = NULL; |
c_server_name = NULL; |
257 |
|
|
258 |
|
rb_scan_args (argc, argv, "12", &message, &channel_name, &server_name); |
259 |
|
|
260 |
if (NIL_P (message)) |
if (NIL_P (message)) |
261 |
{ |
{ |
262 |
ruby_plugin->printf_server (ruby_plugin, |
ruby_plugin->printf_server (ruby_plugin, |
266 |
} |
} |
267 |
|
|
268 |
Check_Type (message, T_STRING); |
Check_Type (message, T_STRING); |
269 |
|
c_message = STR2CSTR (message); |
270 |
|
|
271 |
if (!NIL_P (channel_name)) |
if (!NIL_P (channel_name)) |
272 |
|
{ |
273 |
Check_Type (channel_name, T_STRING); |
Check_Type (channel_name, T_STRING); |
274 |
|
c_channel_name = STR2CSTR (channel_name); |
275 |
|
} |
276 |
|
|
277 |
if (!NIL_P (server_name)) |
if (!NIL_P (server_name)) |
278 |
|
{ |
279 |
Check_Type (server_name, T_STRING); |
Check_Type (server_name, T_STRING); |
280 |
|
c_server_name = STR2CSTR (server_name); |
281 |
c_message = STR2CSTR (message); |
} |
|
if (!NIL_P (channel_name)) |
|
|
c_channel_name = STR2CSTR (channel_name); |
|
|
if (!NIL_P (server_name)) |
|
|
c_server_name = STR2CSTR (server_name); |
|
282 |
|
|
283 |
ruby_plugin->printf (ruby_plugin, |
ruby_plugin->printf (ruby_plugin, |
284 |
c_server_name, c_channel_name, |
c_server_name, c_channel_name, |
335 |
*/ |
*/ |
336 |
|
|
337 |
static VALUE |
static VALUE |
338 |
weechat_ruby_command (VALUE class, VALUE command, VALUE channel_name, |
weechat_ruby_command (int argc, VALUE *argv, VALUE class) |
|
VALUE server_name) |
|
339 |
{ |
{ |
340 |
|
VALUE command, channel_name, server_name; |
341 |
char *c_command, *c_channel_name, *c_server_name; |
char *c_command, *c_channel_name, *c_server_name; |
342 |
|
|
343 |
/* make gcc happy */ |
/* make gcc happy */ |
351 |
return INT2FIX (0); |
return INT2FIX (0); |
352 |
} |
} |
353 |
|
|
354 |
|
command = Qnil; |
355 |
|
channel_name = Qnil; |
356 |
|
server_name = Qnil; |
357 |
c_command = NULL; |
c_command = NULL; |
358 |
c_channel_name = NULL; |
c_channel_name = NULL; |
359 |
c_server_name = NULL; |
c_server_name = NULL; |
360 |
|
|
361 |
|
rb_scan_args(argc, argv, "12", &command, &channel_name, &server_name); |
362 |
|
|
363 |
if (NIL_P (command)) |
if (NIL_P (command)) |
364 |
{ |
{ |
365 |
ruby_plugin->printf_server (ruby_plugin, |
ruby_plugin->printf_server (ruby_plugin, |
369 |
} |
} |
370 |
|
|
371 |
Check_Type (command, T_STRING); |
Check_Type (command, T_STRING); |
372 |
|
c_command = STR2CSTR (command); |
373 |
|
|
374 |
if (!NIL_P (channel_name)) |
if (!NIL_P (channel_name)) |
375 |
|
{ |
376 |
Check_Type (channel_name, T_STRING); |
Check_Type (channel_name, T_STRING); |
377 |
|
c_channel_name = STR2CSTR (channel_name); |
378 |
|
} |
379 |
|
|
380 |
if (!NIL_P (server_name)) |
if (!NIL_P (server_name)) |
381 |
|
{ |
382 |
Check_Type (server_name, T_STRING); |
Check_Type (server_name, T_STRING); |
383 |
|
c_server_name = STR2CSTR (server_name); |
384 |
c_command = STR2CSTR (command); |
} |
|
if (!NIL_P (channel_name)) |
|
|
c_channel_name = STR2CSTR (channel_name); |
|
|
if (!NIL_P (server_name)) |
|
|
c_server_name = STR2CSTR (server_name); |
|
385 |
|
|
386 |
ruby_plugin->exec_command (ruby_plugin, |
ruby_plugin->exec_command (ruby_plugin, |
387 |
c_server_name, c_channel_name, |
c_server_name, c_channel_name, |
440 |
*/ |
*/ |
441 |
|
|
442 |
static VALUE |
static VALUE |
443 |
weechat_ruby_add_command_handler (VALUE class, VALUE command, VALUE function, |
weechat_ruby_add_command_handler (int argc, VALUE *argv, VALUE class) |
|
VALUE description, VALUE arguments, |
|
|
VALUE arguments_description) |
|
444 |
{ |
{ |
445 |
char *c_command, *c_function, *c_description, *c_arguments; |
VALUE command, function, description, arguments, arguments_description; |
446 |
char *c_arguments_description; |
char *c_command, *c_function, *c_description, *c_arguments, *c_arguments_description; |
447 |
|
|
448 |
/* make gcc happy */ |
/* make gcc happy */ |
449 |
(void) class; |
(void) class; |
456 |
return INT2FIX (0); |
return INT2FIX (0); |
457 |
} |
} |
458 |
|
|
459 |
|
command = Qnil; |
460 |
|
function = Qnil; |
461 |
|
description = Qnil; |
462 |
|
arguments = Qnil; |
463 |
|
arguments_description = Qnil; |
464 |
c_command = NULL; |
c_command = NULL; |
465 |
c_function = NULL; |
c_function = NULL; |
466 |
c_description = NULL; |
c_description = NULL; |
467 |
c_arguments = NULL; |
c_arguments = NULL; |
468 |
c_arguments_description = NULL; |
c_arguments_description = NULL; |
469 |
|
|
470 |
|
rb_scan_args (argc, argv, "23", &command, &function, &description, |
471 |
|
&arguments, &arguments_description); |
472 |
|
|
473 |
if (NIL_P (command) || NIL_P (function)) |
if (NIL_P (command) || NIL_P (function)) |
474 |
{ |
{ |
475 |
ruby_plugin->printf_server (ruby_plugin, |
ruby_plugin->printf_server (ruby_plugin, |
479 |
} |
} |
480 |
|
|
481 |
Check_Type (command, T_STRING); |
Check_Type (command, T_STRING); |
482 |
|
c_command = STR2CSTR (command); |
483 |
Check_Type (function, T_STRING); |
Check_Type (function, T_STRING); |
484 |
|
c_function = STR2CSTR (function); |
485 |
|
|
486 |
if (!NIL_P (description)) |
if (!NIL_P (description)) |
487 |
|
{ |
488 |
Check_Type (description, T_STRING); |
Check_Type (description, T_STRING); |
489 |
|
c_description = STR2CSTR (description); |
490 |
|
} |
491 |
|
|
492 |
if (!NIL_P (arguments)) |
if (!NIL_P (arguments)) |
493 |
|
{ |
494 |
Check_Type (arguments, T_STRING); |
Check_Type (arguments, T_STRING); |
495 |
if (!NIL_P (arguments_description)) |
c_arguments = STR2CSTR (arguments); |
496 |
Check_Type (arguments_description, T_STRING); |
} |
497 |
|
|
498 |
c_command = STR2CSTR (command); |
if (!NIL_P (arguments_description)) { |
499 |
c_function = STR2CSTR (function); |
Check_Type (arguments_description, T_STRING); |
500 |
if (!NIL_P (description)) |
c_arguments_description = STR2CSTR (arguments_description); |
501 |
c_description = STR2CSTR (description); |
} |
|
if (!NIL_P (arguments)) |
|
|
c_arguments = STR2CSTR (arguments); |
|
|
if (!NIL_P (arguments_description)) |
|
|
c_arguments_description = STR2CSTR (arguments_description); |
|
502 |
|
|
503 |
if (ruby_plugin->cmd_handler_add (ruby_plugin, |
if (ruby_plugin->cmd_handler_add (ruby_plugin, |
504 |
c_command, |
c_command, |
561 |
*/ |
*/ |
562 |
|
|
563 |
static VALUE |
static VALUE |
564 |
weechat_ruby_get_info (VALUE class, VALUE arg, VALUE server_name) |
weechat_ruby_get_info (int argc, VALUE *argv, VALUE class) |
565 |
{ |
{ |
566 |
char *c_arg, *c_server_name, *info; |
char *c_arg, *c_server_name, *info; |
567 |
VALUE return_value; |
VALUE arg, server_name, return_value; |
568 |
|
|
569 |
/* make gcc happy */ |
/* make gcc happy */ |
570 |
(void) class; |
(void) class; |
577 |
return INT2FIX (0); |
return INT2FIX (0); |
578 |
} |
} |
579 |
|
|
580 |
|
arg = Qnil; |
581 |
|
server_name = Qnil; |
582 |
c_arg = NULL; |
c_arg = NULL; |
583 |
c_server_name = NULL; |
c_server_name = NULL; |
584 |
|
|
585 |
|
rb_scan_args (argc, argv, "11", &arg, &server_name); |
586 |
|
|
587 |
if (NIL_P (arg)) |
if (NIL_P (arg)) |
588 |
{ |
{ |
593 |
} |
} |
594 |
|
|
595 |
Check_Type (arg, T_STRING); |
Check_Type (arg, T_STRING); |
|
if (!NIL_P (server_name)) |
|
|
Check_Type (server_name, T_STRING); |
|
|
|
|
596 |
c_arg = STR2CSTR (arg); |
c_arg = STR2CSTR (arg); |
597 |
|
|
598 |
if (!NIL_P (server_name)) |
if (!NIL_P (server_name)) |
599 |
c_server_name = STR2CSTR (server_name); |
{ |
600 |
|
Check_Type (server_name, T_STRING); |
601 |
|
c_server_name = STR2CSTR (server_name); |
602 |
|
} |
603 |
|
|
604 |
if (c_arg) |
if (c_arg) |
605 |
{ |
{ |
623 |
static VALUE |
static VALUE |
624 |
weechat_ruby_get_dcc_info (VALUE class) |
weechat_ruby_get_dcc_info (VALUE class) |
625 |
{ |
{ |
626 |
|
t_plugin_dcc_info *dcc_info, *ptr_dcc; |
627 |
|
VALUE dcc_list, dcc_list_member; |
628 |
|
char timebuffer1[64]; |
629 |
|
char timebuffer2[64]; |
630 |
|
struct in_addr in; |
631 |
|
|
632 |
/* make gcc happy */ |
/* make gcc happy */ |
633 |
(void) class; |
(void) class; |
634 |
|
|
639 |
"script not initialized"); |
"script not initialized"); |
640 |
return INT2FIX (0); |
return INT2FIX (0); |
641 |
} |
} |
642 |
|
|
643 |
|
dcc_list = rb_ary_new(); |
644 |
|
|
645 |
/* TODO: get dcc info for Ruby */ |
if (NIL_P (dcc_list)) |
646 |
return INT2FIX (1); |
return Qnil; |
647 |
|
|
648 |
|
dcc_info = ruby_plugin->get_dcc_info (ruby_plugin); |
649 |
|
if (!dcc_info) |
650 |
|
return dcc_list; |
651 |
|
|
652 |
|
for(ptr_dcc = dcc_info; ptr_dcc; ptr_dcc = ptr_dcc->next_dcc) |
653 |
|
{ |
654 |
|
strftime(timebuffer1, sizeof(timebuffer1), "%F %T", |
655 |
|
localtime(&ptr_dcc->start_time)); |
656 |
|
strftime(timebuffer2, sizeof(timebuffer2), "%F %T", |
657 |
|
localtime(&ptr_dcc->start_transfer)); |
658 |
|
in.s_addr = htonl(ptr_dcc->addr); |
659 |
|
|
660 |
|
dcc_list_member = rb_hash_new (); |
661 |
|
|
662 |
|
if (!NIL_P (dcc_list_member)) |
663 |
|
{ |
664 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("server"), |
665 |
|
rb_str_new2(ptr_dcc->server)); |
666 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("channel"), |
667 |
|
rb_str_new2(ptr_dcc->channel)); |
668 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("type"), |
669 |
|
INT2FIX(ptr_dcc->type)); |
670 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("status"), |
671 |
|
INT2FIX(ptr_dcc->status)); |
672 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("start_time"), |
673 |
|
rb_str_new2(timebuffer1)); |
674 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("start_transfer"), |
675 |
|
rb_str_new2(timebuffer2)); |
676 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("address"), |
677 |
|
rb_str_new2(inet_ntoa(in))); |
678 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("port"), |
679 |
|
INT2FIX(ptr_dcc->port)); |
680 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("nick"), |
681 |
|
rb_str_new2(ptr_dcc->nick)); |
682 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("remote_file"), |
683 |
|
rb_str_new2(ptr_dcc->filename)); |
684 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("local_file"), |
685 |
|
rb_str_new2(ptr_dcc->local_filename)); |
686 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("filename_suffix"), |
687 |
|
INT2FIX(ptr_dcc->filename_suffix)); |
688 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("size"), |
689 |
|
INT2FIX(ptr_dcc->size)); |
690 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("pos"), |
691 |
|
INT2FIX(ptr_dcc->pos)); |
692 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("start_resume"), |
693 |
|
INT2FIX(ptr_dcc->start_resume)); |
694 |
|
rb_hash_aset (dcc_list_member, rb_str_new2("cps"), |
695 |
|
INT2FIX(ptr_dcc->bytes_per_sec)); |
696 |
|
|
697 |
|
if (NIL_P (rb_ary_push (dcc_list, dcc_list_member))) |
698 |
|
{ |
699 |
|
rb_gc_unregister_address (&dcc_list_member); |
700 |
|
rb_gc_unregister_address (&dcc_list); |
701 |
|
ruby_plugin->free_dcc_info (ruby_plugin, dcc_info); |
702 |
|
return Qnil; |
703 |
|
} |
704 |
|
} |
705 |
|
else |
706 |
|
{ |
707 |
|
rb_gc_unregister_address (&dcc_list); |
708 |
|
ruby_plugin->free_dcc_info (ruby_plugin, dcc_info); |
709 |
|
return Qnil; |
710 |
|
} |
711 |
|
} |
712 |
|
|
713 |
|
ruby_plugin->free_dcc_info (ruby_plugin, dcc_info); |
714 |
|
|
715 |
|
return dcc_list; |
716 |
} |
} |
717 |
|
|
718 |
/* |
/* |
910 |
} |
} |
911 |
|
|
912 |
/* |
/* |
913 |
* Ruby subroutines |
* weechat_ruby_output : redirection for stdout and stderr |
914 |
*/ |
*/ |
915 |
|
|
916 |
/* TODO: write Ruby functions interface */ |
static VALUE |
917 |
|
weechat_ruby_output(VALUE self, VALUE str) |
918 |
|
{ |
919 |
|
/* make gcc happy */ |
920 |
|
(void) self; |
921 |
|
|
922 |
|
ruby_plugin->printf_server (ruby_plugin, |
923 |
|
"Ruby stdout/stderr: %s", |
924 |
|
STR2CSTR(str)); |
925 |
|
return Qnil; |
926 |
|
} |
927 |
|
|
928 |
|
|
929 |
/* |
/* |
930 |
* weechat_ruby_load: load a Ruby script |
* weechat_ruby_load: load a Ruby script |
933 |
int |
int |
934 |
weechat_ruby_load (t_weechat_plugin *plugin, char *filename) |
weechat_ruby_load (t_weechat_plugin *plugin, char *filename) |
935 |
{ |
{ |
936 |
/* make gcc happy */ |
char modname[64]; |
937 |
(void) plugin; |
VALUE curModule; |
938 |
(void) filename; |
VALUE ruby_retcode; |
939 |
|
int ruby_error; |
940 |
|
|
941 |
|
plugin->printf_server (plugin, "Loading Ruby script \"%s\"", filename); |
942 |
|
ruby_current_script = NULL; |
943 |
|
|
944 |
|
snprintf(modname, sizeof(modname), "%s%d", MOD_NAME_PREFIX, modnum); |
945 |
|
modnum++; |
946 |
|
|
947 |
|
curModule = rb_define_module(modname); |
948 |
|
|
949 |
|
ruby_current_script_filename = strdup (filename); |
950 |
|
|
951 |
|
ruby_retcode = rb_protect_funcall (curModule, rb_intern("load_eval_file"), |
952 |
|
&ruby_error, 1, rb_str_new2(filename)); |
953 |
|
|
954 |
|
free (ruby_current_script_filename); |
955 |
|
|
956 |
|
if (NUM2INT(ruby_retcode) != 0) |
957 |
|
{ |
958 |
|
VALUE ruby_eval_error; |
959 |
|
|
960 |
|
switch (NUM2INT(ruby_retcode)) |
961 |
|
{ |
962 |
|
case 1: |
963 |
|
ruby_plugin->printf_server (ruby_plugin, |
964 |
|
"Ruby error: unable to read file \"%s\"", |
965 |
|
filename); |
966 |
|
break; |
967 |
|
case 2: |
968 |
|
ruby_plugin->printf_server (ruby_plugin, |
969 |
|
"Ruby error: error while loading file \"%s\"", |
970 |
|
filename); |
971 |
|
break; |
972 |
|
case 3: |
973 |
|
ruby_plugin->printf_server (ruby_plugin, |
974 |
|
"Ruby error: unable to find \"weechat_init\" function in file \"%s\"", |
975 |
|
filename); |
976 |
|
break; |
977 |
|
} |
978 |
|
|
979 |
|
if (NUM2INT(ruby_retcode) == 1 || NUM2INT(ruby_retcode) == 2) |
980 |
|
{ |
981 |
|
ruby_eval_error = rb_iv_get(curModule, "@load_eval_file_error"); |
982 |
|
if (ruby_eval_error) |
983 |
|
ruby_plugin->printf_server (ruby_plugin, |
984 |
|
"Ruby error: %s", STR2CSTR(ruby_eval_error)); |
985 |
|
} |
986 |
|
|
987 |
|
return 0; |
988 |
|
} |
989 |
|
|
990 |
|
ruby_retcode = rb_protect_funcall (curModule, rb_intern("weechat_init"), &ruby_error, 0); |
991 |
|
if (ruby_error) { |
992 |
|
VALUE ruby_error_info = rb_inspect(ruby_errinfo); |
993 |
|
rb_backtrace(); |
994 |
|
ruby_plugin->printf_server (ruby_plugin, |
995 |
|
"Ruby error: unable to eval weechat_init in file \"%s\"", |
996 |
|
filename); |
997 |
|
ruby_plugin->printf_server (ruby_plugin, |
998 |
|
"Ruby error: %s", STR2CSTR(ruby_error_info)); |
999 |
|
return 0; |
1000 |
|
} |
1001 |
|
|
1002 |
|
if (ruby_current_script == NULL) { |
1003 |
|
plugin->printf_server (plugin, |
1004 |
|
"Ruby error: function \"register\" not found " |
1005 |
|
"in file \"%s\"", |
1006 |
|
filename); |
1007 |
|
return 0; |
1008 |
|
} |
1009 |
|
|
1010 |
|
ruby_current_script->interpreter = (VALUE *) curModule; |
1011 |
|
rb_gc_register_address (ruby_current_script->interpreter); |
1012 |
|
|
1013 |
/* TODO: load & exec Ruby script */ |
return 1; |
|
return 0; |
|
1014 |
} |
} |
1015 |
|
|
1016 |
/* |
/* |
1020 |
void |
void |
1021 |
weechat_ruby_unload (t_weechat_plugin *plugin, t_plugin_script *script) |
weechat_ruby_unload (t_weechat_plugin *plugin, t_plugin_script *script) |
1022 |
{ |
{ |
1023 |
/* make gcc happy */ |
plugin->printf_server (plugin, |
1024 |
(void) plugin; |
"Unloading Ruby script \"%s\"", |
1025 |
(void) script; |
script->name); |
1026 |
|
|
1027 |
|
if (script->interpreter) |
1028 |
|
rb_gc_unregister_address (script->interpreter); |
1029 |
|
|
1030 |
/* TODO: unload a Ruby script */ |
weechat_script_remove (plugin, &ruby_scripts, script); |
1031 |
} |
} |
1032 |
|
|
1033 |
/* |
/* |
1037 |
void |
void |
1038 |
weechat_ruby_unload_name (t_weechat_plugin *plugin, char *name) |
weechat_ruby_unload_name (t_weechat_plugin *plugin, char *name) |
1039 |
{ |
{ |
1040 |
/* make gcc happy */ |
t_plugin_script *ptr_script; |
|
(void) plugin; |
|
|
(void) name; |
|
1041 |
|
|
1042 |
/* TODO: unload a Ruby script by name */ |
ptr_script = weechat_script_search (plugin, &ruby_scripts, name); |
1043 |
|
if (ptr_script) |
1044 |
|
{ |
1045 |
|
weechat_ruby_unload (plugin, ptr_script); |
1046 |
|
plugin->printf_server (plugin, |
1047 |
|
"Ruby script \"%s\" unloaded", |
1048 |
|
name); |
1049 |
|
} |
1050 |
|
else |
1051 |
|
{ |
1052 |
|
plugin->printf_server (plugin, |
1053 |
|
"Ruby error: script \"%s\" not loaded", |
1054 |
|
name); |
1055 |
|
} |
1056 |
} |
} |
1057 |
|
|
1058 |
/* |
/* |
1062 |
void |
void |
1063 |
weechat_ruby_unload_all (t_weechat_plugin *plugin) |
weechat_ruby_unload_all (t_weechat_plugin *plugin) |
1064 |
{ |
{ |
1065 |
/* make gcc happy */ |
|
1066 |
(void) plugin; |
plugin->printf_server (plugin, |
1067 |
|
"Unloading all Ruby scripts"); |
1068 |
|
while (ruby_scripts) |
1069 |
|
weechat_ruby_unload (plugin, ruby_scripts); |
1070 |
|
|
1071 |
/* TODO: unload all Ruby scripts */ |
plugin->printf_server (plugin, |
1072 |
|
"Ruby scripts unloaded"); |
1073 |
} |
} |
1074 |
|
|
1075 |
/* |
/* |
1227 |
int |
int |
1228 |
weechat_plugin_init (t_weechat_plugin *plugin) |
weechat_plugin_init (t_weechat_plugin *plugin) |
1229 |
{ |
{ |
1230 |
|
char *weechat_ruby_code = |
1231 |
|
{ |
1232 |
|
"class IO\n" |
1233 |
|
" def write(msg)\n" |
1234 |
|
" msg.each {|s|\n" |
1235 |
|
" if (s.chomp != \"\")\n" |
1236 |
|
" WeechatOutputs.write(msg.chomp)\n" |
1237 |
|
" end\n" |
1238 |
|
" }\n" |
1239 |
|
" end\n" |
1240 |
|
"end\n" |
1241 |
|
"\n" |
1242 |
|
"class Module\n" |
1243 |
|
" @load_eval_file_error = ''\n" |
1244 |
|
"\n" |
1245 |
|
" def load_eval_file (file)\n" |
1246 |
|
" lines = ''\n" |
1247 |
|
" begin\n" |
1248 |
|
" f = File.open(file, 'r')\n" |
1249 |
|
" lines = f.readlines.join\n" |
1250 |
|
" rescue => e\n" |
1251 |
|
" @load_eval_file_error = e\n" |
1252 |
|
" return 1\n" |
1253 |
|
" end\n" |
1254 |
|
"\n" |
1255 |
|
" begin\n" |
1256 |
|
" module_eval(lines)\n" |
1257 |
|
" rescue => e\n" |
1258 |
|
" @load_eval_file_error = e\n" |
1259 |
|
" return 2\n" |
1260 |
|
" end\n" |
1261 |
|
"\n" |
1262 |
|
" has_init = false\n" |
1263 |
|
"\n" |
1264 |
|
" instance_methods.each do |meth|\n" |
1265 |
|
" if meth == 'weechat_init'\n" |
1266 |
|
" has_init = true\n" |
1267 |
|
" end\n" |
1268 |
|
" module_eval('module_function :' + meth)\n" |
1269 |
|
" end\n" |
1270 |
|
"\n" |
1271 |
|
" unless has_init\n" |
1272 |
|
" return 3\n" |
1273 |
|
" end\n" |
1274 |
|
"\n" |
1275 |
|
" return 0\n" |
1276 |
|
" end\n" |
1277 |
|
"end\n" |
1278 |
|
}; |
1279 |
ruby_plugin = plugin; |
ruby_plugin = plugin; |
1280 |
|
int ruby_error = 0; |
1281 |
|
|
1282 |
plugin->printf_server (plugin, "Loading Ruby module \"weechat\""); |
plugin->printf_server (plugin, "Loading Ruby module \"weechat\""); |
1283 |
|
|
1284 |
/* TODO: initialize Ruby interpreter */ |
ruby_init (); |
1285 |
|
ruby_init_loadpath (); |
1286 |
|
ruby_script ("__weechat_plugin__"); |
1287 |
|
|
1288 |
|
mWeechat = rb_define_module("Weechat"); |
1289 |
|
rb_define_const(mWeechat, "PLUGIN_RC_OK", INT2NUM(PLUGIN_RC_OK)); |
1290 |
|
rb_define_const(mWeechat, "PLUGIN_RC_KO", INT2NUM(PLUGIN_RC_KO)); |
1291 |
|
rb_define_const(mWeechat, "PLUGIN_RC_OK_IGNORE_WEECHAT", INT2NUM(PLUGIN_RC_OK_IGNORE_WEECHAT)); |
1292 |
|
rb_define_const(mWeechat, "PLUGIN_RC_OK_IGNORE_PLUGINS", INT2NUM(PLUGIN_RC_OK_IGNORE_PLUGINS)); |
1293 |
|
rb_define_const(mWeechat, "PLUGIN_RC_OK_IGNORE_ALL", INT2NUM(PLUGIN_RC_OK_IGNORE_ALL)); |
1294 |
|
rb_define_module_function (mWeechat, "register", weechat_ruby_register, 4); |
1295 |
|
rb_define_module_function (mWeechat, "print", weechat_ruby_print, -1); |
1296 |
|
rb_define_module_function (mWeechat, "print_infobar", weechat_ruby_print_infobar, 2); |
1297 |
|
rb_define_module_function (mWeechat, "command", weechat_ruby_command, -1); |
1298 |
|
rb_define_module_function (mWeechat, "add_message_handler", weechat_ruby_add_message_handler, 2); |
1299 |
|
rb_define_module_function (mWeechat, "add_command_handler", weechat_ruby_add_command_handler, -1); |
1300 |
|
rb_define_module_function (mWeechat, "remove_handler", weechat_ruby_remove_handler, 2); |
1301 |
|
rb_define_module_function (mWeechat, "get_info", weechat_ruby_get_info, -1); |
1302 |
|
rb_define_module_function (mWeechat, "get_dcc_info", weechat_ruby_get_dcc_info, 0); |
1303 |
|
rb_define_module_function (mWeechat, "get_config", weechat_ruby_get_config, 1); |
1304 |
|
rb_define_module_function (mWeechat, "set_config", weechat_ruby_set_config, 2); |
1305 |
|
rb_define_module_function (mWeechat, "get_plugin_config", weechat_ruby_get_plugin_config, 1); |
1306 |
|
rb_define_module_function (mWeechat, "set_plugin_config", weechat_ruby_set_plugin_config, 2); |
1307 |
|
|
1308 |
|
/* redirect stdin and stdout */ |
1309 |
|
mWeechatOutputs = rb_define_module("WeechatOutputs"); |
1310 |
|
rb_define_singleton_method(mWeechatOutputs, "write", weechat_ruby_output, 1); |
1311 |
|
|
1312 |
plugin->cmd_handler_add (plugin, "ruby", |
plugin->cmd_handler_add (plugin, "ruby", |
1313 |
"list/load/unload Ruby scripts", |
"list/load/unload Ruby scripts", |
1314 |
"[load filename] | [autoload] | [reload] | [unload]", |
"[load filename] | [autoload] | [reload] | [unload]", |
1319 |
plugin->mkdir_home (plugin, "ruby"); |
plugin->mkdir_home (plugin, "ruby"); |
1320 |
plugin->mkdir_home (plugin, "ruby/autoload"); |
plugin->mkdir_home (plugin, "ruby/autoload"); |
1321 |
|
|
1322 |
|
rb_eval_string_protect(weechat_ruby_code, &ruby_error); |
1323 |
|
if (ruby_error) { |
1324 |
|
VALUE ruby_error_info = rb_inspect(ruby_errinfo); |
1325 |
|
rb_backtrace(); |
1326 |
|
ruby_plugin->printf_server (ruby_plugin, |
1327 |
|
"Ruby error: unable to eval weechat ruby internal code"); |
1328 |
|
ruby_plugin->printf_server (ruby_plugin, |
1329 |
|
"Ruby error: %s", STR2CSTR(ruby_error_info)); |
1330 |
|
return PLUGIN_RC_KO; |
1331 |
|
} |
1332 |
|
|
1333 |
weechat_script_auto_load (plugin, "ruby", weechat_ruby_load); |
weechat_script_auto_load (plugin, "ruby", weechat_ruby_load); |
1334 |
|
|
1335 |
/* init ok */ |
/* init ok */ |
1346 |
/* unload all scripts */ |
/* unload all scripts */ |
1347 |
weechat_ruby_unload_all (plugin); |
weechat_ruby_unload_all (plugin); |
1348 |
|
|
1349 |
/* TODO: free interpreter */ |
ruby_finalize(); |
1350 |
|
|
|
|
|
1351 |
ruby_plugin->printf_server (ruby_plugin, |
ruby_plugin->printf_server (ruby_plugin, |
1352 |
"Ruby plugin ended"); |
"Ruby plugin ended"); |
1353 |
} |
} |