summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2008-03-22 23:36:12 +0100
committerSebastien Helleu <flashcode@flashtux.org>2008-03-22 23:36:12 +0100
commit61ca92972886cd7a9bc301ae7e23d6dde74920bc (patch)
tree7b69905a86b095f4fe6dffaa5a86ae6a0725c125 /src/core
parent8c4dc57d8e5a6b1f9f239bdcbf30dd07480993be (diff)
downloadweechat-61ca92972886cd7a9bc301ae7e23d6dde74920bc.zip
Added tags for lines and custom filtering by tags or regex (task #7674), fixed many memory leaks
Diffstat (limited to 'src/core')
-rw-r--r--src/core/wee-command.c211
-rw-r--r--src/core/wee-config-file.c61
-rw-r--r--src/core/wee-config-file.h1
-rw-r--r--src/core/wee-config.c103
-rw-r--r--src/core/wee-debug.c2
-rw-r--r--src/core/wee-hook.c78
-rw-r--r--src/core/wee-hook.h16
-rw-r--r--src/core/wee-input.c4
-rw-r--r--src/core/wee-string.c125
-rw-r--r--src/core/wee-string.h3
-rw-r--r--src/core/wee-util.c3
-rw-r--r--src/core/weechat.c4
12 files changed, 546 insertions, 65 deletions
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index d42a99ce6..f7a7108d4 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -45,6 +45,7 @@
#include "../gui/gui-buffer.h"
#include "../gui/gui-chat.h"
#include "../gui/gui-color.h"
+#include "../gui/gui-filter.h"
#include "../gui/gui-history.h"
#include "../gui/gui-input.h"
#include "../gui/gui-keyboard.h"
@@ -172,7 +173,7 @@ command_bar (void *data, struct t_gui_buffer *buffer,
}
error = NULL;
number = strtol (argv[5], &error, 10);
- if (error && (error[0] == '\0'))
+ if (error && !error[0])
{
size = number;
separator = 0;
@@ -241,7 +242,7 @@ command_buffer (void *data, struct t_gui_buffer *buffer,
ptr_buffer = ptr_buffer->next_buffer)
{
gui_chat_printf (NULL,
- "%s[%s%d%s]%s (%s) %s / %s",
+ " %s[%s%d%s]%s (%s) %s / %s",
GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS),
GUI_COLOR(GUI_COLOR_CHAT),
ptr_buffer->number,
@@ -268,7 +269,7 @@ command_buffer (void *data, struct t_gui_buffer *buffer,
{
error = NULL;
number = strtol (argv[i], &error, 10);
- if (error && (error[0] == '\0'))
+ if (error && !error[0])
{
ptr_buffer = gui_buffer_search_by_number (number);
if (ptr_buffer)
@@ -297,7 +298,7 @@ command_buffer (void *data, struct t_gui_buffer *buffer,
number = strtol (((argv[2][0] == '+') || (argv[2][0] == '-')) ?
argv[2] + 1 : argv[2],
&error, 10);
- if (error && (error[0] == '\0'))
+ if (error && !error[0])
{
if (argv[2][0] == '+')
gui_buffer_move_to_number (buffer,
@@ -354,7 +355,7 @@ command_buffer (void *data, struct t_gui_buffer *buffer,
/* set notify level for buffer */
error = NULL;
number = strtol (argv[2], &error, 10);
- if (error && (error[0] == '\0'))
+ if (error && !error[0])
{
if ((number < GUI_BUFFER_NOTIFY_LEVEL_MIN)
|| (number > GUI_BUFFER_NOTIFY_LEVEL_MAX))
@@ -441,7 +442,7 @@ command_buffer (void *data, struct t_gui_buffer *buffer,
/* relative jump '-' */
error = NULL;
number = strtol (argv[1] + 1, &error, 10);
- if (error && (error[0] == '\0'))
+ if (error && !error[0])
{
target_buffer = buffer->number - (int) number;
if (target_buffer < 1)
@@ -456,7 +457,7 @@ command_buffer (void *data, struct t_gui_buffer *buffer,
/* relative jump '+' */
error = NULL;
number = strtol (argv[1] + 1, &error, 10);
- if (error && (error[0] == '\0'))
+ if (error && !error[0])
{
target_buffer = buffer->number + (int) number;
if (last_gui_buffer && target_buffer > last_gui_buffer->number)
@@ -470,7 +471,7 @@ command_buffer (void *data, struct t_gui_buffer *buffer,
/* absolute jump by number, or by category/name */
error = NULL;
number = strtol (argv[1], &error, 10);
- if (error && (error[0] == '\0'))
+ if (error && !error[0])
gui_buffer_switch_by_number (gui_current_window,
(int) number);
else
@@ -539,6 +540,169 @@ command_builtin (void *data, struct t_gui_buffer *buffer,
}
/*
+ * command_filter: manage message filters
+ */
+
+int
+command_filter (void *data, struct t_gui_buffer *buffer,
+ int argc, char **argv, char **argv_eol)
+{
+ struct t_gui_filter *ptr_filter;
+ int i;
+ long number;
+ char *error;
+
+ /* make C compiler happy */
+ (void) data;
+ (void) buffer;
+
+ if ((argc == 1)
+ || ((argc == 2) && (string_strcasecmp (argv[1], "list") == 0)))
+ {
+ /* display all key bindings */
+ gui_chat_printf (NULL, "");
+ gui_chat_printf (NULL, "%s",
+ (gui_filters_enabled) ?
+ _("Filters are enabled") : _("Filters are disabled"));
+
+ if (gui_filters)
+ {
+ gui_chat_printf (NULL, _("Message filters:"));
+ i = 0;
+ for (ptr_filter = gui_filters; ptr_filter;
+ ptr_filter = ptr_filter->next_filter)
+ {
+ i++;
+ gui_chat_printf (NULL,
+ _(" %s[%s%d%s]%s buffer: %s%s%s / tags: %s / "
+ "regex: %s"),
+ GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS),
+ GUI_COLOR(GUI_COLOR_CHAT),
+ i,
+ GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS),
+ GUI_COLOR(GUI_COLOR_CHAT),
+ GUI_COLOR(GUI_COLOR_CHAT_BUFFER),
+ ptr_filter->buffer,
+ GUI_COLOR(GUI_COLOR_CHAT),
+ ptr_filter->tags,
+ ptr_filter->regex);
+ }
+ }
+ else
+ gui_chat_printf (NULL, _("No message filter defined"));
+
+ return WEECHAT_RC_OK;
+ }
+
+ /* enable filters */
+ if (string_strcasecmp (argv[1], "enable") == 0)
+ {
+ if (!gui_filters_enabled)
+ {
+ gui_filter_enable ();
+ gui_chat_printf (NULL, _("Filters enabled"));
+ }
+ return WEECHAT_RC_OK;
+ }
+
+ /* disable filters */
+ if (string_strcasecmp (argv[1], "disable") == 0)
+ {
+ if (gui_filters_enabled)
+ {
+ gui_filter_disable ();
+ gui_chat_printf (NULL, _("Filters disabled"));
+ }
+ return WEECHAT_RC_OK;
+ }
+
+ /* toggle filters on/off */
+ if (string_strcasecmp (argv[1], "toggle") == 0)
+ {
+ if (gui_filters_enabled)
+ gui_filter_disable ();
+ else
+ gui_filter_enable ();
+ return WEECHAT_RC_OK;
+ }
+
+ /* add filter */
+ if (string_strcasecmp (argv[1], "add") == 0)
+ {
+ if (argc < 5)
+ {
+ gui_chat_printf (NULL,
+ _("%sError: missing arguments for \"%s\" "
+ "command"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ "filter add");
+ return WEECHAT_RC_ERROR;
+ }
+ if (gui_filter_search (argv[2], argv[3], argv_eol[4]))
+ {
+ gui_chat_printf (NULL,
+ _("%sError: filter already exists"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]);
+ return WEECHAT_RC_ERROR;
+ }
+ if ((strcmp (argv[3], "*") == 0) && (strcmp (argv_eol[4], "*") == 0))
+ {
+ gui_chat_printf (NULL,
+ _("%sError: you must specify at least tag(s) or "
+ "regex for filter"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]);
+ return WEECHAT_RC_ERROR;
+ }
+
+ gui_filter_new (argv[2], argv[3], argv_eol[4]);
+ gui_chat_printf (NULL, _("Filter added"));
+
+ return WEECHAT_RC_OK;
+ }
+
+ /* delete filter */
+ if (string_strcasecmp (argv[1], "del") == 0)
+ {
+ if (argc < 3)
+ {
+ gui_chat_printf (NULL,
+ _("%sError: missing arguments for \"%s\" "
+ "command"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ "filter del");
+ return WEECHAT_RC_ERROR;
+ }
+ error = NULL;
+ number = strtol (argv[2], &error, 10);
+ if (error && !error[0])
+ {
+ ptr_filter = gui_filter_search_by_number (number);
+ if (ptr_filter)
+ {
+ gui_filter_free (ptr_filter);
+ gui_chat_printf (NULL, _("Filter deleted"));
+ }
+ else
+ {
+ gui_chat_printf (NULL,
+ _("%sError: filter not found"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]);
+ return WEECHAT_RC_ERROR;
+ }
+ }
+ else
+ {
+ gui_chat_printf (NULL,
+ _("%sError: wrong filter number"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]);
+ return WEECHAT_RC_ERROR;
+ }
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
* command_help: display help about commands
*/
@@ -1948,7 +2112,7 @@ command_window (void *data, struct t_gui_buffer *buffer,
{
error = NULL;
number = strtol (argv[2], &error, 10);
- if (error && (error[0] == '\0')
+ if (error && !error[0]
&& (number > 0) && (number < 100))
gui_window_split_horiz (gui_current_window, number);
}
@@ -1962,7 +2126,7 @@ command_window (void *data, struct t_gui_buffer *buffer,
{
error = NULL;
number = strtol (argv[2], &error, 10);
- if (error && (error[0] == '\0')
+ if (error && !error[0]
&& (number > 0) && (number < 100))
gui_window_split_vertic (gui_current_window, number);
}
@@ -1976,7 +2140,7 @@ command_window (void *data, struct t_gui_buffer *buffer,
{
error = NULL;
number = strtol (argv[2], &error, 10);
- if (error && (error[0] == '\0')
+ if (error && !error[0]
&& (number > 0) && (number < 100))
gui_window_resize (gui_current_window, number);
}
@@ -2016,7 +2180,7 @@ command_window (void *data, struct t_gui_buffer *buffer,
/* jump to window by buffer number */
error = NULL;
number = strtol (argv[1] + 1, &error, 10);
- if (error && (error[0] == '\0'))
+ if (error && !error[0])
gui_window_switch_by_buffer (gui_current_window, number);
}
else if (string_strcasecmp (argv[1], "-1") == 0)
@@ -2117,6 +2281,29 @@ command_init ()
"added if not found at beginning of command)"),
"%w",
&command_builtin, NULL);
+ hook_command (NULL, "filter",
+ N_("filter messages in buffers, to hide/show them according "
+ "to tags or regex"),
+ N_("[list] | [enable|disable|toggle] | "
+ "[add buffer tags regex] | "
+ "[del number]"),
+ N_(" list: list all filters\n"
+ " enable: enable filters (filters are enabled by "
+ "default)\n"
+ "disable: disable filters\n"
+ " toggle: toggle filters\n"
+ " add: add a filter\n"
+ " del: delete a filter\n"
+ " number: number of filter to delete (look at list to "
+ "find it)\n"
+ " buffer: buffer where filter is active: it may be "
+ "a name (category.name) or \"*\" for all buffers\n"
+ " tags: comma separated list of tags, for "
+ "example: \"irc_join,irc_part,irc_quit\"\n"
+ " regex: regular expression to search in "
+ "line (use \t to separate prefix from message)"),
+ "list|enable|disable|toggle|add|del",
+ &command_filter, NULL);
hook_command (NULL, "help",
N_("display help about commands"),
N_("[command]"),
diff --git a/src/core/wee-config-file.c b/src/core/wee-config-file.c
index d8dc5317d..2a932b2bf 100644
--- a/src/core/wee-config-file.c
+++ b/src/core/wee-config-file.c
@@ -323,7 +323,7 @@ config_file_new_option (struct t_config_file *config_file,
new_option->max = max;
error = NULL;
number = strtol (default_value, &error, 10);
- if (!error || (error[0] != '\0'))
+ if (!error || error[0])
number = 0;
new_option->default_value = malloc (sizeof (int));
*((int *)new_option->default_value) = number;
@@ -337,7 +337,7 @@ config_file_new_option (struct t_config_file *config_file,
new_option->max = max;
new_option->default_value = (default_value) ?
strdup (default_value) : NULL;
- new_option->value = strdup (default_value) ?
+ new_option->value = (default_value) ?
strdup (default_value) : NULL;
break;
case CONFIG_OPTION_COLOR:
@@ -558,7 +558,7 @@ config_file_option_set (struct t_config_option *option, char *new_value,
{
error = NULL;
number = strtol (new_value, &error, 10);
- if (error && (error[0] == '\0'))
+ if (error && !error[0])
{
if (number == *((int *)option->value))
return 1;
@@ -867,7 +867,8 @@ config_file_write_internal (struct t_config_file *config_file,
snprintf (filename2, filename_length + 32, "%s.weechattmp", filename);
/* open temp file in write mode */
- if ((config_file->file = fopen (filename2, "w")) == NULL)
+ config_file->file = fopen (filename2, "w");
+ if (!config_file->file)
{
gui_chat_printf (NULL,
_("%sError: cannot create file \"%s\""),
@@ -976,10 +977,12 @@ config_file_read (struct t_config_file *config_file)
return -2;
snprintf (filename, filename_length, "%s%s%s",
weechat_home, DIR_SEPARATOR, config_file->filename);
- if ((config_file->file = fopen (filename, "r")) == NULL)
+ config_file->file = fopen (filename, "r");
+ if (!config_file->file)
{
config_file_write_internal (config_file, 1);
- if ((config_file->file = fopen (filename, "r")) == NULL)
+ config_file->file = fopen (filename, "r");
+ if (!config_file->file)
{
gui_chat_printf (NULL,
_("%sWarning: config file \"%s\" not found"),
@@ -1018,7 +1021,7 @@ config_file_read (struct t_config_file *config_file)
if (ptr_line[0] == '[')
{
pos = strchr (line, ']');
- if (pos == NULL)
+ if (!pos)
{
gui_chat_printf (NULL,
_("%sWarning: %s, line %d: invalid "
@@ -1054,8 +1057,8 @@ config_file_read (struct t_config_file *config_file)
}
else
{
- pos = strchr (line, '=');
- if (pos == NULL)
+ pos = strstr (line, " = ");
+ if (!pos)
{
gui_chat_printf (NULL,
_("%sWarning: %s, line %d: invalid "
@@ -1066,10 +1069,10 @@ config_file_read (struct t_config_file *config_file)
else
{
pos[0] = '\0';
- pos++;
+ pos += 3;
/* remove spaces before '=' */
- pos2 = pos - 2;
+ pos2 = pos - 4;
while ((pos2 > line) && (pos2[0] == ' '))
{
pos2[0] = '\0';
@@ -1237,6 +1240,25 @@ config_file_reload (struct t_config_file *config_file)
}
/*
+ * config_file_option_free: free data in an option
+ */
+
+void
+config_file_option_free_data (struct t_config_option *option)
+{
+ if (option->name)
+ free (option->name);
+ if (option->description)
+ free (option->description);
+ if (option->string_values)
+ string_free_exploded (option->string_values);
+ if (option->default_value)
+ free (option->default_value);
+ if (option->value)
+ free (option->value);
+}
+
+/*
* config_file_option_free: free an option
*/
@@ -1264,16 +1286,9 @@ config_file_option_free (struct t_config_section *section,
(option->next_option)->prev_option = option->prev_option;
/* free data */
- if (option->name)
- free (option->name);
- if (option->description)
- free (option->description);
- if (option->string_values)
- string_free_exploded (option->string_values);
- if (option->default_value)
- free (option->default_value);
- if (option->value)
- free (option->value);
+ config_file_option_free_data (option);
+
+ free (option);
section->options = new_options;
}
@@ -1313,6 +1328,8 @@ config_file_section_free (struct t_config_file *config_file,
if (section->name)
free (section->name);
+ free (section);
+
config_file->sections = new_sections;
}
@@ -1350,6 +1367,8 @@ config_file_free (struct t_config_file *config_file)
if (config_file->filename)
free (config_file->filename);
+ free (config_file);
+
config_files = new_config_files;
}
diff --git a/src/core/wee-config-file.h b/src/core/wee-config-file.h
index df21e2909..0b65f53f3 100644
--- a/src/core/wee-config-file.h
+++ b/src/core/wee-config-file.h
@@ -156,6 +156,7 @@ extern void config_file_write_line (struct t_config_file *config_file,
extern int config_file_write (struct t_config_file *config_files);
extern int config_file_read (struct t_config_file *config_file);
extern int config_file_reload (struct t_config_file *config_file);
+extern void config_file_option_free_data (struct t_config_option *option);
extern void config_file_option_free (struct t_config_section *section,
struct t_config_option *option);
extern void config_file_section_free (struct t_config_file *config_file,
diff --git a/src/core/wee-config.c b/src/core/wee-config.c
index a7364d253..a6abd624c 100644
--- a/src/core/wee-config.c
+++ b/src/core/wee-config.c
@@ -45,6 +45,7 @@
#include "../gui/gui-buffer.h"
#include "../gui/gui-chat.h"
#include "../gui/gui-color.h"
+#include "../gui/gui-filter.h"
#include "../gui/gui-hotlist.h"
#include "../gui/gui-infobar.h"
#include "../gui/gui-keyboard.h"
@@ -434,6 +435,12 @@ config_weechat_reload (void *data, struct t_config_file *config_file)
/* remove all keys */
gui_keyboard_free_all ();
+ /* remove all bars */
+ gui_bar_free_all ();
+
+ /* remove all filters */
+ gui_filter_free_all ();
+
return config_file_reload (weechat_config_file);
}
@@ -458,17 +465,21 @@ config_weechat_read_bar (void *data, struct t_config_file *config_file,
if (value && value[0])
{
argv = string_explode (value, ";", 0, 0, &argc);
- if (argc == 5)
+ if (argv)
{
- error = NULL;
- number = strtol (argv[2], &error, 10);
- if (error && (error[0] == '\0'))
+ if (argc == 5)
{
- size = number;
- gui_bar_new (NULL, option_name, argv[0], argv[1], size,
- (argv[3][0] == '0') ? 0 : 1,
- argv[4]);
+ error = NULL;
+ number = strtol (argv[2], &error, 10);
+ if (error && !error[0])
+ {
+ size = number;
+ gui_bar_new (NULL, option_name, argv[0], argv[1], size,
+ (argv[3][0] == '0') ? 0 : 1,
+ argv[4]);
+ }
}
+ string_free_exploded (argv);
}
}
}
@@ -505,6 +516,68 @@ config_weechat_write_bars (void *data, struct t_config_file *config_file,
}
/*
+ * config_weechat_read_filter: read a filter in configuration file
+ */
+
+void
+config_weechat_read_filter (void *data, struct t_config_file *config_file,
+ char *option_name, char *value)
+{
+ char **argv, **argv_eol;
+ int argc;
+
+ /* make C compiler happy */
+ (void) data;
+ (void) config_file;
+
+ if (option_name)
+ {
+ if (value && value[0])
+ {
+ argv = string_explode (value, ";", 0, 0, &argc);
+ argv_eol = string_explode (value, ";", 1, 0, NULL);
+ if (argv && argv_eol && (argc >= 3))
+ {
+ gui_filter_new (argv[0], argv[1], argv_eol[2]);
+ }
+ if (argv)
+ string_free_exploded (argv);
+ if (argv_eol)
+ string_free_exploded (argv_eol);
+ }
+ }
+}
+
+/*
+ * config_weechat_write_filters: write filters section in configuration file
+ * Return: 0 = successful
+ * -1 = write error
+ */
+
+void
+config_weechat_write_filters (void *data, struct t_config_file *config_file,
+ char *section_name)
+{
+ struct t_gui_filter *ptr_filter;
+
+ /* make C compiler happy */
+ (void) data;
+
+ config_file_write_line (config_file, section_name, NULL);
+
+ for (ptr_filter = gui_filters; ptr_filter;
+ ptr_filter = ptr_filter->next_filter)
+ {
+ config_file_write_line (config_file,
+ "filter",
+ "%s;%s;%s",
+ ptr_filter->buffer,
+ ptr_filter->tags,
+ ptr_filter->regex);
+ }
+}
+
+/*
* config_weechat_read_key: read a key in configuration file
*/
@@ -1398,6 +1471,20 @@ config_weechat_init ()
return 0;
}
+ /* filters */
+ ptr_section = config_file_new_section (weechat_config_file, "filters",
+ &config_weechat_read_filter,
+ NULL,
+ &config_weechat_write_filters,
+ NULL,
+ &config_weechat_write_filters,
+ NULL);
+ if (!ptr_section)
+ {
+ config_file_free (weechat_config_file);
+ return 0;
+ }
+
/* keys */
ptr_section = config_file_new_section (weechat_config_file, "keys",
&config_weechat_read_key,
diff --git a/src/core/wee-debug.c b/src/core/wee-debug.c
index e886021a3..746d73c8e 100644
--- a/src/core/wee-debug.c
+++ b/src/core/wee-debug.c
@@ -35,6 +35,7 @@
#include "../gui/gui-bar-item.h"
#include "../gui/gui-buffer.h"
#include "../gui/gui-chat.h"
+#include "../gui/gui-filter.h"
#include "../gui/gui-hotlist.h"
#include "../gui/gui-main.h"
#include "../gui/gui-window.h"
@@ -75,6 +76,7 @@ debug_dump (int crash)
gui_window_print_log ();
gui_buffer_print_log ();
+ gui_filter_print_log ();
gui_bar_print_log ();
gui_bar_item_print_log ();
gui_hotlist_print_log ();
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c
index fe57e98c2..4816ff2fc 100644
--- a/src/core/wee-hook.c
+++ b/src/core/wee-hook.c
@@ -718,7 +718,7 @@ hook_fd_exec (fd_set *read_fds, fd_set *write_fds, fd_set *exception_fds)
&& (FD_ISSET(HOOK_FD(ptr_hook, fd), exception_fds)))))
{
ptr_hook->running = 1;
- (HOOK_FD(ptr_hook, callback)) (ptr_hook->callback_data);
+ (void) (HOOK_FD(ptr_hook, callback)) (ptr_hook->callback_data);
ptr_hook->running = 0;
}
@@ -734,8 +734,8 @@ hook_fd_exec (fd_set *read_fds, fd_set *write_fds, fd_set *exception_fds)
struct t_hook *
hook_print (struct t_weechat_plugin *plugin, struct t_gui_buffer *buffer,
- char *message, int strip_colors, t_hook_callback_print *callback,
- void *callback_data)
+ char *tags, char *message, int strip_colors,
+ t_hook_callback_print *callback, void *callback_data)
{
struct t_hook *new_hook;
struct t_hook_print *new_hook_print;
@@ -755,6 +755,16 @@ hook_print (struct t_weechat_plugin *plugin, struct t_gui_buffer *buffer,
new_hook->hook_data = new_hook_print;
new_hook_print->callback = callback;
new_hook_print->buffer = buffer;
+ if (tags)
+ {
+ new_hook_print->tags_array = string_explode (tags, ",", 0, 0,
+ &new_hook_print->tags_count);
+ }
+ else
+ {
+ new_hook_print->tags_count = 0;
+ new_hook_print->tags_array = NULL;
+ }
new_hook_print->message = (message) ? strdup (message) : NULL;
new_hook_print->strip_colors = strip_colors;
@@ -768,11 +778,12 @@ hook_print (struct t_weechat_plugin *plugin, struct t_gui_buffer *buffer,
*/
void
-hook_print_exec (struct t_gui_buffer *buffer, time_t date, char *prefix,
- char *message)
+hook_print_exec (struct t_gui_buffer *buffer, time_t date, int tags_count,
+ char **tags_array, char *prefix, char *message)
{
struct t_hook *ptr_hook, *next_hook;
char *prefix_no_color, *message_no_color;
+ int tags_match, tag_found, i, j;
if (!message || !message[0])
return;
@@ -802,17 +813,59 @@ hook_print_exec (struct t_gui_buffer *buffer, time_t date, char *prefix,
|| string_strcasestr (prefix_no_color, HOOK_PRINT(ptr_hook, message))
|| string_strcasestr (message_no_color, HOOK_PRINT(ptr_hook, message))))
{
- ptr_hook->running = 1;
- (void) (HOOK_PRINT(ptr_hook, callback))
- (ptr_hook->callback_data, buffer, date,
- (HOOK_PRINT(ptr_hook, strip_colors)) ? prefix_no_color : prefix,
- (HOOK_PRINT(ptr_hook, strip_colors)) ? message_no_color : message);
- ptr_hook->running = 0;
+ /* check if tags match */
+ if (HOOK_PRINT(ptr_hook, tags_array))
+ {
+ /* if there are tags in message printed */
+ if (tags_array)
+ {
+ tags_match = 1;
+ for (i = 0; i < HOOK_PRINT(ptr_hook, tags_count); i++)
+ {
+ /* search for tag in message */
+ tag_found = 0;
+ for (j = 0; j < tags_count; j++)
+ {
+ if (string_strcasecmp (HOOK_PRINT(ptr_hook, tags_array)[i],
+ tags_array[j]) != 0)
+ {
+ tag_found = 1;
+ break;
+ }
+ }
+ /* tag was asked by hook but not found in message? */
+ if (!tag_found)
+ {
+ tags_match = 0;
+ break;
+ }
+ }
+ }
+ else
+ tags_match = 0;
+ }
+ else
+ tags_match = 1;
+
+ /* run callback */
+ if (tags_match)
+ {
+ ptr_hook->running = 1;
+ (void) (HOOK_PRINT(ptr_hook, callback))
+ (ptr_hook->callback_data, buffer, date,
+ tags_count, tags_array,
+ (HOOK_PRINT(ptr_hook, strip_colors)) ? prefix_no_color : prefix,
+ (HOOK_PRINT(ptr_hook, strip_colors)) ? message_no_color : message);
+ ptr_hook->running = 0;
+ }
}
ptr_hook = next_hook;
}
+ free (prefix_no_color);
+ free (message_no_color);
+
hook_exec_end ();
}
@@ -869,8 +922,7 @@ hook_signal_send (char *signal, char *type_data, void *signal_data)
if (!ptr_hook->deleted
&& !ptr_hook->running
- && ((string_strcasecmp (HOOK_SIGNAL(ptr_hook, signal), "*") == 0)
- || (string_strcasecmp (HOOK_SIGNAL(ptr_hook, signal), signal) == 0)))
+ && (string_match (signal, HOOK_SIGNAL(ptr_hook, signal), 0)))
{
ptr_hook->running = 1;
(void) (HOOK_SIGNAL(ptr_hook, callback))
diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h
index 8cdb7946e..a287be2fa 100644
--- a/src/core/wee-hook.h
+++ b/src/core/wee-hook.h
@@ -104,12 +104,16 @@ struct t_hook_fd
};
typedef int (t_hook_callback_print)(void *data, struct t_gui_buffer *buffer,
- time_t date, char *prefix, char *message);
+ time_t date, int tags_count,
+ char **tags, char *prefix,
+ char *message);
struct t_hook_print
{
t_hook_callback_print *callback; /* print callback */
struct t_gui_buffer *buffer; /* buffer selected (NULL = all) */
+ int tags_count; /* number of tags selected */
+ char **tags_array; /* tags selected (NULL = any) */
char *message; /* part of message (NULL/empty = all)*/
int strip_colors; /* strip colors in msg for callback? */
};
@@ -120,7 +124,8 @@ typedef int (t_hook_callback_signal)(void *data, char *signal,
struct t_hook_signal
{
t_hook_callback_signal *callback; /* signal callback */
- char *signal; /* signal selected ("*" = any signal)*/
+ char *signal; /* signal selected (may begin or end */
+ /* with "*", "*" == any signal) */
};
typedef int (t_hook_callback_config)(void *data, char *type, char *option,
@@ -190,11 +195,14 @@ extern void hook_fd_exec (fd_set *read_fds, fd_set *write_fds,
fd_set *exception_fds);
extern struct t_hook *hook_print (struct t_weechat_plugin *plugin,
struct t_gui_buffer *buffer,
- char *message, int strip_colors,
+ char *tags, char *message,
+ int strip_colors,
t_hook_callback_print *callback,
void *callback_data);
extern void hook_print_exec (struct t_gui_buffer *buffer,
- time_t date, char *prefix, char *message);
+ time_t date, int tags_count,
+ char **tags_array, char *prefix,
+ char *message);
extern struct t_hook *hook_signal (struct t_weechat_plugin *plugin,
char *signal,
t_hook_callback_signal *callback,
diff --git a/src/core/wee-input.c b/src/core/wee-input.c
index ed1c34587..e0f18cf3a 100644
--- a/src/core/wee-input.c
+++ b/src/core/wee-input.c
@@ -111,10 +111,6 @@ input_exec_command (struct t_gui_buffer *buffer, char *string,
switch (rc)
{
case 0: /* command hooked, KO */
- gui_chat_printf (NULL,
- _("%sError: command \"%s\" failed"),
- gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
- command + 1);
break;
case 1: /* command hooked, OK (executed) */
break;
diff --git a/src/core/wee-string.c b/src/core/wee-string.c
index 827fad7ce..3fc7f9866 100644
--- a/src/core/wee-string.c
+++ b/src/core/wee-string.c
@@ -244,6 +244,90 @@ string_strcasestr (char *string, char *search)
}
/*
+ * string_match: return 1 if string matches a mask
+ * mask can begin or end with "*", no other "*" are allowed
+ * inside mask
+ */
+
+int
+string_match (char *string, char *mask, int case_sensitive)
+{
+ char last, *mask2;
+ int len_string, len_mask, rc;
+
+ if (!mask || !mask[0])
+ return 0;
+
+ /* if mask is "*", then any string matches */
+ if (strcmp (mask, "*") == 0)
+ return 1;
+
+ len_string = strlen (string);
+ len_mask = strlen (mask);
+
+ last = mask[len_mask - 1];
+
+ /* mask begins with "*" */
+ if ((mask[0] == '*') && (last != '*'))
+ {
+ /* not enough chars in string to match */
+ if (len_string < len_mask - 1)
+ return 0;
+ /* check if end of string matches */
+ if ((case_sensitive && (strcmp (string + len_string - (len_mask - 1),
+ mask + 1) == 0))
+ || (!case_sensitive && (string_strcasecmp (string + len_string - (len_mask - 1),
+ mask + 1) == 0)))
+ return 1;
+ /* no match */
+ return 0;
+ }
+
+ /* mask ends with "*" */
+ if ((mask[0] != '*') && (last == '*'))
+ {
+ /* not enough chars in string to match */
+ if (len_string < len_mask - 1)
+ return 0;
+ /* check if beginning of string matches */
+ if ((case_sensitive && (strncmp (string, mask, len_mask - 1) == 0))
+ || (!case_sensitive && (string_strncasecmp (string,
+ mask,
+ len_mask - 1) == 0)))
+ return 1;
+ /* no match */
+ return 0;
+ }
+
+ /* mask begins and ends with "*" */
+ if ((mask[0] == '*') && (last == '*'))
+ {
+ /* not enough chars in string to match */
+ if (len_string < len_mask - 1)
+ return 0;
+ /* keep only relevant chars in mask for searching string */
+ mask2 = string_strndup (mask + 1, len_mask - 2);
+ if (!mask2)
+ return 0;
+ /* search string */
+ rc = ((case_sensitive && strstr (string, mask2))
+ || (!case_sensitive && string_strcasestr (string, mask2))) ?
+ 1 : 0;
+ /* free and return */
+ free (mask2);
+ return rc;
+ }
+
+ /* no "*" at all, compare strings */
+ if ((case_sensitive && (strcmp (string, mask) == 0))
+ || (!case_sensitive && (string_strcasecmp (string, mask) == 0)))
+ return 1;
+
+ /* no match */
+ return 0;
+}
+
+/*
* string_replace: replace a string by new one in a string
* note: returned value has to be free() after use
*/
@@ -417,7 +501,7 @@ string_convert_hex_chars (char *string)
snprintf (hex_str, sizeof (hex_str),
"0x%c%c", string[1], string[2]);
number = strtol (hex_str, &error, 16);
- if (error && (error[0] == '\0'))
+ if (error && !error[0])
{
output[pos_output++] = number;
string += 3;
@@ -550,7 +634,7 @@ string_explode (char *string, char *separators, int keep_eol,
{
array[i] =
(char *)malloc ((ptr2 - ptr1 + 1) * sizeof (char));
- array[i] = strncpy (array[i], ptr1, ptr2 - ptr1);
+ strncpy (array[i], ptr1, ptr2 - ptr1);
array[i][ptr2 - ptr1] = '\0';
}
ptr1 = ++ptr2;
@@ -566,6 +650,8 @@ string_explode (char *string, char *separators, int keep_eol,
if (num_items != NULL)
*num_items = i;
+ free (string2);
+
return array;
}
@@ -587,6 +673,41 @@ string_free_exploded (char **exploded_string)
}
/*
+ * string_build_with_exploded: build a string with exploded string
+ * note: returned value has to be free() after use
+ */
+
+char *
+string_build_with_exploded (char **exploded_string, char *separator)
+{
+ int i, length, length_separator;
+ char *result;
+
+ if (!exploded_string || !separator)
+ return NULL;
+
+ length = 0;
+ length_separator = strlen (separator);
+
+ for (i = 0; exploded_string[i]; i++)
+ {
+ length += strlen (exploded_string[i]) + length_separator;
+ }
+
+ result = (char *)malloc ((length + 1) * sizeof (char));
+ result[0] = '\0';
+
+ for (i = 0; exploded_string[i]; i++)
+ {
+ strcat (result, exploded_string[i]);
+ if (exploded_string[i + 1])
+ strcat (result, separator);
+ }
+
+ return result;
+}
+
+/*
* string_split_command: split a list of commands separated by 'sep'
* and ecscaped with '\'
* - empty commands are removed
diff --git a/src/core/wee-string.h b/src/core/wee-string.h
index 8c7901302..a66ad12a1 100644
--- a/src/core/wee-string.h
+++ b/src/core/wee-string.h
@@ -28,6 +28,7 @@ extern int string_strncasecmp (char *string1, char *string2, int max);
extern int string_strcmp_ignore_chars (char *string1, char *string2,
char *chars_ignored, int case_sensitive);
extern char *string_strcasestr (char *string, char *search);
+extern int string_match (char *string, char *mask, int case_sensitive);
extern char *string_replace (char *string, char *search, char *replace);
extern char *string_remove_quotes (char *string, char *quotes);
extern char *string_strip (char *string, int left, int right, char *chars);
@@ -35,6 +36,8 @@ extern char *string_convert_hex_chars (char *string);
extern char **string_explode (char *string, char *separators, int keep_eol,
int num_items_max, int *num_items);
extern void string_free_exploded (char **exploded_string);
+extern char *string_build_with_exploded (char **exploded_string,
+ char *separator);
extern char **string_split_command (char *command, char separator);
extern void string_free_splitted_command (char **splitted_command);
extern char *string_iconv (int from_utf8, char *from_code, char *to_code,
diff --git a/src/core/wee-util.c b/src/core/wee-util.c
index dec328343..e61a07eeb 100644
--- a/src/core/wee-util.c
+++ b/src/core/wee-util.c
@@ -174,6 +174,7 @@ util_exec_on_files (char *directory, void *data,
DIR *dir;
struct dirent *entry;
struct stat statbuf;
+ int rc;
if (!directory || !callback)
return;
@@ -188,7 +189,7 @@ util_exec_on_files (char *directory, void *data,
lstat (complete_filename, &statbuf);
if (!S_ISDIR(statbuf.st_mode))
{
- (int) (*callback) (data, complete_filename);
+ rc = (*callback) (data, complete_filename);
}
}
closedir (dir);
diff --git a/src/core/weechat.c b/src/core/weechat.c
index 3dd42e587..3f192968d 100644
--- a/src/core/weechat.c
+++ b/src/core/weechat.c
@@ -524,11 +524,15 @@ main (int argc, char *argv[])
command_startup (0); /* command executed before plugins */
plugin_init (auto_load_plugins); /* init plugin interface(s) */
command_startup (1); /* command executed after plugins */
+
gui_main_loop (); /* WeeChat main loop */
+
plugin_end (); /* end plugin interface(s) */
if (CONFIG_BOOLEAN(config_look_save_on_exit))
(void) config_weechat_write (NULL); /* save WeeChat config file */
gui_main_end (); /* shut down WeeChat GUI */
+ config_file_free_all (); /* free all configuration files */
+ gui_keyboard_end (); /* end keyboard */
unhook_all (); /* remove all hooks */
weechat_shutdown (EXIT_SUCCESS, 0); /* quit WeeChat (oh no, why?) */