diff --git a/src/plugins/scripts/lua/weechat-lua.c b/src/plugins/scripts/lua/weechat-lua.c index fce16b30a..a727d3618 100644 --- a/src/plugins/scripts/lua/weechat-lua.c +++ b/src/plugins/scripts/lua/weechat-lua.c @@ -55,11 +55,14 @@ lua_State *lua_current_interpreter = NULL; * weechat_lua_exec: execute a Lua script */ -int +void * weechat_lua_exec (t_weechat_plugin *plugin, t_plugin_script *script, + int ret_type, char *function, char *arg1, char *arg2, char *arg3) { + void *ret_value; + int *ret_i; lua_current_interpreter = script->interpreter; @@ -86,10 +89,27 @@ weechat_lua_exec (t_weechat_plugin *plugin, plugin->print_server (plugin, "Lua error: %s", lua_tostring (lua_current_interpreter, -1)); - return PLUGIN_RC_KO; + return NULL; } - return lua_tonumber (lua_current_interpreter, -1); + if (ret_type == SCRIPT_EXEC_STRING) + ret_value = strdup ((char *) lua_tostring (lua_current_interpreter, -1)); + else if (ret_type == SCRIPT_EXEC_INT) + { + ret_i = (int *) malloc (sizeof(int)); + if (ret_i) + *ret_i = lua_tonumber (lua_current_interpreter, -1); + ret_value = ret_i; + } + else + { + lua_plugin->print_server (lua_plugin, + "Lua error: wrong parameters for function \"%s\"", + function); + return NULL; + } + + return ret_value; } /* @@ -101,9 +121,23 @@ weechat_lua_cmd_msg_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[2], NULL); + { + r = (int *) weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[2], NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -120,9 +154,20 @@ weechat_lua_timer_handler (t_weechat_plugin *plugin, /* make gcc happy */ (void) argc; (void) argv; + int *r; + int ret; - return weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, NULL, NULL, NULL); + r = (int *) weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, NULL, NULL, NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; } /* @@ -134,9 +179,23 @@ weechat_lua_keyboard_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { - if (argc >= 2) - return weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[1], argv[2]); + int *r; + int ret; + + if (argc >= 3) + { + r = (int *) weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[1], argv[2]); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -150,12 +209,12 @@ weechat_lua_modifier (t_weechat_plugin *plugin, int argc, char **argv, char *modifier_args, void *modifier_pointer) { - /*if (argc >= 2) - return weechat_lua_exec (plugin, (t_plugin_script *)modifier_pointer, - modifier_args, argv[0], argv[1], NULL); + if (argc >= 2) + return (char *) weechat_lua_exec (plugin, (t_plugin_script *)modifier_pointer, + SCRIPT_EXEC_STRING, + modifier_args, argv[0], argv[1], NULL); else - return NULL;*/ - return NULL; + return NULL; } /* @@ -968,12 +1027,13 @@ weechat_lua_remove_modifier (lua_State *L) return 1; } + type = NULL; command = NULL; function = NULL; n = lua_gettop (lua_current_interpreter); - if (n != 2) + if (n != 3) { lua_plugin->print_server (lua_plugin, "Lua error: wrong parameters for " @@ -2153,12 +2213,19 @@ weechat_lua_load (t_weechat_plugin *plugin, char *filename) void weechat_lua_unload (t_weechat_plugin *plugin, t_plugin_script *script) { + int *r; + plugin->print_server (plugin, "Unloading Lua script \"%s\"", script->name); if (script->shutdown_func[0]) - weechat_lua_exec (plugin, script, script->shutdown_func, NULL, NULL, NULL); + { + r = weechat_lua_exec (plugin, script, SCRIPT_EXEC_INT, + script->shutdown_func, NULL, NULL, NULL); + if (r) + free (r); + } lua_close (script->interpreter); @@ -2215,11 +2282,12 @@ weechat_lua_cmd (t_weechat_plugin *plugin, int cmd_argc, char **cmd_argv, char *handler_args, void *handler_pointer) { - int argc, handler_found; + int argc, handler_found, modifier_found; char **argv, *path_script; t_plugin_script *ptr_script; t_plugin_handler *ptr_handler; - + t_plugin_modifier *ptr_modifier; + /* make gcc happy */ (void) handler_args; (void) handler_pointer; @@ -2330,7 +2398,34 @@ weechat_lua_cmd (t_weechat_plugin *plugin, } if (!handler_found) plugin->print_server (plugin, " (none)"); - break; + + /* list Lua modifiers */ + plugin->print_server (plugin, ""); + plugin->print_server (plugin, "Lua modifiers:"); + modifier_found = 0; + for (ptr_modifier = plugin->modifiers; + ptr_modifier; ptr_modifier = ptr_modifier->next_modifier) + { + modifier_found = 1; + if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_IN) + plugin->print_server (plugin, " IRC(%s, %s) => Lua(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_IN_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_USER) + plugin->print_server (plugin, " IRC(%s, %s) => Lua(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_USER_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_OUT) + plugin->print_server (plugin, " IRC(%s, %s) => Lua(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_OUT_STR, + ptr_modifier->modifier_args); + } + if (!modifier_found) + plugin->print_server (plugin, " (none)"); + break; case 1: if (plugin->ascii_strcasecmp (plugin, argv[0], "autoload") == 0) weechat_script_auto_load (plugin, "lua", weechat_lua_load); diff --git a/src/plugins/scripts/perl/weechat-perl.c b/src/plugins/scripts/perl/weechat-perl.c index 72c933dce..8b97977b5 100644 --- a/src/plugins/scripts/perl/weechat-perl.c +++ b/src/plugins/scripts/perl/weechat-perl.c @@ -112,17 +112,20 @@ char *perl_weechat_code = * weechat_perl_exec: execute a Perl script */ -int +void * weechat_perl_exec (t_weechat_plugin *plugin, t_plugin_script *script, + int ret_type, char *function, char *arg1, char *arg2, char *arg3) { char empty_arg[1] = { '\0' }; char *func; char *argv[4]; unsigned int count; - int return_code; - SV *sv; + void *ret_value; + int *ret_i; + SV *ret_s; + int mem_err; /* this code is placed here to conform ISO C90 */ dSP; @@ -131,7 +134,7 @@ weechat_perl_exec (t_weechat_plugin *plugin, int size = strlen (script->interpreter) + strlen(function) + 3; func = (char *) malloc ( size * sizeof(char)); if (!func) - return PLUGIN_RC_KO; + return NULL; snprintf (func, size, "%s::%s", (char *) script->interpreter, function); #else func = function; @@ -141,6 +144,9 @@ weechat_perl_exec (t_weechat_plugin *plugin, ENTER; SAVETMPS; PUSHMARK(sp); + + perl_current_script = script; + if (arg1) { argv[0] = (arg1) ? arg1 : empty_arg; @@ -161,29 +167,50 @@ weechat_perl_exec (t_weechat_plugin *plugin, else argv[0] = NULL; - perl_current_script = script; - count = perl_call_argv (func, G_EVAL | G_SCALAR, argv); - + ret_value = NULL; + mem_err = 1; + SPAGAIN; - sv = GvSV (gv_fetchpv ("@", TRUE, SVt_PV)); - return_code = PLUGIN_RC_KO; - if (SvTRUE (sv)) + if (SvTRUE (ERRSV)) { - plugin->print_server (plugin, "Perl error: %s", SvPV_nolen (sv)); - POPs; + plugin->print_server (plugin, "Perl error: %s", SvPV_nolen (ERRSV)); + POPs; /* poping the 'undef' */ + mem_err = 0; } else { if (count != 1) - { + { plugin->print_server (plugin, - "Perl error: too much values from \"%s\" (%d). Expected: 1.", + "Perl error: function \"%s\" must return 1 valid value (%d)", function, count); - } + mem_err = 0; + } else - return_code = POPi; + { + if (ret_type == SCRIPT_EXEC_STRING) + { + ret_s = newSVsv(POPs); + ret_value = strdup (SvPV_nolen (ret_s)); + SvREFCNT_dec (ret_s); + } + else if (ret_type == SCRIPT_EXEC_INT) + { + ret_i = (int *) malloc (sizeof(int)); + if (ret_i) + *ret_i = POPi; + ret_value = ret_i; + } + else + { + plugin->print_server (plugin, + "Perl error: function \"%s\" is internally misused.", + function); + mem_err = 0; + } + } } PUTBACK; @@ -193,8 +220,16 @@ weechat_perl_exec (t_weechat_plugin *plugin, #ifndef MULTIPLICITY free (func); #endif + + if (ret_value == NULL && mem_err == 1) + { + plugin->print_server (plugin, + "Python error: unable to alloc memory in function \"%s\"", + function); + return NULL; + } - return return_code; + return ret_value; } /* @@ -206,9 +241,23 @@ weechat_perl_cmd_msg_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[2], NULL); + { + r = (int *) weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[2], NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -225,9 +274,20 @@ weechat_perl_timer_handler (t_weechat_plugin *plugin, /* make gcc happy */ (void) argc; (void) argv; + int *r; + int ret; - return weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, NULL, NULL, NULL); + r = (int *) weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, NULL, NULL, NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; } /* @@ -239,9 +299,23 @@ weechat_perl_keyboard_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[1], argv[2]); + { + r = (int *) weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[1], argv[2]); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -255,12 +329,12 @@ weechat_perl_modifier (t_weechat_plugin *plugin, int argc, char **argv, char *modifier_args, void *modifier_pointer) { - /*if (argc >= 2) - return weechat_perl_exec (plugin, (t_plugin_script *)modifier_pointer, - modifier_args, argv[0], argv[1], NULL); + if (argc >= 2) + return (char *) weechat_perl_exec (plugin, (t_plugin_script *)modifier_pointer, + SCRIPT_EXEC_STRING, + modifier_args, argv[0], argv[1], NULL); else - return NULL;*/ - return NULL; + return NULL; } /* @@ -1729,7 +1803,7 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) { STRLEN len; t_plugin_script tempscript; - int eval; + int *eval; struct stat buf; #ifndef MULTIPLICITY @@ -1754,7 +1828,9 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) snprintf(pkgname, sizeof(pkgname), "%s%d", PKG_NAME_PREFIX, perl_num); perl_num++; tempscript.interpreter = "WeechatPerlScriptLoader"; - eval = weechat_perl_exec (plugin, &tempscript, "weechat_perl_load_eval_file", filename, pkgname, ""); + eval = weechat_perl_exec (plugin, &tempscript, + SCRIPT_EXEC_INT, + "weechat_perl_load_eval_file", filename, pkgname, ""); #else perl_current_interpreter = perl_alloc(); @@ -1773,15 +1849,24 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) perl_parse (perl_current_interpreter, weechat_perl_xs_init, 3, perl_args, NULL); eval_pv (perl_weechat_code, TRUE); - eval = weechat_perl_exec (plugin, &tempscript, "weechat_perl_load_eval_file", filename, "", ""); + eval = weechat_perl_exec (plugin, &tempscript, + SCRIPT_EXEC_INT, + "weechat_perl_load_eval_file", filename, "", ""); free (perl_current_script_filename); #endif - - if ( eval != 0) + if (eval == NULL) { - if (eval == 2) + plugin->print_server (plugin, + "Perl error: memory error while parsing file \"%s\"", + filename); + return 0; + } + + if ( *eval != 0) + { + if (*eval == 2) { plugin->print_server (plugin, "Perl error: unable to parse file \"%s\"", @@ -1789,12 +1874,13 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) plugin->print_server (plugin, "Perl error: %s", #ifndef MULTIPLICITY - SvPV(perl_get_sv("WeechatPerlScriptLoader::weechat_perl_load_eval_file_error", FALSE), len)); + SvPV(perl_get_sv("WeechatPerlScriptLoader::weechat_perl_load_eval_file_error", FALSE), len) #else - SvPV(perl_get_sv("weechat_perl_load_eval_file_error", FALSE), len)); + SvPV(perl_get_sv("weechat_perl_load_eval_file_error", FALSE), len) #endif + ); } - else if ( eval == 1) + else if (*eval == 1) { plugin->print_server (plugin, "Perl error: unable to run file \"%s\"", @@ -1811,10 +1897,13 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) #endif if ((perl_current_script != NULL) && (perl_current_script != &tempscript)) weechat_script_remove (plugin, &perl_scripts, perl_current_script); - + + free (eval); return 0; } + free (eval); + if (perl_current_script == NULL) { plugin->print_server (plugin, @@ -1844,6 +1933,8 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) void weechat_perl_unload (t_weechat_plugin *plugin, t_plugin_script *script) { + int *r; + plugin->print_server (plugin, "Unloading Perl script \"%s\"", script->name); @@ -1855,8 +1946,13 @@ weechat_perl_unload (t_weechat_plugin *plugin, t_plugin_script *script) #endif if (script->shutdown_func[0]) - weechat_perl_exec (plugin, script, script->shutdown_func, NULL, NULL, NULL); - + { + r = (int *) weechat_perl_exec (plugin, script, SCRIPT_EXEC_INT, + script->shutdown_func, NULL, NULL, NULL); + if (r) + free (r); + } + #ifndef MULTIPLICITY if (script->interpreter) free (script->interpreter); @@ -1918,10 +2014,11 @@ weechat_perl_cmd (t_weechat_plugin *plugin, int cmd_argc, char **cmd_argv, char *handler_args, void *handler_pointer) { - int argc, handler_found; + int argc, handler_found, modifier_found; char **argv, *path_script; t_plugin_script *ptr_script; t_plugin_handler *ptr_handler; + t_plugin_modifier *ptr_modifier; if (cmd_argc < 3) return PLUGIN_RC_KO; @@ -2033,7 +2130,35 @@ weechat_perl_cmd (t_weechat_plugin *plugin, } if (!handler_found) plugin->print_server (plugin, " (none)"); - break; + + /* List Perl modifiers */ + plugin->print_server (plugin, ""); + plugin->print_server (plugin, "Python modifiers:"); + modifier_found = 0; + for (ptr_modifier = plugin->modifiers; + ptr_modifier; ptr_modifier = ptr_modifier->next_modifier) + { + modifier_found = 1; + if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_IN) + plugin->print_server (plugin, " IRC(%s, %s) => Perl(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_IN_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_USER) + plugin->print_server (plugin, " IRC(%s, %s) => Perl(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_USER_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_OUT) + plugin->print_server (plugin, " IRC(%s, %s) => Perl(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_OUT_STR, + ptr_modifier->modifier_args); + } + if (!modifier_found) + plugin->print_server (plugin, " (none)"); + break; + case 1: if (plugin->ascii_strcasecmp (plugin, argv[0], "autoload") == 0) weechat_script_auto_load (plugin, "perl", weechat_perl_load); diff --git a/src/plugins/scripts/python/weechat-python.c b/src/plugins/scripts/python/weechat-python.c index 1b34d20b2..eb52c9db0 100644 --- a/src/plugins/scripts/python/weechat-python.c +++ b/src/plugins/scripts/python/weechat-python.c @@ -48,21 +48,24 @@ t_plugin_script *python_current_script = NULL; char *python_current_script_filename = NULL; PyThreadState *python_mainThreadState = NULL; +char python_buffer_output[128]; /* * weechat_python_exec: execute a Python script */ -int +void * weechat_python_exec (t_weechat_plugin *plugin, t_plugin_script *script, + int ret_type, char *function, char *arg1, char *arg2, char *arg3) { PyObject *evMain; PyObject *evDict; PyObject *evFunc; PyObject *rc; - int ret; + void *ret_value; + int *ret_i; /* PyEval_AcquireLock (); */ PyThreadState_Swap (script->interpreter); @@ -77,11 +80,9 @@ weechat_python_exec (t_weechat_plugin *plugin, "Python error: unable to run function \"%s\"", function); /* PyEval_ReleaseThread (python_current_script->interpreter); */ - return PLUGIN_RC_KO; + return NULL; } - ret = -1; - python_current_script = script; if (arg1) @@ -97,30 +98,60 @@ weechat_python_exec (t_weechat_plugin *plugin, rc = PyObject_CallFunction (evFunc, "s", arg1); } else - rc = PyObject_CallFunction (evFunc, ""); + rc = PyObject_CallFunction (evFunc, NULL); + + ret_value = NULL; - if (rc == Py_None) + /* + ugly hack : rc = NULL while 'return weechat.PLUGIN_RC_OK .... + because of '#define PLUGIN_RC_OK 0' + */ + if (rc == NULL) + rc = PyInt_FromLong (0); + + if (PyString_Check (rc) && (ret_type == SCRIPT_EXEC_STRING)) { - python_plugin->print_server (python_plugin, "Python error: function \"%s\" must return a valid value", function); - /* PyEval_ReleaseThread (python_current_script->interpreter); */ - return PLUGIN_RC_OK; + if (PyString_AsString (rc)) + ret_value = strdup (PyString_AsString(rc)); + else + ret_value = NULL; + + Py_XDECREF(rc); } - - if (rc) + else if (PyInt_Check (rc) && (ret_type == SCRIPT_EXEC_INT)) { - ret = (int) PyInt_AsLong(rc); - Py_XDECREF(rc); + + ret_i = (int *) malloc (sizeof(int)); + if (ret_i) + *ret_i = (int) PyInt_AsLong(rc); + ret_value = ret_i; + + Py_XDECREF(rc); + } + else + { + python_plugin->print_server (python_plugin, + "Python error: function \"%s\" must return a valid value", + function); + /* PyEval_ReleaseThread (python_current_script->interpreter); */ + return NULL; + } + + if (ret_value == NULL) + { + plugin->print_server (plugin, + "Python error: unable to alloc memory in function \"%s\"", + function); + /* PyEval_ReleaseThread (python_current_script->interpreter); */ + return NULL; } if (PyErr_Occurred ()) PyErr_Print (); - if (ret < 0) - ret = PLUGIN_RC_OK; - /* PyEval_ReleaseThread (python_current_script->interpreter); */ - return ret; + return ret_value; } /* @@ -132,9 +163,23 @@ weechat_python_cmd_msg_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[2], NULL); + { + r = (int *) weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[2], NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -151,9 +196,20 @@ weechat_python_timer_handler (t_weechat_plugin *plugin, /* make gcc happy */ (void) argc; (void) argv; + int *r; + int ret; - return weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, NULL, NULL, NULL); + r = (int *) weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, NULL, NULL, NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; } /* @@ -165,9 +221,23 @@ weechat_python_keyboard_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[1], argv[2]); + { + r = (int *) weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[1], argv[2]); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -180,13 +250,13 @@ char * weechat_python_modifier (t_weechat_plugin *plugin, int argc, char **argv, char *modifier_args, void *modifier_pointer) -{ - /*if (argc >= 2) - return weechat_python_exec (plugin, (t_plugin_script *)modifier_pointer, - modifier_args, argv[0], argv[1], NULL); +{ + if (argc >= 2) + return (char *) weechat_python_exec (plugin, (t_plugin_script *)modifier_pointer, + SCRIPT_EXEC_STRING, + modifier_args, argv[0], argv[1], NULL); else - return NULL;*/ - return NULL; + return NULL; } /* @@ -787,7 +857,7 @@ weechat_python_add_modifier (PyObject *self, PyObject *args) if (python_plugin->modifier_add (python_plugin, type, command, weechat_python_modifier, function, - (void *)python_current_script)) + (void *)python_current_script)) return Py_BuildValue ("i", 1); return Py_BuildValue ("i", 0); @@ -1641,7 +1711,7 @@ PyMethodDef weechat_python_funcs[] = { static PyObject * weechat_python_output (PyObject *self, PyObject *args) { - char *msg, *p; + char *msg, *m, *p; /* make gcc happy */ (void) self; @@ -1649,19 +1719,43 @@ weechat_python_output (PyObject *self, PyObject *args) if (!PyArg_ParseTuple (args, "s", &msg)) { - python_plugin->print_server (python_plugin, - "Python error: unable to get " - "stdout/stderr message(s)"); - return NULL; + return Py_None; + if (strlen(python_buffer_output) > 0) + { + python_plugin->print_server (python_plugin, + "Python stdout/stderr : %s", + python_buffer_output); + python_buffer_output[0] = '\0'; + } + } + else + { + m = msg; + while ((p = strchr (m, '\n')) != NULL) + { + *p = '\0'; + if (strlen (m) + strlen (python_buffer_output) > 0) + python_plugin->print_server (python_plugin, + "Python stdout/stderr : %s%s", + python_buffer_output, m); + *p = '\n'; + python_buffer_output[0] = '\0'; + m = ++p; + } + + if (strlen(m) + strlen(python_buffer_output) > sizeof(python_buffer_output)) + { + python_plugin->print_server (python_plugin, + "Python stdout/stderr : %s%s", + python_buffer_output, m); + python_buffer_output[0] = '\0'; + } + else + strcat (python_buffer_output, m); } - while ((p = strrchr(msg, '\n')) != NULL) - *p = '\0'; - - if (strlen(msg) > 0) - python_plugin->print_server (python_plugin, - "Python stdin/stdout: %s", msg); - return Py_BuildValue ("i", 1); + Py_INCREF(Py_None); + return Py_None; } /* @@ -1802,12 +1896,19 @@ weechat_python_load (t_weechat_plugin *plugin, char *filename) void weechat_python_unload (t_weechat_plugin *plugin, t_plugin_script *script) { + int *r; + plugin->print_server (plugin, "Unloading Python script \"%s\"", script->name); if (script->shutdown_func[0]) - weechat_python_exec (plugin, script, script->shutdown_func, NULL, NULL, NULL); + { + r = (int *) weechat_python_exec (plugin, script, SCRIPT_EXEC_INT, + script->shutdown_func, NULL, NULL, NULL); + if (r) + free (r); + } PyThreadState_Swap (script->interpreter); Py_EndInterpreter (script->interpreter); @@ -1865,10 +1966,11 @@ weechat_python_cmd (t_weechat_plugin *plugin, int cmd_argc, char **cmd_argv, char *handler_args, void *handler_pointer) { - int argc, handler_found; + int argc, handler_found, modifier_found; char **argv, *path_script; t_plugin_script *ptr_script; t_plugin_handler *ptr_handler; + t_plugin_modifier *ptr_modifier; /* make gcc happy */ (void) handler_args; @@ -1980,7 +2082,35 @@ weechat_python_cmd (t_weechat_plugin *plugin, } if (!handler_found) plugin->print_server (plugin, " (none)"); + + /* list Python modifiers */ + plugin->print_server (plugin, ""); + plugin->print_server (plugin, "Python modifiers:"); + modifier_found = 0; + for (ptr_modifier = plugin->modifiers; + ptr_modifier; ptr_modifier = ptr_modifier->next_modifier) + { + modifier_found = 1; + if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_IN) + plugin->print_server (plugin, " IRC(%s, %s) => Python(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_IN_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_USER) + plugin->print_server (plugin, " IRC(%s, %s) => Python(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_USER_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_OUT) + plugin->print_server (plugin, " IRC(%s, %s) => Python(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_OUT_STR, + ptr_modifier->modifier_args); + } + if (!modifier_found) + plugin->print_server (plugin, " (none)"); break; + case 1: if (plugin->ascii_strcasecmp (plugin, argv[0], "autoload") == 0) weechat_script_auto_load (plugin, "python", weechat_python_load); @@ -2035,6 +2165,9 @@ weechat_plugin_init (t_weechat_plugin *plugin) python_plugin = plugin; plugin->print_server (plugin, "Loading Python module \"weechat\""); + + /* init stdout/stderr buffer */ + python_buffer_output[0] = '\0'; Py_Initialize (); if (Py_IsInitialized () == 0) diff --git a/src/plugins/scripts/ruby/weechat-ruby.c b/src/plugins/scripts/ruby/weechat-ruby.c index b5d6ad93e..e46e80bfc 100644 --- a/src/plugins/scripts/ruby/weechat-ruby.c +++ b/src/plugins/scripts/ruby/weechat-ruby.c @@ -54,6 +54,8 @@ VALUE ruby_mWeechat, ruby_mWeechatOutputs; #define MOD_NAME_PREFIX "WeechatRubyModule" int ruby_num = 0; +char ruby_buffer_output[128]; + typedef struct protect_call_arg { VALUE recv; ID mid; @@ -107,13 +109,15 @@ rb_protect_funcall (VALUE recv, ID mid, int *state, int argc, ...) * weechat_ruby_exec: execute a Ruby script */ -int +void * weechat_ruby_exec (t_weechat_plugin *plugin, t_plugin_script *script, + int ret_type, char *function, char *arg1, char *arg2, char *arg3) { - VALUE ruby_retcode, err; - int ruby_error; + VALUE rc, err; + int ruby_error, *ret_i; + void *ret_value; /* make gcc happy */ (void) plugin; @@ -124,24 +128,24 @@ weechat_ruby_exec (t_weechat_plugin *plugin, if (arg2) { if (arg3) - ruby_retcode = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), + rc = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), &ruby_error, 3, rb_str_new2(arg1), rb_str_new2(arg2), rb_str_new2(arg3)); else - ruby_retcode = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), + rc = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), &ruby_error, 2, rb_str_new2(arg1), rb_str_new2(arg2)); } else - ruby_retcode = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), + rc = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), &ruby_error, 1, rb_str_new2(arg1)); } else - ruby_retcode = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), + rc = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), &ruby_error, 0); if (ruby_error) @@ -152,21 +156,41 @@ weechat_ruby_exec (t_weechat_plugin *plugin, err = rb_inspect(rb_gv_get("$!")); ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - /* - err = rb_inspect(rb_gv_get("$@")); - ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - */ - - return PLUGIN_RC_KO; + + return NULL; } - if (TYPE(ruby_retcode) != T_FIXNUM) + if ((TYPE(rc) == T_STRING) && ret_type == SCRIPT_EXEC_STRING) { - ruby_plugin->print_server (ruby_plugin, "Ruby error: function \"%s\" must return a valid value", function); + if (STR2CSTR (rc)) + ret_value = strdup (STR2CSTR (rc)); + else + ret_value = NULL; + } + else if ((TYPE(rc) == T_FIXNUM) && ret_type == SCRIPT_EXEC_INT) + { + ret_i = (int *) malloc (sizeof(int)); + if (ret_i) + *ret_i = NUM2INT(rc); + ret_value = ret_i; + } + else + { + ruby_plugin->print_server (ruby_plugin, + "Ruby error: function \"%s\" must return a valid value", + function); return PLUGIN_RC_OK; } - return NUM2INT(ruby_retcode); + if (ret_value == NULL) + { + plugin->print_server (plugin, + "Ruby error: unable to alloc memory in function \"%s\"", + function); + return NULL; + } + + return ret_value; } /* @@ -178,9 +202,23 @@ weechat_ruby_cmd_msg_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[2], NULL); + { + r = (int *) weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[2], NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -197,9 +235,20 @@ weechat_ruby_timer_handler (t_weechat_plugin *plugin, /* make gcc happy */ (void) argc; (void) argv; + int *r; + int ret; - return weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, NULL, NULL, NULL); + r = (int *) weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, NULL, NULL, NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; } /* @@ -211,9 +260,23 @@ weechat_ruby_keyboard_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { - if (argc >= 2) - return weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[1], argv[2]); + int *r; + int ret; + + if (argc >= 3) + { + r = (int *) weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[1], argv[2]); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -227,12 +290,12 @@ weechat_ruby_modifier (t_weechat_plugin *plugin, int argc, char **argv, char *modifier_args, void *modifier_pointer) { - /*if (argc >= 2) - return weechat_ruby_exec (plugin, (t_plugin_script *)modifier_pointer, - modifier_args, argv[0], argv[1], NULL); + if (argc >= 2) + return (char *) weechat_ruby_exec (plugin, (t_plugin_script *)modifier_pointer, + SCRIPT_EXEC_STRING, + modifier_args, argv[0], argv[1], NULL); else - return NULL;*/ - return NULL; + return NULL; } /* @@ -1868,18 +1931,35 @@ weechat_ruby_get_buffer_data (int argc, VALUE *argv, VALUE class) static VALUE weechat_ruby_output(VALUE self, VALUE str) { - char *msg, *p; + char *msg, *p, *m; /* make gcc happy */ (void) self; msg = strdup(STR2CSTR(str)); - while ((p = strrchr(msg, '\n')) != NULL) + m = msg; + while ((p = strchr (m, '\n')) != NULL) + { *p = '\0'; + if (strlen (m) + strlen (ruby_buffer_output) > 0) + ruby_plugin->print_server (ruby_plugin, + "Ruby stdout/stderr : %s%s", + ruby_buffer_output, m); + *p = '\n'; + ruby_buffer_output[0] = '\0'; + m = ++p; + } - if (strlen(msg) > 0) + if (strlen(m) + strlen(ruby_buffer_output) > sizeof(ruby_buffer_output)) + { ruby_plugin->print_server (ruby_plugin, - "Ruby stdout/stderr: %s", msg); + "Ruby stdout/stderr : %s%s", + ruby_buffer_output, m); + ruby_buffer_output[0] = '\0'; + } + else + strcat (ruby_buffer_output, m); + if (msg) free (msg); @@ -1938,10 +2018,6 @@ weechat_ruby_load (t_weechat_plugin *plugin, char *filename) if (ruby_retcode == Qnil) { err = rb_inspect(rb_gv_get("$!")); ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - /* - err = rb_inspect(rb_gv_get("$@")); - ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - */ return 0; } @@ -1991,11 +2067,7 @@ weechat_ruby_load (t_weechat_plugin *plugin, char *filename) err = rb_inspect(rb_gv_get("$!")); ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - /* - err = rb_inspect(rb_gv_get("$!")); - ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - */ - + if (ruby_current_script != NULL) weechat_script_remove (plugin, &ruby_scripts, ruby_current_script); return 0; @@ -2022,12 +2094,19 @@ weechat_ruby_load (t_weechat_plugin *plugin, char *filename) void weechat_ruby_unload (t_weechat_plugin *plugin, t_plugin_script *script) { + int *r; + plugin->print_server (plugin, "Unloading Ruby script \"%s\"", script->name); if (script->shutdown_func[0]) - weechat_ruby_exec (plugin, script, script->shutdown_func, NULL, NULL, NULL); + { + r = (int *) weechat_ruby_exec (plugin, script, SCRIPT_EXEC_INT, + script->shutdown_func, NULL, NULL, NULL); + if (r) + free (r); + } if (script->interpreter) rb_gc_unregister_address (script->interpreter); @@ -2086,10 +2165,11 @@ weechat_ruby_cmd (t_weechat_plugin *plugin, int cmd_argc, char **cmd_argv, char *handler_args, void *handler_pointer) { - int argc, handler_found; + int argc, handler_found, modifier_found; char **argv, *path_script; t_plugin_script *ptr_script; t_plugin_handler *ptr_handler; + t_plugin_modifier *ptr_modifier; /* make gcc happy */ (void) handler_args; @@ -2201,7 +2281,34 @@ weechat_ruby_cmd (t_weechat_plugin *plugin, } if (!handler_found) plugin->print_server (plugin, " (none)"); - break; + + /* list Ruby modifiers */ + plugin->print_server (plugin, ""); + plugin->print_server (plugin, "Ruby modifiers:"); + modifier_found = 0; + for (ptr_modifier = plugin->modifiers; + ptr_modifier; ptr_modifier = ptr_modifier->next_modifier) + { + modifier_found = 1; + if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_IN) + plugin->print_server (plugin, " IRC(%s, %s) => Ruby(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_IN_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_USER) + plugin->print_server (plugin, " IRC(%s, %s) => Ruby(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_USER_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_OUT) + plugin->print_server (plugin, " IRC(%s, %s) => Ruby(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_OUT_STR, + ptr_modifier->modifier_args); + } + if (!modifier_found) + plugin->print_server (plugin, " (none)"); + break; case 1: if (plugin->ascii_strcasecmp (plugin, argv[0], "autoload") == 0) weechat_script_auto_load (plugin, "ruby", weechat_ruby_load); @@ -2299,6 +2406,9 @@ weechat_plugin_init (t_weechat_plugin *plugin) ruby_error = 0; plugin->print_server (plugin, "Loading Ruby module \"weechat\""); + + /* init stdout/stderr buffer */ + ruby_buffer_output[0] = '\0'; ruby_init (); ruby_init_loadpath (); diff --git a/src/plugins/scripts/weechat-script.h b/src/plugins/scripts/weechat-script.h index e18bfe37c..c3c61caf0 100644 --- a/src/plugins/scripts/weechat-script.h +++ b/src/plugins/scripts/weechat-script.h @@ -23,6 +23,10 @@ #ifndef __WEECHAT_WEECHAT_SCRIPT_H #define __WEECHAT_WEECHAT_SCRIPT_H 1 +/* constants which defines return types for weechat__exec functions */ +#define SCRIPT_EXEC_INT 1 +#define SCRIPT_EXEC_STRING 2 + typedef struct t_plugin_script t_plugin_script; struct t_plugin_script diff --git a/weechat/src/plugins/scripts/lua/weechat-lua.c b/weechat/src/plugins/scripts/lua/weechat-lua.c index fce16b30a..a727d3618 100644 --- a/weechat/src/plugins/scripts/lua/weechat-lua.c +++ b/weechat/src/plugins/scripts/lua/weechat-lua.c @@ -55,11 +55,14 @@ lua_State *lua_current_interpreter = NULL; * weechat_lua_exec: execute a Lua script */ -int +void * weechat_lua_exec (t_weechat_plugin *plugin, t_plugin_script *script, + int ret_type, char *function, char *arg1, char *arg2, char *arg3) { + void *ret_value; + int *ret_i; lua_current_interpreter = script->interpreter; @@ -86,10 +89,27 @@ weechat_lua_exec (t_weechat_plugin *plugin, plugin->print_server (plugin, "Lua error: %s", lua_tostring (lua_current_interpreter, -1)); - return PLUGIN_RC_KO; + return NULL; } - return lua_tonumber (lua_current_interpreter, -1); + if (ret_type == SCRIPT_EXEC_STRING) + ret_value = strdup ((char *) lua_tostring (lua_current_interpreter, -1)); + else if (ret_type == SCRIPT_EXEC_INT) + { + ret_i = (int *) malloc (sizeof(int)); + if (ret_i) + *ret_i = lua_tonumber (lua_current_interpreter, -1); + ret_value = ret_i; + } + else + { + lua_plugin->print_server (lua_plugin, + "Lua error: wrong parameters for function \"%s\"", + function); + return NULL; + } + + return ret_value; } /* @@ -101,9 +121,23 @@ weechat_lua_cmd_msg_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[2], NULL); + { + r = (int *) weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[2], NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -120,9 +154,20 @@ weechat_lua_timer_handler (t_weechat_plugin *plugin, /* make gcc happy */ (void) argc; (void) argv; + int *r; + int ret; - return weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, NULL, NULL, NULL); + r = (int *) weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, NULL, NULL, NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; } /* @@ -134,9 +179,23 @@ weechat_lua_keyboard_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { - if (argc >= 2) - return weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[1], argv[2]); + int *r; + int ret; + + if (argc >= 3) + { + r = (int *) weechat_lua_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[1], argv[2]); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -150,12 +209,12 @@ weechat_lua_modifier (t_weechat_plugin *plugin, int argc, char **argv, char *modifier_args, void *modifier_pointer) { - /*if (argc >= 2) - return weechat_lua_exec (plugin, (t_plugin_script *)modifier_pointer, - modifier_args, argv[0], argv[1], NULL); + if (argc >= 2) + return (char *) weechat_lua_exec (plugin, (t_plugin_script *)modifier_pointer, + SCRIPT_EXEC_STRING, + modifier_args, argv[0], argv[1], NULL); else - return NULL;*/ - return NULL; + return NULL; } /* @@ -968,12 +1027,13 @@ weechat_lua_remove_modifier (lua_State *L) return 1; } + type = NULL; command = NULL; function = NULL; n = lua_gettop (lua_current_interpreter); - if (n != 2) + if (n != 3) { lua_plugin->print_server (lua_plugin, "Lua error: wrong parameters for " @@ -2153,12 +2213,19 @@ weechat_lua_load (t_weechat_plugin *plugin, char *filename) void weechat_lua_unload (t_weechat_plugin *plugin, t_plugin_script *script) { + int *r; + plugin->print_server (plugin, "Unloading Lua script \"%s\"", script->name); if (script->shutdown_func[0]) - weechat_lua_exec (plugin, script, script->shutdown_func, NULL, NULL, NULL); + { + r = weechat_lua_exec (plugin, script, SCRIPT_EXEC_INT, + script->shutdown_func, NULL, NULL, NULL); + if (r) + free (r); + } lua_close (script->interpreter); @@ -2215,11 +2282,12 @@ weechat_lua_cmd (t_weechat_plugin *plugin, int cmd_argc, char **cmd_argv, char *handler_args, void *handler_pointer) { - int argc, handler_found; + int argc, handler_found, modifier_found; char **argv, *path_script; t_plugin_script *ptr_script; t_plugin_handler *ptr_handler; - + t_plugin_modifier *ptr_modifier; + /* make gcc happy */ (void) handler_args; (void) handler_pointer; @@ -2330,7 +2398,34 @@ weechat_lua_cmd (t_weechat_plugin *plugin, } if (!handler_found) plugin->print_server (plugin, " (none)"); - break; + + /* list Lua modifiers */ + plugin->print_server (plugin, ""); + plugin->print_server (plugin, "Lua modifiers:"); + modifier_found = 0; + for (ptr_modifier = plugin->modifiers; + ptr_modifier; ptr_modifier = ptr_modifier->next_modifier) + { + modifier_found = 1; + if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_IN) + plugin->print_server (plugin, " IRC(%s, %s) => Lua(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_IN_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_USER) + plugin->print_server (plugin, " IRC(%s, %s) => Lua(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_USER_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_OUT) + plugin->print_server (plugin, " IRC(%s, %s) => Lua(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_OUT_STR, + ptr_modifier->modifier_args); + } + if (!modifier_found) + plugin->print_server (plugin, " (none)"); + break; case 1: if (plugin->ascii_strcasecmp (plugin, argv[0], "autoload") == 0) weechat_script_auto_load (plugin, "lua", weechat_lua_load); diff --git a/weechat/src/plugins/scripts/perl/weechat-perl.c b/weechat/src/plugins/scripts/perl/weechat-perl.c index 72c933dce..8b97977b5 100644 --- a/weechat/src/plugins/scripts/perl/weechat-perl.c +++ b/weechat/src/plugins/scripts/perl/weechat-perl.c @@ -112,17 +112,20 @@ char *perl_weechat_code = * weechat_perl_exec: execute a Perl script */ -int +void * weechat_perl_exec (t_weechat_plugin *plugin, t_plugin_script *script, + int ret_type, char *function, char *arg1, char *arg2, char *arg3) { char empty_arg[1] = { '\0' }; char *func; char *argv[4]; unsigned int count; - int return_code; - SV *sv; + void *ret_value; + int *ret_i; + SV *ret_s; + int mem_err; /* this code is placed here to conform ISO C90 */ dSP; @@ -131,7 +134,7 @@ weechat_perl_exec (t_weechat_plugin *plugin, int size = strlen (script->interpreter) + strlen(function) + 3; func = (char *) malloc ( size * sizeof(char)); if (!func) - return PLUGIN_RC_KO; + return NULL; snprintf (func, size, "%s::%s", (char *) script->interpreter, function); #else func = function; @@ -141,6 +144,9 @@ weechat_perl_exec (t_weechat_plugin *plugin, ENTER; SAVETMPS; PUSHMARK(sp); + + perl_current_script = script; + if (arg1) { argv[0] = (arg1) ? arg1 : empty_arg; @@ -161,29 +167,50 @@ weechat_perl_exec (t_weechat_plugin *plugin, else argv[0] = NULL; - perl_current_script = script; - count = perl_call_argv (func, G_EVAL | G_SCALAR, argv); - + ret_value = NULL; + mem_err = 1; + SPAGAIN; - sv = GvSV (gv_fetchpv ("@", TRUE, SVt_PV)); - return_code = PLUGIN_RC_KO; - if (SvTRUE (sv)) + if (SvTRUE (ERRSV)) { - plugin->print_server (plugin, "Perl error: %s", SvPV_nolen (sv)); - POPs; + plugin->print_server (plugin, "Perl error: %s", SvPV_nolen (ERRSV)); + POPs; /* poping the 'undef' */ + mem_err = 0; } else { if (count != 1) - { + { plugin->print_server (plugin, - "Perl error: too much values from \"%s\" (%d). Expected: 1.", + "Perl error: function \"%s\" must return 1 valid value (%d)", function, count); - } + mem_err = 0; + } else - return_code = POPi; + { + if (ret_type == SCRIPT_EXEC_STRING) + { + ret_s = newSVsv(POPs); + ret_value = strdup (SvPV_nolen (ret_s)); + SvREFCNT_dec (ret_s); + } + else if (ret_type == SCRIPT_EXEC_INT) + { + ret_i = (int *) malloc (sizeof(int)); + if (ret_i) + *ret_i = POPi; + ret_value = ret_i; + } + else + { + plugin->print_server (plugin, + "Perl error: function \"%s\" is internally misused.", + function); + mem_err = 0; + } + } } PUTBACK; @@ -193,8 +220,16 @@ weechat_perl_exec (t_weechat_plugin *plugin, #ifndef MULTIPLICITY free (func); #endif + + if (ret_value == NULL && mem_err == 1) + { + plugin->print_server (plugin, + "Python error: unable to alloc memory in function \"%s\"", + function); + return NULL; + } - return return_code; + return ret_value; } /* @@ -206,9 +241,23 @@ weechat_perl_cmd_msg_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[2], NULL); + { + r = (int *) weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[2], NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -225,9 +274,20 @@ weechat_perl_timer_handler (t_weechat_plugin *plugin, /* make gcc happy */ (void) argc; (void) argv; + int *r; + int ret; - return weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, NULL, NULL, NULL); + r = (int *) weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, NULL, NULL, NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; } /* @@ -239,9 +299,23 @@ weechat_perl_keyboard_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[1], argv[2]); + { + r = (int *) weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[1], argv[2]); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -255,12 +329,12 @@ weechat_perl_modifier (t_weechat_plugin *plugin, int argc, char **argv, char *modifier_args, void *modifier_pointer) { - /*if (argc >= 2) - return weechat_perl_exec (plugin, (t_plugin_script *)modifier_pointer, - modifier_args, argv[0], argv[1], NULL); + if (argc >= 2) + return (char *) weechat_perl_exec (plugin, (t_plugin_script *)modifier_pointer, + SCRIPT_EXEC_STRING, + modifier_args, argv[0], argv[1], NULL); else - return NULL;*/ - return NULL; + return NULL; } /* @@ -1729,7 +1803,7 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) { STRLEN len; t_plugin_script tempscript; - int eval; + int *eval; struct stat buf; #ifndef MULTIPLICITY @@ -1754,7 +1828,9 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) snprintf(pkgname, sizeof(pkgname), "%s%d", PKG_NAME_PREFIX, perl_num); perl_num++; tempscript.interpreter = "WeechatPerlScriptLoader"; - eval = weechat_perl_exec (plugin, &tempscript, "weechat_perl_load_eval_file", filename, pkgname, ""); + eval = weechat_perl_exec (plugin, &tempscript, + SCRIPT_EXEC_INT, + "weechat_perl_load_eval_file", filename, pkgname, ""); #else perl_current_interpreter = perl_alloc(); @@ -1773,15 +1849,24 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) perl_parse (perl_current_interpreter, weechat_perl_xs_init, 3, perl_args, NULL); eval_pv (perl_weechat_code, TRUE); - eval = weechat_perl_exec (plugin, &tempscript, "weechat_perl_load_eval_file", filename, "", ""); + eval = weechat_perl_exec (plugin, &tempscript, + SCRIPT_EXEC_INT, + "weechat_perl_load_eval_file", filename, "", ""); free (perl_current_script_filename); #endif - - if ( eval != 0) + if (eval == NULL) { - if (eval == 2) + plugin->print_server (plugin, + "Perl error: memory error while parsing file \"%s\"", + filename); + return 0; + } + + if ( *eval != 0) + { + if (*eval == 2) { plugin->print_server (plugin, "Perl error: unable to parse file \"%s\"", @@ -1789,12 +1874,13 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) plugin->print_server (plugin, "Perl error: %s", #ifndef MULTIPLICITY - SvPV(perl_get_sv("WeechatPerlScriptLoader::weechat_perl_load_eval_file_error", FALSE), len)); + SvPV(perl_get_sv("WeechatPerlScriptLoader::weechat_perl_load_eval_file_error", FALSE), len) #else - SvPV(perl_get_sv("weechat_perl_load_eval_file_error", FALSE), len)); + SvPV(perl_get_sv("weechat_perl_load_eval_file_error", FALSE), len) #endif + ); } - else if ( eval == 1) + else if (*eval == 1) { plugin->print_server (plugin, "Perl error: unable to run file \"%s\"", @@ -1811,10 +1897,13 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) #endif if ((perl_current_script != NULL) && (perl_current_script != &tempscript)) weechat_script_remove (plugin, &perl_scripts, perl_current_script); - + + free (eval); return 0; } + free (eval); + if (perl_current_script == NULL) { plugin->print_server (plugin, @@ -1844,6 +1933,8 @@ weechat_perl_load (t_weechat_plugin *plugin, char *filename) void weechat_perl_unload (t_weechat_plugin *plugin, t_plugin_script *script) { + int *r; + plugin->print_server (plugin, "Unloading Perl script \"%s\"", script->name); @@ -1855,8 +1946,13 @@ weechat_perl_unload (t_weechat_plugin *plugin, t_plugin_script *script) #endif if (script->shutdown_func[0]) - weechat_perl_exec (plugin, script, script->shutdown_func, NULL, NULL, NULL); - + { + r = (int *) weechat_perl_exec (plugin, script, SCRIPT_EXEC_INT, + script->shutdown_func, NULL, NULL, NULL); + if (r) + free (r); + } + #ifndef MULTIPLICITY if (script->interpreter) free (script->interpreter); @@ -1918,10 +2014,11 @@ weechat_perl_cmd (t_weechat_plugin *plugin, int cmd_argc, char **cmd_argv, char *handler_args, void *handler_pointer) { - int argc, handler_found; + int argc, handler_found, modifier_found; char **argv, *path_script; t_plugin_script *ptr_script; t_plugin_handler *ptr_handler; + t_plugin_modifier *ptr_modifier; if (cmd_argc < 3) return PLUGIN_RC_KO; @@ -2033,7 +2130,35 @@ weechat_perl_cmd (t_weechat_plugin *plugin, } if (!handler_found) plugin->print_server (plugin, " (none)"); - break; + + /* List Perl modifiers */ + plugin->print_server (plugin, ""); + plugin->print_server (plugin, "Python modifiers:"); + modifier_found = 0; + for (ptr_modifier = plugin->modifiers; + ptr_modifier; ptr_modifier = ptr_modifier->next_modifier) + { + modifier_found = 1; + if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_IN) + plugin->print_server (plugin, " IRC(%s, %s) => Perl(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_IN_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_USER) + plugin->print_server (plugin, " IRC(%s, %s) => Perl(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_USER_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_OUT) + plugin->print_server (plugin, " IRC(%s, %s) => Perl(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_OUT_STR, + ptr_modifier->modifier_args); + } + if (!modifier_found) + plugin->print_server (plugin, " (none)"); + break; + case 1: if (plugin->ascii_strcasecmp (plugin, argv[0], "autoload") == 0) weechat_script_auto_load (plugin, "perl", weechat_perl_load); diff --git a/weechat/src/plugins/scripts/python/weechat-python.c b/weechat/src/plugins/scripts/python/weechat-python.c index 1b34d20b2..eb52c9db0 100644 --- a/weechat/src/plugins/scripts/python/weechat-python.c +++ b/weechat/src/plugins/scripts/python/weechat-python.c @@ -48,21 +48,24 @@ t_plugin_script *python_current_script = NULL; char *python_current_script_filename = NULL; PyThreadState *python_mainThreadState = NULL; +char python_buffer_output[128]; /* * weechat_python_exec: execute a Python script */ -int +void * weechat_python_exec (t_weechat_plugin *plugin, t_plugin_script *script, + int ret_type, char *function, char *arg1, char *arg2, char *arg3) { PyObject *evMain; PyObject *evDict; PyObject *evFunc; PyObject *rc; - int ret; + void *ret_value; + int *ret_i; /* PyEval_AcquireLock (); */ PyThreadState_Swap (script->interpreter); @@ -77,11 +80,9 @@ weechat_python_exec (t_weechat_plugin *plugin, "Python error: unable to run function \"%s\"", function); /* PyEval_ReleaseThread (python_current_script->interpreter); */ - return PLUGIN_RC_KO; + return NULL; } - ret = -1; - python_current_script = script; if (arg1) @@ -97,30 +98,60 @@ weechat_python_exec (t_weechat_plugin *plugin, rc = PyObject_CallFunction (evFunc, "s", arg1); } else - rc = PyObject_CallFunction (evFunc, ""); + rc = PyObject_CallFunction (evFunc, NULL); + + ret_value = NULL; - if (rc == Py_None) + /* + ugly hack : rc = NULL while 'return weechat.PLUGIN_RC_OK .... + because of '#define PLUGIN_RC_OK 0' + */ + if (rc == NULL) + rc = PyInt_FromLong (0); + + if (PyString_Check (rc) && (ret_type == SCRIPT_EXEC_STRING)) { - python_plugin->print_server (python_plugin, "Python error: function \"%s\" must return a valid value", function); - /* PyEval_ReleaseThread (python_current_script->interpreter); */ - return PLUGIN_RC_OK; + if (PyString_AsString (rc)) + ret_value = strdup (PyString_AsString(rc)); + else + ret_value = NULL; + + Py_XDECREF(rc); } - - if (rc) + else if (PyInt_Check (rc) && (ret_type == SCRIPT_EXEC_INT)) { - ret = (int) PyInt_AsLong(rc); - Py_XDECREF(rc); + + ret_i = (int *) malloc (sizeof(int)); + if (ret_i) + *ret_i = (int) PyInt_AsLong(rc); + ret_value = ret_i; + + Py_XDECREF(rc); + } + else + { + python_plugin->print_server (python_plugin, + "Python error: function \"%s\" must return a valid value", + function); + /* PyEval_ReleaseThread (python_current_script->interpreter); */ + return NULL; + } + + if (ret_value == NULL) + { + plugin->print_server (plugin, + "Python error: unable to alloc memory in function \"%s\"", + function); + /* PyEval_ReleaseThread (python_current_script->interpreter); */ + return NULL; } if (PyErr_Occurred ()) PyErr_Print (); - if (ret < 0) - ret = PLUGIN_RC_OK; - /* PyEval_ReleaseThread (python_current_script->interpreter); */ - return ret; + return ret_value; } /* @@ -132,9 +163,23 @@ weechat_python_cmd_msg_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[2], NULL); + { + r = (int *) weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[2], NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -151,9 +196,20 @@ weechat_python_timer_handler (t_weechat_plugin *plugin, /* make gcc happy */ (void) argc; (void) argv; + int *r; + int ret; - return weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, NULL, NULL, NULL); + r = (int *) weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, NULL, NULL, NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; } /* @@ -165,9 +221,23 @@ weechat_python_keyboard_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[1], argv[2]); + { + r = (int *) weechat_python_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[1], argv[2]); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -180,13 +250,13 @@ char * weechat_python_modifier (t_weechat_plugin *plugin, int argc, char **argv, char *modifier_args, void *modifier_pointer) -{ - /*if (argc >= 2) - return weechat_python_exec (plugin, (t_plugin_script *)modifier_pointer, - modifier_args, argv[0], argv[1], NULL); +{ + if (argc >= 2) + return (char *) weechat_python_exec (plugin, (t_plugin_script *)modifier_pointer, + SCRIPT_EXEC_STRING, + modifier_args, argv[0], argv[1], NULL); else - return NULL;*/ - return NULL; + return NULL; } /* @@ -787,7 +857,7 @@ weechat_python_add_modifier (PyObject *self, PyObject *args) if (python_plugin->modifier_add (python_plugin, type, command, weechat_python_modifier, function, - (void *)python_current_script)) + (void *)python_current_script)) return Py_BuildValue ("i", 1); return Py_BuildValue ("i", 0); @@ -1641,7 +1711,7 @@ PyMethodDef weechat_python_funcs[] = { static PyObject * weechat_python_output (PyObject *self, PyObject *args) { - char *msg, *p; + char *msg, *m, *p; /* make gcc happy */ (void) self; @@ -1649,19 +1719,43 @@ weechat_python_output (PyObject *self, PyObject *args) if (!PyArg_ParseTuple (args, "s", &msg)) { - python_plugin->print_server (python_plugin, - "Python error: unable to get " - "stdout/stderr message(s)"); - return NULL; + return Py_None; + if (strlen(python_buffer_output) > 0) + { + python_plugin->print_server (python_plugin, + "Python stdout/stderr : %s", + python_buffer_output); + python_buffer_output[0] = '\0'; + } + } + else + { + m = msg; + while ((p = strchr (m, '\n')) != NULL) + { + *p = '\0'; + if (strlen (m) + strlen (python_buffer_output) > 0) + python_plugin->print_server (python_plugin, + "Python stdout/stderr : %s%s", + python_buffer_output, m); + *p = '\n'; + python_buffer_output[0] = '\0'; + m = ++p; + } + + if (strlen(m) + strlen(python_buffer_output) > sizeof(python_buffer_output)) + { + python_plugin->print_server (python_plugin, + "Python stdout/stderr : %s%s", + python_buffer_output, m); + python_buffer_output[0] = '\0'; + } + else + strcat (python_buffer_output, m); } - while ((p = strrchr(msg, '\n')) != NULL) - *p = '\0'; - - if (strlen(msg) > 0) - python_plugin->print_server (python_plugin, - "Python stdin/stdout: %s", msg); - return Py_BuildValue ("i", 1); + Py_INCREF(Py_None); + return Py_None; } /* @@ -1802,12 +1896,19 @@ weechat_python_load (t_weechat_plugin *plugin, char *filename) void weechat_python_unload (t_weechat_plugin *plugin, t_plugin_script *script) { + int *r; + plugin->print_server (plugin, "Unloading Python script \"%s\"", script->name); if (script->shutdown_func[0]) - weechat_python_exec (plugin, script, script->shutdown_func, NULL, NULL, NULL); + { + r = (int *) weechat_python_exec (plugin, script, SCRIPT_EXEC_INT, + script->shutdown_func, NULL, NULL, NULL); + if (r) + free (r); + } PyThreadState_Swap (script->interpreter); Py_EndInterpreter (script->interpreter); @@ -1865,10 +1966,11 @@ weechat_python_cmd (t_weechat_plugin *plugin, int cmd_argc, char **cmd_argv, char *handler_args, void *handler_pointer) { - int argc, handler_found; + int argc, handler_found, modifier_found; char **argv, *path_script; t_plugin_script *ptr_script; t_plugin_handler *ptr_handler; + t_plugin_modifier *ptr_modifier; /* make gcc happy */ (void) handler_args; @@ -1980,7 +2082,35 @@ weechat_python_cmd (t_weechat_plugin *plugin, } if (!handler_found) plugin->print_server (plugin, " (none)"); + + /* list Python modifiers */ + plugin->print_server (plugin, ""); + plugin->print_server (plugin, "Python modifiers:"); + modifier_found = 0; + for (ptr_modifier = plugin->modifiers; + ptr_modifier; ptr_modifier = ptr_modifier->next_modifier) + { + modifier_found = 1; + if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_IN) + plugin->print_server (plugin, " IRC(%s, %s) => Python(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_IN_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_USER) + plugin->print_server (plugin, " IRC(%s, %s) => Python(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_USER_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_OUT) + plugin->print_server (plugin, " IRC(%s, %s) => Python(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_OUT_STR, + ptr_modifier->modifier_args); + } + if (!modifier_found) + plugin->print_server (plugin, " (none)"); break; + case 1: if (plugin->ascii_strcasecmp (plugin, argv[0], "autoload") == 0) weechat_script_auto_load (plugin, "python", weechat_python_load); @@ -2035,6 +2165,9 @@ weechat_plugin_init (t_weechat_plugin *plugin) python_plugin = plugin; plugin->print_server (plugin, "Loading Python module \"weechat\""); + + /* init stdout/stderr buffer */ + python_buffer_output[0] = '\0'; Py_Initialize (); if (Py_IsInitialized () == 0) diff --git a/weechat/src/plugins/scripts/ruby/weechat-ruby.c b/weechat/src/plugins/scripts/ruby/weechat-ruby.c index b5d6ad93e..e46e80bfc 100644 --- a/weechat/src/plugins/scripts/ruby/weechat-ruby.c +++ b/weechat/src/plugins/scripts/ruby/weechat-ruby.c @@ -54,6 +54,8 @@ VALUE ruby_mWeechat, ruby_mWeechatOutputs; #define MOD_NAME_PREFIX "WeechatRubyModule" int ruby_num = 0; +char ruby_buffer_output[128]; + typedef struct protect_call_arg { VALUE recv; ID mid; @@ -107,13 +109,15 @@ rb_protect_funcall (VALUE recv, ID mid, int *state, int argc, ...) * weechat_ruby_exec: execute a Ruby script */ -int +void * weechat_ruby_exec (t_weechat_plugin *plugin, t_plugin_script *script, + int ret_type, char *function, char *arg1, char *arg2, char *arg3) { - VALUE ruby_retcode, err; - int ruby_error; + VALUE rc, err; + int ruby_error, *ret_i; + void *ret_value; /* make gcc happy */ (void) plugin; @@ -124,24 +128,24 @@ weechat_ruby_exec (t_weechat_plugin *plugin, if (arg2) { if (arg3) - ruby_retcode = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), + rc = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), &ruby_error, 3, rb_str_new2(arg1), rb_str_new2(arg2), rb_str_new2(arg3)); else - ruby_retcode = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), + rc = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), &ruby_error, 2, rb_str_new2(arg1), rb_str_new2(arg2)); } else - ruby_retcode = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), + rc = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), &ruby_error, 1, rb_str_new2(arg1)); } else - ruby_retcode = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), + rc = rb_protect_funcall ((VALUE) script->interpreter, rb_intern(function), &ruby_error, 0); if (ruby_error) @@ -152,21 +156,41 @@ weechat_ruby_exec (t_weechat_plugin *plugin, err = rb_inspect(rb_gv_get("$!")); ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - /* - err = rb_inspect(rb_gv_get("$@")); - ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - */ - - return PLUGIN_RC_KO; + + return NULL; } - if (TYPE(ruby_retcode) != T_FIXNUM) + if ((TYPE(rc) == T_STRING) && ret_type == SCRIPT_EXEC_STRING) { - ruby_plugin->print_server (ruby_plugin, "Ruby error: function \"%s\" must return a valid value", function); + if (STR2CSTR (rc)) + ret_value = strdup (STR2CSTR (rc)); + else + ret_value = NULL; + } + else if ((TYPE(rc) == T_FIXNUM) && ret_type == SCRIPT_EXEC_INT) + { + ret_i = (int *) malloc (sizeof(int)); + if (ret_i) + *ret_i = NUM2INT(rc); + ret_value = ret_i; + } + else + { + ruby_plugin->print_server (ruby_plugin, + "Ruby error: function \"%s\" must return a valid value", + function); return PLUGIN_RC_OK; } - return NUM2INT(ruby_retcode); + if (ret_value == NULL) + { + plugin->print_server (plugin, + "Ruby error: unable to alloc memory in function \"%s\"", + function); + return NULL; + } + + return ret_value; } /* @@ -178,9 +202,23 @@ weechat_ruby_cmd_msg_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r; + int ret; + if (argc >= 3) - return weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[2], NULL); + { + r = (int *) weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[2], NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -197,9 +235,20 @@ weechat_ruby_timer_handler (t_weechat_plugin *plugin, /* make gcc happy */ (void) argc; (void) argv; + int *r; + int ret; - return weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, NULL, NULL, NULL); + r = (int *) weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, NULL, NULL, NULL); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; } /* @@ -211,9 +260,23 @@ weechat_ruby_keyboard_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { - if (argc >= 2) - return weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, - handler_args, argv[0], argv[1], argv[2]); + int *r; + int ret; + + if (argc >= 3) + { + r = (int *) weechat_ruby_exec (plugin, (t_plugin_script *)handler_pointer, + SCRIPT_EXEC_INT, + handler_args, argv[0], argv[1], argv[2]); + if (r == NULL) + ret = PLUGIN_RC_KO; + else + { + ret = *r; + free (r); + } + return ret; + } else return PLUGIN_RC_KO; } @@ -227,12 +290,12 @@ weechat_ruby_modifier (t_weechat_plugin *plugin, int argc, char **argv, char *modifier_args, void *modifier_pointer) { - /*if (argc >= 2) - return weechat_ruby_exec (plugin, (t_plugin_script *)modifier_pointer, - modifier_args, argv[0], argv[1], NULL); + if (argc >= 2) + return (char *) weechat_ruby_exec (plugin, (t_plugin_script *)modifier_pointer, + SCRIPT_EXEC_STRING, + modifier_args, argv[0], argv[1], NULL); else - return NULL;*/ - return NULL; + return NULL; } /* @@ -1868,18 +1931,35 @@ weechat_ruby_get_buffer_data (int argc, VALUE *argv, VALUE class) static VALUE weechat_ruby_output(VALUE self, VALUE str) { - char *msg, *p; + char *msg, *p, *m; /* make gcc happy */ (void) self; msg = strdup(STR2CSTR(str)); - while ((p = strrchr(msg, '\n')) != NULL) + m = msg; + while ((p = strchr (m, '\n')) != NULL) + { *p = '\0'; + if (strlen (m) + strlen (ruby_buffer_output) > 0) + ruby_plugin->print_server (ruby_plugin, + "Ruby stdout/stderr : %s%s", + ruby_buffer_output, m); + *p = '\n'; + ruby_buffer_output[0] = '\0'; + m = ++p; + } - if (strlen(msg) > 0) + if (strlen(m) + strlen(ruby_buffer_output) > sizeof(ruby_buffer_output)) + { ruby_plugin->print_server (ruby_plugin, - "Ruby stdout/stderr: %s", msg); + "Ruby stdout/stderr : %s%s", + ruby_buffer_output, m); + ruby_buffer_output[0] = '\0'; + } + else + strcat (ruby_buffer_output, m); + if (msg) free (msg); @@ -1938,10 +2018,6 @@ weechat_ruby_load (t_weechat_plugin *plugin, char *filename) if (ruby_retcode == Qnil) { err = rb_inspect(rb_gv_get("$!")); ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - /* - err = rb_inspect(rb_gv_get("$@")); - ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - */ return 0; } @@ -1991,11 +2067,7 @@ weechat_ruby_load (t_weechat_plugin *plugin, char *filename) err = rb_inspect(rb_gv_get("$!")); ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - /* - err = rb_inspect(rb_gv_get("$!")); - ruby_plugin->print_server (ruby_plugin, "Ruby error: \"%s\"", STR2CSTR(err)); - */ - + if (ruby_current_script != NULL) weechat_script_remove (plugin, &ruby_scripts, ruby_current_script); return 0; @@ -2022,12 +2094,19 @@ weechat_ruby_load (t_weechat_plugin *plugin, char *filename) void weechat_ruby_unload (t_weechat_plugin *plugin, t_plugin_script *script) { + int *r; + plugin->print_server (plugin, "Unloading Ruby script \"%s\"", script->name); if (script->shutdown_func[0]) - weechat_ruby_exec (plugin, script, script->shutdown_func, NULL, NULL, NULL); + { + r = (int *) weechat_ruby_exec (plugin, script, SCRIPT_EXEC_INT, + script->shutdown_func, NULL, NULL, NULL); + if (r) + free (r); + } if (script->interpreter) rb_gc_unregister_address (script->interpreter); @@ -2086,10 +2165,11 @@ weechat_ruby_cmd (t_weechat_plugin *plugin, int cmd_argc, char **cmd_argv, char *handler_args, void *handler_pointer) { - int argc, handler_found; + int argc, handler_found, modifier_found; char **argv, *path_script; t_plugin_script *ptr_script; t_plugin_handler *ptr_handler; + t_plugin_modifier *ptr_modifier; /* make gcc happy */ (void) handler_args; @@ -2201,7 +2281,34 @@ weechat_ruby_cmd (t_weechat_plugin *plugin, } if (!handler_found) plugin->print_server (plugin, " (none)"); - break; + + /* list Ruby modifiers */ + plugin->print_server (plugin, ""); + plugin->print_server (plugin, "Ruby modifiers:"); + modifier_found = 0; + for (ptr_modifier = plugin->modifiers; + ptr_modifier; ptr_modifier = ptr_modifier->next_modifier) + { + modifier_found = 1; + if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_IN) + plugin->print_server (plugin, " IRC(%s, %s) => Ruby(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_IN_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_USER) + plugin->print_server (plugin, " IRC(%s, %s) => Ruby(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_USER_STR, + ptr_modifier->modifier_args); + else if (ptr_modifier->type == PLUGIN_MODIFIER_IRC_OUT) + plugin->print_server (plugin, " IRC(%s, %s) => Ruby(%s)", + ptr_modifier->command, + PLUGIN_MODIFIER_IRC_OUT_STR, + ptr_modifier->modifier_args); + } + if (!modifier_found) + plugin->print_server (plugin, " (none)"); + break; case 1: if (plugin->ascii_strcasecmp (plugin, argv[0], "autoload") == 0) weechat_script_auto_load (plugin, "ruby", weechat_ruby_load); @@ -2299,6 +2406,9 @@ weechat_plugin_init (t_weechat_plugin *plugin) ruby_error = 0; plugin->print_server (plugin, "Loading Ruby module \"weechat\""); + + /* init stdout/stderr buffer */ + ruby_buffer_output[0] = '\0'; ruby_init (); ruby_init_loadpath (); diff --git a/weechat/src/plugins/scripts/weechat-script.h b/weechat/src/plugins/scripts/weechat-script.h index e18bfe37c..c3c61caf0 100644 --- a/weechat/src/plugins/scripts/weechat-script.h +++ b/weechat/src/plugins/scripts/weechat-script.h @@ -23,6 +23,10 @@ #ifndef __WEECHAT_WEECHAT_SCRIPT_H #define __WEECHAT_WEECHAT_SCRIPT_H 1 +/* constants which defines return types for weechat__exec functions */ +#define SCRIPT_EXEC_INT 1 +#define SCRIPT_EXEC_STRING 2 + typedef struct t_plugin_script t_plugin_script; struct t_plugin_script