diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/command.c | 265 | ||||
-rw-r--r-- | src/common/command.h | 3 | ||||
-rw-r--r-- | src/common/weeconfig.c | 2 | ||||
-rw-r--r-- | src/irc/irc-recv.c | 54 |
4 files changed, 215 insertions, 109 deletions
diff --git a/src/common/command.c b/src/common/command.c index 30a4e7935..dc1b1ea0f 100644 --- a/src/common/command.c +++ b/src/common/command.c @@ -324,45 +324,27 @@ alias_insert_sorted (t_weechat_alias *alias) t_weechat_alias * alias_new (char *alias_name, char *alias_command) { - char *pos; - t_weechat_alias *new_alias; + t_weechat_alias *new_alias, *ptr_alias; + + if (alias_name[0] == '/') + alias_name++; - if (weelist_search (index_commands, alias_name)) - { - irc_display_prefix (NULL, NULL, PREFIX_ERROR); - gui_printf (NULL, _("%s alias or command \"%s\" already exists!\n"), - WEECHAT_ERROR, alias_name); - return NULL; - } - pos = strchr (alias_command, ' '); - if (pos) - pos[0] = '\0'; - if (alias_search (alias_command)) - { - irc_display_prefix (NULL, NULL, PREFIX_ERROR); - gui_printf (NULL, _("%s alias cannot run another alias!\n"), - WEECHAT_ERROR); - return NULL; - } - if (!weelist_search (index_commands, alias_command)) + ptr_alias = alias_search (alias_name); + if (ptr_alias) { - irc_display_prefix (NULL, NULL, PREFIX_ERROR); - gui_printf (NULL, _("%s target command \"/%s\" does not exist!\n"), - WEECHAT_ERROR, alias_command); - return NULL; + if (ptr_alias->alias_command) + free (ptr_alias->alias_command); + ptr_alias->alias_command = strdup (alias_command); + return ptr_alias; } - if (pos) - pos[0] = ' '; 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) + 2); + new_alias->alias_command = (char *) malloc (strlen (alias_command) + 1); + new_alias->running = 0; if (new_alias->alias_command) - { - new_alias->alias_command[0] = '/'; - strcpy (new_alias->alias_command + 1, alias_command); - } + strcpy (new_alias->alias_command, alias_command); alias_insert_sorted (new_alias); return new_alias; } @@ -516,6 +498,110 @@ free_exploded_string (char **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) * returns: 1 if command was executed succesfully * 0 if error (command not executed) @@ -526,6 +612,7 @@ exec_weechat_command (t_irc_server *server, t_irc_channel *channel, char *string { int i, argc, return_code, length1, length2; char *command, *pos, *ptr_args, *ptr_args_color, **argv, *alias_command; + char **commands, **ptr_cmd, **ptr_next_cmd; t_weechat_alias *ptr_alias; if ((!string) || (!string[0]) || (string[0] != '/')) @@ -704,25 +791,69 @@ exec_weechat_command (t_irc_server *server, t_irc_channel *channel, char *string { if (ascii_strcasecmp (ptr_alias->alias_name, command + 1) == 0) { - if (ptr_args) - { - length1 = strlen (ptr_alias->alias_command); - length2 = strlen (ptr_args); - alias_command = (char *)malloc (length1 + 1 + length2 + 1); - if (alias_command) - { - strcpy (alias_command, ptr_alias->alias_command); - alias_command[length1] = ' '; - strcpy (alias_command + length1 + 1, ptr_args); - } - (void) exec_weechat_command (server, channel, alias_command); - if (alias_command) - free (alias_command); - } - else - (void) exec_weechat_command (server, channel, - ptr_alias->alias_command); - + if (ptr_alias->running == 1) + { + gui_printf (NULL, + _("%s circular reference when calling alias \"/%s\"\n"), + WEECHAT_ERROR, ptr_alias->alias_name); + } + else + { + /* an alias can contain many commandes separated by ';' */ + commands = split_multi_command (ptr_alias->alias_command, ';'); + if (commands) + { + 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) + { + if (*ptr_cmd[0] != '/') + 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); + free (alias_command); + } + } + else + { + if (*ptr_cmd[0] == '/') + (void) exec_weechat_command (server, channel, *ptr_cmd); + else + { + alias_command = (char *) malloc (1 + strlen(*ptr_cmd) + 1); + if (alias_command) + { + strcpy (alias_command, "/"); + strcat (alias_command, *ptr_cmd); + (void) exec_weechat_command (server, channel, alias_command); + free (alias_command); + } + } + } + } + ptr_alias->running = 0; + free_multi_command (commands); + } + } + free_exploded_string (argv); free (command); if (ptr_args_color) @@ -907,20 +1038,13 @@ weechat_cmd_alias (t_irc_server *server, t_irc_channel *channel, while (pos[0] == ' ') pos++; if (!pos[0]) - { - irc_display_prefix (NULL, NULL, PREFIX_ERROR); - gui_printf (NULL, _("%s missing arguments for \"%s\" command\n"), - WEECHAT_ERROR, "alias"); - return -1; - } - if (arguments[0] == '/') - { - irc_display_prefix (NULL, NULL, PREFIX_ERROR); - gui_printf (NULL, _("%s alias can not start with \"/\"\n"), - WEECHAT_ERROR, "alias"); + { + irc_display_prefix (NULL, NULL, PREFIX_ERROR); + gui_printf (NULL, _("%s missing arguments for \"%s\" command\n"), + WEECHAT_ERROR, "alias"); return -1; - } - if (!alias_new (arguments, pos)) + } + if (!alias_new (arguments, pos)) return -1; if (weelist_add (&index_commands, &last_index_command, arguments)) { @@ -939,6 +1063,19 @@ weechat_cmd_alias (t_irc_server *server, t_irc_channel *channel, } else { + ptr_alias = alias_search (arguments); + if (ptr_alias) + { + gui_printf (NULL, "\n"); + gui_printf (NULL, _("List of aliases:\n")); + gui_printf (NULL, " %s %s=>%s %s\n", + ptr_alias->alias_name, + GUI_COLOR(COLOR_WIN_CHAT_DARK), + GUI_COLOR(COLOR_WIN_CHAT), + ptr_alias->alias_command); + return 0; + } + irc_display_prefix (NULL, NULL, PREFIX_ERROR); gui_printf (NULL, _("%s missing arguments for \"%s\" command\n"), WEECHAT_ERROR, "alias"); @@ -959,7 +1096,7 @@ weechat_cmd_alias (t_irc_server *server, t_irc_channel *channel, ptr_alias->alias_name, GUI_COLOR(COLOR_WIN_CHAT_DARK), GUI_COLOR(COLOR_WIN_CHAT), - ptr_alias->alias_command + 1); + ptr_alias->alias_command); } } else diff --git a/src/common/command.h b/src/common/command.h index bdbc420d5..c87d31061 100644 --- a/src/common/command.h +++ b/src/common/command.h @@ -50,6 +50,7 @@ struct t_weechat_alias { char *alias_name; char *alias_command; + int running; t_weechat_alias *prev_alias; t_weechat_alias *next_alias; }; @@ -66,6 +67,8 @@ extern t_weechat_alias *alias_new (char *, char *); 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 *); extern void user_command (t_irc_server *, t_irc_channel *, char *); extern int weechat_cmd_alias (t_irc_server *, t_irc_channel *, char *); diff --git a/src/common/weeconfig.c b/src/common/weeconfig.c index 99e4099f6..0cf3af771 100644 --- a/src/common/weeconfig.c +++ b/src/common/weeconfig.c @@ -2367,7 +2367,7 @@ config_write (char *config_name) ptr_alias = ptr_alias->next_alias) { fprintf (file, "%s = \"%s\"\n", - ptr_alias->alias_name, ptr_alias->alias_command + 1); + ptr_alias->alias_name, ptr_alias->alias_command); } /* ignore section */ diff --git a/src/irc/irc-recv.c b/src/irc/irc-recv.c index c35e1692b..eeb6c7454 100644 --- a/src/irc/irc-recv.c +++ b/src/irc/irc-recv.c @@ -2431,9 +2431,9 @@ irc_cmd_recv_topic (t_irc_server *server, char *host, char *nick, char *argument int irc_cmd_recv_004 (t_irc_server *server, char *host, char *nick, char *arguments) { - char *pos, *buffer, *s, *q; - int i, f; - t_irc_channel *ptr_channel; + char *pos; + char **commands, **ptr; + t_irc_channel *ptr_channel; pos = strchr (arguments, ' '); if (pos) @@ -2454,50 +2454,16 @@ irc_cmd_recv_004 (t_irc_server *server, char *host, char *nick, char *arguments) /* execute command once connected */ if (server->command && server->command[0]) - { + { /* splitting command on ';' which can be escaped with '\;' */ - buffer = (char *) malloc ( (strlen(server->command) + 1) * sizeof (char)); - - if (buffer) + commands = split_multi_command (server->command, ';'); + if (commands) { - s = server->command; - i = 0; - while(*s != '\0') - { - f = 0; - if (*s == ';') - { - if (s == server->command) - f = 1; - else if ( *(s-1) != '\\') - f = 1; - else if ( *(s-1) == '\\') - f = 2; - } - if (f == 1) - { - buffer[i] = '\0'; - i = -1; - q = buffer; - while (*q == ' ') q++; - if (q && q[0]) - user_command (server, NULL, q); - } - else if (f == 2) - buffer[--i] = *s; - else - buffer[i] = *s; - i++; s++; - } - buffer[i] = '\0'; - q = buffer; - while (*q == ' ') q++; - if (q && q[0]) - user_command (server, NULL, q); - - free (buffer); + for (ptr=commands; *ptr; ptr++) + user_command (server, NULL, *ptr); + free_multi_command (commands); } - + if (server->command_delay > 0) sleep (server->command_delay); } |