summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/Makefile.am2
-rw-r--r--src/common/alias.c367
-rw-r--r--src/common/alias.h46
-rw-r--r--src/common/command.c496
-rw-r--r--src/common/command.h18
-rw-r--r--src/common/completion.c1
-rw-r--r--src/common/util.c205
-rw-r--r--src/common/util.h2
-rw-r--r--src/common/weechat.c1
-rw-r--r--src/common/weeconfig.c4
-rw-r--r--src/irc/irc-mode.c2
-rw-r--r--src/irc/irc-recv.c20
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);
}