diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Makefile.am | 2 | ||||
-rw-r--r-- | src/common/alias.c | 367 | ||||
-rw-r--r-- | src/common/alias.h | 46 | ||||
-rw-r--r-- | src/common/command.c | 496 | ||||
-rw-r--r-- | src/common/command.h | 18 | ||||
-rw-r--r-- | src/common/completion.c | 1 | ||||
-rw-r--r-- | src/common/util.c | 205 | ||||
-rw-r--r-- | src/common/util.h | 2 | ||||
-rw-r--r-- | src/common/weechat.c | 1 | ||||
-rw-r--r-- | src/common/weeconfig.c | 4 | ||||
-rw-r--r-- | src/irc/irc-mode.c | 2 | ||||
-rw-r--r-- | src/irc/irc-recv.c | 20 |
12 files changed, 709 insertions, 455 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am index e858f0368..f15ca0cfe 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -21,6 +21,8 @@ noinst_LIBRARIES = lib_weechat_main.a lib_weechat_main_a_SOURCES = weechat.c \ weechat.h \ + alias.c \ + alias.h \ backtrace.c \ backtrace.h \ command.c \ diff --git a/src/common/alias.c b/src/common/alias.c new file mode 100644 index 000000000..e60e08999 --- /dev/null +++ b/src/common/alias.c @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2003-2006 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* alias.c: WeeChat alias */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <string.h> + +#include "weechat.h" +#include "alias.h" +#include "util.h" +#include "../irc/irc.h" + + +t_weechat_alias *weechat_alias = NULL; +t_weechat_alias *weechat_last_alias = NULL; + + +/* + * alias_search: search an alias + */ + +t_weechat_alias * +alias_search (char *alias_name) +{ + t_weechat_alias *ptr_alias; + + for (ptr_alias = weechat_alias; ptr_alias; ptr_alias = ptr_alias->next_alias) + { + if (ascii_strcasecmp (alias_name, ptr_alias->alias_name) == 0) + return ptr_alias; + } + return NULL; +} + +/* + * alias_find_pos: find position for an alias (for sorting aliases) + */ + +t_weechat_alias * +alias_find_pos (char *alias_name) +{ + t_weechat_alias *ptr_alias; + + for (ptr_alias = weechat_alias; ptr_alias; ptr_alias = ptr_alias->next_alias) + { + if (ascii_strcasecmp (alias_name, ptr_alias->alias_name) < 0) + return ptr_alias; + } + return NULL; +} + +/* + * alias_insert_sorted: insert alias into sorted list + */ + +void +alias_insert_sorted (t_weechat_alias *alias) +{ + t_weechat_alias *pos_alias; + + pos_alias = alias_find_pos (alias->alias_name); + + if (weechat_alias) + { + if (pos_alias) + { + /* insert alias into the list (before alias found) */ + alias->prev_alias = pos_alias->prev_alias; + alias->next_alias = pos_alias; + if (pos_alias->prev_alias) + pos_alias->prev_alias->next_alias = alias; + else + weechat_alias = alias; + pos_alias->prev_alias = alias; + } + else + { + /* add alias to the end */ + alias->prev_alias = weechat_last_alias; + alias->next_alias = NULL; + weechat_last_alias->next_alias = alias; + weechat_last_alias = alias; + } + } + else + { + alias->prev_alias = NULL; + alias->next_alias = NULL; + weechat_alias = alias; + weechat_last_alias = alias; + } +} + +/* + * alias_new: create new alias and add it to alias list + */ + +t_weechat_alias * +alias_new (char *alias_name, char *alias_command) +{ + t_weechat_alias *new_alias, *ptr_alias; + + while (alias_name[0] == '/') + { + alias_name++; + } + + if (ascii_strcasecmp (alias_name, "builtin") == 0) + return NULL; + + ptr_alias = alias_search (alias_name); + if (ptr_alias) + { + if (ptr_alias->alias_command) + free (ptr_alias->alias_command); + ptr_alias->alias_command = strdup (alias_command); + return ptr_alias; + } + + if ((new_alias = ((t_weechat_alias *) malloc (sizeof (t_weechat_alias))))) + { + new_alias->alias_name = strdup (alias_name); + new_alias->alias_command = (char *) malloc (strlen (alias_command) + 1); + new_alias->running = 0; + if (new_alias->alias_command) + strcpy (new_alias->alias_command, alias_command); + alias_insert_sorted (new_alias); + return new_alias; + } + else + return NULL; +} + +/* + * alias_get_final_command: get final command pointed by an alias + */ + +char * +alias_get_final_command (t_weechat_alias *alias) +{ + t_weechat_alias *ptr_alias; + char *result; + + if (alias->running) + { + irc_display_prefix (NULL, NULL, PREFIX_ERROR); + gui_printf (NULL, + _("%s circular reference when calling alias \"/%s\"\n"), + WEECHAT_ERROR, alias->alias_name); + return NULL; + } + + ptr_alias = alias_search ((alias->alias_command[0] == '/') ? + alias->alias_command + 1 : alias->alias_command); + if (ptr_alias) + { + alias->running = 1; + result = alias_get_final_command (ptr_alias); + alias->running = 0; + return result; + } + return (alias->alias_command[0] == '/') ? + alias->alias_command + 1 : alias->alias_command; +} + +/* + * alias_add_word: add word to string and increment length + * This function should NOT be called directly. + */ + +void +alias_add_word (char **alias, int *length, char *word) +{ + int length_word; + + if (!word) + return; + + length_word = strlen (word); + if (length_word == 0) + return; + + if (*alias == NULL) + { + *alias = (char *) malloc (length_word + 1); + strcpy (*alias, word); + } + else + { + *alias = realloc (*alias, strlen (*alias) + length_word + 1); + strcat (*alias, word); + } + *length += length_word; +} + +/* + * alias_replace_args: replace arguments ($1, $2, .. or $*) in alias arguments + */ + +char * +alias_replace_args (char *alias_args, char *user_args) +{ + char **argv, *start, *pos, *res; + int argc, length_res; + + argv = explode_string (user_args, " ", 0, &argc); + + res = NULL; + length_res = 0; + start = alias_args; + pos = start; + while (pos && pos[0]) + { + if ((pos[0] == '\\') && (pos[1] == '$')) + { + pos[0] = '\0'; + alias_add_word (&res, &length_res, start); + alias_add_word (&res, &length_res, "$"); + pos[0] = '\\'; + start = pos + 2; + pos = start; + } + else + { + if (pos[0] == '$') + { + if (pos[1] == '*') + { + pos[0] = '\0'; + alias_add_word (&res, &length_res, start); + alias_add_word (&res, &length_res, user_args); + pos[0] = '$'; + start = pos + 2; + pos = start; + } + else + { + if ((pos[1] >= '1') && (pos[1] <= '9')) + { + pos[0] = '\0'; + alias_add_word (&res, &length_res, start); + if (pos[1] - '0' <= argc) + alias_add_word (&res, &length_res, argv[pos[1] - '1']); + pos[0] = '$'; + start = pos + 2; + pos = start; + } + else + pos++; + } + } + else + pos++; + } + } + if (argv) + free_exploded_string (argv); + return res; +} + +/* + * alias_replace_vars: replace special vars ($nick, $channel, $server) in a string + */ + +char * +alias_replace_vars (char *string) +{ + char *nick, *channel, *server; + char empty_string[1] = { '\0' }; + char *res, *temp; + + nick = (SERVER(gui_current_window->buffer) + && SERVER(gui_current_window->buffer)->nick) ? + SERVER(gui_current_window->buffer)->nick : empty_string; + channel = (CHANNEL(gui_current_window->buffer)) ? + CHANNEL(gui_current_window->buffer)->name : empty_string; + server = (SERVER(gui_current_window->buffer)) ? + SERVER(gui_current_window->buffer)->name : empty_string; + + /* replace nick */ + temp = weechat_strreplace (string, "$nick", nick); + if (!temp) + return NULL; + res = temp; + + /* replace channel */ + temp = weechat_strreplace (res, "$channel", channel); + free (res); + if (!temp) + return NULL; + res = temp; + + /* replace server */ + temp = weechat_strreplace (res, "$server", server); + free (res); + if (!temp) + return NULL; + res = temp; + + /* return result */ + return res; +} + +/* + * alias_free: free an alias and reomve it from list + */ + +void +alias_free (t_weechat_alias *alias) +{ + t_weechat_alias *new_weechat_alias; + + /* remove alias from list */ + if (weechat_last_alias == alias) + weechat_last_alias = alias->prev_alias; + if (alias->prev_alias) + { + (alias->prev_alias)->next_alias = alias->next_alias; + new_weechat_alias = weechat_alias; + } + else + new_weechat_alias = alias->next_alias; + + if (alias->next_alias) + (alias->next_alias)->prev_alias = alias->prev_alias; + + /* free data */ + if (alias->alias_name) + free (alias->alias_name); + if (alias->alias_command) + free (alias->alias_command); + free (alias); + weechat_alias = new_weechat_alias; +} + +/* + * alias_free_all: free all alias + */ + +void +alias_free_all () +{ + while (weechat_alias) + alias_free (weechat_alias); +} diff --git a/src/common/alias.h b/src/common/alias.h new file mode 100644 index 000000000..f90ccfdbc --- /dev/null +++ b/src/common/alias.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2003-2006 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef __WEECHAT_ALIAS_H +#define __WEECHAT_ALIAS_H 1 + +typedef struct t_weechat_alias t_weechat_alias; + +struct t_weechat_alias +{ + char *alias_name; + char *alias_command; + int running; + t_weechat_alias *prev_alias; + t_weechat_alias *next_alias; +}; + +extern t_weechat_alias *weechat_alias; +extern t_weechat_alias *weechat_last_alias; + +extern t_weechat_alias *alias_search (char *); +extern t_weechat_alias *alias_new (char *, char *); +extern char *alias_get_final_command (t_weechat_alias *); +extern char *alias_replace_args (char *, char *); +extern char *alias_replace_vars (char *); +extern void alias_free (t_weechat_alias *); +extern void alias_free_all (); + +#endif /* alias.h */ diff --git a/src/common/command.c b/src/common/command.c index e973025e8..8b6c311c6 100644 --- a/src/common/command.c +++ b/src/common/command.c @@ -30,6 +30,7 @@ #include "weechat.h" #include "command.h" +#include "alias.h" #include "fifo.h" #include "log.h" #include "session.h" @@ -53,7 +54,9 @@ t_weechat_command weechat_commands[] = N_("alias_name: name of alias\n" " command: command name (WeeChat or IRC command, many commands " "can be separated by semicolons)\n" - "arguments: arguments for command"), + "arguments: arguments for command\n\n" + "Note: in command, special variables $1, $2,..,$9 are replaced by " + "arguments given by user, and $* is replaced by all arguments."), "%- %A", 0, MAX_ARGS, 1, NULL, weechat_cmd_alias }, { "buffer", N_("manage buffers"), N_("[action [args] | number | [[server] [channel]]]"), @@ -225,9 +228,6 @@ t_weechat_command weechat_commands[] = { NULL, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, NULL } }; -t_weechat_alias *weechat_alias = NULL; -t_weechat_alias *weechat_last_alias = NULL; - t_weelist *index_commands; t_weelist *last_index_command; @@ -275,403 +275,6 @@ command_index_free () } /* - * alias_search: search an alias - */ - -t_weechat_alias * -alias_search (char *alias_name) -{ - t_weechat_alias *ptr_alias; - - for (ptr_alias = weechat_alias; ptr_alias; ptr_alias = ptr_alias->next_alias) - { - if (ascii_strcasecmp (alias_name, ptr_alias->alias_name) == 0) - return ptr_alias; - } - return NULL; -} - -/* - * alias_find_pos: find position for an alias (for sorting aliases) - */ - -t_weechat_alias * -alias_find_pos (char *alias_name) -{ - t_weechat_alias *ptr_alias; - - for (ptr_alias = weechat_alias; ptr_alias; ptr_alias = ptr_alias->next_alias) - { - if (ascii_strcasecmp (alias_name, ptr_alias->alias_name) < 0) - return ptr_alias; - } - return NULL; -} - -/* - * alias_insert_sorted: insert alias into sorted list - */ - -void -alias_insert_sorted (t_weechat_alias *alias) -{ - t_weechat_alias *pos_alias; - - pos_alias = alias_find_pos (alias->alias_name); - - if (weechat_alias) - { - if (pos_alias) - { - /* insert alias into the list (before alias found) */ - alias->prev_alias = pos_alias->prev_alias; - alias->next_alias = pos_alias; - if (pos_alias->prev_alias) - pos_alias->prev_alias->next_alias = alias; - else - weechat_alias = alias; - pos_alias->prev_alias = alias; - } - else - { - /* add alias to the end */ - alias->prev_alias = weechat_last_alias; - alias->next_alias = NULL; - weechat_last_alias->next_alias = alias; - weechat_last_alias = alias; - } - } - else - { - alias->prev_alias = NULL; - alias->next_alias = NULL; - weechat_alias = alias; - weechat_last_alias = alias; - } -} - -/* - * alias_new: create new alias and add it to alias list - */ - -t_weechat_alias * -alias_new (char *alias_name, char *alias_command) -{ - t_weechat_alias *new_alias, *ptr_alias; - - while (alias_name[0] == '/') - { - alias_name++; - } - - if (ascii_strcasecmp (alias_name, "builtin") == 0) - return NULL; - - ptr_alias = alias_search (alias_name); - if (ptr_alias) - { - if (ptr_alias->alias_command) - free (ptr_alias->alias_command); - ptr_alias->alias_command = strdup (alias_command); - return ptr_alias; - } - - if ((new_alias = ((t_weechat_alias *) malloc (sizeof (t_weechat_alias))))) - { - new_alias->alias_name = strdup (alias_name); - new_alias->alias_command = (char *) malloc (strlen (alias_command) + 1); - new_alias->running = 0; - if (new_alias->alias_command) - strcpy (new_alias->alias_command, alias_command); - alias_insert_sorted (new_alias); - return new_alias; - } - else - return NULL; -} - -/* - * alias_get_final_command: get final command pointer by an alias - */ - -char * -alias_get_final_command (t_weechat_alias *alias) -{ - t_weechat_alias *ptr_alias; - char *result; - - if (alias->running) - { - irc_display_prefix (NULL, NULL, PREFIX_ERROR); - gui_printf (NULL, - _("%s circular reference when calling alias \"/%s\"\n"), - WEECHAT_ERROR, alias->alias_name); - return NULL; - } - - ptr_alias = alias_search ((alias->alias_command[0] == '/') ? - alias->alias_command + 1 : alias->alias_command); - if (ptr_alias) - { - alias->running = 1; - result = alias_get_final_command (ptr_alias); - alias->running = 0; - return result; - } - return (alias->alias_command[0] == '/') ? - alias->alias_command + 1 : alias->alias_command; -} - -/* - * alias_free: free an alias and reomve it from list - */ - -void -alias_free (t_weechat_alias *alias) -{ - t_weechat_alias *new_weechat_alias; - - /* remove alias from list */ - if (weechat_last_alias == alias) - weechat_last_alias = alias->prev_alias; - if (alias->prev_alias) - { - (alias->prev_alias)->next_alias = alias->next_alias; - new_weechat_alias = weechat_alias; - } - else - new_weechat_alias = alias->next_alias; - - if (alias->next_alias) - (alias->next_alias)->prev_alias = alias->prev_alias; - - /* free data */ - if (alias->alias_name) - free (alias->alias_name); - if (alias->alias_command) - free (alias->alias_command); - free (alias); - weechat_alias = new_weechat_alias; -} - -/* - * alias_free_all: free all alias - */ - -void -alias_free_all () -{ - while (weechat_alias) - alias_free (weechat_alias); -} - -/* - * explode_string: explode a string according to separators - */ - -char ** -explode_string (char *string, char *separators, int num_items_max, - int *num_items) -{ - int i, n_items; - char **array; - char *ptr, *ptr1, *ptr2; - - if (num_items != NULL) - *num_items = 0; - - n_items = num_items_max; - - if (!string || !string[0]) - return NULL; - - if (num_items_max == 0) - { - /* calculate number of items */ - ptr = string; - i = 1; - while ((ptr = strpbrk (ptr, separators))) - { - while (strchr (separators, ptr[0]) != NULL) - ptr++; - i++; - } - n_items = i; - } - - array = - (char **) malloc ((num_items_max ? n_items : n_items + 1) * - sizeof (char *)); - - ptr1 = string; - ptr2 = string; - - for (i = 0; i < n_items; i++) - { - while (strchr (separators, ptr1[0]) != NULL) - ptr1++; - if (i == (n_items - 1) || (ptr2 = strpbrk (ptr1, separators)) == NULL) - if ((ptr2 = strchr (ptr1, '\r')) == NULL) - if ((ptr2 = strchr (ptr1, '\n')) == NULL) - ptr2 = strchr (ptr1, '\0'); - - if ((ptr1 == NULL) || (ptr2 == NULL)) - { - array[i] = NULL; - } - else - { - if (ptr2 - ptr1 > 0) - { - array[i] = - (char *) malloc ((ptr2 - ptr1 + 1) * sizeof (char)); - array[i] = strncpy (array[i], ptr1, ptr2 - ptr1); - array[i][ptr2 - ptr1] = '\0'; - ptr1 = ++ptr2; - } - else - { - array[i] = NULL; - } - } - } - if (num_items_max == 0) - { - array[i] = NULL; - if (num_items != NULL) - *num_items = i; - } - else - { - if (num_items != NULL) - *num_items = num_items_max; - } - - return array; -} - -/* - * free_exploded_string: free an exploded string - */ - -void -free_exploded_string (char **exploded_string) -{ - int i; - - if (exploded_string) - { - for (i = 0; exploded_string[i]; i++) - free (exploded_string[i]); - free (exploded_string); - } -} - -/* - * split_multi_command: split a serie of commands separated by 'sep' - * and ecscaped with '\' - * - empty commands are removed - * - spaces on the left of each commands are stripped - * - * result must be freed with free_multi_command - */ - -char ** -split_multi_command (char *command, char sep) -{ - int nb_substr, arr_idx, str_idx, type; - char **array; - char *buffer, *ptr, *p; - - if (command == NULL) - return NULL; - - nb_substr = 1; - ptr = command; - while ( (p = strchr(ptr, sep)) != NULL) - { - nb_substr++; - ptr = ++p; - } - - array = (char **) malloc ((nb_substr + 1) * sizeof(char *)); - if (!array) - return NULL; - - buffer = (char *) malloc ( (strlen(command) + 1) * sizeof (char)); - if (!buffer) - { - free (array); - return NULL; - } - - ptr = command; - str_idx = 0; - arr_idx = 0; - while(*ptr != '\0') - { - type = 0; - if (*ptr == ';') - { - if (ptr == command) - type = 1; - else if ( *(ptr-1) != '\\') - type = 1; - else if ( *(ptr-1) == '\\') - type = 2; - } - if (type == 1) - { - buffer[str_idx] = '\0'; - str_idx = -1; - p = buffer; - /* strip white spaces a the begining of the line */ - while (*p == ' ') p++; - if (p && p[0]) - array[arr_idx++] = strdup (p); - } - else if (type == 2) - buffer[--str_idx] = *ptr; - else - buffer[str_idx] = *ptr; - str_idx++; - ptr++; - } - - buffer[str_idx] = '\0'; - p = buffer; - while (*p == ' ') p++; - if (p && p[0]) - array[arr_idx++] = strdup (p); - - array[arr_idx] = NULL; - - free (buffer); - - array = (char **) realloc (array, (arr_idx + 1) * sizeof(char *)); - - return array; -} - -/* - * free_multi_command : free a list of commands splitted - * with split_multi_command - */ - -void -free_multi_command (char **commands) -{ - int i; - - if (commands) - { - for (i = 0; commands[i]; i++) - free (commands[i]); - free (commands); - } -} - -/* * exec_weechat_command: executes a command (WeeChat internal or IRC) * if only_builtin == 1, then try only WeeChat/IRC commands * (not plugins neither aliases) @@ -687,6 +290,8 @@ exec_weechat_command (t_irc_server *server, t_irc_channel *channel, char *string char *command, *pos, *ptr_args, *ptr_args2, *ptr_args3; char **argv, **argv2, *alias_command; char **commands, **ptr_cmd, **ptr_next_cmd; + char *args_replaced, *vars_replaced, *new_ptr_cmd; + int some_args_replaced; t_weechat_alias *ptr_alias; if ((!string) || (!string[0]) || (string[0] != '/')) @@ -721,7 +326,13 @@ exec_weechat_command (t_irc_server *server, t_irc_channel *channel, char *string if (only_builtin) rc = -1; else - rc = plugin_cmd_handler_exec ((server) ? server->name : "", command + 1, ptr_args); + { + vars_replaced = alias_replace_vars (ptr_args); + rc = plugin_cmd_handler_exec ((server) ? server->name : "", command + 1, + (vars_replaced) ? vars_replaced : ptr_args); + if (vars_replaced) + free (vars_replaced); + } #else rc = -1; #endif @@ -755,55 +366,82 @@ exec_weechat_command (t_irc_server *server, t_irc_channel *channel, char *string } else { - /* an alias can contain many commandes separated by ';' */ + /* an alias can contain many commands separated by ';' */ commands = split_multi_command (ptr_alias->alias_command, ';'); if (commands) { - ptr_alias->running = 1; + some_args_replaced = 0; + ptr_alias->running = 1; for (ptr_cmd=commands; *ptr_cmd; ptr_cmd++) { ptr_next_cmd = ptr_cmd; ptr_next_cmd++; - - if (*ptr_next_cmd == NULL && ptr_args) - { - /* if alias has arguments, they are now - arguments of the last command in the list */ - length1 = strlen (*ptr_cmd); - length2 = strlen (ptr_args); - alias_command = (char *) malloc ( 1 + length1 + 1 + length2 + 1); - if (alias_command) + vars_replaced = alias_replace_vars (*ptr_cmd); + new_ptr_cmd = (vars_replaced) ? vars_replaced : *ptr_cmd; + args_replaced = alias_replace_args (new_ptr_cmd, ptr_args); + if (args_replaced) + { + some_args_replaced = 1; + if (*ptr_cmd[0] == '/') + (void) exec_weechat_command (server, channel, args_replaced, only_builtin); + else { - if (*ptr_cmd[0] != '/') + alias_command = (char *) malloc (1 + strlen(args_replaced) + 1); + if (alias_command) + { strcpy (alias_command, "/"); - else - strcpy (alias_command, ""); - - strcat (alias_command, *ptr_cmd); - strcat (alias_command, " "); - strcat (alias_command, ptr_args); - - (void) exec_weechat_command (server, channel, alias_command, only_builtin); - free (alias_command); + strcat (alias_command, args_replaced); + (void) exec_weechat_command (server, channel, alias_command, only_builtin); + free (alias_command); + } } + free (args_replaced); } else { - if (*ptr_cmd[0] == '/') - (void) exec_weechat_command (server, channel, *ptr_cmd, only_builtin); - else + /* if alias has arguments, they are now + arguments of the last command in the list (if no $1,$2,..$*) was found */ + if ((*ptr_next_cmd == NULL) && ptr_args && (!some_args_replaced)) { - alias_command = (char *) malloc (1 + strlen(*ptr_cmd) + 1); + length1 = strlen (new_ptr_cmd); + length2 = strlen (ptr_args); + + alias_command = (char *) malloc ( 1 + length1 + 1 + length2 + 1); if (alias_command) { - strcpy (alias_command, "/"); - strcat (alias_command, *ptr_cmd); + if (*ptr_cmd[0] != '/') + strcpy (alias_command, "/"); + else + strcpy (alias_command, ""); + + strcat (alias_command, new_ptr_cmd); + strcat (alias_command, " "); + strcat (alias_command, ptr_args); + (void) exec_weechat_command (server, channel, alias_command, only_builtin); free (alias_command); } } + else + { + if (*ptr_cmd[0] == '/') + (void) exec_weechat_command (server, channel, new_ptr_cmd, only_builtin); + else + { + alias_command = (char *) malloc (1 + strlen (new_ptr_cmd) + 1); + if (alias_command) + { + strcpy (alias_command, "/"); + strcat (alias_command, new_ptr_cmd); + (void) exec_weechat_command (server, channel, alias_command, only_builtin); + free (alias_command); + } + } + } } + if (vars_replaced) + free (vars_replaced); } ptr_alias->running = 0; free_multi_command (commands); diff --git a/src/common/command.h b/src/common/command.h index c79be0979..83b1c24f9 100644 --- a/src/common/command.h +++ b/src/common/command.h @@ -46,31 +46,13 @@ struct t_weechat_command /* function called when user enters cmd */ }; -typedef struct t_weechat_alias t_weechat_alias; - -struct t_weechat_alias -{ - char *alias_name; - char *alias_command; - int running; - t_weechat_alias *prev_alias; - t_weechat_alias *next_alias; -}; - extern t_weechat_command weechat_commands[]; -extern t_weechat_alias *weechat_alias; extern t_weelist *index_commands; extern t_weelist *last_index_command; extern void command_index_build (); extern void command_index_free (); -extern t_weechat_alias *alias_search (char *); -extern t_weechat_alias *alias_new (char *, char *); -extern char *alias_get_final_command (t_weechat_alias *); -extern void alias_free_all (); -extern char **explode_string (char *, char *, int, int *); -extern void free_exploded_string (char **); extern char **split_multi_command (char *, char); extern void free_multi_command (char **); extern int exec_weechat_command (t_irc_server *, t_irc_channel *, char *, int); diff --git a/src/common/completion.c b/src/common/completion.c index 868fade18..9f71ef9f6 100644 --- a/src/common/completion.c +++ b/src/common/completion.c @@ -29,6 +29,7 @@ #include "weechat.h" #include "completion.h" +#include "alias.h" #include "command.h" #include "log.h" #include "utf8.h" diff --git a/src/common/util.c b/src/common/util.c index 6f0742230..b32b22174 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -320,3 +320,208 @@ get_timeval_diff (struct timeval *tv1, struct timeval *tv2) } return ((diff_usec / 1000) + (diff_sec * 1000)); } + +/* + * explode_string: explode a string according to separators + */ + +char ** +explode_string (char *string, char *separators, int num_items_max, + int *num_items) +{ + int i, n_items; + char **array; + char *ptr, *ptr1, *ptr2; + + if (num_items != NULL) + *num_items = 0; + + n_items = num_items_max; + + if (!string || !string[0]) + return NULL; + + if (num_items_max == 0) + { + /* calculate number of items */ + ptr = string; + i = 1; + while ((ptr = strpbrk (ptr, separators))) + { + while (strchr (separators, ptr[0]) != NULL) + ptr++; + i++; + } + n_items = i; + } + + array = + (char **) malloc ((num_items_max ? n_items : n_items + 1) * + sizeof (char *)); + + ptr1 = string; + ptr2 = string; + + for (i = 0; i < n_items; i++) + { + while (strchr (separators, ptr1[0]) != NULL) + ptr1++; + if (i == (n_items - 1) || (ptr2 = strpbrk (ptr1, separators)) == NULL) + if ((ptr2 = strchr (ptr1, '\r')) == NULL) + if ((ptr2 = strchr (ptr1, '\n')) == NULL) + ptr2 = strchr (ptr1, '\0'); + + if ((ptr1 == NULL) || (ptr2 == NULL)) + { + array[i] = NULL; + } + else + { + if (ptr2 - ptr1 > 0) + { + array[i] = + (char *) malloc ((ptr2 - ptr1 + 1) * sizeof (char)); + array[i] = strncpy (array[i], ptr1, ptr2 - ptr1); + array[i][ptr2 - ptr1] = '\0'; + ptr1 = ++ptr2; + } + else + { + array[i] = NULL; + } + } + } + if (num_items_max == 0) + { + array[i] = NULL; + if (num_items != NULL) + *num_items = i; + } + else + { + if (num_items != NULL) + *num_items = num_items_max; + } + + return array; +} + +/* + * free_exploded_string: free an exploded string + */ + +void +free_exploded_string (char **exploded_string) +{ + int i; + + if (exploded_string) + { + for (i = 0; exploded_string[i]; i++) + free (exploded_string[i]); + free (exploded_string); + } +} + +/* + * split_multi_command: split a list of commands separated by 'sep' + * and ecscaped with '\' + * - empty commands are removed + * - spaces on the left of each commands are stripped + * Result must be freed with free_multi_command + */ + +char ** +split_multi_command (char *command, char sep) +{ + int nb_substr, arr_idx, str_idx, type; + char **array; + char *buffer, *ptr, *p; + + if (command == NULL) + return NULL; + + nb_substr = 1; + ptr = command; + while ( (p = strchr(ptr, sep)) != NULL) + { + nb_substr++; + ptr = ++p; + } + + array = (char **) malloc ((nb_substr + 1) * sizeof(char *)); + if (!array) + return NULL; + + buffer = (char *) malloc ( (strlen(command) + 1) * sizeof (char)); + if (!buffer) + { + free (array); + return NULL; + } + + ptr = command; + str_idx = 0; + arr_idx = 0; + while(*ptr != '\0') + { + type = 0; + if (*ptr == ';') + { + if (ptr == command) + type = 1; + else if ( *(ptr-1) != '\\') + type = 1; + else if ( *(ptr-1) == '\\') + type = 2; + } + if (type == 1) + { + buffer[str_idx] = '\0'; + str_idx = -1; + p = buffer; + /* strip white spaces a the begining of the line */ + while (*p == ' ') p++; + if (p && p[0]) + array[arr_idx++] = strdup (p); + } + else if (type == 2) + buffer[--str_idx] = *ptr; + else + buffer[str_idx] = *ptr; + str_idx++; + ptr++; + } + + buffer[str_idx] = '\0'; + p = buffer; + while (*p == ' ') p++; + if (p && p[0]) + array[arr_idx++] = strdup (p); + + array[arr_idx] = NULL; + + free (buffer); + + array = (char **) realloc (array, (arr_idx + 1) * sizeof(char *)); + + return array; +} + +/* + * free_multi_command : free a list of commands splitted + * with split_multi_command + */ + +void +free_multi_command (char **commands) +{ + int i; + + if (commands) + { + for (i = 0; commands[i]; i++) + free (commands[i]); + free (commands); + } +} diff --git a/src/common/util.h b/src/common/util.h index 3e1add637..144791d69 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -30,5 +30,7 @@ extern char *weechat_iconv (char *, char *, char *); extern int weechat_iconv_check (char *, char *); extern char *weechat_strreplace (char *, char *, char *); extern long get_timeval_diff (struct timeval *, struct timeval *); +extern char **explode_string (char *, char *, int, int *); +extern void free_exploded_string (char **); #endif /* util.h */ diff --git a/src/common/weechat.c b/src/common/weechat.c index 9b7dca78c..1857faaac 100644 --- a/src/common/weechat.c +++ b/src/common/weechat.c @@ -56,6 +56,7 @@ #endif #include "weechat.h" +#include "alias.h" #include "backtrace.h" #include "command.h" #include "fifo.h" diff --git a/src/common/weeconfig.c b/src/common/weeconfig.c index 08f4db61c..c04265f33 100644 --- a/src/common/weeconfig.c +++ b/src/common/weeconfig.c @@ -37,6 +37,7 @@ #include "weechat.h" #include "weeconfig.h" +#include "alias.h" #include "command.h" #include "fifo.h" #include "log.h" @@ -1008,7 +1009,8 @@ t_config_option weechat_options_server[] = "", NULL, NULL, &(cfg_server.hostname), NULL }, { "server_command", N_("command(s) to run when connected to server"), N_("command(s) to run when connected to server (many commands should be " - "separated by ';', use '\\;' for a semicolon)"), + "separated by ';', use '\\;' for a semicolon, special variables $nick, " + "$channel and $server are replaced by their value)"), OPTION_TYPE_STRING, 0, 0, 0, "", NULL, NULL, &(cfg_server.command), NULL }, { "server_command_delay", N_("delay (in seconds) after command was executed"), diff --git a/src/irc/irc-mode.c b/src/irc/irc-mode.c index d899cc72d..76079e03c 100644 --- a/src/irc/irc-mode.c +++ b/src/irc/irc-mode.c @@ -29,7 +29,7 @@ #include "../common/weechat.h" #include "irc.h" -#include "../common/command.h" +#include "../common/util.h" #include "../gui/gui.h" diff --git a/src/irc/irc-recv.c b/src/irc/irc-recv.c index 0428a6363..7c9c4a9ea 100644 --- a/src/irc/irc-recv.c +++ b/src/irc/irc-recv.c @@ -37,6 +37,7 @@ #include "../common/weechat.h" #include "irc.h" +#include "../common/alias.h" #include "../common/command.h" #include "../common/hotlist.h" #include "../common/util.h" @@ -736,13 +737,14 @@ irc_cmd_recv_mode (t_irc_server *server, char *host, char *nick, char *arguments { irc_display_prefix (server, server->buffer, PREFIX_INFO); gui_printf (server->buffer, - _("User mode %s%s %s[%s%s%s]\n"), - GUI_COLOR(COLOR_WIN_CHAT_NICK), - nick, + _("User mode %s[%s%s%s]%s by %s%s\n"), GUI_COLOR(COLOR_WIN_CHAT_DARK), GUI_COLOR(COLOR_WIN_CHAT), pos_modes, - GUI_COLOR(COLOR_WIN_CHAT_DARK)); + GUI_COLOR(COLOR_WIN_CHAT_DARK), + GUI_COLOR(COLOR_WIN_CHAT), + GUI_COLOR(COLOR_WIN_CHAT_NICK), + nick); } irc_mode_user_set (server, pos_modes); } @@ -2333,7 +2335,7 @@ int irc_cmd_recv_001 (t_irc_server *server, char *host, char *nick, char *arguments) { char *pos; - char **commands, **ptr; + char **commands, **ptr, *vars_replaced; t_irc_channel *ptr_channel; char *away_msg; @@ -2362,7 +2364,13 @@ irc_cmd_recv_001 (t_irc_server *server, char *host, char *nick, char *arguments) if (commands) { for (ptr = commands; *ptr; ptr++) - user_command (server, NULL, *ptr, 0); + { + vars_replaced = alias_replace_vars (*ptr); + user_command (server, NULL, + (vars_replaced) ? vars_replaced : *ptr, 0); + if (vars_replaced) + free (vars_replaced); + } free_multi_command (commands); } |