mirror of
https://github.com/weechat/weechat.git
synced 2026-07-09 03:03:12 +02:00
Added tags for lines and custom filtering by tags or regex (task #7674), fixed many memory leaks
This commit is contained in:
+199
-12
@@ -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
|
||||
@@ -538,6 +539,169 @@ command_builtin (void *data, struct t_gui_buffer *buffer,
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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]"),
|
||||
|
||||
+40
-21
@@ -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';
|
||||
@@ -1236,6 +1239,25 @@ config_file_reload (struct t_config_file *config_file)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
+95
-8
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -504,6 +515,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,
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
+65
-13
@@ -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))
|
||||
|
||||
+12
-4
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
+123
-2
@@ -243,6 +243,90 @@ string_strcasestr (char *string, char *search)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
@@ -586,6 +672,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 '\'
|
||||
|
||||
@@ -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,
|
||||
|
||||
+2
-1
@@ -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);
|
||||
|
||||
@@ -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?) */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user