diff options
-rw-r--r-- | src/common/command.c | 265 | ||||
-rw-r--r-- | src/common/command.h | 1 | ||||
-rw-r--r-- | src/common/weechat.c | 4 | ||||
-rw-r--r-- | src/irc/irc-recv.c | 2 | ||||
-rw-r--r-- | src/plugins/perl/wee-perl.c | 39 | ||||
-rw-r--r-- | src/plugins/plugins.c | 137 | ||||
-rw-r--r-- | src/plugins/plugins.h | 24 | ||||
-rw-r--r-- | weechat/src/common/command.c | 265 | ||||
-rw-r--r-- | weechat/src/common/command.h | 1 | ||||
-rw-r--r-- | weechat/src/common/weechat.c | 4 | ||||
-rw-r--r-- | weechat/src/irc/irc-recv.c | 2 | ||||
-rw-r--r-- | weechat/src/plugins/perl/wee-perl.c | 39 | ||||
-rw-r--r-- | weechat/src/plugins/plugins.c | 137 | ||||
-rw-r--r-- | weechat/src/plugins/plugins.h | 24 |
14 files changed, 578 insertions, 366 deletions
diff --git a/src/common/command.c b/src/common/command.c index a427cc7d7..c8396c76a 100644 --- a/src/common/command.c +++ b/src/common/command.c @@ -524,154 +524,157 @@ exec_weechat_command (t_irc_server *server, char *string) ptr_args = NULL; } - argv = explode_string (ptr_args, " ", 0, &argc); - - for (i = 0; weechat_commands[i].command_name; i++) + if (!plugin_exec_command (command + 1, ptr_args)) { - if (strcasecmp (weechat_commands[i].command_name, command + 1) == 0) + argv = explode_string (ptr_args, " ", 0, &argc); + + for (i = 0; weechat_commands[i].command_name; i++) { - if ((argc < weechat_commands[i].min_arg) - || (argc > weechat_commands[i].max_arg)) + if (strcasecmp (weechat_commands[i].command_name, command + 1) == 0) { - if (weechat_commands[i].min_arg == - weechat_commands[i].max_arg) - gui_printf (NULL, - _("%s wrong argument count for %s command \"%s\" " - "(expected: %d arg%s)\n"), - WEECHAT_ERROR, PACKAGE_NAME, - command + 1, - weechat_commands[i].max_arg, - (weechat_commands[i].max_arg > - 1) ? "s" : ""); - else - gui_printf (NULL, - _("%s wrong argument count for %s command \"%s\" " - "(expected: between %d and %d arg%s)\n"), - WEECHAT_ERROR, PACKAGE_NAME, - command + 1, - weechat_commands[i].min_arg, - weechat_commands[i].max_arg, - (weechat_commands[i].max_arg > - 1) ? "s" : ""); - } - else - { - if (weechat_commands[i].cmd_function_args) - return_code = (int) (weechat_commands[i].cmd_function_args) - (argc, argv); + if ((argc < weechat_commands[i].min_arg) + || (argc > weechat_commands[i].max_arg)) + { + if (weechat_commands[i].min_arg == + weechat_commands[i].max_arg) + gui_printf (NULL, + _("%s wrong argument count for %s command \"%s\" " + "(expected: %d arg%s)\n"), + WEECHAT_ERROR, PACKAGE_NAME, + command + 1, + weechat_commands[i].max_arg, + (weechat_commands[i].max_arg > + 1) ? "s" : ""); + else + gui_printf (NULL, + _("%s wrong argument count for %s command \"%s\" " + "(expected: between %d and %d arg%s)\n"), + WEECHAT_ERROR, PACKAGE_NAME, + command + 1, + weechat_commands[i].min_arg, + weechat_commands[i].max_arg, + (weechat_commands[i].max_arg > + 1) ? "s" : ""); + } else - return_code = (int) (weechat_commands[i].cmd_function_1arg) - (ptr_args); - if (return_code < 0) - gui_printf (NULL, - _("%s %s command \"%s\" failed\n"), - WEECHAT_ERROR, PACKAGE_NAME, command + 1); - } - if (argv) - { - for (j = 0; argv[j]; j++) - free (argv[j]); - free (argv); + { + if (weechat_commands[i].cmd_function_args) + return_code = (int) (weechat_commands[i].cmd_function_args) + (argc, argv); + else + return_code = (int) (weechat_commands[i].cmd_function_1arg) + (ptr_args); + if (return_code < 0) + gui_printf (NULL, + _("%s %s command \"%s\" failed\n"), + WEECHAT_ERROR, PACKAGE_NAME, command + 1); + } + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; } - return 1; } - } - for (i = 0; irc_commands[i].command_name; i++) - { - if ((strcasecmp (irc_commands[i].command_name, command + 1) == 0) && - ((irc_commands[i].cmd_function_args) || - (irc_commands[i].cmd_function_1arg))) + for (i = 0; irc_commands[i].command_name; i++) { - if ((argc < irc_commands[i].min_arg) - || (argc > irc_commands[i].max_arg)) + if ((strcasecmp (irc_commands[i].command_name, command + 1) == 0) && + ((irc_commands[i].cmd_function_args) || + (irc_commands[i].cmd_function_1arg))) { - if (irc_commands[i].min_arg == irc_commands[i].max_arg) - gui_printf - (NULL, - _("%s wrong argument count for IRC command \"%s\" " - "(expected: %d arg%s)\n"), - WEECHAT_ERROR, - command + 1, - irc_commands[i].max_arg, - (irc_commands[i].max_arg > 1) ? "s" : ""); + if ((argc < irc_commands[i].min_arg) + || (argc > irc_commands[i].max_arg)) + { + if (irc_commands[i].min_arg == irc_commands[i].max_arg) + gui_printf + (NULL, + _("%s wrong argument count for IRC command \"%s\" " + "(expected: %d arg%s)\n"), + WEECHAT_ERROR, + command + 1, + irc_commands[i].max_arg, + (irc_commands[i].max_arg > 1) ? "s" : ""); + else + gui_printf + (NULL, + _("%s wrong argument count for IRC command \"%s\" " + "(expected: between %d and %d arg%s)\n"), + WEECHAT_ERROR, + command + 1, + irc_commands[i].min_arg, irc_commands[i].max_arg, + (irc_commands[i].max_arg > 1) ? "s" : ""); + } else - gui_printf - (NULL, - _("%s wrong argument count for IRC command \"%s\" " - "(expected: between %d and %d arg%s)\n"), - WEECHAT_ERROR, - command + 1, - irc_commands[i].min_arg, irc_commands[i].max_arg, - (irc_commands[i].max_arg > 1) ? "s" : ""); + { + if ((irc_commands[i].need_connection) && + ((!server) || (!server->is_connected))) + { + gui_printf (NULL, + _("%s command \"%s\" needs a server connection!\n"), + WEECHAT_ERROR, irc_commands[i].command_name); + return 0; + } + if (irc_commands[i].cmd_function_args) + return_code = (int) (irc_commands[i].cmd_function_args) + (server, argc, argv); + else + return_code = (int) (irc_commands[i].cmd_function_1arg) + (server, ptr_args); + if (return_code < 0) + gui_printf (NULL, + _("%s IRC command \"%s\" failed\n"), + WEECHAT_ERROR, command + 1); + } + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; } - else + } + for (ptr_alias = weechat_alias; ptr_alias; + ptr_alias = ptr_alias->next_alias) + { + if (strcasecmp (ptr_alias->alias_name, command + 1) == 0) { - if ((irc_commands[i].need_connection) && - ((!server) || (!server->is_connected))) + if (ptr_args) { - gui_printf (NULL, - _("%s command \"%s\" needs a server connection!\n"), - WEECHAT_ERROR, irc_commands[i].command_name); - return 0; + length1 = strlen (ptr_alias->alias_command); + length2 = strlen (ptr_args); + alias_command = (char *)malloc (length1 + 1 + length2 + 1); + strcpy (alias_command, ptr_alias->alias_command); + alias_command[length1] = ' '; + strcpy (alias_command + length1 + 1, ptr_args); + exec_weechat_command (server, alias_command); + free (alias_command); } - if (irc_commands[i].cmd_function_args) - return_code = (int) (irc_commands[i].cmd_function_args) - (server, argc, argv); else - return_code = (int) (irc_commands[i].cmd_function_1arg) - (server, ptr_args); - if (return_code < 0) - gui_printf (NULL, - _("%s IRC command \"%s\" failed\n"), - WEECHAT_ERROR, command + 1); - } - if (argv) - { - for (j = 0; argv[j]; j++) - free (argv[j]); - free (argv); + exec_weechat_command (server, ptr_alias->alias_command); + + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; } - return 1; } - } - for (ptr_alias = weechat_alias; ptr_alias; - ptr_alias = ptr_alias->next_alias) - { - if (strcasecmp (ptr_alias->alias_name, command + 1) == 0) + gui_printf (NULL, + _("%s unknown command \"%s\" (type /help for help)\n"), + WEECHAT_ERROR, + command + 1); + if (argv) { - if (ptr_args) - { - length1 = strlen (ptr_alias->alias_command); - length2 = strlen (ptr_args); - alias_command = (char *)malloc (length1 + 1 + length2 + 1); - strcpy (alias_command, ptr_alias->alias_command); - alias_command[length1] = ' '; - strcpy (alias_command + length1 + 1, ptr_args); - exec_weechat_command (server, alias_command); - free (alias_command); - } - else - exec_weechat_command (server, ptr_alias->alias_command); - - if (argv) - { - for (j = 0; argv[j]; j++) - free (argv[j]); - free (argv); - } - return 1; + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); } } - gui_printf (NULL, - _("%s unknown command \"%s\" (type /help for help)\n"), - WEECHAT_ERROR, - command + 1); - if (argv) - { - for (j = 0; argv[j]; j++) - free (argv[j]); - free (argv); - } return 0; } @@ -766,9 +769,9 @@ weechat_cmd_alias (char *arguments) WEECHAT_ERROR, "alias"); return -1; } - index_command_new (arguments); if (!alias_new (arguments, pos)) return -1; + index_command_new (arguments); gui_printf (NULL, _("Alias \"%s\" => \"%s\" created\n"), arguments, pos); } @@ -998,7 +1001,7 @@ weechat_cmd_perl (int argc, char **argv) if (strcmp (argv[0], "load") == 0) { /* load Perl script */ - plugins_load (PLUGIN_PERL, argv[1]); + plugin_load (PLUGIN_PERL, argv[1]); } else { diff --git a/src/common/command.h b/src/common/command.h index 59183f70d..bd006869c 100644 --- a/src/common/command.h +++ b/src/common/command.h @@ -62,6 +62,7 @@ struct t_index_command extern t_weechat_alias *weechat_alias; extern t_index_command *index_commands; +extern t_index_command *index_command_search (char *); extern t_index_command *index_command_new (char *); extern void index_command_build (); extern t_weechat_alias *alias_new (char *, char *); diff --git a/src/common/weechat.c b/src/common/weechat.c index 2efadda8a..75262fecc 100644 --- a/src/common/weechat.c +++ b/src/common/weechat.c @@ -273,7 +273,7 @@ main (int argc, char *argv[]) gui_init (); /* init plugin interface(s) */ - plugins_init (); + plugin_init (); /* Welcome message - yeah! */ if (cfg_look_startup_logo) @@ -324,7 +324,7 @@ main (int argc, char *argv[]) gui_main_loop (); /* end plugin interface(s) */ - plugins_end (); + plugin_end (); /* disconnect from all servers */ server_disconnect_all (); diff --git a/src/irc/irc-recv.c b/src/irc/irc-recv.c index a338d4a8f..6c53c806a 100644 --- a/src/irc/irc-recv.c +++ b/src/irc/irc-recv.c @@ -78,7 +78,7 @@ irc_recv_command (t_irc_server *server, char *entire_line, if (irc_commands[i].recv_function != NULL) { return_code = (int) (irc_commands[i].recv_function) (server, host, arguments); - plugins_event_msg (irc_commands[i].command_name, entire_line); + plugin_event_msg (irc_commands[i].command_name, entire_line); return return_code; } diff --git a/src/plugins/perl/wee-perl.c b/src/plugins/perl/wee-perl.c index 2433e8fab..21926bf4a 100644 --- a/src/plugins/perl/wee-perl.c +++ b/src/plugins/perl/wee-perl.c @@ -31,8 +31,9 @@ #include <perl.h> #include <XSUB.h> #include "../../common/weechat.h" -#include "wee-perl.h" #include "../plugins.h" +#include "wee-perl.h" +#include "../../common/command.h" #include "../../gui/gui.h" @@ -81,7 +82,7 @@ static XS (XS_IRC_register) name, version, description); } else - gui_printf (NULL, + gui_printf (gui_current_window, _("%s unable to load Perl script \"%s\" (not enough memory)\n"), WEECHAT_ERROR, name); XST_mPV (0, VERSION); @@ -121,7 +122,34 @@ static XS (XS_IRC_add_message_handler) name = SvPV (ST (0), integer); function = SvPV (ST (1), integer); - plugins_msg_handler_add (PLUGIN_PERL, name, function); + plugin_handler_add (&plugin_msg_handlers, &last_plugin_msg_handler, + PLUGIN_PERL, name, function); + XSRETURN_EMPTY; +} + +/* + * IRC::add_command_handler: add command handler (define/redefine commands) + */ + +static XS (XS_IRC_add_command_handler) +{ + char *name, *function; + int integer; + dXSARGS; + + name = SvPV (ST (0), integer); + function = SvPV (ST (1), integer); + if (index_command_search (name)) + { + gui_printf (gui_current_window, + _("Perl error: alias or command \"%s\" already exists!\n"), + name); + } + else + { + plugin_handler_add (&plugin_cmd_handlers, &last_plugin_cmd_handler, + PLUGIN_PERL, name, function); + } XSRETURN_EMPTY; } @@ -136,6 +164,7 @@ xs_init (pTHX) newXS ("IRC::register", XS_IRC_register, "IRC"); newXS ("IRC::print", XS_IRC_print, "IRC"); newXS ("IRC::add_message_handler", XS_IRC_add_message_handler, "IRC"); + newXS ("IRC::add_command_handler", XS_IRC_add_command_handler, "IRC"); } /* @@ -232,7 +261,7 @@ wee_perl_exec (char *function, char *arguments) return_code = 1; if (SvTRUE (sv)) { - gui_printf (NULL, + gui_printf (gui_current_window, _("Perl error: %s\n"), SvPV (sv, count)); POPs; @@ -241,7 +270,7 @@ wee_perl_exec (char *function, char *arguments) { if (count != 1) { - gui_printf (NULL, + gui_printf (gui_current_window, _("Perl error: too much values from \"%s\" (%d). Expected: 1.\n"), function, count); } diff --git a/src/plugins/plugins.c b/src/plugins/plugins.c index 8ef0627e4..704ccf474 100644 --- a/src/plugins/plugins.c +++ b/src/plugins/plugins.c @@ -37,18 +37,19 @@ #endif -t_plugin_handler *plugins_msg_handlers = NULL; +t_plugin_handler *plugin_msg_handlers = NULL; t_plugin_handler *last_plugin_msg_handler = NULL; -t_plugin_handler *plugins_cmd_handlers = NULL; + +t_plugin_handler *plugin_cmd_handlers = NULL; t_plugin_handler *last_plugin_cmd_handler = NULL; /* - * plugins_init: initialize all plugins + * plugin_init: initialize all plugins */ void -plugins_init () +plugin_init () { #ifdef PLUGIN_PERL wee_perl_init(); @@ -56,11 +57,11 @@ plugins_init () } /* - * plugins_load: load a plugin + * plugin_load: load a plugin */ void -plugins_load (int plugin_type, char *filename) +plugin_load (int plugin_type, char *filename) { #ifdef PLUGINS switch (plugin_type) @@ -81,11 +82,11 @@ plugins_load (int plugin_type, char *filename) } /* - * plugins_unload: unload a plugin + * plugin_unload: unload a plugin */ void -plugins_unload (int plugin_type, char *scriptname) +plugin_unload (int plugin_type, char *scriptname) { #ifdef PLUGINS switch (plugin_type) @@ -106,11 +107,33 @@ plugins_unload (int plugin_type, char *scriptname) } /* - * plugins_msg_handler_add: add a message handler + * plugin_handler_search: look for message/command handler + */ + +t_plugin_handler * +plugin_handler_search (t_plugin_handler *plugin_handlers, char *name) +{ + t_plugin_handler *ptr_plugin_handler; + + for (ptr_plugin_handler = plugin_handlers; ptr_plugin_handler; + ptr_plugin_handler = ptr_plugin_handler->next_handler) + { + /* handler found */ + if (strcasecmp (ptr_plugin_handler->name, name) == 0) + return ptr_plugin_handler; + } + /* handler not found */ + return NULL; +} + +/* + * plugin_handler_add: add a message/command handler */ void -plugins_msg_handler_add (int plugin_type, char *message, char *function) +plugin_handler_add (t_plugin_handler **plugin_handlers, + t_plugin_handler **last_plugin_handler, + int plugin_type, char *name, char *function) { t_plugin_handler *new_plugin_handler; @@ -118,43 +141,45 @@ plugins_msg_handler_add (int plugin_type, char *message, char *function) if (new_plugin_handler) { new_plugin_handler->plugin_type = plugin_type; - new_plugin_handler->name = strdup (message); + new_plugin_handler->name = strdup (name); new_plugin_handler->function_name = strdup (function); /* add new handler to list */ - new_plugin_handler->prev_handler = last_plugin_msg_handler; + new_plugin_handler->prev_handler = *last_plugin_handler; new_plugin_handler->next_handler = NULL; - if (plugins_msg_handlers) - last_plugin_msg_handler->next_handler = new_plugin_handler; + if (*plugin_handlers) + (*last_plugin_handler)->next_handler = new_plugin_handler; else - plugins_msg_handlers = new_plugin_handler; - last_plugin_msg_handler = new_plugin_handler; + *plugin_handlers = new_plugin_handler; + *last_plugin_handler = new_plugin_handler; } else gui_printf (NULL, _("%s unable to add handler for \"%s\" message (not enough memory)\n"), - WEECHAT_ERROR, message); + WEECHAT_ERROR, name); } /* - * plugins_msg_handler_free: free message handler + * plugin_handler_free: free message/command handler */ void -plugins_msg_handler_free (t_plugin_handler *ptr_plugin_handler) +plugin_handler_free (t_plugin_handler **plugin_handlers, + t_plugin_handler **last_plugin_handler, + t_plugin_handler *ptr_plugin_handler) { - t_plugin_handler *new_plugins_msg_handlers; + t_plugin_handler *new_plugin_handlers; /* remove handler from list */ - if (last_plugin_msg_handler == ptr_plugin_handler) - last_plugin_msg_handler = ptr_plugin_handler->prev_handler; + if (*last_plugin_handler == ptr_plugin_handler) + *last_plugin_handler = ptr_plugin_handler->prev_handler; if (ptr_plugin_handler->prev_handler) { (ptr_plugin_handler->prev_handler)->next_handler = ptr_plugin_handler->next_handler; - new_plugins_msg_handlers = plugins_msg_handlers; + new_plugin_handlers = *plugin_handlers; } else - new_plugins_msg_handlers = ptr_plugin_handler->next_handler; + new_plugin_handlers = ptr_plugin_handler->next_handler; if (ptr_plugin_handler->next_handler) (ptr_plugin_handler->next_handler)->prev_handler = ptr_plugin_handler->prev_handler; @@ -163,55 +188,93 @@ plugins_msg_handler_free (t_plugin_handler *ptr_plugin_handler) free (ptr_plugin_handler->name); free (ptr_plugin_handler->function_name); free (ptr_plugin_handler); - plugins_msg_handlers = new_plugins_msg_handlers; + *plugin_handlers = new_plugin_handlers; } /* - * plugins_remove_all_msg_handlers: remove all message handlers + * plugin_handler_free_all: remove all message/command handlers */ void -plugins_msg_handlers_free_all () +plugin_handler_free_all (t_plugin_handler **plugin_handlers, + t_plugin_handler **last_plugin_handler) { - while (plugins_msg_handlers) - plugins_msg_handler_free (plugins_msg_handlers); + while (*plugin_handlers) + plugin_handler_free (plugin_handlers, last_plugin_handler, + *plugin_handlers); } /* - * plugins_event_msg: IRC message received => call all handlers for this message + * plugin_event_msg: IRC message received => call all handlers for this message */ void -plugins_event_msg (char *command, char *arguments) +plugin_event_msg (char *irc_command, char *arguments) +{ + #ifdef PLUGINS + t_plugin_handler *ptr_plugin_handler; + + for (ptr_plugin_handler = plugin_msg_handlers; ptr_plugin_handler; + ptr_plugin_handler = ptr_plugin_handler->next_handler) + { + if (strcasecmp (ptr_plugin_handler->name, irc_command) == 0) + { + #ifdef PLUGIN_PERL + if (ptr_plugin_handler->plugin_type == PLUGIN_PERL) + wee_perl_exec (ptr_plugin_handler->function_name, arguments); + #endif + } + } + #else + /* make gcc happy */ + (void) irc_command; + (void) arguments; + #endif +} + +/* + * plugin_exec_command: execute a command handler + */ + +int +plugin_exec_command (char *user_command, char *arguments) { #ifdef PLUGINS t_plugin_handler *ptr_plugin_handler; - for (ptr_plugin_handler = plugins_msg_handlers; ptr_plugin_handler; + for (ptr_plugin_handler = plugin_cmd_handlers; ptr_plugin_handler; ptr_plugin_handler = ptr_plugin_handler->next_handler) { - if (strcasecmp (ptr_plugin_handler->name, command) == 0) + if (strcasecmp (ptr_plugin_handler->name, user_command) == 0) { #ifdef PLUGIN_PERL if (ptr_plugin_handler->plugin_type == PLUGIN_PERL) wee_perl_exec (ptr_plugin_handler->function_name, arguments); #endif + + /* command executed */ + return 1; } } #else /* make gcc happy */ - (void) command; + (void) user_command; + (void) arguments; #endif + + /* no command executed */ + return 0; } /* - * plugins_end: shutdown plugin interface + * plugin_end: shutdown plugin interface */ void -plugins_end () +plugin_end () { - plugins_msg_handlers_free_all (); + plugin_handler_free_all (&plugin_msg_handlers, &last_plugin_msg_handler); + plugin_handler_free_all (&plugin_cmd_handlers, &last_plugin_cmd_handler); #ifdef PLUGIN_PERL wee_perl_end(); diff --git a/src/plugins/plugins.h b/src/plugins/plugins.h index aa1553f1e..9c9fea300 100644 --- a/src/plugins/plugins.h +++ b/src/plugins/plugins.h @@ -33,18 +33,28 @@ typedef struct t_plugin_handler t_plugin_handler; struct t_plugin_handler { int plugin_type; /* plugin type (Perl, Python, Ruby) */ - char *name; /* name (message or command) */ + char *name; /* name of IRC command (PRIVMSG, ..) + or command (without first '/') */ char *function_name; /* name of function (handler) */ t_plugin_handler *prev_handler; /* link to previous handler */ t_plugin_handler *next_handler; /* link to next handler */ }; +extern t_plugin_handler *plugin_msg_handlers; +extern t_plugin_handler *last_plugin_msg_handler; -extern void plugins_init (); -extern void plugins_load (int, char *); -extern void plugins_unload (int, char *); -extern void plugins_msg_handler_add (int, char *, char *); -extern void plugins_event_msg (char *, char *); -extern void plugins_end (); +extern t_plugin_handler *plugin_cmd_handlers; +extern t_plugin_handler *last_plugin_cmd_handler; + + +extern void plugin_init (); +extern void plugin_load (int, char *); +extern void plugin_unload (int, char *); +extern t_plugin_handler *plugin_handler_search (t_plugin_handler *, char *); +extern void plugin_handler_add (t_plugin_handler **, t_plugin_handler **, + int, char *, char *); +extern void plugin_event_msg (char *, char *); +extern int plugin_exec_command (char *, char *); +extern void plugin_end (); #endif /* plugins.h */ diff --git a/weechat/src/common/command.c b/weechat/src/common/command.c index a427cc7d7..c8396c76a 100644 --- a/weechat/src/common/command.c +++ b/weechat/src/common/command.c @@ -524,154 +524,157 @@ exec_weechat_command (t_irc_server *server, char *string) ptr_args = NULL; } - argv = explode_string (ptr_args, " ", 0, &argc); - - for (i = 0; weechat_commands[i].command_name; i++) + if (!plugin_exec_command (command + 1, ptr_args)) { - if (strcasecmp (weechat_commands[i].command_name, command + 1) == 0) + argv = explode_string (ptr_args, " ", 0, &argc); + + for (i = 0; weechat_commands[i].command_name; i++) { - if ((argc < weechat_commands[i].min_arg) - || (argc > weechat_commands[i].max_arg)) + if (strcasecmp (weechat_commands[i].command_name, command + 1) == 0) { - if (weechat_commands[i].min_arg == - weechat_commands[i].max_arg) - gui_printf (NULL, - _("%s wrong argument count for %s command \"%s\" " - "(expected: %d arg%s)\n"), - WEECHAT_ERROR, PACKAGE_NAME, - command + 1, - weechat_commands[i].max_arg, - (weechat_commands[i].max_arg > - 1) ? "s" : ""); - else - gui_printf (NULL, - _("%s wrong argument count for %s command \"%s\" " - "(expected: between %d and %d arg%s)\n"), - WEECHAT_ERROR, PACKAGE_NAME, - command + 1, - weechat_commands[i].min_arg, - weechat_commands[i].max_arg, - (weechat_commands[i].max_arg > - 1) ? "s" : ""); - } - else - { - if (weechat_commands[i].cmd_function_args) - return_code = (int) (weechat_commands[i].cmd_function_args) - (argc, argv); + if ((argc < weechat_commands[i].min_arg) + || (argc > weechat_commands[i].max_arg)) + { + if (weechat_commands[i].min_arg == + weechat_commands[i].max_arg) + gui_printf (NULL, + _("%s wrong argument count for %s command \"%s\" " + "(expected: %d arg%s)\n"), + WEECHAT_ERROR, PACKAGE_NAME, + command + 1, + weechat_commands[i].max_arg, + (weechat_commands[i].max_arg > + 1) ? "s" : ""); + else + gui_printf (NULL, + _("%s wrong argument count for %s command \"%s\" " + "(expected: between %d and %d arg%s)\n"), + WEECHAT_ERROR, PACKAGE_NAME, + command + 1, + weechat_commands[i].min_arg, + weechat_commands[i].max_arg, + (weechat_commands[i].max_arg > + 1) ? "s" : ""); + } else - return_code = (int) (weechat_commands[i].cmd_function_1arg) - (ptr_args); - if (return_code < 0) - gui_printf (NULL, - _("%s %s command \"%s\" failed\n"), - WEECHAT_ERROR, PACKAGE_NAME, command + 1); - } - if (argv) - { - for (j = 0; argv[j]; j++) - free (argv[j]); - free (argv); + { + if (weechat_commands[i].cmd_function_args) + return_code = (int) (weechat_commands[i].cmd_function_args) + (argc, argv); + else + return_code = (int) (weechat_commands[i].cmd_function_1arg) + (ptr_args); + if (return_code < 0) + gui_printf (NULL, + _("%s %s command \"%s\" failed\n"), + WEECHAT_ERROR, PACKAGE_NAME, command + 1); + } + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; } - return 1; } - } - for (i = 0; irc_commands[i].command_name; i++) - { - if ((strcasecmp (irc_commands[i].command_name, command + 1) == 0) && - ((irc_commands[i].cmd_function_args) || - (irc_commands[i].cmd_function_1arg))) + for (i = 0; irc_commands[i].command_name; i++) { - if ((argc < irc_commands[i].min_arg) - || (argc > irc_commands[i].max_arg)) + if ((strcasecmp (irc_commands[i].command_name, command + 1) == 0) && + ((irc_commands[i].cmd_function_args) || + (irc_commands[i].cmd_function_1arg))) { - if (irc_commands[i].min_arg == irc_commands[i].max_arg) - gui_printf - (NULL, - _("%s wrong argument count for IRC command \"%s\" " - "(expected: %d arg%s)\n"), - WEECHAT_ERROR, - command + 1, - irc_commands[i].max_arg, - (irc_commands[i].max_arg > 1) ? "s" : ""); + if ((argc < irc_commands[i].min_arg) + || (argc > irc_commands[i].max_arg)) + { + if (irc_commands[i].min_arg == irc_commands[i].max_arg) + gui_printf + (NULL, + _("%s wrong argument count for IRC command \"%s\" " + "(expected: %d arg%s)\n"), + WEECHAT_ERROR, + command + 1, + irc_commands[i].max_arg, + (irc_commands[i].max_arg > 1) ? "s" : ""); + else + gui_printf + (NULL, + _("%s wrong argument count for IRC command \"%s\" " + "(expected: between %d and %d arg%s)\n"), + WEECHAT_ERROR, + command + 1, + irc_commands[i].min_arg, irc_commands[i].max_arg, + (irc_commands[i].max_arg > 1) ? "s" : ""); + } else - gui_printf - (NULL, - _("%s wrong argument count for IRC command \"%s\" " - "(expected: between %d and %d arg%s)\n"), - WEECHAT_ERROR, - command + 1, - irc_commands[i].min_arg, irc_commands[i].max_arg, - (irc_commands[i].max_arg > 1) ? "s" : ""); + { + if ((irc_commands[i].need_connection) && + ((!server) || (!server->is_connected))) + { + gui_printf (NULL, + _("%s command \"%s\" needs a server connection!\n"), + WEECHAT_ERROR, irc_commands[i].command_name); + return 0; + } + if (irc_commands[i].cmd_function_args) + return_code = (int) (irc_commands[i].cmd_function_args) + (server, argc, argv); + else + return_code = (int) (irc_commands[i].cmd_function_1arg) + (server, ptr_args); + if (return_code < 0) + gui_printf (NULL, + _("%s IRC command \"%s\" failed\n"), + WEECHAT_ERROR, command + 1); + } + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; } - else + } + for (ptr_alias = weechat_alias; ptr_alias; + ptr_alias = ptr_alias->next_alias) + { + if (strcasecmp (ptr_alias->alias_name, command + 1) == 0) { - if ((irc_commands[i].need_connection) && - ((!server) || (!server->is_connected))) + if (ptr_args) { - gui_printf (NULL, - _("%s command \"%s\" needs a server connection!\n"), - WEECHAT_ERROR, irc_commands[i].command_name); - return 0; + length1 = strlen (ptr_alias->alias_command); + length2 = strlen (ptr_args); + alias_command = (char *)malloc (length1 + 1 + length2 + 1); + strcpy (alias_command, ptr_alias->alias_command); + alias_command[length1] = ' '; + strcpy (alias_command + length1 + 1, ptr_args); + exec_weechat_command (server, alias_command); + free (alias_command); } - if (irc_commands[i].cmd_function_args) - return_code = (int) (irc_commands[i].cmd_function_args) - (server, argc, argv); else - return_code = (int) (irc_commands[i].cmd_function_1arg) - (server, ptr_args); - if (return_code < 0) - gui_printf (NULL, - _("%s IRC command \"%s\" failed\n"), - WEECHAT_ERROR, command + 1); - } - if (argv) - { - for (j = 0; argv[j]; j++) - free (argv[j]); - free (argv); + exec_weechat_command (server, ptr_alias->alias_command); + + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; } - return 1; } - } - for (ptr_alias = weechat_alias; ptr_alias; - ptr_alias = ptr_alias->next_alias) - { - if (strcasecmp (ptr_alias->alias_name, command + 1) == 0) + gui_printf (NULL, + _("%s unknown command \"%s\" (type /help for help)\n"), + WEECHAT_ERROR, + command + 1); + if (argv) { - if (ptr_args) - { - length1 = strlen (ptr_alias->alias_command); - length2 = strlen (ptr_args); - alias_command = (char *)malloc (length1 + 1 + length2 + 1); - strcpy (alias_command, ptr_alias->alias_command); - alias_command[length1] = ' '; - strcpy (alias_command + length1 + 1, ptr_args); - exec_weechat_command (server, alias_command); - free (alias_command); - } - else - exec_weechat_command (server, ptr_alias->alias_command); - - if (argv) - { - for (j = 0; argv[j]; j++) - free (argv[j]); - free (argv); - } - return 1; + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); } } - gui_printf (NULL, - _("%s unknown command \"%s\" (type /help for help)\n"), - WEECHAT_ERROR, - command + 1); - if (argv) - { - for (j = 0; argv[j]; j++) - free (argv[j]); - free (argv); - } return 0; } @@ -766,9 +769,9 @@ weechat_cmd_alias (char *arguments) WEECHAT_ERROR, "alias"); return -1; } - index_command_new (arguments); if (!alias_new (arguments, pos)) return -1; + index_command_new (arguments); gui_printf (NULL, _("Alias \"%s\" => \"%s\" created\n"), arguments, pos); } @@ -998,7 +1001,7 @@ weechat_cmd_perl (int argc, char **argv) if (strcmp (argv[0], "load") == 0) { /* load Perl script */ - plugins_load (PLUGIN_PERL, argv[1]); + plugin_load (PLUGIN_PERL, argv[1]); } else { diff --git a/weechat/src/common/command.h b/weechat/src/common/command.h index 59183f70d..bd006869c 100644 --- a/weechat/src/common/command.h +++ b/weechat/src/common/command.h @@ -62,6 +62,7 @@ struct t_index_command extern t_weechat_alias *weechat_alias; extern t_index_command *index_commands; +extern t_index_command *index_command_search (char *); extern t_index_command *index_command_new (char *); extern void index_command_build (); extern t_weechat_alias *alias_new (char *, char *); diff --git a/weechat/src/common/weechat.c b/weechat/src/common/weechat.c index 2efadda8a..75262fecc 100644 --- a/weechat/src/common/weechat.c +++ b/weechat/src/common/weechat.c @@ -273,7 +273,7 @@ main (int argc, char *argv[]) gui_init (); /* init plugin interface(s) */ - plugins_init (); + plugin_init (); /* Welcome message - yeah! */ if (cfg_look_startup_logo) @@ -324,7 +324,7 @@ main (int argc, char *argv[]) gui_main_loop (); /* end plugin interface(s) */ - plugins_end (); + plugin_end (); /* disconnect from all servers */ server_disconnect_all (); diff --git a/weechat/src/irc/irc-recv.c b/weechat/src/irc/irc-recv.c index a338d4a8f..6c53c806a 100644 --- a/weechat/src/irc/irc-recv.c +++ b/weechat/src/irc/irc-recv.c @@ -78,7 +78,7 @@ irc_recv_command (t_irc_server *server, char *entire_line, if (irc_commands[i].recv_function != NULL) { return_code = (int) (irc_commands[i].recv_function) (server, host, arguments); - plugins_event_msg (irc_commands[i].command_name, entire_line); + plugin_event_msg (irc_commands[i].command_name, entire_line); return return_code; } diff --git a/weechat/src/plugins/perl/wee-perl.c b/weechat/src/plugins/perl/wee-perl.c index 2433e8fab..21926bf4a 100644 --- a/weechat/src/plugins/perl/wee-perl.c +++ b/weechat/src/plugins/perl/wee-perl.c @@ -31,8 +31,9 @@ #include <perl.h> #include <XSUB.h> #include "../../common/weechat.h" -#include "wee-perl.h" #include "../plugins.h" +#include "wee-perl.h" +#include "../../common/command.h" #include "../../gui/gui.h" @@ -81,7 +82,7 @@ static XS (XS_IRC_register) name, version, description); } else - gui_printf (NULL, + gui_printf (gui_current_window, _("%s unable to load Perl script \"%s\" (not enough memory)\n"), WEECHAT_ERROR, name); XST_mPV (0, VERSION); @@ -121,7 +122,34 @@ static XS (XS_IRC_add_message_handler) name = SvPV (ST (0), integer); function = SvPV (ST (1), integer); - plugins_msg_handler_add (PLUGIN_PERL, name, function); + plugin_handler_add (&plugin_msg_handlers, &last_plugin_msg_handler, + PLUGIN_PERL, name, function); + XSRETURN_EMPTY; +} + +/* + * IRC::add_command_handler: add command handler (define/redefine commands) + */ + +static XS (XS_IRC_add_command_handler) +{ + char *name, *function; + int integer; + dXSARGS; + + name = SvPV (ST (0), integer); + function = SvPV (ST (1), integer); + if (index_command_search (name)) + { + gui_printf (gui_current_window, + _("Perl error: alias or command \"%s\" already exists!\n"), + name); + } + else + { + plugin_handler_add (&plugin_cmd_handlers, &last_plugin_cmd_handler, + PLUGIN_PERL, name, function); + } XSRETURN_EMPTY; } @@ -136,6 +164,7 @@ xs_init (pTHX) newXS ("IRC::register", XS_IRC_register, "IRC"); newXS ("IRC::print", XS_IRC_print, "IRC"); newXS ("IRC::add_message_handler", XS_IRC_add_message_handler, "IRC"); + newXS ("IRC::add_command_handler", XS_IRC_add_command_handler, "IRC"); } /* @@ -232,7 +261,7 @@ wee_perl_exec (char *function, char *arguments) return_code = 1; if (SvTRUE (sv)) { - gui_printf (NULL, + gui_printf (gui_current_window, _("Perl error: %s\n"), SvPV (sv, count)); POPs; @@ -241,7 +270,7 @@ wee_perl_exec (char *function, char *arguments) { if (count != 1) { - gui_printf (NULL, + gui_printf (gui_current_window, _("Perl error: too much values from \"%s\" (%d). Expected: 1.\n"), function, count); } diff --git a/weechat/src/plugins/plugins.c b/weechat/src/plugins/plugins.c index 8ef0627e4..704ccf474 100644 --- a/weechat/src/plugins/plugins.c +++ b/weechat/src/plugins/plugins.c @@ -37,18 +37,19 @@ #endif -t_plugin_handler *plugins_msg_handlers = NULL; +t_plugin_handler *plugin_msg_handlers = NULL; t_plugin_handler *last_plugin_msg_handler = NULL; -t_plugin_handler *plugins_cmd_handlers = NULL; + +t_plugin_handler *plugin_cmd_handlers = NULL; t_plugin_handler *last_plugin_cmd_handler = NULL; /* - * plugins_init: initialize all plugins + * plugin_init: initialize all plugins */ void -plugins_init () +plugin_init () { #ifdef PLUGIN_PERL wee_perl_init(); @@ -56,11 +57,11 @@ plugins_init () } /* - * plugins_load: load a plugin + * plugin_load: load a plugin */ void -plugins_load (int plugin_type, char *filename) +plugin_load (int plugin_type, char *filename) { #ifdef PLUGINS switch (plugin_type) @@ -81,11 +82,11 @@ plugins_load (int plugin_type, char *filename) } /* - * plugins_unload: unload a plugin + * plugin_unload: unload a plugin */ void -plugins_unload (int plugin_type, char *scriptname) +plugin_unload (int plugin_type, char *scriptname) { #ifdef PLUGINS switch (plugin_type) @@ -106,11 +107,33 @@ plugins_unload (int plugin_type, char *scriptname) } /* - * plugins_msg_handler_add: add a message handler + * plugin_handler_search: look for message/command handler + */ + +t_plugin_handler * +plugin_handler_search (t_plugin_handler *plugin_handlers, char *name) +{ + t_plugin_handler *ptr_plugin_handler; + + for (ptr_plugin_handler = plugin_handlers; ptr_plugin_handler; + ptr_plugin_handler = ptr_plugin_handler->next_handler) + { + /* handler found */ + if (strcasecmp (ptr_plugin_handler->name, name) == 0) + return ptr_plugin_handler; + } + /* handler not found */ + return NULL; +} + +/* + * plugin_handler_add: add a message/command handler */ void -plugins_msg_handler_add (int plugin_type, char *message, char *function) +plugin_handler_add (t_plugin_handler **plugin_handlers, + t_plugin_handler **last_plugin_handler, + int plugin_type, char *name, char *function) { t_plugin_handler *new_plugin_handler; @@ -118,43 +141,45 @@ plugins_msg_handler_add (int plugin_type, char *message, char *function) if (new_plugin_handler) { new_plugin_handler->plugin_type = plugin_type; - new_plugin_handler->name = strdup (message); + new_plugin_handler->name = strdup (name); new_plugin_handler->function_name = strdup (function); /* add new handler to list */ - new_plugin_handler->prev_handler = last_plugin_msg_handler; + new_plugin_handler->prev_handler = *last_plugin_handler; new_plugin_handler->next_handler = NULL; - if (plugins_msg_handlers) - last_plugin_msg_handler->next_handler = new_plugin_handler; + if (*plugin_handlers) + (*last_plugin_handler)->next_handler = new_plugin_handler; else - plugins_msg_handlers = new_plugin_handler; - last_plugin_msg_handler = new_plugin_handler; + *plugin_handlers = new_plugin_handler; + *last_plugin_handler = new_plugin_handler; } else gui_printf (NULL, _("%s unable to add handler for \"%s\" message (not enough memory)\n"), - WEECHAT_ERROR, message); + WEECHAT_ERROR, name); } /* - * plugins_msg_handler_free: free message handler + * plugin_handler_free: free message/command handler */ void -plugins_msg_handler_free (t_plugin_handler *ptr_plugin_handler) +plugin_handler_free (t_plugin_handler **plugin_handlers, + t_plugin_handler **last_plugin_handler, + t_plugin_handler *ptr_plugin_handler) { - t_plugin_handler *new_plugins_msg_handlers; + t_plugin_handler *new_plugin_handlers; /* remove handler from list */ - if (last_plugin_msg_handler == ptr_plugin_handler) - last_plugin_msg_handler = ptr_plugin_handler->prev_handler; + if (*last_plugin_handler == ptr_plugin_handler) + *last_plugin_handler = ptr_plugin_handler->prev_handler; if (ptr_plugin_handler->prev_handler) { (ptr_plugin_handler->prev_handler)->next_handler = ptr_plugin_handler->next_handler; - new_plugins_msg_handlers = plugins_msg_handlers; + new_plugin_handlers = *plugin_handlers; } else - new_plugins_msg_handlers = ptr_plugin_handler->next_handler; + new_plugin_handlers = ptr_plugin_handler->next_handler; if (ptr_plugin_handler->next_handler) (ptr_plugin_handler->next_handler)->prev_handler = ptr_plugin_handler->prev_handler; @@ -163,55 +188,93 @@ plugins_msg_handler_free (t_plugin_handler *ptr_plugin_handler) free (ptr_plugin_handler->name); free (ptr_plugin_handler->function_name); free (ptr_plugin_handler); - plugins_msg_handlers = new_plugins_msg_handlers; + *plugin_handlers = new_plugin_handlers; } /* - * plugins_remove_all_msg_handlers: remove all message handlers + * plugin_handler_free_all: remove all message/command handlers */ void -plugins_msg_handlers_free_all () +plugin_handler_free_all (t_plugin_handler **plugin_handlers, + t_plugin_handler **last_plugin_handler) { - while (plugins_msg_handlers) - plugins_msg_handler_free (plugins_msg_handlers); + while (*plugin_handlers) + plugin_handler_free (plugin_handlers, last_plugin_handler, + *plugin_handlers); } /* - * plugins_event_msg: IRC message received => call all handlers for this message + * plugin_event_msg: IRC message received => call all handlers for this message */ void -plugins_event_msg (char *command, char *arguments) +plugin_event_msg (char *irc_command, char *arguments) +{ + #ifdef PLUGINS + t_plugin_handler *ptr_plugin_handler; + + for (ptr_plugin_handler = plugin_msg_handlers; ptr_plugin_handler; + ptr_plugin_handler = ptr_plugin_handler->next_handler) + { + if (strcasecmp (ptr_plugin_handler->name, irc_command) == 0) + { + #ifdef PLUGIN_PERL + if (ptr_plugin_handler->plugin_type == PLUGIN_PERL) + wee_perl_exec (ptr_plugin_handler->function_name, arguments); + #endif + } + } + #else + /* make gcc happy */ + (void) irc_command; + (void) arguments; + #endif +} + +/* + * plugin_exec_command: execute a command handler + */ + +int +plugin_exec_command (char *user_command, char *arguments) { #ifdef PLUGINS t_plugin_handler *ptr_plugin_handler; - for (ptr_plugin_handler = plugins_msg_handlers; ptr_plugin_handler; + for (ptr_plugin_handler = plugin_cmd_handlers; ptr_plugin_handler; ptr_plugin_handler = ptr_plugin_handler->next_handler) { - if (strcasecmp (ptr_plugin_handler->name, command) == 0) + if (strcasecmp (ptr_plugin_handler->name, user_command) == 0) { #ifdef PLUGIN_PERL if (ptr_plugin_handler->plugin_type == PLUGIN_PERL) wee_perl_exec (ptr_plugin_handler->function_name, arguments); #endif + + /* command executed */ + return 1; } } #else /* make gcc happy */ - (void) command; + (void) user_command; + (void) arguments; #endif + + /* no command executed */ + return 0; } /* - * plugins_end: shutdown plugin interface + * plugin_end: shutdown plugin interface */ void -plugins_end () +plugin_end () { - plugins_msg_handlers_free_all (); + plugin_handler_free_all (&plugin_msg_handlers, &last_plugin_msg_handler); + plugin_handler_free_all (&plugin_cmd_handlers, &last_plugin_cmd_handler); #ifdef PLUGIN_PERL wee_perl_end(); diff --git a/weechat/src/plugins/plugins.h b/weechat/src/plugins/plugins.h index aa1553f1e..9c9fea300 100644 --- a/weechat/src/plugins/plugins.h +++ b/weechat/src/plugins/plugins.h @@ -33,18 +33,28 @@ typedef struct t_plugin_handler t_plugin_handler; struct t_plugin_handler { int plugin_type; /* plugin type (Perl, Python, Ruby) */ - char *name; /* name (message or command) */ + char *name; /* name of IRC command (PRIVMSG, ..) + or command (without first '/') */ char *function_name; /* name of function (handler) */ t_plugin_handler *prev_handler; /* link to previous handler */ t_plugin_handler *next_handler; /* link to next handler */ }; +extern t_plugin_handler *plugin_msg_handlers; +extern t_plugin_handler *last_plugin_msg_handler; -extern void plugins_init (); -extern void plugins_load (int, char *); -extern void plugins_unload (int, char *); -extern void plugins_msg_handler_add (int, char *, char *); -extern void plugins_event_msg (char *, char *); -extern void plugins_end (); +extern t_plugin_handler *plugin_cmd_handlers; +extern t_plugin_handler *last_plugin_cmd_handler; + + +extern void plugin_init (); +extern void plugin_load (int, char *); +extern void plugin_unload (int, char *); +extern t_plugin_handler *plugin_handler_search (t_plugin_handler *, char *); +extern void plugin_handler_add (t_plugin_handler **, t_plugin_handler **, + int, char *, char *); +extern void plugin_event_msg (char *, char *); +extern int plugin_exec_command (char *, char *); +extern void plugin_end (); #endif /* plugins.h */ |