diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2008-03-22 23:36:12 +0100 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2008-03-22 23:36:12 +0100 |
commit | 61ca92972886cd7a9bc301ae7e23d6dde74920bc (patch) | |
tree | 7b69905a86b095f4fe6dffaa5a86ae6a0725c125 /src/core | |
parent | 8c4dc57d8e5a6b1f9f239bdcbf30dd07480993be (diff) | |
download | weechat-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.c | 211 | ||||
-rw-r--r-- | src/core/wee-config-file.c | 61 | ||||
-rw-r--r-- | src/core/wee-config-file.h | 1 | ||||
-rw-r--r-- | src/core/wee-config.c | 103 | ||||
-rw-r--r-- | src/core/wee-debug.c | 2 | ||||
-rw-r--r-- | src/core/wee-hook.c | 78 | ||||
-rw-r--r-- | src/core/wee-hook.h | 16 | ||||
-rw-r--r-- | src/core/wee-input.c | 4 | ||||
-rw-r--r-- | src/core/wee-string.c | 125 | ||||
-rw-r--r-- | src/core/wee-string.h | 3 | ||||
-rw-r--r-- | src/core/wee-util.c | 3 | ||||
-rw-r--r-- | src/core/weechat.c | 4 |
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?) */ |