diff options
Diffstat (limited to 'src')
30 files changed, 2317 insertions, 1107 deletions
diff --git a/src/core/wee-hashtable.h b/src/core/wee-hashtable.h index b611a51a9..bc497bbf3 100644 --- a/src/core/wee-hashtable.h +++ b/src/core/wee-hashtable.h @@ -24,6 +24,34 @@ struct t_hashtable; struct t_infolist; struct t_infolist_item; +/* + * Macros to set various values as string value in the hashtable; + * variable hashtable must be defined and str_value must be a static + * area where the value as string will be put (the size must be large enough + * for any value stored with these macros). + */ +#define HASHTABLE_SET_STR(__name, __string) \ + hashtable_set (hashtable, __name, __string); +#define HASHTABLE_SET_STR_NOT_NULL(__name, __string) \ + hashtable_set (hashtable, __name, (__string) ? __string : ""); +#define HASHTABLE_SET_INT(__name, __int) \ + snprintf (str_value, sizeof (str_value), "%d", __int); \ + hashtable_set (hashtable, __name, str_value); +#define HASHTABLE_SET_TIME(__name, __time) \ + snprintf (str_value, sizeof (str_value), "%lld", (long long)__time); \ + hashtable_set (hashtable, __name, str_value); +#define HASHTABLE_SET_PTR(__name, __pointer) \ + if (__pointer) \ + { \ + snprintf (str_value, sizeof (str_value), \ + "0x%lx", (long unsigned int)__pointer); \ + hashtable_set (hashtable, __name, str_value); \ + } \ + else \ + { \ + hashtable_set (hashtable, __name, ""); \ + } + typedef unsigned long long (t_hashtable_hash_key)(struct t_hashtable *hashtable, const void *key); typedef int (t_hashtable_keycmp)(struct t_hashtable *hashtable, diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c index 66be9451a..e112c8549 100644 --- a/src/core/wee-hook.c +++ b/src/core/wee-hook.c @@ -65,8 +65,8 @@ char *hook_type_string[HOOK_NUM_TYPES] = -{ "command", "command_run", "timer", "fd", "process", "connect", "print", - "signal", "hsignal", "config", "completion", "modifier", +{ "command", "command_run", "timer", "fd", "process", "connect", "line", + "print", "signal", "hsignal", "config", "completion", "modifier", "info", "info_hashtable", "infolist", "hdata", "focus" }; struct t_hook *weechat_hooks[HOOK_NUM_TYPES]; /* list of hooks */ struct t_hook *last_weechat_hook[HOOK_NUM_TYPES]; /* last hook */ @@ -984,6 +984,9 @@ hook_command_run_exec (struct t_gui_buffer *buffer, const char *command) char *command2; const char *ptr_command; + if (!weechat_hooks[HOOK_TYPE_COMMAND_RUN]) + return WEECHAT_RC_OK; + ptr_command = command; command2 = NULL; @@ -1279,6 +1282,9 @@ hook_timer_exec () struct timeval tv_time; struct t_hook *ptr_hook, *next_hook; + if (!weechat_hooks[HOOK_TYPE_TIMER]) + return; + hook_timer_check_system_clock (); gettimeofday (&tv_time, NULL); @@ -1409,6 +1415,9 @@ hook_fd_exec () int i, num_fd, timeout, ready, found; struct t_hook *ptr_hook, *next_hook; + if (!weechat_hooks[HOOK_TYPE_FD]) + return; + /* build an array of "struct pollfd" for poll() */ num_fd = 0; for (ptr_hook = weechat_hooks[HOOK_TYPE_FD]; ptr_hook; @@ -2405,6 +2414,146 @@ hook_connect_gnutls_set_certificates (gnutls_session_t tls_session, #endif /* HAVE_GNUTLS */ /* + * Hooks a line added in a buffer. + * + * Returns pointer to new hook, NULL if error. + */ + +struct t_hook * +hook_line (struct t_weechat_plugin *plugin, const char *buffer_type, + const char *buffer_name, const char *tags, + t_hook_callback_line *callback, const void *callback_pointer, + void *callback_data) +{ + struct t_hook *new_hook; + struct t_hook_line *new_hook_line; + + if (!callback) + return NULL; + + new_hook = malloc (sizeof (*new_hook)); + if (!new_hook) + return NULL; + new_hook_line = malloc (sizeof (*new_hook_line)); + if (!new_hook_line) + { + free (new_hook); + return NULL; + } + + hook_init_data (new_hook, plugin, HOOK_TYPE_LINE, HOOK_PRIORITY_DEFAULT, + callback_pointer, callback_data); + + new_hook->hook_data = new_hook_line; + new_hook_line->callback = callback; + if (!buffer_type || !buffer_type[0]) + new_hook_line->buffer_type = GUI_BUFFER_TYPE_FORMATTED; + else if (strcmp (buffer_type, "*") == 0) + new_hook_line->buffer_type = -1; + else + new_hook_line->buffer_type = gui_buffer_search_type (buffer_type); + new_hook_line->buffers = string_split ( + (buffer_name && buffer_name[0]) ? buffer_name : "*", + ",", 0, 0, &new_hook_line->num_buffers); + new_hook_line->tags_array = string_split_tags (tags, + &new_hook_line->tags_count); + + hook_add_to_list (new_hook); + + return new_hook; +} + +/* + * Executes a line hook and updates the line data. + */ + +void +hook_line_exec (struct t_gui_line *line) +{ + struct t_hook *ptr_hook, *next_hook; + struct t_hashtable *hashtable, *hashtable2; + char str_value[128], *str_tags; + + if (!weechat_hooks[HOOK_TYPE_LINE]) + return; + + hashtable = NULL; + + hook_exec_start (); + + ptr_hook = weechat_hooks[HOOK_TYPE_LINE]; + while (ptr_hook) + { + next_hook = ptr_hook->next_hook; + + if (!ptr_hook->deleted && !ptr_hook->running + && ((HOOK_LINE(ptr_hook, buffer_type) == -1) + || ((int)(line->data->buffer->type) == (HOOK_LINE(ptr_hook, buffer_type)))) + && gui_buffer_match_list_split (line->data->buffer, + HOOK_LINE(ptr_hook, num_buffers), + HOOK_LINE(ptr_hook, buffers)) + && (!HOOK_LINE(ptr_hook, tags_array) + || gui_line_match_tags (line->data, + HOOK_LINE(ptr_hook, tags_count), + HOOK_LINE(ptr_hook, tags_array)))) + { + /* create the hashtable that will be sent to callback */ + if (!hashtable) + { + hashtable = hashtable_new (32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, NULL); + if (!hashtable) + break; + } + HASHTABLE_SET_PTR("buffer", line->data->buffer); + HASHTABLE_SET_PTR("buffer_name", line->data->buffer->full_name); + HASHTABLE_SET_PTR("buffer_type", + gui_buffer_type_string[line->data->buffer->type]); + HASHTABLE_SET_INT("y", line->data->y); + HASHTABLE_SET_TIME("date", line->data->date); + HASHTABLE_SET_TIME("date_printed", line->data->date_printed); + HASHTABLE_SET_STR_NOT_NULL("str_time", line->data->str_time); + HASHTABLE_SET_INT("tags_count", line->data->tags_count); + str_tags = string_build_with_split_string ( + (const char **)line->data->tags_array, ","); + HASHTABLE_SET_STR_NOT_NULL("tags", str_tags); + if (str_tags) + free (str_tags); + HASHTABLE_SET_INT("displayed", line->data->displayed); + HASHTABLE_SET_INT("notify_level", line->data->notify_level); + HASHTABLE_SET_INT("highlight", line->data->highlight); + HASHTABLE_SET_STR_NOT_NULL("prefix", line->data->prefix); + HASHTABLE_SET_STR_NOT_NULL("message", line->data->message); + + /* run callback */ + ptr_hook->running = 1; + hashtable2 = (HOOK_LINE(ptr_hook, callback)) + (ptr_hook->callback_pointer, + ptr_hook->callback_data, + hashtable); + ptr_hook->running = 0; + + if (hashtable2) + { + gui_line_hook_update (line, hashtable, hashtable2); + hashtable_free (hashtable2); + if (!line->data->buffer) + break; + } + } + + ptr_hook = next_hook; + } + + hook_exec_end (); + + if (hashtable) + hashtable_free (hashtable); +} + +/* * Hooks a message printed by WeeChat. * * Returns pointer to new hook, NULL if error. @@ -2459,6 +2608,9 @@ hook_print_exec (struct t_gui_buffer *buffer, struct t_gui_line *line) struct t_hook *ptr_hook, *next_hook; char *prefix_no_color, *message_no_color; + if (!weechat_hooks[HOOK_TYPE_PRINT]) + return; + if (!line->data->message || !line->data->message[0]) return; @@ -2487,26 +2639,25 @@ hook_print_exec (struct t_gui_buffer *buffer, struct t_gui_line *line) && (!HOOK_PRINT(ptr_hook, message) || !HOOK_PRINT(ptr_hook, message)[0] || string_strcasestr (prefix_no_color, HOOK_PRINT(ptr_hook, message)) - || string_strcasestr (message_no_color, HOOK_PRINT(ptr_hook, message)))) - { - /* check if tags match */ - if (!HOOK_PRINT(ptr_hook, tags_array) + || string_strcasestr (message_no_color, HOOK_PRINT(ptr_hook, message))) + && (!HOOK_PRINT(ptr_hook, tags_array) || gui_line_match_tags (line->data, HOOK_PRINT(ptr_hook, tags_count), - HOOK_PRINT(ptr_hook, tags_array))) - { - /* run callback */ - ptr_hook->running = 1; - (void) (HOOK_PRINT(ptr_hook, callback)) - (ptr_hook->callback_pointer, - ptr_hook->callback_data, buffer, line->data->date, - line->data->tags_count, - (const char **)line->data->tags_array, - (int)line->data->displayed, (int)line->data->highlight, - (HOOK_PRINT(ptr_hook, strip_colors)) ? prefix_no_color : line->data->prefix, - (HOOK_PRINT(ptr_hook, strip_colors)) ? message_no_color : line->data->message); - ptr_hook->running = 0; - } + HOOK_PRINT(ptr_hook, tags_array)))) + { + /* run callback */ + ptr_hook->running = 1; + (void) (HOOK_PRINT(ptr_hook, callback)) + (ptr_hook->callback_pointer, + ptr_hook->callback_data, + buffer, + line->data->date, + line->data->tags_count, + (const char **)line->data->tags_array, + (int)line->data->displayed, (int)line->data->highlight, + (HOOK_PRINT(ptr_hook, strip_colors)) ? prefix_no_color : line->data->prefix, + (HOOK_PRINT(ptr_hook, strip_colors)) ? message_no_color : line->data->message); + ptr_hook->running = 0; } ptr_hook = next_hook; @@ -2861,6 +3012,9 @@ hook_completion_exec (struct t_weechat_plugin *plugin, /* make C compiler happy */ (void) plugin; + if (!weechat_hooks[HOOK_TYPE_COMPLETION]) + return; + hook_exec_start (); pos = strchr (completion_item, ':'); @@ -3991,6 +4145,13 @@ unhook (struct t_hook *hook) } } break; + case HOOK_TYPE_LINE: + if (HOOK_LINE(hook, tags_array)) + { + string_free_split_tags (HOOK_LINE(hook, tags_array)); + HOOK_LINE(hook, tags_array) = NULL; + } + break; case HOOK_TYPE_PRINT: if (HOOK_PRINT(hook, tags_array)) { @@ -4251,349 +4412,318 @@ hook_add_to_infolist_pointer (struct t_infolist *infolist, struct t_hook *hook) return 0; if (!infolist_new_var_pointer (ptr_item, "callback_data", (void *)hook->callback_data)) return 0; + + /* hook deleted? return only hook info above */ + if (hook->deleted) + return 1; + + /* hook not deleted: add extra hook info */ switch (hook->type) { case HOOK_TYPE_COMMAND: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_COMMAND(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "command", HOOK_COMMAND(hook, command))) - return 0; - if (!infolist_new_var_string (ptr_item, "description", - HOOK_COMMAND(hook, description))) - return 0; - if (!infolist_new_var_string (ptr_item, "description_nls", - (HOOK_COMMAND(hook, description) - && HOOK_COMMAND(hook, description)[0]) ? - _(HOOK_COMMAND(hook, description)) : "")) - return 0; - if (!infolist_new_var_string (ptr_item, "args", - HOOK_COMMAND(hook, args))) - return 0; - if (!infolist_new_var_string (ptr_item, "args_nls", - (HOOK_COMMAND(hook, args) - && HOOK_COMMAND(hook, args)[0]) ? - _(HOOK_COMMAND(hook, args)) : "")) - return 0; - if (!infolist_new_var_string (ptr_item, "args_description", - HOOK_COMMAND(hook, args_description))) - return 0; - if (!infolist_new_var_string (ptr_item, "args_description_nls", - (HOOK_COMMAND(hook, args_description) - && HOOK_COMMAND(hook, args_description)[0]) ? - _(HOOK_COMMAND(hook, args_description)) : "")) - return 0; - if (!infolist_new_var_string (ptr_item, "completion", HOOK_COMMAND(hook, completion))) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_COMMAND(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "command", HOOK_COMMAND(hook, command))) + return 0; + if (!infolist_new_var_string (ptr_item, "description", + HOOK_COMMAND(hook, description))) + return 0; + if (!infolist_new_var_string (ptr_item, "description_nls", + (HOOK_COMMAND(hook, description) + && HOOK_COMMAND(hook, description)[0]) ? + _(HOOK_COMMAND(hook, description)) : "")) + return 0; + if (!infolist_new_var_string (ptr_item, "args", + HOOK_COMMAND(hook, args))) + return 0; + if (!infolist_new_var_string (ptr_item, "args_nls", + (HOOK_COMMAND(hook, args) + && HOOK_COMMAND(hook, args)[0]) ? + _(HOOK_COMMAND(hook, args)) : "")) + return 0; + if (!infolist_new_var_string (ptr_item, "args_description", + HOOK_COMMAND(hook, args_description))) + return 0; + if (!infolist_new_var_string (ptr_item, "args_description_nls", + (HOOK_COMMAND(hook, args_description) + && HOOK_COMMAND(hook, args_description)[0]) ? + _(HOOK_COMMAND(hook, args_description)) : "")) + return 0; + if (!infolist_new_var_string (ptr_item, "completion", HOOK_COMMAND(hook, completion))) + return 0; break; case HOOK_TYPE_COMMAND_RUN: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_COMMAND_RUN(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "command", HOOK_COMMAND_RUN(hook, command))) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_COMMAND_RUN(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "command", HOOK_COMMAND_RUN(hook, command))) + return 0; break; case HOOK_TYPE_TIMER: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_TIMER(hook, callback))) - return 0; - snprintf (value, sizeof (value), "%ld", HOOK_TIMER(hook, interval)); - if (!infolist_new_var_string (ptr_item, "interval", value)) - return 0; - if (!infolist_new_var_integer (ptr_item, "align_second", HOOK_TIMER(hook, align_second))) - return 0; - if (!infolist_new_var_integer (ptr_item, "remaining_calls", HOOK_TIMER(hook, remaining_calls))) - return 0; - if (!infolist_new_var_buffer (ptr_item, "last_exec", - &(HOOK_TIMER(hook, last_exec)), - sizeof (HOOK_TIMER(hook, last_exec)))) - return 0; - if (!infolist_new_var_buffer (ptr_item, "next_exec", - &(HOOK_TIMER(hook, next_exec)), - sizeof (HOOK_TIMER(hook, next_exec)))) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_TIMER(hook, callback))) + return 0; + snprintf (value, sizeof (value), "%ld", HOOK_TIMER(hook, interval)); + if (!infolist_new_var_string (ptr_item, "interval", value)) + return 0; + if (!infolist_new_var_integer (ptr_item, "align_second", HOOK_TIMER(hook, align_second))) + return 0; + if (!infolist_new_var_integer (ptr_item, "remaining_calls", HOOK_TIMER(hook, remaining_calls))) + return 0; + if (!infolist_new_var_buffer (ptr_item, "last_exec", + &(HOOK_TIMER(hook, last_exec)), + sizeof (HOOK_TIMER(hook, last_exec)))) + return 0; + if (!infolist_new_var_buffer (ptr_item, "next_exec", + &(HOOK_TIMER(hook, next_exec)), + sizeof (HOOK_TIMER(hook, next_exec)))) + return 0; break; case HOOK_TYPE_FD: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_FD(hook, callback))) - return 0; - if (!infolist_new_var_integer (ptr_item, "fd", HOOK_FD(hook, fd))) - return 0; - if (!infolist_new_var_integer (ptr_item, "flags", HOOK_FD(hook, flags))) - return 0; - if (!infolist_new_var_integer (ptr_item, "error", HOOK_FD(hook, error))) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_FD(hook, callback))) + return 0; + if (!infolist_new_var_integer (ptr_item, "fd", HOOK_FD(hook, fd))) + return 0; + if (!infolist_new_var_integer (ptr_item, "flags", HOOK_FD(hook, flags))) + return 0; + if (!infolist_new_var_integer (ptr_item, "error", HOOK_FD(hook, error))) + return 0; break; case HOOK_TYPE_PROCESS: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_PROCESS(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "command", HOOK_PROCESS(hook, command))) - return 0; - if (!infolist_new_var_string (ptr_item, "options", hashtable_get_string (HOOK_PROCESS(hook, options), "keys_values"))) - return 0; - if (!infolist_new_var_integer (ptr_item, "detached", HOOK_PROCESS(hook, detached))) - return 0; - if (!infolist_new_var_integer (ptr_item, "timeout", (int)(HOOK_PROCESS(hook, timeout)))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_read_stdin", HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDIN]))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_write_stdin", HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDIN]))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_read_stdout", HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDOUT]))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_write_stdout", HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDOUT]))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_read_stderr", HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDERR]))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_write_stderr", HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDERR]))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_pid", HOOK_PROCESS(hook, child_pid))) - return 0; - if (!infolist_new_var_pointer (ptr_item, "hook_fd_stdin", HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDIN]))) - return 0; - if (!infolist_new_var_pointer (ptr_item, "hook_fd_stdout", HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDOUT]))) - return 0; - if (!infolist_new_var_pointer (ptr_item, "hook_fd_stderr", HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDERR]))) - return 0; - if (!infolist_new_var_pointer (ptr_item, "hook_timer", HOOK_PROCESS(hook, hook_timer))) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_PROCESS(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "command", HOOK_PROCESS(hook, command))) + return 0; + if (!infolist_new_var_string (ptr_item, "options", hashtable_get_string (HOOK_PROCESS(hook, options), "keys_values"))) + return 0; + if (!infolist_new_var_integer (ptr_item, "detached", HOOK_PROCESS(hook, detached))) + return 0; + if (!infolist_new_var_integer (ptr_item, "timeout", (int)(HOOK_PROCESS(hook, timeout)))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_read_stdin", HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDIN]))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_write_stdin", HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDIN]))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_read_stdout", HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDOUT]))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_write_stdout", HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDOUT]))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_read_stderr", HOOK_PROCESS(hook, child_read[HOOK_PROCESS_STDERR]))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_write_stderr", HOOK_PROCESS(hook, child_write[HOOK_PROCESS_STDERR]))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_pid", HOOK_PROCESS(hook, child_pid))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "hook_fd_stdin", HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDIN]))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "hook_fd_stdout", HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDOUT]))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "hook_fd_stderr", HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDERR]))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "hook_timer", HOOK_PROCESS(hook, hook_timer))) + return 0; break; case HOOK_TYPE_CONNECT: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_CONNECT(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "address", HOOK_CONNECT(hook, address))) - return 0; - if (!infolist_new_var_integer (ptr_item, "port", HOOK_CONNECT(hook, port))) - return 0; - if (!infolist_new_var_integer (ptr_item, "sock", HOOK_CONNECT(hook, sock))) - return 0; - if (!infolist_new_var_integer (ptr_item, "ipv6", HOOK_CONNECT(hook, ipv6))) - return 0; - if (!infolist_new_var_integer (ptr_item, "retry", HOOK_CONNECT(hook, retry))) - return 0; + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_CONNECT(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "address", HOOK_CONNECT(hook, address))) + return 0; + if (!infolist_new_var_integer (ptr_item, "port", HOOK_CONNECT(hook, port))) + return 0; + if (!infolist_new_var_integer (ptr_item, "sock", HOOK_CONNECT(hook, sock))) + return 0; + if (!infolist_new_var_integer (ptr_item, "ipv6", HOOK_CONNECT(hook, ipv6))) + return 0; + if (!infolist_new_var_integer (ptr_item, "retry", HOOK_CONNECT(hook, retry))) + return 0; #ifdef HAVE_GNUTLS - if (!infolist_new_var_pointer (ptr_item, "gnutls_sess", HOOK_CONNECT(hook, gnutls_sess))) - return 0; - if (!infolist_new_var_pointer (ptr_item, "gnutls_cb", HOOK_CONNECT(hook, gnutls_cb))) - return 0; - if (!infolist_new_var_integer (ptr_item, "gnutls_dhkey_size", HOOK_CONNECT(hook, gnutls_dhkey_size))) - return 0; + if (!infolist_new_var_pointer (ptr_item, "gnutls_sess", HOOK_CONNECT(hook, gnutls_sess))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "gnutls_cb", HOOK_CONNECT(hook, gnutls_cb))) + return 0; + if (!infolist_new_var_integer (ptr_item, "gnutls_dhkey_size", HOOK_CONNECT(hook, gnutls_dhkey_size))) + return 0; #endif /* HAVE_GNUTLS */ - if (!infolist_new_var_string (ptr_item, "local_hostname", HOOK_CONNECT(hook, local_hostname))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_read", HOOK_CONNECT(hook, child_read))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_write", HOOK_CONNECT(hook, child_write))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_recv", HOOK_CONNECT(hook, child_recv))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_send", HOOK_CONNECT(hook, child_send))) - return 0; - if (!infolist_new_var_integer (ptr_item, "child_pid", HOOK_CONNECT(hook, child_pid))) - return 0; - if (!infolist_new_var_pointer (ptr_item, "hook_child_timer", HOOK_CONNECT(hook, hook_child_timer))) - return 0; - if (!infolist_new_var_pointer (ptr_item, "hook_fd", HOOK_CONNECT(hook, hook_fd))) - return 0; - if (!infolist_new_var_pointer (ptr_item, "handshake_hook_fd", HOOK_CONNECT(hook, handshake_hook_fd))) - return 0; - if (!infolist_new_var_pointer (ptr_item, "handshake_hook_timer", HOOK_CONNECT(hook, handshake_hook_timer))) - return 0; - if (!infolist_new_var_integer (ptr_item, "handshake_fd_flags", HOOK_CONNECT(hook, handshake_fd_flags))) - return 0; - if (!infolist_new_var_string (ptr_item, "handshake_ip_address", HOOK_CONNECT(hook, handshake_ip_address))) - return 0; - } + if (!infolist_new_var_string (ptr_item, "local_hostname", HOOK_CONNECT(hook, local_hostname))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_read", HOOK_CONNECT(hook, child_read))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_write", HOOK_CONNECT(hook, child_write))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_recv", HOOK_CONNECT(hook, child_recv))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_send", HOOK_CONNECT(hook, child_send))) + return 0; + if (!infolist_new_var_integer (ptr_item, "child_pid", HOOK_CONNECT(hook, child_pid))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "hook_child_timer", HOOK_CONNECT(hook, hook_child_timer))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "hook_fd", HOOK_CONNECT(hook, hook_fd))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "handshake_hook_fd", HOOK_CONNECT(hook, handshake_hook_fd))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "handshake_hook_timer", HOOK_CONNECT(hook, handshake_hook_timer))) + return 0; + if (!infolist_new_var_integer (ptr_item, "handshake_fd_flags", HOOK_CONNECT(hook, handshake_fd_flags))) + return 0; + if (!infolist_new_var_string (ptr_item, "handshake_ip_address", HOOK_CONNECT(hook, handshake_ip_address))) + return 0; + break; + case HOOK_TYPE_LINE: + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_LINE(hook, callback))) + return 0; + if (!infolist_new_var_integer (ptr_item, "buffer_type", HOOK_LINE(hook, buffer_type))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "buffers", HOOK_LINE(hook, buffers))) + return 0; + if (!infolist_new_var_integer (ptr_item, "num_buffers", HOOK_LINE(hook, num_buffers))) + return 0; + if (!infolist_new_var_integer (ptr_item, "tags_count", HOOK_LINE(hook, tags_count))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "tags_array", HOOK_LINE(hook, tags_array))) + return 0; break; case HOOK_TYPE_PRINT: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_PRINT(hook, callback))) - return 0; - if (!infolist_new_var_pointer (ptr_item, "buffer", HOOK_PRINT(hook, buffer))) - return 0; - if (!infolist_new_var_integer (ptr_item, "tags_count", HOOK_PRINT(hook, tags_count))) - return 0; - if (!infolist_new_var_pointer (ptr_item, "tags_array", HOOK_PRINT(hook, tags_array))) - return 0; - if (!infolist_new_var_string (ptr_item, "message", HOOK_PRINT(hook, message))) - return 0; - if (!infolist_new_var_integer (ptr_item, "strip_colors", HOOK_PRINT(hook, strip_colors))) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_PRINT(hook, callback))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "buffer", HOOK_PRINT(hook, buffer))) + return 0; + if (!infolist_new_var_integer (ptr_item, "tags_count", HOOK_PRINT(hook, tags_count))) + return 0; + if (!infolist_new_var_pointer (ptr_item, "tags_array", HOOK_PRINT(hook, tags_array))) + return 0; + if (!infolist_new_var_string (ptr_item, "message", HOOK_PRINT(hook, message))) + return 0; + if (!infolist_new_var_integer (ptr_item, "strip_colors", HOOK_PRINT(hook, strip_colors))) + return 0; break; case HOOK_TYPE_SIGNAL: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_SIGNAL(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "signal", HOOK_SIGNAL(hook, signal))) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_SIGNAL(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "signal", HOOK_SIGNAL(hook, signal))) + return 0; break; case HOOK_TYPE_HSIGNAL: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_HSIGNAL(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "signal", HOOK_HSIGNAL(hook, signal))) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_HSIGNAL(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "signal", HOOK_HSIGNAL(hook, signal))) + return 0; break; case HOOK_TYPE_CONFIG: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_CONFIG(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "option", HOOK_CONFIG(hook, option))) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_CONFIG(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "option", HOOK_CONFIG(hook, option))) + return 0; break; case HOOK_TYPE_COMPLETION: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_COMPLETION(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "completion_item", HOOK_COMPLETION(hook, completion_item))) - return 0; - if (!infolist_new_var_string (ptr_item, "description", HOOK_COMPLETION(hook, description))) - return 0; - if (!infolist_new_var_string (ptr_item, "description_nls", - (HOOK_COMPLETION(hook, description) - && HOOK_COMPLETION(hook, description)[0]) ? - _(HOOK_COMPLETION(hook, description)) : "")) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_COMPLETION(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "completion_item", HOOK_COMPLETION(hook, completion_item))) + return 0; + if (!infolist_new_var_string (ptr_item, "description", HOOK_COMPLETION(hook, description))) + return 0; + if (!infolist_new_var_string (ptr_item, "description_nls", + (HOOK_COMPLETION(hook, description) + && HOOK_COMPLETION(hook, description)[0]) ? + _(HOOK_COMPLETION(hook, description)) : "")) + return 0; break; case HOOK_TYPE_MODIFIER: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_MODIFIER(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "modifier", HOOK_MODIFIER(hook, modifier))) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_MODIFIER(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "modifier", HOOK_MODIFIER(hook, modifier))) + return 0; break; case HOOK_TYPE_INFO: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_INFO(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "info_name", HOOK_INFO(hook, info_name))) - return 0; - if (!infolist_new_var_string (ptr_item, "description", HOOK_INFO(hook, description))) - return 0; - if (!infolist_new_var_string (ptr_item, "description_nls", - (HOOK_INFO(hook, description) - && HOOK_INFO(hook, description)[0]) ? - _(HOOK_INFO(hook, description)) : "")) - return 0; - if (!infolist_new_var_string (ptr_item, "args_description", HOOK_INFO(hook, args_description))) - return 0; - if (!infolist_new_var_string (ptr_item, "args_description_nls", - (HOOK_INFO(hook, args_description) - && HOOK_INFO(hook, args_description)[0]) ? - _(HOOK_INFO(hook, args_description)) : "")) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_INFO(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "info_name", HOOK_INFO(hook, info_name))) + return 0; + if (!infolist_new_var_string (ptr_item, "description", HOOK_INFO(hook, description))) + return 0; + if (!infolist_new_var_string (ptr_item, "description_nls", + (HOOK_INFO(hook, description) + && HOOK_INFO(hook, description)[0]) ? + _(HOOK_INFO(hook, description)) : "")) + return 0; + if (!infolist_new_var_string (ptr_item, "args_description", HOOK_INFO(hook, args_description))) + return 0; + if (!infolist_new_var_string (ptr_item, "args_description_nls", + (HOOK_INFO(hook, args_description) + && HOOK_INFO(hook, args_description)[0]) ? + _(HOOK_INFO(hook, args_description)) : "")) + return 0; break; case HOOK_TYPE_INFO_HASHTABLE: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_INFO_HASHTABLE(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "info_name", HOOK_INFO_HASHTABLE(hook, info_name))) - return 0; - if (!infolist_new_var_string (ptr_item, "description", HOOK_INFO_HASHTABLE(hook, description))) - return 0; - if (!infolist_new_var_string (ptr_item, "description_nls", - (HOOK_INFO_HASHTABLE(hook, description) - && HOOK_INFO_HASHTABLE(hook, description)[0]) ? - _(HOOK_INFO_HASHTABLE(hook, description)) : "")) - return 0; - if (!infolist_new_var_string (ptr_item, "args_description", HOOK_INFO_HASHTABLE(hook, args_description))) - return 0; - if (!infolist_new_var_string (ptr_item, "args_description_nls", - (HOOK_INFO_HASHTABLE(hook, args_description) - && HOOK_INFO_HASHTABLE(hook, args_description)[0]) ? - _(HOOK_INFO_HASHTABLE(hook, args_description)) : "")) - return 0; - if (!infolist_new_var_string (ptr_item, "output_description", HOOK_INFO_HASHTABLE(hook, output_description))) - return 0; - if (!infolist_new_var_string (ptr_item, "output_description_nls", - (HOOK_INFO_HASHTABLE(hook, output_description) - && HOOK_INFO_HASHTABLE(hook, output_description)[0]) ? - _(HOOK_INFO_HASHTABLE(hook, output_description)) : "")) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_INFO_HASHTABLE(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "info_name", HOOK_INFO_HASHTABLE(hook, info_name))) + return 0; + if (!infolist_new_var_string (ptr_item, "description", HOOK_INFO_HASHTABLE(hook, description))) + return 0; + if (!infolist_new_var_string (ptr_item, "description_nls", + (HOOK_INFO_HASHTABLE(hook, description) + && HOOK_INFO_HASHTABLE(hook, description)[0]) ? + _(HOOK_INFO_HASHTABLE(hook, description)) : "")) + return 0; + if (!infolist_new_var_string (ptr_item, "args_description", HOOK_INFO_HASHTABLE(hook, args_description))) + return 0; + if (!infolist_new_var_string (ptr_item, "args_description_nls", + (HOOK_INFO_HASHTABLE(hook, args_description) + && HOOK_INFO_HASHTABLE(hook, args_description)[0]) ? + _(HOOK_INFO_HASHTABLE(hook, args_description)) : "")) + return 0; + if (!infolist_new_var_string (ptr_item, "output_description", HOOK_INFO_HASHTABLE(hook, output_description))) + return 0; + if (!infolist_new_var_string (ptr_item, "output_description_nls", + (HOOK_INFO_HASHTABLE(hook, output_description) + && HOOK_INFO_HASHTABLE(hook, output_description)[0]) ? + _(HOOK_INFO_HASHTABLE(hook, output_description)) : "")) + return 0; break; case HOOK_TYPE_INFOLIST: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_INFOLIST(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "infolist_name", HOOK_INFOLIST(hook, infolist_name))) - return 0; - if (!infolist_new_var_string (ptr_item, "description", HOOK_INFOLIST(hook, description))) - return 0; - if (!infolist_new_var_string (ptr_item, "description_nls", - (HOOK_INFOLIST(hook, description) - && HOOK_INFOLIST(hook, description)[0]) ? - _(HOOK_INFOLIST(hook, description)) : "")) - return 0; - if (!infolist_new_var_string (ptr_item, "pointer_description", HOOK_INFOLIST(hook, pointer_description))) - return 0; - if (!infolist_new_var_string (ptr_item, "pointer_description_nls", - (HOOK_INFOLIST(hook, pointer_description) - && HOOK_INFOLIST(hook, pointer_description)[0]) ? - _(HOOK_INFOLIST(hook, pointer_description)) : "")) - return 0; - if (!infolist_new_var_string (ptr_item, "args_description", HOOK_INFOLIST(hook, args_description))) - return 0; - if (!infolist_new_var_string (ptr_item, "args_description_nls", - (HOOK_INFOLIST(hook, args_description) - && HOOK_INFOLIST(hook, args_description)[0]) ? - _(HOOK_INFOLIST(hook, args_description)) : "")) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_INFOLIST(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "infolist_name", HOOK_INFOLIST(hook, infolist_name))) + return 0; + if (!infolist_new_var_string (ptr_item, "description", HOOK_INFOLIST(hook, description))) + return 0; + if (!infolist_new_var_string (ptr_item, "description_nls", + (HOOK_INFOLIST(hook, description) + && HOOK_INFOLIST(hook, description)[0]) ? + _(HOOK_INFOLIST(hook, description)) : "")) + return 0; + if (!infolist_new_var_string (ptr_item, "pointer_description", HOOK_INFOLIST(hook, pointer_description))) + return 0; + if (!infolist_new_var_string (ptr_item, "pointer_description_nls", + (HOOK_INFOLIST(hook, pointer_description) + && HOOK_INFOLIST(hook, pointer_description)[0]) ? + _(HOOK_INFOLIST(hook, pointer_description)) : "")) + return 0; + if (!infolist_new_var_string (ptr_item, "args_description", HOOK_INFOLIST(hook, args_description))) + return 0; + if (!infolist_new_var_string (ptr_item, "args_description_nls", + (HOOK_INFOLIST(hook, args_description) + && HOOK_INFOLIST(hook, args_description)[0]) ? + _(HOOK_INFOLIST(hook, args_description)) : "")) + return 0; break; case HOOK_TYPE_HDATA: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_HDATA(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "hdata_name", HOOK_HDATA(hook, hdata_name))) - return 0; - if (!infolist_new_var_string (ptr_item, "description", HOOK_HDATA(hook, description))) - return 0; - if (!infolist_new_var_string (ptr_item, "description_nls", - (HOOK_HDATA(hook, description) - && HOOK_HDATA(hook, description)[0]) ? - _(HOOK_HDATA(hook, description)) : "")) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_HDATA(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "hdata_name", HOOK_HDATA(hook, hdata_name))) + return 0; + if (!infolist_new_var_string (ptr_item, "description", HOOK_HDATA(hook, description))) + return 0; + if (!infolist_new_var_string (ptr_item, "description_nls", + (HOOK_HDATA(hook, description) + && HOOK_HDATA(hook, description)[0]) ? + _(HOOK_HDATA(hook, description)) : "")) + return 0; break; case HOOK_TYPE_FOCUS: - if (!hook->deleted) - { - if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_FOCUS(hook, callback))) - return 0; - if (!infolist_new_var_string (ptr_item, "area", HOOK_FOCUS(hook, area))) - return 0; - } + if (!infolist_new_var_pointer (ptr_item, "callback", HOOK_FOCUS(hook, callback))) + return 0; + if (!infolist_new_var_string (ptr_item, "area", HOOK_FOCUS(hook, area))) + return 0; break; case HOOK_NUM_TYPES: /* @@ -4865,6 +4995,33 @@ hook_print_log () } } break; + case HOOK_TYPE_LINE: + log_printf (" line data:"); + log_printf (" callback. . . . . . . : 0x%lx", HOOK_LINE(ptr_hook, callback)); + log_printf (" buffer_type . . . . . : %d", HOOK_LINE(ptr_hook, buffer_type)); + log_printf (" buffers . . . . . . . : 0x%lx", HOOK_LINE(ptr_hook, buffers)); + log_printf (" num_buffers . . . . . : %d", HOOK_LINE(ptr_hook, num_buffers)); + for (i = 0; i < HOOK_LINE(ptr_hook, num_buffers); i++) + { + log_printf (" buffers[%03d]. . . : '%s'", + i, HOOK_LINE(ptr_hook, buffers)[i]); + } + log_printf (" tags_count. . . . . . : %d", HOOK_LINE(ptr_hook, tags_count)); + log_printf (" tags_array. . . . . . : 0x%lx", HOOK_LINE(ptr_hook, tags_array)); + if (HOOK_LINE(ptr_hook, tags_array)) + { + for (i = 0; i < HOOK_LINE(ptr_hook, tags_count); i++) + { + for (j = 0; HOOK_LINE(ptr_hook, tags_array)[i][j]; j++) + { + log_printf (" tags_array[%03d][%03d]: '%s'", + i, + j, + HOOK_LINE(ptr_hook, tags_array)[i][j]); + } + } + } + break; case HOOK_TYPE_PRINT: log_printf (" print data:"); log_printf (" callback. . . . . . . : 0x%lx", HOOK_PRINT(ptr_hook, callback)); diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h index f01f05b9c..70d521c78 100644 --- a/src/core/wee-hook.h +++ b/src/core/wee-hook.h @@ -50,6 +50,7 @@ enum t_hook_type HOOK_TYPE_FD, /* socket of file descriptor */ HOOK_TYPE_PROCESS, /* sub-process (fork) */ HOOK_TYPE_CONNECT, /* connect to peer with fork */ + HOOK_TYPE_LINE, /* new line in a buffer */ HOOK_TYPE_PRINT, /* printed message */ HOOK_TYPE_SIGNAL, /* signal */ HOOK_TYPE_HSIGNAL, /* signal (using hashtable) */ @@ -100,6 +101,7 @@ enum t_hook_type #define HOOK_FD(hook, var) (((struct t_hook_fd *)hook->hook_data)->var) #define HOOK_PROCESS(hook, var) (((struct t_hook_process *)hook->hook_data)->var) #define HOOK_CONNECT(hook, var) (((struct t_hook_connect *)hook->hook_data)->var) +#define HOOK_LINE(hook, var) (((struct t_hook_line *)hook->hook_data)->var) #define HOOK_PRINT(hook, var) (((struct t_hook_print *)hook->hook_data)->var) #define HOOK_SIGNAL(hook, var) (((struct t_hook_signal *)hook->hook_data)->var) #define HOOK_HSIGNAL(hook, var) (((struct t_hook_hsignal *)hook->hook_data)->var) @@ -282,6 +284,24 @@ struct t_hook_connect int sock_v6[HOOK_CONNECT_MAX_SOCKETS]; /* IPv6 sockets for connecting */ }; +/* hook line */ + +typedef struct t_hashtable *(t_hook_callback_line)(const void *pointer, + void *data, + struct t_hashtable *line); + +struct t_hook_line +{ + t_hook_callback_line *callback; /* line callback */ + int buffer_type; /* -1 = any type, ≥ 0: only this type*/ + char **buffers; /* list of buffer masks where the */ + /* hook is executed (see the */ + /* function "buffer_match_list") */ + int num_buffers; /* number of buffers in list */ + int tags_count; /* number of tags selected */ + char ***tags_array; /* tags selected (NULL = any) */ +}; + /* hook print */ typedef int (t_hook_callback_print)(const void *pointer, void *data, @@ -520,6 +540,14 @@ extern int hook_connect_gnutls_set_certificates (gnutls_session_t tls_session, gnutls_retr_st *answer); #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x020b00 */ #endif /* HAVE_GNUTLS */ +extern struct t_hook *hook_line (struct t_weechat_plugin *plugin, + const char *buffer_type, + const char *buffer_name, + const char *tags, + t_hook_callback_line *callback, + const void *callback_pointer, + void *callback_data); +extern void hook_line_exec (struct t_gui_line *line); extern struct t_hook *hook_print (struct t_weechat_plugin *plugin, struct t_gui_buffer *buffer, const char *tags, const char *message, diff --git a/src/core/wee-upgrade.c b/src/core/wee-upgrade.c index 5afa33266..30f131646 100644 --- a/src/core/wee-upgrade.c +++ b/src/core/wee-upgrade.c @@ -631,7 +631,8 @@ upgrade_weechat_read_buffer_line (struct t_infolist *infolist) switch (upgrade_current_buffer->type) { case GUI_BUFFER_TYPE_FORMATTED: - new_line = gui_line_add (upgrade_current_buffer, + new_line = gui_line_new (upgrade_current_buffer, + -1, infolist_time (infolist, "date"), infolist_time (infolist, "date_printed"), infolist_string (infolist, "tags"), @@ -639,6 +640,7 @@ upgrade_weechat_read_buffer_line (struct t_infolist *infolist) infolist_string (infolist, "message")); if (new_line) { + gui_line_add (new_line); new_line->data->highlight = infolist_integer (infolist, "highlight"); if (infolist_integer (infolist, "last_read_line")) @@ -646,9 +648,12 @@ upgrade_weechat_read_buffer_line (struct t_infolist *infolist) } break; case GUI_BUFFER_TYPE_FREE: - gui_line_add_y (upgrade_current_buffer, - infolist_integer (infolist, "y"), - infolist_string (infolist, "message")); + new_line = gui_line_new (upgrade_current_buffer, + infolist_integer (infolist, "y"), + 0, 0, NULL, NULL, + infolist_string (infolist, "message")); + if (new_line) + gui_line_add_y (new_line); break; case GUI_BUFFER_NUM_TYPES: break; diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c index 8c4751752..a108c8c14 100644 --- a/src/gui/gui-buffer.c +++ b/src/gui/gui-buffer.c @@ -79,6 +79,9 @@ char *gui_buffer_reserved_names[] = NULL }; +char *gui_buffer_type_string[GUI_BUFFER_NUM_TYPES] = +{ "formatted", "free" }; + char *gui_buffer_notify_string[GUI_BUFFER_NUM_NOTIFY] = { "none", "highlight", "message", "all" }; @@ -119,6 +122,26 @@ char *gui_buffer_properties_set[] = /* + * Searches for buffer type. + * + * Returns pointer to hotlist found, NULL if not found. + */ + +int +gui_buffer_search_type (const char *type) +{ + int i; + + for (i = 0; i < GUI_BUFFER_NUM_TYPES; i++) + { + if (string_strcasecmp (gui_buffer_type_string[i], type) == 0) + return i; + } + + return -1; +} + +/* * Gets plugin name of buffer. * * Note: during upgrade process (at startup after /upgrade), the name of plugin diff --git a/src/gui/gui-buffer.h b/src/gui/gui-buffer.h index fa9eb761c..e852a8715 100644 --- a/src/gui/gui-buffer.h +++ b/src/gui/gui-buffer.h @@ -236,6 +236,7 @@ extern int gui_buffers_visited_count; extern int gui_buffers_visited_frozen; extern struct t_gui_buffer *gui_buffer_last_displayed; extern char *gui_buffer_reserved_names[]; +extern char *gui_buffer_type_string[]; extern char *gui_buffer_notify_string[]; extern char *gui_buffer_properties_get_integer[]; extern char *gui_buffer_properties_get_string[]; @@ -244,6 +245,7 @@ extern char *gui_buffer_properties_set[]; /* buffer functions */ +extern int gui_buffer_search_type (const char *type); extern const char *gui_buffer_get_plugin_name (struct t_gui_buffer *buffer); extern const char *gui_buffer_get_short_name (struct t_gui_buffer *buffer); extern void gui_buffer_build_full_name (struct t_gui_buffer *buffer); diff --git a/src/gui/gui-chat.c b/src/gui/gui-chat.c index 9af2d2371..b0b18ec7d 100644 --- a/src/gui/gui-chat.c +++ b/src/gui/gui-chat.c @@ -55,7 +55,7 @@ int gui_chat_time_length = 0; /* length of time for each line (in chars) */ int gui_chat_mute = GUI_CHAT_MUTE_DISABLED; /* mute mode */ struct t_gui_buffer *gui_chat_mute_buffer = NULL; /* mute buffer */ int gui_chat_display_tags = 0; /* display tags? */ -char *gui_chat_lines_waiting_buffer = NULL; /* lines waiting for core */ +char **gui_chat_lines_waiting_buffer = NULL; /* lines waiting for core */ /* buffer */ @@ -635,6 +635,278 @@ gui_chat_build_string_message_tags (struct t_gui_line *line) } /* + * Checks if the buffer pointer is valid for printing a chat message, + * according to buffer type. + * + * Returns: + * 1: buffer is valid + * 0: buffer is not valid + */ + +int +gui_chat_buffer_valid (struct t_gui_buffer *buffer, + int buffer_type) +{ + /* check buffer pointer, closing and type */ + if (!buffer || !gui_buffer_valid (buffer) + || buffer->closing + || ((int)(buffer->type) != buffer_type)) + { + return 0; + } + + /* check if mute is enabled */ + if ((buffer_type == GUI_BUFFER_TYPE_FORMATTED) + && ((gui_chat_mute == GUI_CHAT_MUTE_ALL_BUFFERS) + || ((gui_chat_mute == GUI_CHAT_MUTE_BUFFER) + && (gui_chat_mute_buffer == buffer)))) + { + return 0; + } + + return 1; +} + +/* + * Displays a message in a buffer with optional date and tags. + * This function is called internally by the function + * gui_chat_printf_date_tags. + */ + +void +gui_chat_printf_date_tags_internal (struct t_gui_buffer *buffer, + time_t date, + time_t date_printed, + const char *tags, + char *message) +{ + int display_time, length_data, length_str; + char *ptr_msg, *pos_prefix, *pos_tab; + char *modifier_data, *string, *new_string; + struct t_gui_line *new_line; + + new_line = NULL; + string = NULL; + modifier_data = NULL; + new_string = NULL; + + display_time = 1; + + pos_prefix = NULL; + ptr_msg = message; + + /* space followed by tab => prefix ignored */ + if ((ptr_msg[0] == ' ') && (ptr_msg[1] == '\t')) + { + ptr_msg += 2; + } + else + { + /* if two first chars are tab, then do not display time */ + if ((ptr_msg[0] == '\t') && (ptr_msg[1] == '\t')) + { + display_time = 0; + ptr_msg += 2; + } + else + { + /* if tab found, use prefix (before tab) */ + pos_tab = strchr (ptr_msg, '\t'); + if (pos_tab) + { + pos_tab[0] = '\0'; + pos_prefix = ptr_msg; + ptr_msg = pos_tab + 1; + } + } + } + + new_line = gui_line_new (buffer, + -1, + (display_time) ? date : 0, + date_printed, + tags, + pos_prefix, + ptr_msg); + if (!new_line) + goto no_print; + + hook_line_exec (new_line); + + if (!new_line->data->buffer) + goto no_print; + + /* call modifier for message printed ("weechat_print") */ + if (buffer) + { + length_data = strlen (gui_buffer_get_plugin_name (new_line->data->buffer)) + + 1 + + strlen (new_line->data->buffer->name) + + 1 + + ((tags) ? strlen (tags) : 0) + + 1; + modifier_data = malloc (length_data); + length_str = ((new_line->data->prefix) ? strlen (new_line->data->prefix) + 1 : 0) + + (new_line->data->message ? strlen (new_line->data->message) : 0) + + 1; + string = malloc (length_str); + if (modifier_data && string) + { + snprintf (modifier_data, length_data, + "%s;%s;%s", + gui_buffer_get_plugin_name (new_line->data->buffer), + new_line->data->buffer->name, + (tags) ? tags : ""); + snprintf (string, length_str, + "%s%s%s", + (new_line->data->prefix) ? new_line->data->prefix : "", + (new_line->data->prefix) ? "\t" : "", + (new_line->data->message) ? new_line->data->message : ""); + new_string = hook_modifier_exec (NULL, + "weechat_print", + modifier_data, + string); + if (new_string) + { + if (!new_string[0] && message[0]) + { + /* + * modifier returned empty message, then we'll not + * print anything + */ + goto no_print; + } + else if (strcmp (message, new_string) != 0) + { + /* use new message if there are changes */ + pos_prefix = NULL; + ptr_msg = new_string; + pos_tab = strchr (new_string, '\t'); + if (pos_tab) + { + pos_tab[0] = '\0'; + pos_prefix = ptr_msg; + ptr_msg = pos_tab + 1; + } + if (pos_prefix) + { + if (new_line->data->prefix) + string_shared_free (new_line->data->prefix); + new_line->data->prefix = (char *)string_shared_get (pos_prefix); + new_line->data->prefix_length = gui_chat_strlen_screen (pos_prefix); + } + else + { + if (new_line->data->prefix) + { + free (new_line->data->prefix); + new_line->data->prefix = NULL; + } + new_line->data->prefix_length = 0; + } + if (new_line->data->message) + free (new_line->data->message); + new_line->data->message = strdup (ptr_msg); + } + } + } + } + + gui_line_add (new_line); + if (new_line->data->buffer && buffer->print_hooks_enabled) + hook_print_exec (new_line->data->buffer, new_line); + + gui_buffer_ask_chat_refresh (new_line->data->buffer, 1); + + if (string) + free (string); + if (modifier_data) + free (modifier_data); + if (new_string) + free (new_string); + + return; + +no_print: + if (new_line) + { + gui_line_free_data (new_line); + free (new_line); + } + if (string) + free (string); + if (modifier_data) + free (modifier_data); + if (new_string) + free (new_string); +} + +/* + * Adds a line when WeeChat is waiting for the core buffer. + * + * The line is stored in an internal buffer area and will be displayed later + * in the core buffer. + */ + +void +gui_chat_add_line_waiting_buffer (const char *message) +{ + if (!gui_chat_lines_waiting_buffer) + { + gui_chat_lines_waiting_buffer = string_dyn_alloc (1024); + if (!gui_chat_lines_waiting_buffer) + return; + } + + if (*gui_chat_lines_waiting_buffer[0]) + string_dyn_concat (gui_chat_lines_waiting_buffer, "\n"); + + string_dyn_concat (gui_chat_lines_waiting_buffer, message); +} + +/* + * Displays lines that are waiting for buffer. + * + * If "f" is not NULL, the lines are written in this file (which is commonly + * stdout or stderr). + * If "f" is NULL, the lines are displayed in core buffer if the GUI is + * initialized (gui_init_ok == 1), otherwise on stdout. + */ + +void +gui_chat_print_lines_waiting_buffer (FILE *f) +{ + char **lines; + int num_lines, i; + + if (gui_chat_lines_waiting_buffer) + { + lines = string_split (*gui_chat_lines_waiting_buffer, "\n", 0, 0, + &num_lines); + if (lines) + { + for (i = 0; i < num_lines; i++) + { + if (!f && gui_init_ok) + gui_chat_printf (NULL, "%s", lines[i]); + else + string_fprintf ((f) ? f : stdout, "%s\n", lines[i]); + } + string_free_split (lines); + } + /* + * gui_chat_lines_waiting_buffer may be NULL after call to + * gui_chat_printf (if not enough memory) + */ + } + if (gui_chat_lines_waiting_buffer) + { + string_dyn_free (gui_chat_lines_waiting_buffer, 1); + gui_chat_lines_waiting_buffer = NULL; + } +} + +/* * Displays a message in a buffer with optional date and tags. * * Note: this function works only with formatted buffers (not buffers with free @@ -646,38 +918,19 @@ gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date, const char *tags, const char *message, ...) { time_t date_printed; - int display_time, length, at_least_one_message_printed, msg_discarded; - char *pos, *pos_prefix, *pos_tab, *pos_end, *pos_lines; - char *modifier_data, *new_msg, *ptr_msg, *lines_waiting; - struct t_gui_line *ptr_line; + char *pos, *pos_end; if (!message) return; - if (!gui_buffer_valid (buffer)) - return; - if (gui_init_ok) { if (!buffer) buffer = gui_buffer_search_main (); - - if (!buffer || buffer->closing) - return; - - if (buffer->type != GUI_BUFFER_TYPE_FORMATTED) - buffer = gui_buffers; - - if (buffer->type != GUI_BUFFER_TYPE_FORMATTED) + if (!gui_chat_buffer_valid (buffer, GUI_BUFFER_TYPE_FORMATTED)) return; } - /* if mute is enabled for buffer (or all buffers), then just return */ - if ((gui_chat_mute == GUI_CHAT_MUTE_ALL_BUFFERS) - || ((gui_chat_mute == GUI_CHAT_MUTE_BUFFER) - && (gui_chat_mute_buffer == buffer))) - return; - weechat_va_format (message); if (!vbuffer) return; @@ -688,8 +941,6 @@ gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date, if (date <= 0) date = date_printed; - at_least_one_message_printed = 0; - pos = vbuffer; while (pos) { @@ -698,145 +949,19 @@ gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date, if (pos_end) pos_end[0] = '\0'; - /* call modifier for message printed ("weechat_print") */ - new_msg = NULL; - msg_discarded = 0; - if (buffer) + if (gui_init_ok) { - length = strlen (gui_buffer_get_plugin_name (buffer)) + 1 + - strlen (buffer->name) + 1 + ((tags) ? strlen (tags) : 0) + 1; - modifier_data = malloc (length); - if (modifier_data) - { - snprintf (modifier_data, length, "%s;%s;%s", - gui_buffer_get_plugin_name (buffer), - buffer->name, - (tags) ? tags : ""); - new_msg = hook_modifier_exec (NULL, - "weechat_print", - modifier_data, - pos); - free (modifier_data); - if (new_msg) - { - if (!new_msg[0] && pos[0]) - { - /* - * modifier returned empty message, then we'll not - * print anything - */ - free (new_msg); - new_msg = NULL; - msg_discarded = 1; - } - else if (strcmp (message, new_msg) == 0) - { - /* no changes in new message */ - free (new_msg); - new_msg = NULL; - } - } - } + gui_chat_printf_date_tags_internal (buffer, date, date_printed, + tags, pos); } - - if (!msg_discarded) + else { - pos_prefix = NULL; - display_time = 1; - ptr_msg = (new_msg) ? new_msg : pos; - - /* space followed by tab => prefix ignored */ - if ((ptr_msg[0] == ' ') && (ptr_msg[1] == '\t')) - { - ptr_msg += 2; - } - else - { - /* if two first chars are tab, then do not display time */ - if ((ptr_msg[0] == '\t') && (ptr_msg[1] == '\t')) - { - display_time = 0; - ptr_msg += 2; - } - else - { - /* if tab found, use prefix (before tab) */ - pos_tab = strchr (ptr_msg, '\t'); - if (pos_tab) - { - pos_tab[0] = '\0'; - pos_prefix = ptr_msg; - ptr_msg = pos_tab + 1; - } - } - } - - if (gui_init_ok) - { - ptr_line = gui_line_add (buffer, (display_time) ? date : 0, - date_printed, tags, pos_prefix, ptr_msg); - if (ptr_line) - { - if (buffer && buffer->print_hooks_enabled) - hook_print_exec (buffer, ptr_line); - if (ptr_line->data->displayed) - at_least_one_message_printed = 1; - } - } - else - { - length = ((pos_prefix) ? strlen (pos_prefix) + 1 : 0) + - strlen (ptr_msg) + 1; - if (gui_chat_lines_waiting_buffer) - { - length += strlen (gui_chat_lines_waiting_buffer) + 1; - lines_waiting = realloc (gui_chat_lines_waiting_buffer, length); - if (lines_waiting) - { - gui_chat_lines_waiting_buffer = lines_waiting; - } - else - { - free (gui_chat_lines_waiting_buffer); - gui_chat_lines_waiting_buffer = NULL; - } - } - else - { - gui_chat_lines_waiting_buffer = malloc (length); - if (gui_chat_lines_waiting_buffer) - gui_chat_lines_waiting_buffer[0] = '\0'; - } - if (gui_chat_lines_waiting_buffer) - { - pos_lines = gui_chat_lines_waiting_buffer + - strlen (gui_chat_lines_waiting_buffer); - if (pos_lines > gui_chat_lines_waiting_buffer) - { - pos_lines[0] = '\n'; - pos_lines++; - } - if (pos_prefix) - { - memcpy (pos_lines, pos_prefix, strlen (pos_prefix)); - pos_lines += strlen (pos_prefix); - pos_lines[0] = '\t'; - pos_lines++; - } - memcpy (pos_lines, ptr_msg, strlen (ptr_msg) + 1); - } - } + gui_chat_add_line_waiting_buffer (pos); } - if (new_msg) - free (new_msg); - pos = (pos_end && pos_end[1]) ? pos_end + 1 : NULL; } - if (gui_init_ok && at_least_one_message_printed) - gui_buffer_ask_chat_refresh (buffer, 1); - free (vbuffer); } @@ -850,25 +975,17 @@ gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date, void gui_chat_printf_y (struct t_gui_buffer *buffer, int y, const char *message, ...) { - struct t_gui_line *ptr_line; - int i, num_lines_to_add; + struct t_gui_line *ptr_line, *new_line, *new_line_empty; + int i, last_y, num_lines_to_add; - if (!gui_buffer_valid (buffer)) + if (gui_init_ok && !gui_chat_buffer_valid (buffer, GUI_BUFFER_TYPE_FREE)) return; - if (gui_init_ok) + /* if y is negative, add a line -N lines after the last line */ + if (y < 0) { - if (!buffer) - buffer = gui_buffer_search_main (); - - if (!buffer || buffer->closing) - return; - - if (buffer->type != GUI_BUFFER_TYPE_FREE) - buffer = gui_buffers; - - if (buffer->type != GUI_BUFFER_TYPE_FREE) - return; + y = (buffer->own_lines && buffer->own_lines->last_line) ? + buffer->own_lines->last_line->data->y - y : (-1 * y) - 1; } weechat_va_format (message); @@ -877,42 +994,33 @@ gui_chat_printf_y (struct t_gui_buffer *buffer, int y, const char *message, ...) utf8_normalize (vbuffer, '?'); - /* no message: delete line */ - if (!vbuffer[0]) + new_line = gui_line_new (buffer, y, 0, 0, NULL, NULL, vbuffer); + if (!new_line) + goto end; + + hook_line_exec (new_line); + + if (!new_line->data->buffer) { - if (gui_init_ok && (y >= 0)) - { - for (ptr_line = buffer->own_lines->first_line; ptr_line; - ptr_line = ptr_line->next_line) - { - if (ptr_line->data->y >= y) - break; - } - if (ptr_line && (ptr_line->data->y == y)) - { - if (ptr_line->next_line) - gui_line_clear (ptr_line); - else - gui_line_free (buffer, ptr_line); - gui_buffer_ask_chat_refresh (buffer, 2); - } - } + gui_line_free_data (new_line); + free (new_line); + goto end; } - else + + if (new_line->data->message && new_line->data->message[0]) { if (gui_init_ok) { - /* if y is negative, add a line -N lines after the last line */ - if (y < 0) + /* compute the number of lines to add before y */ + if (new_line->data->buffer->own_lines + && new_line->data->buffer->own_lines->last_line) { - y = (buffer->own_lines && buffer->own_lines->last_line) ? - buffer->own_lines->last_line->data->y - y : (-1 * y) - 1; + num_lines_to_add = y - new_line->data->buffer->own_lines->last_line->data->y - 1; } - /* compute the number of lines to add before y */ - if (buffer->own_lines && buffer->own_lines->last_line) - num_lines_to_add = y - buffer->own_lines->last_line->data->y - 1; else + { num_lines_to_add = y; + } if (num_lines_to_add > 0) { /* @@ -922,59 +1030,47 @@ gui_chat_printf_y (struct t_gui_buffer *buffer, int y, const char *message, ...) */ for (i = y - num_lines_to_add; i < y; i++) { - gui_line_add_y (buffer, i, ""); + new_line_empty = gui_line_new (new_line->data->buffer, + i, 0, 0, NULL, NULL, ""); + if (new_line_empty) + gui_line_add_y (new_line_empty); } } - gui_line_add_y (buffer, y, vbuffer); - gui_buffer_ask_chat_refresh (buffer, 1); + gui_line_add_y (new_line); } else - string_fprintf (stdout, "%s\n", vbuffer); + { + string_fprintf (stdout, "%s\n", new_line->data->message); + gui_line_free_data (new_line); + free (new_line); + } } - - free (vbuffer); -} - -/* - * Displays lines that are waiting for buffer. - * - * If "f" is not NULL, the lines are written in this file (which is commonly - * stdout or stderr). - * If "f" is NULL, the lines are displayed in core buffer if the GUI is - * initialized (gui_init_ok == 1), otherwise on stdout. - */ - -void -gui_chat_print_lines_waiting_buffer (FILE *f) -{ - char **lines; - int num_lines, i; - - if (gui_chat_lines_waiting_buffer) + else if (gui_init_ok) { - lines = string_split (gui_chat_lines_waiting_buffer, "\n", 0, 0, - &num_lines); - if (lines) + /* delete line */ + last_y = (new_line->data->buffer->own_lines->last_line) ? + new_line->data->buffer->own_lines->last_line->data->y : 0; + if (y <= last_y) { - for (i = 0; i < num_lines; i++) + for (ptr_line = new_line->data->buffer->own_lines->first_line; + ptr_line; ptr_line = ptr_line->next_line) { - if (!f && gui_init_ok) - gui_chat_printf (NULL, "%s", lines[i]); + if (ptr_line->data->y >= y) + break; + } + if (ptr_line && (ptr_line->data->y == y)) + { + if (ptr_line->next_line) + gui_line_clear (ptr_line); else - string_fprintf ((f) ? f : stdout, "%s\n", lines[i]); + gui_line_free (new_line->data->buffer, ptr_line); + gui_buffer_ask_chat_refresh (new_line->data->buffer, 2); } - string_free_split (lines); } - /* - * gui_chat_lines_waiting_buffer may be NULL after call to - * gui_chat_printf (if not enough memory) - */ - } - if (gui_chat_lines_waiting_buffer) - { - free (gui_chat_lines_waiting_buffer); - gui_chat_lines_waiting_buffer = NULL; } + +end: + free (vbuffer); } /* @@ -1106,7 +1202,7 @@ gui_chat_end () /* free lines waiting for buffer (should always be NULL here) */ if (gui_chat_lines_waiting_buffer) { - free (gui_chat_lines_waiting_buffer); + string_dyn_free (gui_chat_lines_waiting_buffer, 1); gui_chat_lines_waiting_buffer = NULL; } } diff --git a/src/gui/gui-chat.h b/src/gui/gui-chat.h index 135a79bb6..bd2cfb7c5 100644 --- a/src/gui/gui-chat.h +++ b/src/gui/gui-chat.h @@ -86,6 +86,8 @@ extern int gui_chat_get_time_length (); extern void gui_chat_change_time_format (); extern char *gui_chat_build_string_prefix_message (struct t_gui_line *line); extern char *gui_chat_build_string_message_tags (struct t_gui_line *line); +extern int gui_chat_buffer_valid (struct t_gui_buffer *buffer, + int buffer_type); extern void gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date, const char *tags, const char *message, ...); diff --git a/src/gui/gui-focus.c b/src/gui/gui-focus.c index 9e622bc1b..8028ccfba 100644 --- a/src/gui/gui-focus.c +++ b/src/gui/gui-focus.c @@ -39,29 +39,6 @@ #include "gui-window.h" -#define FOCUS_STR(__name, __string) \ - hashtable_set (hashtable, __name, __string); -#define FOCUS_STR_VAR(__name, __var) \ - hashtable_set (hashtable, __name, (__var) ? __var : ""); -#define FOCUS_INT(__name, __int) \ - snprintf (str_value, sizeof (str_value), "%d", __int); \ - hashtable_set (hashtable, __name, str_value); -#define FOCUS_TIME(__name, __time) \ - snprintf (str_value, sizeof (str_value), "%lld", (long long)__time); \ - hashtable_set (hashtable, __name, str_value); -#define FOCUS_PTR(__name, __pointer) \ - if (__pointer) \ - { \ - snprintf (str_value, sizeof (str_value), \ - "0x%lx", (long unsigned int)__pointer); \ - hashtable_set (hashtable, __name, str_value); \ - } \ - else \ - { \ - hashtable_set (hashtable, __name, ""); \ - } - - /* * Gets info about what is pointed by cursor at (x,y). * @@ -177,45 +154,45 @@ gui_focus_to_hashtable (struct t_gui_focus_info *focus_info, const char *key) return NULL; /* key (key from keyboard or mouse event) */ - FOCUS_STR("_key", key); + HASHTABLE_SET_STR("_key", key); /* x,y */ - FOCUS_INT("_x", focus_info->x); - FOCUS_INT("_y", focus_info->y); + HASHTABLE_SET_INT("_x", focus_info->x); + HASHTABLE_SET_INT("_y", focus_info->y); /* window */ - FOCUS_PTR("_window", focus_info->window); + HASHTABLE_SET_PTR("_window", focus_info->window); if (focus_info->window) { - FOCUS_INT("_window_number", (focus_info->window)->number); + HASHTABLE_SET_INT("_window_number", (focus_info->window)->number); } else { - FOCUS_STR("_window_number", "*"); + HASHTABLE_SET_STR("_window_number", "*"); } /* buffer */ - FOCUS_PTR("_buffer", focus_info->buffer); + HASHTABLE_SET_PTR("_buffer", focus_info->buffer); if (focus_info->buffer) { - FOCUS_INT("_buffer_number", (focus_info->buffer)->number); - FOCUS_STR("_buffer_plugin", plugin_get_name ((focus_info->buffer)->plugin)); - FOCUS_STR("_buffer_name", (focus_info->buffer)->name); - FOCUS_STR("_buffer_full_name", (focus_info->buffer)->full_name); + HASHTABLE_SET_INT("_buffer_number", (focus_info->buffer)->number); + HASHTABLE_SET_STR("_buffer_plugin", plugin_get_name ((focus_info->buffer)->plugin)); + HASHTABLE_SET_STR("_buffer_name", (focus_info->buffer)->name); + HASHTABLE_SET_STR("_buffer_full_name", (focus_info->buffer)->full_name); hashtable_map ((focus_info->buffer)->local_variables, &gui_focus_buffer_localvar_map_cb, hashtable); } else { - FOCUS_PTR("_buffer", NULL); - FOCUS_STR("_buffer_number", "-1"); - FOCUS_STR("_buffer_plugin", ""); - FOCUS_STR("_buffer_name", ""); - FOCUS_STR("_buffer_full_name", ""); + HASHTABLE_SET_PTR("_buffer", NULL); + HASHTABLE_SET_STR("_buffer_number", "-1"); + HASHTABLE_SET_STR("_buffer_plugin", ""); + HASHTABLE_SET_STR("_buffer_name", ""); + HASHTABLE_SET_STR("_buffer_full_name", ""); } /* chat area */ - FOCUS_INT("_chat", focus_info->chat); + HASHTABLE_SET_INT("_chat", focus_info->chat); str_time = NULL; str_prefix = NULL; if (focus_info->chat_line) @@ -225,16 +202,16 @@ gui_focus_to_hashtable (struct t_gui_focus_info *focus_info, const char *key) str_tags = string_build_with_split_string ((const char **)((focus_info->chat_line)->data)->tags_array, ","); str_message = gui_color_decode (((focus_info->chat_line)->data)->message, NULL); nick = gui_line_get_nick_tag (focus_info->chat_line); - FOCUS_PTR("_chat_line", focus_info->chat_line); - FOCUS_INT("_chat_line_x", focus_info->chat_line_x); - FOCUS_INT("_chat_line_y", ((focus_info->chat_line)->data)->y); - FOCUS_TIME("_chat_line_date", ((focus_info->chat_line)->data)->date); - FOCUS_TIME("_chat_line_date_printed", ((focus_info->chat_line)->data)->date_printed); - FOCUS_STR_VAR("_chat_line_time", str_time); - FOCUS_STR_VAR("_chat_line_tags", str_tags); - FOCUS_STR_VAR("_chat_line_nick", nick); - FOCUS_STR_VAR("_chat_line_prefix", str_prefix); - FOCUS_STR_VAR("_chat_line_message", str_message); + HASHTABLE_SET_PTR("_chat_line", focus_info->chat_line); + HASHTABLE_SET_INT("_chat_line_x", focus_info->chat_line_x); + HASHTABLE_SET_INT("_chat_line_y", ((focus_info->chat_line)->data)->y); + HASHTABLE_SET_TIME("_chat_line_date", ((focus_info->chat_line)->data)->date); + HASHTABLE_SET_TIME("_chat_line_date_printed", ((focus_info->chat_line)->data)->date_printed); + HASHTABLE_SET_STR_NOT_NULL("_chat_line_time", str_time); + HASHTABLE_SET_STR_NOT_NULL("_chat_line_tags", str_tags); + HASHTABLE_SET_STR_NOT_NULL("_chat_line_nick", nick); + HASHTABLE_SET_STR_NOT_NULL("_chat_line_prefix", str_prefix); + HASHTABLE_SET_STR_NOT_NULL("_chat_line_message", str_message); if (str_time) free (str_time); if (str_prefix) @@ -246,35 +223,35 @@ gui_focus_to_hashtable (struct t_gui_focus_info *focus_info, const char *key) } else { - FOCUS_PTR("_chat_line", NULL); - FOCUS_STR("_chat_line_x", "-1"); - FOCUS_STR("_chat_line_y", "-1"); - FOCUS_STR("_chat_line_date", "-1"); - FOCUS_STR("_chat_line_date_printed", "-1"); - FOCUS_STR("_chat_line_time", ""); - FOCUS_STR("_chat_line_tags", ""); - FOCUS_STR("_chat_line_nick", ""); - FOCUS_STR("_chat_line_prefix", ""); - FOCUS_STR("_chat_line_message", ""); + HASHTABLE_SET_PTR("_chat_line", NULL); + HASHTABLE_SET_STR("_chat_line_x", "-1"); + HASHTABLE_SET_STR("_chat_line_y", "-1"); + HASHTABLE_SET_STR("_chat_line_date", "-1"); + HASHTABLE_SET_STR("_chat_line_date_printed", "-1"); + HASHTABLE_SET_STR("_chat_line_time", ""); + HASHTABLE_SET_STR("_chat_line_tags", ""); + HASHTABLE_SET_STR("_chat_line_nick", ""); + HASHTABLE_SET_STR("_chat_line_prefix", ""); + HASHTABLE_SET_STR("_chat_line_message", ""); } - FOCUS_STR_VAR("_chat_word", focus_info->chat_word); - FOCUS_STR_VAR("_chat_bol", focus_info->chat_bol); - FOCUS_STR_VAR("_chat_eol", focus_info->chat_eol); + HASHTABLE_SET_STR_NOT_NULL("_chat_word", focus_info->chat_word); + HASHTABLE_SET_STR_NOT_NULL("_chat_bol", focus_info->chat_bol); + HASHTABLE_SET_STR_NOT_NULL("_chat_eol", focus_info->chat_eol); /* bar/item */ if (focus_info->bar_window) { - FOCUS_STR("_bar_name", ((focus_info->bar_window)->bar)->name); - FOCUS_STR("_bar_filling", gui_bar_filling_string[gui_bar_get_filling ((focus_info->bar_window)->bar)]); + HASHTABLE_SET_STR("_bar_name", ((focus_info->bar_window)->bar)->name); + HASHTABLE_SET_STR("_bar_filling", gui_bar_filling_string[gui_bar_get_filling ((focus_info->bar_window)->bar)]); } else { - FOCUS_STR("_bar_name", ""); - FOCUS_STR("_bar_filling", ""); + HASHTABLE_SET_STR("_bar_name", ""); + HASHTABLE_SET_STR("_bar_filling", ""); } - FOCUS_STR_VAR("_bar_item_name", focus_info->bar_item); - FOCUS_INT("_bar_item_line", focus_info->bar_item_line); - FOCUS_INT("_bar_item_col", focus_info->bar_item_col); + HASHTABLE_SET_STR_NOT_NULL("_bar_item_name", focus_info->bar_item); + HASHTABLE_SET_INT("_bar_item_line", focus_info->bar_item_line); + HASHTABLE_SET_INT("_bar_item_col", focus_info->bar_item_col); return hashtable; } diff --git a/src/gui/gui-line.c b/src/gui/gui-line.c index fd7677198..4d4983121 100644 --- a/src/gui/gui-line.c +++ b/src/gui/gui-line.c @@ -977,6 +977,25 @@ gui_line_add_to_list (struct t_gui_lines *lines, } /* + * Frees data in a line. + */ + +void +gui_line_free_data (struct t_gui_line *line) +{ + if (line->data->str_time) + free (line->data->str_time); + gui_line_tags_free (line->data); + if (line->data->prefix) + string_shared_free (line->data->prefix); + if (line->data->message) + free (line->data->message); + free (line->data); + + line->data = NULL; +} + +/* * Removes a line from a "t_gui_lines" structure. */ @@ -1041,16 +1060,7 @@ gui_line_remove_from_list (struct t_gui_buffer *buffer, /* free data */ if (free_data) - { - if (line->data->str_time) - free (line->data->str_time); - gui_line_tags_free (line->data); - if (line->data->prefix) - string_shared_free (line->data->prefix); - if (line->data->message) - free (line->data->message); - free (line->data); - } + gui_line_free_data (line); /* remove line from list */ if (line->prev_line) @@ -1189,122 +1199,358 @@ gui_line_free_all (struct t_gui_buffer *buffer) int gui_line_get_notify_level (struct t_gui_line *line) { - int i; + int i, notify_level, *max_notify_level; + const char *nick; + + notify_level = GUI_HOTLIST_LOW; for (i = 0; i < line->data->tags_count; i++) { if (string_strcasecmp (line->data->tags_array[i], "notify_none") == 0) - return -1; + notify_level = -1; if (string_strcasecmp (line->data->tags_array[i], "notify_highlight") == 0) - return GUI_HOTLIST_HIGHLIGHT; + notify_level = GUI_HOTLIST_HIGHLIGHT; if (string_strcasecmp (line->data->tags_array[i], "notify_private") == 0) - return GUI_HOTLIST_PRIVATE; + notify_level = GUI_HOTLIST_PRIVATE; if (string_strcasecmp (line->data->tags_array[i], "notify_message") == 0) - return GUI_HOTLIST_MESSAGE; + notify_level = GUI_HOTLIST_MESSAGE; } - return GUI_HOTLIST_LOW; + + max_notify_level = NULL; + nick = gui_line_get_nick_tag (line); + if (nick) + { + max_notify_level = hashtable_get (line->data->buffer->hotlist_max_level_nicks, + nick); + } + if (max_notify_level && (*max_notify_level < notify_level)) + notify_level = *max_notify_level; + + return notify_level; +} + +/* + * Gets highlight flag for a line, using the notify level in the line. + * + * Returns 1 for highlight otherwise 0. + */ + +int +gui_line_get_highlight (struct t_gui_line *line) +{ + int highlight, *max_notify_level; + const char *nick; + + highlight = 0; + + if (line->data->notify_level == GUI_HOTLIST_HIGHLIGHT) + { + highlight = 1; + } + else + { + max_notify_level = NULL; + nick = gui_line_get_nick_tag (line); + if (nick) + { + max_notify_level = hashtable_get (line->data->buffer->hotlist_max_level_nicks, + nick); + } + if (max_notify_level && (*max_notify_level < GUI_HOTLIST_HIGHLIGHT)) + highlight = 0; + else + highlight = gui_line_has_highlight (line); + } + + return highlight; } /* - * Adds a new line for a buffer. + * Creates a new line for a buffer. */ struct t_gui_line * -gui_line_add (struct t_gui_buffer *buffer, time_t date, +gui_line_new (struct t_gui_buffer *buffer, int y, time_t date, time_t date_printed, const char *tags, const char *prefix, const char *message) { struct t_gui_line *new_line; struct t_gui_line_data *new_line_data; - struct t_gui_window *ptr_win; - char *message_for_signal; - const char *nick; - int notify_level, *max_notify_level, lines_removed; - time_t current_time; - - /* - * remove line(s) if necessary, according to history options: - * max_lines: if > 0, keep only N lines in buffer - * max_minutes: if > 0, keep only lines from last N minutes - */ - lines_removed = 0; - current_time = time (NULL); - while (buffer->own_lines->first_line - && (((CONFIG_INTEGER(config_history_max_buffer_lines_number) > 0) - && (buffer->own_lines->lines_count + 1 > - CONFIG_INTEGER(config_history_max_buffer_lines_number))) - || ((CONFIG_INTEGER(config_history_max_buffer_lines_minutes) > 0) - && (current_time - buffer->own_lines->first_line->data->date_printed > - CONFIG_INTEGER(config_history_max_buffer_lines_minutes) * 60)))) - { - gui_line_free (buffer, buffer->own_lines->first_line); - lines_removed++; - } /* create new line */ new_line = malloc (sizeof (*new_line)); if (!new_line) - { - log_printf (_("Not enough memory for new line")); return NULL; - } /* create data for line */ new_line_data = malloc (sizeof (*new_line_data)); if (!new_line_data) { free (new_line); - log_printf (_("Not enough memory for new line")); return NULL; } new_line->data = new_line_data; /* fill data in new line */ new_line->data->buffer = buffer; - new_line->data->y = -1; - new_line->data->date = date; - new_line->data->date_printed = date_printed; - new_line->data->str_time = gui_chat_get_time_string (date); - gui_line_tags_alloc (new_line->data, tags); - new_line->data->refresh_needed = 0; - new_line->data->prefix = (prefix) ? - (char *)string_shared_get (prefix) : ((date != 0) ? (char *)string_shared_get ("") : NULL); - new_line->data->prefix_length = (prefix) ? - gui_chat_strlen_screen (prefix) : 0; new_line->data->message = (message) ? strdup (message) : strdup (""); - /* get notify level and max notify level for nick in buffer */ - notify_level = gui_line_get_notify_level (new_line); - max_notify_level = NULL; - nick = gui_line_get_nick_tag (new_line); - if (nick) - max_notify_level = hashtable_get (buffer->hotlist_max_level_nicks, nick); - if (max_notify_level - && (*max_notify_level < notify_level)) - notify_level = *max_notify_level; - - if (notify_level == GUI_HOTLIST_HIGHLIGHT) - new_line->data->highlight = 1; - else if (max_notify_level && (*max_notify_level < GUI_HOTLIST_HIGHLIGHT)) - new_line->data->highlight = 0; + if (buffer->type == GUI_BUFFER_TYPE_FORMATTED) + { + new_line->data->y = -1; + new_line->data->date = date; + new_line->data->date_printed = date_printed; + new_line->data->str_time = gui_chat_get_time_string (date); + gui_line_tags_alloc (new_line->data, tags); + new_line->data->refresh_needed = 0; + new_line->data->prefix = (prefix) ? + (char *)string_shared_get (prefix) : ((date != 0) ? (char *)string_shared_get ("") : NULL); + new_line->data->prefix_length = (prefix) ? + gui_chat_strlen_screen (prefix) : 0; + new_line->data->notify_level = gui_line_get_notify_level (new_line); + new_line->data->highlight = gui_line_get_highlight (new_line); + } else - new_line->data->highlight = gui_line_has_highlight (new_line); + { + new_line->data->y = y; + new_line->data->date = 0; + new_line->data->date_printed = 0; + new_line->data->str_time = NULL; + new_line->data->tags_count = 0; + new_line->data->tags_array = NULL; + new_line->data->refresh_needed = 1; + new_line->data->prefix = NULL; + new_line->data->prefix_length = 0; + new_line->data->notify_level = 0; + new_line->data->highlight = 0; + } - /* check if line is filtered or not */ + /* set display flag (check if line is filtered or not) */ new_line->data->displayed = gui_filter_check_line (new_line->data); + new_line->prev_line = NULL; + new_line->next_line = NULL; + + return new_line; +} + +/* + * Updates data in a line via the hook_line. + */ + +void +gui_line_hook_update (struct t_gui_line *line, + struct t_hashtable *hashtable, + struct t_hashtable *hashtable2) +{ + const char *ptr_value, *ptr_value2; + struct t_gui_buffer *ptr_buffer; + long unsigned int value_pointer; + long value; + char *error; + int rc, tags_updated, notify_level_updated, highlight_updated; + + tags_updated = 0; + notify_level_updated = 0; + highlight_updated = 0; + + ptr_value2 = hashtable_get (hashtable2, "buffer_name"); + if (ptr_value2) + { + if (ptr_value2[0]) + { + ptr_buffer = gui_buffer_search_by_full_name (ptr_value2); + if (gui_chat_buffer_valid (ptr_buffer, line->data->buffer->type)) + line->data->buffer = ptr_buffer; + } + else + { + line->data->buffer = NULL; + return; + } + } + else + { + ptr_value2 = hashtable_get (hashtable2, "buffer"); + if (ptr_value2) + { + if (ptr_value2[0]) + { + if ((ptr_value2[0] == '0') && (ptr_value2[1] == 'x')) + { + rc = sscanf (ptr_value2 + 2, "%lx", &value_pointer); + ptr_buffer = (struct t_gui_buffer *)value_pointer; + if ((rc != EOF) && (rc >= 1) + && gui_chat_buffer_valid (ptr_buffer, line->data->buffer->type)) + { + line->data->buffer = ptr_buffer; + } + } + } + else + { + line->data->buffer = NULL; + return; + } + } + } + + if (line->data->buffer->type == GUI_BUFFER_TYPE_FREE) + { + /* the field "y" can be changed on buffer with free content */ + ptr_value = hashtable_get (hashtable2, "y"); + if (ptr_value) + { + error = NULL; + value = strtol (ptr_value, &error, 10); + if (error && !error[0] && (value >= 0)) + line->data->y = value; + } + } + + ptr_value2 = hashtable_get (hashtable2, "date"); + if (ptr_value2) + { + error = NULL; + value = strtol (ptr_value2, &error, 10); + if (error && !error[0] && (value >= 0)) + { + line->data->date = (time_t)value; + if (line->data->str_time) + free (line->data->str_time); + line->data->str_time = gui_chat_get_time_string (line->data->date); + } + } + + ptr_value2 = hashtable_get (hashtable2, "date_printed"); + if (ptr_value2) + { + error = NULL; + value = strtol (ptr_value2, &error, 10); + if (error && !error[0] && (value >= 0)) + line->data->date_printed = (time_t)value; + } + + ptr_value = hashtable_get (hashtable, "str_time"); + ptr_value2 = hashtable_get (hashtable2, "str_time"); + if (ptr_value2 && (!ptr_value || (strcmp (ptr_value, ptr_value2) != 0))) + { + if (line->data->str_time) + free (line->data->str_time); + line->data->str_time = (ptr_value2) ? strdup (ptr_value2) : NULL; + } + + ptr_value = hashtable_get (hashtable, "tags"); + ptr_value2 = hashtable_get (hashtable2, "tags"); + if (ptr_value2 && (!ptr_value || (strcmp (ptr_value, ptr_value2) != 0))) + { + tags_updated = 1; + gui_line_tags_free (line->data); + gui_line_tags_alloc (line->data, ptr_value2); + } + + ptr_value2 = hashtable_get (hashtable2, "notify_level"); + if (ptr_value2) + { + error = NULL; + value = strtol (ptr_value2, &error, 10); + if (error && !error[0] && (value >= -1) && (value <= GUI_HOTLIST_MAX)) + { + notify_level_updated = 1; + line->data->notify_level = value; + } + } + + ptr_value2 = hashtable_get (hashtable2, "highlight"); + if (ptr_value2) + { + error = NULL; + value = strtol (ptr_value2, &error, 10); + if (error && !error[0]) + { + highlight_updated = 1; + line->data->highlight = (value) ? 1 : 0; + } + } + + ptr_value = hashtable_get (hashtable, "prefix"); + ptr_value2 = hashtable_get (hashtable2, "prefix"); + if (ptr_value2 && (!ptr_value || (strcmp (ptr_value, ptr_value2) != 0))) + { + if (line->data->prefix) + string_shared_free (line->data->prefix); + line->data->prefix = (char *)string_shared_get ( + (ptr_value2) ? ptr_value2 : ""); + line->data->prefix_length = (line->data->prefix) ? + gui_chat_strlen_screen (line->data->prefix) : 0; + } + + ptr_value = hashtable_get (hashtable, "message"); + ptr_value2 = hashtable_get (hashtable2, "message"); + if (ptr_value2 && (!ptr_value || (strcmp (ptr_value, ptr_value2) != 0))) + { + if (line->data->message) + free (line->data->message); + line->data->message = (ptr_value2) ? strdup (ptr_value2) : NULL; + } + + /* if tags were updated but not notify_level, adjust notify level */ + if (tags_updated && !notify_level_updated) + line->data->notify_level = gui_line_get_notify_level (line); + + /* adjust flag "displayed" if tags were updated */ + if (tags_updated) + line->data->displayed = gui_filter_check_line (line->data); + + if ((tags_updated || notify_level_updated) && !highlight_updated) + line->data->highlight = gui_line_get_highlight (line); +} + +/* + * Adds a new line in a buffer with formatted content. + */ + +void +gui_line_add (struct t_gui_line *line) +{ + struct t_gui_window *ptr_win; + char *message_for_signal; + int lines_removed; + time_t current_time; + + /* + * remove line(s) if necessary, according to history options: + * max_lines: if > 0, keep only N lines in buffer + * max_minutes: if > 0, keep only lines from last N minutes + */ + lines_removed = 0; + current_time = time (NULL); + while (line->data->buffer->own_lines->first_line + && (((CONFIG_INTEGER(config_history_max_buffer_lines_number) > 0) + && (line->data->buffer->own_lines->lines_count + 1 > + CONFIG_INTEGER(config_history_max_buffer_lines_number))) + || ((CONFIG_INTEGER(config_history_max_buffer_lines_minutes) > 0) + && (current_time - line->data->buffer->own_lines->first_line->data->date_printed > + CONFIG_INTEGER(config_history_max_buffer_lines_minutes) * 60)))) + { + gui_line_free (line->data->buffer, + line->data->buffer->own_lines->first_line); + lines_removed++; + } + /* add line to lines list */ - gui_line_add_to_list (buffer->own_lines, new_line); + gui_line_add_to_list (line->data->buffer->own_lines, line); /* update hotlist and/or send signals for line */ - if (new_line->data->displayed) + if (line->data->displayed) { - if (new_line->data->highlight) + if (line->data->highlight) { - (void) gui_hotlist_add (buffer, GUI_HOTLIST_HIGHLIGHT, NULL); + (void) gui_hotlist_add (line->data->buffer, + GUI_HOTLIST_HIGHLIGHT, NULL); if (!weechat_upgrading) { - message_for_signal = gui_chat_build_string_prefix_message (new_line); + message_for_signal = gui_chat_build_string_prefix_message (line); if (message_for_signal) { (void) hook_signal_send ("weechat_highlight", @@ -1316,9 +1562,10 @@ gui_line_add (struct t_gui_buffer *buffer, time_t date, } else { - if (!weechat_upgrading && (notify_level == GUI_HOTLIST_PRIVATE)) + if (!weechat_upgrading + && (line->data->notify_level == GUI_HOTLIST_PRIVATE)) { - message_for_signal = gui_chat_build_string_prefix_message (new_line); + message_for_signal = gui_chat_build_string_prefix_message (line); if (message_for_signal) { (void) hook_signal_send ("weechat_pv", @@ -1327,20 +1574,24 @@ gui_line_add (struct t_gui_buffer *buffer, time_t date, free (message_for_signal); } } - if (notify_level >= GUI_HOTLIST_MIN) - (void) gui_hotlist_add (buffer, notify_level, NULL); + if (line->data->notify_level >= GUI_HOTLIST_MIN) + { + (void) gui_hotlist_add (line->data->buffer, + line->data->notify_level, NULL); + } } } else { (void) hook_signal_send ("buffer_lines_hidden", - WEECHAT_HOOK_SIGNAL_POINTER, buffer); + WEECHAT_HOOK_SIGNAL_POINTER, + line->data->buffer); } /* add mixed line, if buffer is attached to at least one other buffer */ - if (buffer->mixed_lines) + if (line->data->buffer->mixed_lines) { - gui_line_mixed_add (buffer->mixed_lines, new_line->data); + gui_line_mixed_add (line->data->buffer->mixed_lines, line->data); } /* @@ -1352,125 +1603,108 @@ gui_line_add (struct t_gui_buffer *buffer, time_t date, { for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) { - if ((ptr_win->buffer == buffer) - && (buffer->own_lines->lines_count < ptr_win->win_chat_height)) + if ((ptr_win->buffer == line->data->buffer) + && (line->data->buffer->own_lines->lines_count < ptr_win->win_chat_height)) { - gui_buffer_ask_chat_refresh (buffer, 2); + gui_buffer_ask_chat_refresh (line->data->buffer, 2); break; } } } (void) hook_signal_send ("buffer_line_added", - WEECHAT_HOOK_SIGNAL_POINTER, new_line); - - return new_line; + WEECHAT_HOOK_SIGNAL_POINTER, line); } /* - * Adds or updates a line for a buffer with free content. + * Adds or updates a line in a buffer with free content. + * + * Ba careful: when replacing an existing line in the buffer, the "line" + * pointer received as parameter is freed and then becomes invalid. + * So this pointer must not be used after the call to this function. */ void -gui_line_add_y (struct t_gui_buffer *buffer, int y, const char *message) +gui_line_add_y (struct t_gui_line *line) { - struct t_gui_line *ptr_line, *new_line; - struct t_gui_line_data *new_line_data; + struct t_gui_line *ptr_line; struct t_gui_window *ptr_win; + int old_line_displayed; /* search if line exists for "y" */ - for (ptr_line = buffer->own_lines->first_line; ptr_line; + for (ptr_line = line->data->buffer->own_lines->first_line; ptr_line; ptr_line = ptr_line->next_line) { - if (ptr_line->data->y >= y) + if (ptr_line->data->y >= line->data->y) break; } - if (!ptr_line || (ptr_line->data->y > y)) + if (ptr_line && (ptr_line->data->y == line->data->y)) { - new_line = malloc (sizeof (*new_line)); - if (!new_line) - { - log_printf (_("Not enough memory for new line")); - return; - } - - new_line_data = malloc (sizeof (*new_line_data)); - if (!new_line_data) + /* replace line data with the new data */ + old_line_displayed = ptr_line->data->displayed; + if (ptr_line->data->message) { - free (new_line); - log_printf (_("Not enough memory for new line")); - return; + /* remove line from coords if the content is changing */ + for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) + { + gui_window_coords_remove_line (ptr_win, ptr_line); + } } - new_line->data = new_line_data; - - buffer->own_lines->lines_count++; - - /* fill data in new line */ - new_line->data->buffer = buffer; - new_line->data->y = y; - new_line->data->date = 0; - new_line->data->date_printed = 0; - new_line->data->str_time = NULL; - new_line->data->tags_count = 0; - new_line->data->tags_array = NULL; - new_line->data->refresh_needed = 1; - new_line->data->prefix = NULL; - new_line->data->prefix_length = 0; - new_line->data->message = NULL; - new_line->data->highlight = 0; + /* replace ptr_line by line in list */ + gui_line_free_data (ptr_line); + ptr_line->data = line->data; + free (line); + } + else + { /* add line to lines list */ + old_line_displayed = 1; if (ptr_line) { /* add before line found */ - new_line->prev_line = ptr_line->prev_line; - new_line->next_line = ptr_line; + line->prev_line = ptr_line->prev_line; + line->next_line = ptr_line; if (ptr_line->prev_line) - (ptr_line->prev_line)->next_line = new_line; + (ptr_line->prev_line)->next_line = line; else - buffer->own_lines->first_line = new_line; - ptr_line->prev_line = new_line; + line->data->buffer->own_lines->first_line = line; + ptr_line->prev_line = line; } else { /* add at end of list */ - new_line->prev_line = buffer->own_lines->last_line; - if (buffer->own_lines->first_line) - buffer->own_lines->last_line->next_line = new_line; + line->prev_line = line->data->buffer->own_lines->last_line; + if (line->data->buffer->own_lines->first_line) + line->data->buffer->own_lines->last_line->next_line = line; else - buffer->own_lines->first_line = new_line; - buffer->own_lines->last_line = new_line; - new_line->next_line = NULL; + line->data->buffer->own_lines->first_line = line; + line->data->buffer->own_lines->last_line = line; + line->next_line = NULL; } + ptr_line = line; - ptr_line = new_line; + line->data->buffer->own_lines->lines_count++; } - /* set message for line */ - if (ptr_line->data->message) - { - /* remove line from coords if the content is changing */ - for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) - { - gui_window_coords_remove_line (ptr_win, ptr_line); - } - - /* free message in line */ - free (ptr_line->data->message); - } - ptr_line->data->message = (message) ? strdup (message) : strdup (""); - /* check if line is filtered or not */ - ptr_line->data->displayed = gui_filter_check_line (ptr_line->data); - if (!ptr_line->data->displayed) + if (old_line_displayed && !ptr_line->data->displayed) { - buffer->own_lines->lines_hidden++; + (ptr_line->data->buffer->own_lines->lines_hidden)++; (void) hook_signal_send ("buffer_lines_hidden", - WEECHAT_HOOK_SIGNAL_POINTER, buffer); + WEECHAT_HOOK_SIGNAL_POINTER, + ptr_line->data->buffer); + } + else if (!old_line_displayed && ptr_line->data->displayed) + { + if (ptr_line->data->buffer->own_lines->lines_hidden > 0) + (ptr_line->data->buffer->own_lines->lines_hidden)--; } ptr_line->data->refresh_needed = 1; + + gui_buffer_ask_chat_refresh (ptr_line->data->buffer, 1); } /* @@ -1754,6 +1988,7 @@ gui_line_hdata_line_data_cb (const void *pointer, void *data, HDATA_VAR(struct t_gui_line_data, tags_count, INTEGER, 0, NULL, NULL); HDATA_VAR(struct t_gui_line_data, tags_array, SHARED_STRING, 1, "tags_count", NULL); HDATA_VAR(struct t_gui_line_data, displayed, CHAR, 0, NULL, NULL); + HDATA_VAR(struct t_gui_line_data, notify_level, CHAR, 0, NULL, NULL); HDATA_VAR(struct t_gui_line_data, highlight, CHAR, 0, NULL, NULL); HDATA_VAR(struct t_gui_line_data, refresh_needed, CHAR, 0, NULL, NULL); HDATA_VAR(struct t_gui_line_data, prefix, SHARED_STRING, 1, NULL, NULL); @@ -1827,6 +2062,8 @@ gui_line_add_to_infolist (struct t_infolist *infolist, if (!infolist_new_var_integer (ptr_item, "displayed", line->data->displayed)) return 0; + if (!infolist_new_var_integer (ptr_item, "notify_level", line->data->notify_level)) + return 0; if (!infolist_new_var_integer (ptr_item, "highlight", line->data->highlight)) return 0; if (!infolist_new_var_string (ptr_item, "prefix", line->data->prefix)) diff --git a/src/gui/gui-line.h b/src/gui/gui-line.h index 4d8b4cca1..bf4a82416 100644 --- a/src/gui/gui-line.h +++ b/src/gui/gui-line.h @@ -37,6 +37,7 @@ struct t_gui_line_data int tags_count; /* number of tags for line */ char **tags_array; /* tags for line */ char displayed; /* 1 if line is displayed */ + char notify_level; /* notify level for the line */ char highlight; /* 1 if line has highlight */ char refresh_needed; /* 1 if refresh asked (free buffer) */ char *prefix; /* prefix for line (may be NULL) */ @@ -102,18 +103,23 @@ extern void gui_line_compute_buffer_max_length (struct t_gui_buffer *buffer, extern void gui_line_compute_prefix_max_length (struct t_gui_lines *lines); extern void gui_line_mixed_free_buffer (struct t_gui_buffer *buffer); extern void gui_line_mixed_free_all (struct t_gui_buffer *buffer); +extern void gui_line_free_data (struct t_gui_line *line); extern void gui_line_free (struct t_gui_buffer *buffer, struct t_gui_line *line); extern void gui_line_free_all (struct t_gui_buffer *buffer); extern int gui_line_get_notify_level (struct t_gui_line *line); -extern struct t_gui_line *gui_line_add (struct t_gui_buffer *buffer, +extern struct t_gui_line *gui_line_new (struct t_gui_buffer *buffer, + int y, time_t date, time_t date_printed, const char *tags, const char *prefix, const char *message); -extern void gui_line_add_y (struct t_gui_buffer *buffer, int y, - const char *message); +extern void gui_line_hook_update (struct t_gui_line *line, + struct t_hashtable *hashtable, + struct t_hashtable *hashtable2); +extern void gui_line_add (struct t_gui_line *line); +extern void gui_line_add_y (struct t_gui_line *line); extern void gui_line_clear (struct t_gui_line *line); extern void gui_line_mix_buffers (struct t_gui_buffer *buffer); extern struct t_hdata *gui_line_hdata_lines_cb (const void *pointer, diff --git a/src/plugins/guile/weechat-guile-api.c b/src/plugins/guile/weechat-guile-api.c index 6e48fa035..91c3b7c69 100644 --- a/src/plugins/guile/weechat-guile-api.c +++ b/src/plugins/guile/weechat-guile-api.c @@ -2454,6 +2454,58 @@ weechat_guile_api_hook_connect (SCM proxy, SCM address, SCM port, SCM ipv6, API_RETURN_STRING(result); } +struct t_hashtable * +weechat_guile_api_hook_line_cb (const void *pointer, void *data, + struct t_hashtable *line) +{ + struct t_plugin_script *script; + void *func_argv[2]; + char empty_arg[1] = { '\0' }; + const char *ptr_function, *ptr_data; + + script = (struct t_plugin_script *)pointer; + plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); + + if (ptr_function && ptr_function[0]) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + func_argv[1] = line; + + return (struct t_hashtable *)weechat_guile_exec ( + script, + WEECHAT_SCRIPT_EXEC_HASHTABLE, + ptr_function, + "sh", func_argv); + } + + return NULL; +} + +SCM +weechat_guile_api_hook_line (SCM buffer_type, SCM buffer_name, SCM tags, + SCM function, SCM data) +{ + const char *result; + SCM return_value; + + API_INIT_FUNC(1, "hook_line", API_RETURN_EMPTY); + if (!scm_is_string (buffer_type) || !scm_is_string (buffer_name) + || !scm_is_string (tags) || !scm_is_string (function) + || !scm_is_string (data)) + API_WRONG_ARGS(API_RETURN_EMPTY); + + result = API_PTR2STR(plugin_script_api_hook_line (weechat_guile_plugin, + guile_current_script, + API_SCM_TO_STRING(buffer_type), + API_SCM_TO_STRING(buffer_name), + API_SCM_TO_STRING(tags), + &weechat_guile_api_hook_line_cb, + API_SCM_TO_STRING(function), + API_SCM_TO_STRING(data))); + + API_RETURN_STRING(result); +} + int weechat_guile_api_hook_print_cb (const void *pointer, void *data, struct t_gui_buffer *buffer, @@ -4884,6 +4936,7 @@ weechat_guile_api_module_init (void *data) API_DEF_FUNC(hook_process, 4); API_DEF_FUNC(hook_process_hashtable, 5); API_DEF_FUNC(hook_connect, 8); + API_DEF_FUNC(hook_line, 5); API_DEF_FUNC(hook_print, 6); API_DEF_FUNC(hook_signal, 3); API_DEF_FUNC(hook_signal_send, 3); diff --git a/src/plugins/javascript/weechat-js-api.cpp b/src/plugins/javascript/weechat-js-api.cpp index de00752e4..4d2326752 100644 --- a/src/plugins/javascript/weechat-js-api.cpp +++ b/src/plugins/javascript/weechat-js-api.cpp @@ -2361,6 +2361,62 @@ API_FUNC(hook_connect) API_RETURN_STRING(result); } +struct t_hashtable * +weechat_js_api_hook_line_cb (const void *pointer, void *data, + struct t_hashtable *line) +{ + struct t_plugin_script *script; + void *func_argv[2]; + char empty_arg[1] = { '\0' }; + const char *ptr_function, *ptr_data; + struct t_hashtable *ret_hashtable; + + script = (struct t_plugin_script *)pointer; + plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); + + if (ptr_function && ptr_function[0]) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + func_argv[1] = line; + + ret_hashtable = (struct t_hashtable *)weechat_js_exec ( + script, + WEECHAT_SCRIPT_EXEC_HASHTABLE, + ptr_function, + "sh", func_argv); + + return ret_hashtable; + } + + return NULL; +} + +API_FUNC(hook_line) +{ + const char *result; + + API_INIT_FUNC(1, "hook_line", "sssss", API_RETURN_EMPTY); + + v8::String::Utf8Value buffer_type(args[0]); + v8::String::Utf8Value buffer_name(args[1]); + v8::String::Utf8Value tags(args[2]); + v8::String::Utf8Value function(args[3]); + v8::String::Utf8Value data(args[4]); + + result = API_PTR2STR( + plugin_script_api_hook_line ( + weechat_js_plugin, + js_current_script, + *buffer_type, + *buffer_name, + *tags, + &weechat_js_api_hook_line_cb, + *function, + *data)); + + API_RETURN_STRING(result); +} + int weechat_js_api_hook_print_cb (const void *pointer, void *data, struct t_gui_buffer *buffer, @@ -4831,6 +4887,7 @@ WeechatJsV8::loadLibs() API_DEF_FUNC(hook_process); API_DEF_FUNC(hook_process_hashtable); API_DEF_FUNC(hook_connect); + API_DEF_FUNC(hook_line); API_DEF_FUNC(hook_print); API_DEF_FUNC(hook_signal); API_DEF_FUNC(hook_signal_send); diff --git a/src/plugins/lua/weechat-lua-api.c b/src/plugins/lua/weechat-lua-api.c index 40eeab49c..ce23d031c 100644 --- a/src/plugins/lua/weechat-lua-api.c +++ b/src/plugins/lua/weechat-lua-api.c @@ -2583,6 +2583,60 @@ API_FUNC(hook_connect) API_RETURN_STRING(result); } +struct t_hashtable * +weechat_lua_api_hook_line_cb (const void *pointer, void *data, + struct t_hashtable *line) +{ + struct t_plugin_script *script; + void *func_argv[2]; + char empty_arg[1] = { '\0' }; + const char *ptr_function, *ptr_data; + + script = (struct t_plugin_script *)pointer; + plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); + + if (ptr_function && ptr_function[0]) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + func_argv[1] = line; + + return (struct t_hashtable *)weechat_lua_exec ( + script, + WEECHAT_SCRIPT_EXEC_HASHTABLE, + ptr_function, + "sh", func_argv); + } + + return NULL; +} + +API_FUNC(hook_line) +{ + const char *buffer_type, *buffer_name, *tags, *function, *data; + const char *result; + + API_INIT_FUNC(1, "hook_line", API_RETURN_EMPTY); + if (lua_gettop (L) < 5) + API_WRONG_ARGS(API_RETURN_EMPTY); + + buffer_type = lua_tostring (L, -5); + buffer_name = lua_tostring (L, -4); + tags = lua_tostring (L, -3); + function = lua_tostring (L, -2); + data = lua_tostring (L, -1); + + result = API_PTR2STR(plugin_script_api_hook_line (weechat_lua_plugin, + lua_current_script, + buffer_type, + buffer_name, + tags, + &weechat_lua_api_hook_line_cb, + function, + data)); + + API_RETURN_STRING(result); +} + int weechat_lua_api_hook_print_cb (const void *pointer, void *data, struct t_gui_buffer *buffer, @@ -5181,6 +5235,7 @@ const struct luaL_Reg weechat_lua_api_funcs[] = { API_DEF_FUNC(hook_process), API_DEF_FUNC(hook_process_hashtable), API_DEF_FUNC(hook_connect), + API_DEF_FUNC(hook_line), API_DEF_FUNC(hook_print), API_DEF_FUNC(hook_signal), API_DEF_FUNC(hook_signal_send), diff --git a/src/plugins/perl/weechat-perl-api.c b/src/plugins/perl/weechat-perl-api.c index a92f9e93b..a9da3ffa5 100644 --- a/src/plugins/perl/weechat-perl-api.c +++ b/src/plugins/perl/weechat-perl-api.c @@ -2484,6 +2484,61 @@ API_FUNC(hook_connect) API_RETURN_STRING(result); } +struct t_hashtable * +weechat_perl_api_hook_line_cb (const void *pointer, void *data, + struct t_hashtable *line) +{ + struct t_plugin_script *script; + void *func_argv[2]; + char empty_arg[1] = { '\0' }; + const char *ptr_function, *ptr_data; + + script = (struct t_plugin_script *)pointer; + plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); + + if (ptr_function && ptr_function[0]) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + func_argv[1] = line; + + return (struct t_hashtable *)weechat_perl_exec ( + script, + WEECHAT_SCRIPT_EXEC_HASHTABLE, + ptr_function, + "sh", func_argv); + } + + return NULL; +} + +API_FUNC(hook_line) +{ + char *buffer_type, *buffer_name, *tags, *function, *data; + const char *result; + dXSARGS; + + API_INIT_FUNC(1, "hook_line", API_RETURN_EMPTY); + if (items < 5) + API_WRONG_ARGS(API_RETURN_EMPTY); + + buffer_type = SvPV_nolen (ST (0)); + buffer_name = SvPV_nolen (ST (1)); + tags = SvPV_nolen (ST (2)); + function = SvPV_nolen (ST (3)); + data = SvPV_nolen (ST (4)); + + result = API_PTR2STR(plugin_script_api_hook_line (weechat_perl_plugin, + perl_current_script, + buffer_type, + buffer_name, + tags, + &weechat_perl_api_hook_line_cb, + function, + data)); + + API_RETURN_STRING(result); +} + int weechat_perl_api_hook_print_cb (const void *pointer, void *data, struct t_gui_buffer *buffer, @@ -5142,6 +5197,7 @@ weechat_perl_api_init (pTHX) API_DEF_FUNC(hook_process); API_DEF_FUNC(hook_process_hashtable); API_DEF_FUNC(hook_connect); + API_DEF_FUNC(hook_line); API_DEF_FUNC(hook_print); API_DEF_FUNC(hook_signal); API_DEF_FUNC(hook_signal_send); diff --git a/src/plugins/php/weechat-php-api.c b/src/plugins/php/weechat-php-api.c index e821dfd44..6620543bd 100644 --- a/src/plugins/php/weechat-php-api.c +++ b/src/plugins/php/weechat-php-api.c @@ -288,8 +288,8 @@ API_FUNC(iconv_to_internal) char *charset, *string, *result; API_INIT_FUNC(1, "iconv_to_internal", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_charset, &z_string) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", + &z_charset, &z_string) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); charset = ZSTR_VAL(z_charset); @@ -306,8 +306,8 @@ API_FUNC(iconv_from_internal) char *charset, *string, *result; API_INIT_FUNC(1, "iconv_from_internal", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_charset, &z_string) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", + &z_charset, &z_string) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); charset = ZSTR_VAL(z_charset); @@ -343,9 +343,8 @@ API_FUNC(ngettext) const char *result; API_INIT_FUNC(1, "ngettext", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSl", &z_single, &z_plural, - &z_count) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSl", + &z_single, &z_plural, &z_count) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); single = ZSTR_VAL(z_single); @@ -383,8 +382,7 @@ API_FUNC(string_match) char *string, *mask; API_INIT_FUNC(1, "string_match", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSl", &z_string, &z_mask, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSl", &z_string, &z_mask, &z_case_sensitive) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); @@ -406,8 +404,8 @@ API_FUNC(string_has_highlight) API_INIT_FUNC(1, "string_has_highlight", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_string, &z_highlight_words) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_string, + &z_highlight_words) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); string = ZSTR_VAL(z_string); @@ -425,8 +423,8 @@ API_FUNC(string_has_highlight_regex) int result; API_INIT_FUNC(1, "string_has_highlight_regex", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_string, &z_regex) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_string, + &z_regex) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); string = ZSTR_VAL(z_string); @@ -459,8 +457,7 @@ API_FUNC(string_format_size) char *result; API_INIT_FUNC(1, "string_format_size", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "l", &z_size) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "l", &z_size) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); result = weechat_string_format_size ((unsigned long long)z_size); @@ -474,8 +471,8 @@ API_FUNC(string_remove_color) char *string, *replacement, *result; API_INIT_FUNC(1, "string_remove_color", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_string, &z_replacement) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_string, + &z_replacement) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); string = ZSTR_VAL(z_string); @@ -526,9 +523,8 @@ API_FUNC(string_eval_expression) struct t_hashtable *pointers, *extra_vars, *options; API_INIT_FUNC(1, "string_eval_expression", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Saaa", &z_expr, &z_pointers, &z_extra_vars, - &z_options) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Saaa", &z_expr, &z_pointers, + &z_extra_vars, &z_options) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); expr = ZSTR_VAL(z_expr); @@ -563,8 +559,8 @@ API_FUNC(string_eval_path_home) struct t_hashtable *pointers, *extra_vars, *options; API_INIT_FUNC(1, "string_eval_path_home", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Saaa", &z_path, &z_pointers, &z_extra_vars, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Saaa", + &z_path, &z_pointers, &z_extra_vars, &z_options) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -600,8 +596,8 @@ API_FUNC(mkdir_home) int mode; API_INIT_FUNC(1, "mkdir_home", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Sl", &z_directory, &z_mode) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Sl", &z_directory, + &z_mode) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); directory = ZSTR_VAL(z_directory); @@ -620,8 +616,8 @@ API_FUNC(mkdir) int mode; API_INIT_FUNC(1, "mkdir", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Sl", &z_directory, &z_mode) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Sl", &z_directory, + &z_mode) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); directory = ZSTR_VAL(z_directory); @@ -640,8 +636,8 @@ API_FUNC(mkdir_parents) int mode; API_INIT_FUNC(1, "mkdir_parents", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Sl", &z_directory, &z_mode) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Sl", &z_directory, + &z_mode) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); directory = ZSTR_VAL(z_directory); @@ -674,9 +670,8 @@ API_FUNC(list_add) const char *result; API_INIT_FUNC(1, "list_add", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSS", &z_weelist, &z_data, &z_where, - &z_user_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSS", &z_weelist, &z_data, + &z_where, &z_user_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); weelist = (struct t_weelist *)API_STR2PTR(ZSTR_VAL(z_weelist)); @@ -700,8 +695,8 @@ API_FUNC(list_search) const char *result; API_INIT_FUNC(1, "list_search", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_weelist, &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_weelist, + &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); weelist = (struct t_weelist *)API_STR2PTR(ZSTR_VAL(z_weelist)); @@ -720,8 +715,8 @@ API_FUNC(list_search_pos) int result; API_INIT_FUNC(1, "list_search_pos", API_RETURN_INT(-1)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_weelist, &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_weelist, + &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(-1)); weelist = (struct t_weelist *)API_STR2PTR(ZSTR_VAL(z_weelist)); @@ -739,8 +734,8 @@ API_FUNC(list_casesearch) const char *result; API_INIT_FUNC(1, "list_casesearch", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_weelist, &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_weelist, + &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); weelist = (struct t_weelist *)API_STR2PTR(ZSTR_VAL(z_weelist)); @@ -760,8 +755,8 @@ API_FUNC(list_casesearch_pos) int result; API_INIT_FUNC(1, "list_casesearch_pos", API_RETURN_INT(-1)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_weelist, &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_weelist, + &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(-1)); weelist = (struct t_weelist *)API_STR2PTR(ZSTR_VAL(z_weelist)); @@ -780,8 +775,8 @@ API_FUNC(list_get) const char *result; API_INIT_FUNC(1, "list_get", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Sl", &z_weelist, &z_position) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Sl", &z_weelist, + &z_position) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); weelist = (struct t_weelist *)API_STR2PTR(ZSTR_VAL(z_weelist)); @@ -799,8 +794,8 @@ API_FUNC(list_set) char *value; API_INIT_FUNC(1, "list_set", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_item, &z_value) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_item, + &z_value) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); item = (struct t_weelist_item *)API_STR2PTR(ZSTR_VAL(z_item)); @@ -884,8 +879,8 @@ API_FUNC(list_remove) struct t_weelist_item *item; API_INIT_FUNC(1, "list_remove", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_weelist, &z_item) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_weelist, + &z_item) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); weelist = (struct t_weelist *)API_STR2PTR(ZSTR_VAL(z_weelist)); @@ -950,9 +945,8 @@ API_FUNC(config_new) const char *result; API_INIT_FUNC(1, "config_new", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SzS", &z_name, &z_callback_reload, - &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SzS", &z_name, + &z_callback_reload, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); name = ZSTR_VAL(z_name); @@ -1147,8 +1141,7 @@ API_FUNC(config_search_section) const char *result; API_INIT_FUNC(1, "config_search_section", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_config_file, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_config_file, &z_section_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -1287,8 +1280,8 @@ API_FUNC(config_search_option) const char *result; API_INIT_FUNC(1, "config_search_option", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_config_file, &z_section, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", + &z_config_file, &z_section, &z_option_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -1327,8 +1320,8 @@ API_FUNC(config_option_reset) int run_callback, result; API_INIT_FUNC(1, "config_option_reset", API_RETURN_INT(WEECHAT_CONFIG_OPTION_SET_ERROR)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Sl", &z_option, &z_run_callback) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Sl", + &z_option, &z_run_callback) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(WEECHAT_CONFIG_OPTION_SET_ERROR)); option = (struct t_config_option *)API_STR2PTR(ZSTR_VAL(z_option)); @@ -1347,8 +1340,8 @@ API_FUNC(config_option_set) int run_callback, result; API_INIT_FUNC(1, "config_option_set", API_RETURN_INT(WEECHAT_CONFIG_OPTION_SET_ERROR)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSl", &z_option, &z_value, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSl", + &z_option, &z_value, &z_run_callback) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(WEECHAT_CONFIG_OPTION_SET_ERROR)); @@ -1369,8 +1362,8 @@ API_FUNC(config_option_set_null) int run_callback, result; API_INIT_FUNC(1, "config_option_set_null", API_RETURN_INT(WEECHAT_CONFIG_OPTION_SET_ERROR)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Sl", &z_option, &z_run_callback) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Sl", + &z_option, &z_run_callback) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(WEECHAT_CONFIG_OPTION_SET_ERROR)); option = (struct t_config_option *)API_STR2PTR(ZSTR_VAL(z_option)); @@ -1403,8 +1396,8 @@ API_FUNC(config_option_rename) char *new_name; API_INIT_FUNC(1, "config_option_rename", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_option, &z_new_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", + &z_option, &z_new_name) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); option = (struct t_config_option *)API_STR2PTR(ZSTR_VAL(z_option)); @@ -1581,8 +1574,8 @@ API_FUNC(config_write_option) struct t_config_option *option; API_INIT_FUNC(1, "config_write_option", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_config_file, &z_option) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_config_file, + &z_option) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); config_file = (struct t_config_file *)API_STR2PTR(ZSTR_VAL(z_config_file)); @@ -1600,9 +1593,8 @@ API_FUNC(config_write_line) char *option_name, *value; API_INIT_FUNC(1, "config_write_line", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_config_file, &z_option_name, - &z_value) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_config_file, + &z_option_name, &z_value) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); config_file = (struct t_config_file *)API_STR2PTR(ZSTR_VAL(z_config_file)); @@ -1623,8 +1615,8 @@ API_FUNC(config_write) int result; API_INIT_FUNC(1, "config_write", API_RETURN_INT(WEECHAT_CONFIG_WRITE_ERROR)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "S", &z_config_file) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "S", + &z_config_file) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(WEECHAT_CONFIG_WRITE_ERROR)); config_file = (struct t_config_file *)API_STR2PTR(ZSTR_VAL(z_config_file)); @@ -1640,8 +1632,8 @@ API_FUNC(config_read) int result; API_INIT_FUNC(1, "config_read", API_RETURN_INT(WEECHAT_CONFIG_READ_FILE_NOT_FOUND)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "S", &z_config_file) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "S", + &z_config_file) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(WEECHAT_CONFIG_READ_FILE_NOT_FOUND)); config_file = (struct t_config_file *)API_STR2PTR(ZSTR_VAL(z_config_file)); @@ -1657,8 +1649,8 @@ API_FUNC(config_reload) int result; API_INIT_FUNC(1, "config_reload", API_RETURN_INT(WEECHAT_CONFIG_READ_FILE_NOT_FOUND)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "S", &z_config_file) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "S", + &z_config_file) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(WEECHAT_CONFIG_READ_FILE_NOT_FOUND)); config_file = (struct t_config_file *)API_STR2PTR(ZSTR_VAL(z_config_file)); @@ -1720,8 +1712,8 @@ API_FUNC(config_free) struct t_config_file *config_file; API_INIT_FUNC(1, "config_free", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "S", &z_config_file) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "S", + &z_config_file) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); config_file = (struct t_config_file *)API_STR2PTR(ZSTR_VAL(z_config_file)); @@ -1737,8 +1729,8 @@ API_FUNC(config_get) const char *result; API_INIT_FUNC(1, "config_get", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "S", &z_option_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "S", + &z_option_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); option_name = ZSTR_VAL(z_option_name); @@ -1791,8 +1783,8 @@ API_FUNC(config_set_plugin) int result; API_INIT_FUNC(1, "config_set_plugin", API_RETURN_INT(WEECHAT_CONFIG_OPTION_SET_ERROR)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_option, &z_value) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_option, + &z_value) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(WEECHAT_CONFIG_OPTION_SET_ERROR)); option = ZSTR_VAL(z_option); @@ -1811,8 +1803,8 @@ API_FUNC(config_set_desc_plugin) char *option, *description; API_INIT_FUNC(1, "config_set_desc_plugin", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_option, &z_description) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_option, + &z_description) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); option = ZSTR_VAL(z_option); @@ -1852,8 +1844,8 @@ API_FUNC(key_bind) int result; API_INIT_FUNC(1, "key_bind", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Sa", &z_context, &z_keys) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Sa", &z_context, + &z_keys) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); context = ZSTR_VAL(z_context); @@ -1873,8 +1865,8 @@ API_FUNC(key_unbind) char *context, *key; API_INIT_FUNC(1, "key_unbind", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_context, &z_key) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_context, + &z_key) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); context = ZSTR_VAL(z_context); @@ -1923,8 +1915,8 @@ API_FUNC(print) char *message; API_INIT_FUNC(0, "print", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_buffer, &z_message) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_buffer, + &z_message) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -1944,9 +1936,8 @@ API_FUNC(print_date_tags) char *tags, *message; API_INIT_FUNC(1, "print_date_tags", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SlSS", &z_buffer, &z_date, &z_tags, - &z_message) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SlSS", &z_buffer, &z_date, + &z_tags, &z_message) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -1973,8 +1964,8 @@ API_FUNC(print_y) char *message; API_INIT_FUNC(1, "print_y", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SlS", &z_buffer, &z_y, &z_message) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SlS", &z_buffer, &z_y, + &z_message) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -2035,10 +2026,9 @@ API_FUNC(hook_command) const char *result; API_INIT_FUNC(1, "hook_command", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSSSzS", &z_command, &z_description, &z_args, - &z_args_description, &z_completion, &z_callback, - &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSSSzS", &z_command, + &z_description, &z_args, &z_args_description, + &z_completion, &z_callback, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); command = ZSTR_VAL(z_command); @@ -2092,9 +2082,9 @@ API_FUNC(hook_completion) const char *result; API_INIT_FUNC(1, "hook_completion", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSzS", &z_completion, &z_description, - &z_callback, &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSzS", + &z_completion, &z_description, &z_callback, + &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); completion = ZSTR_VAL(z_completion); @@ -2123,8 +2113,8 @@ API_FUNC(hook_completion_get_string) const char *result; API_INIT_FUNC(1, "hook_completion_get_string", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_completion, &z_property) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_completion, + &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); completion = (struct t_gui_completion *)API_STR2PTR(ZSTR_VAL(z_completion)); @@ -2144,9 +2134,8 @@ API_FUNC(hook_completion_list_add) int nick_completion; API_INIT_FUNC(1, "hook_completion_list_add", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSlS", &z_completion, &z_word, - &z_nick_completion, &z_where) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSlS", &z_completion, + &z_word, &z_nick_completion, &z_where) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); completion = (struct t_gui_completion *)API_STR2PTR(ZSTR_VAL(z_completion)); @@ -2186,8 +2175,7 @@ API_FUNC(hook_command_run) const char *result; API_INIT_FUNC(1, "hook_command_run", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SzS", &z_command, &z_callback, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SzS", &z_command, &z_callback, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -2232,9 +2220,9 @@ API_FUNC(hook_timer) const char *result; API_INIT_FUNC(1, "hook_timer", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "lllzS", &z_interval, &z_align_second, - &z_max_calls, &z_callback, &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "lllzS", &z_interval, + &z_align_second, &z_max_calls, &z_callback, + &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); interval = (int)z_interval; @@ -2282,9 +2270,8 @@ API_FUNC(hook_fd) const char *result; API_INIT_FUNC(1, "hook_fd", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "llllzS", &z_fd, &z_flag_read, &z_flag_write, - &z_flag_exception, &z_callback, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "llllzS", &z_fd, &z_flag_read, + &z_flag_write, &z_flag_exception, &z_callback, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -2338,9 +2325,8 @@ API_FUNC(hook_process) const char *result; API_INIT_FUNC(1, "hook_process", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SlzS", &z_command, &z_timeout, &z_callback, - &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SlzS", &z_command, &z_timeout, + &z_callback, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); command = ZSTR_VAL(z_command); @@ -2392,9 +2378,9 @@ API_FUNC(hook_process_hashtable) const char *result; API_INIT_FUNC(1, "hook_process_hashtable", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SalzS", &z_command, &z_options, &z_timeout, - &z_callback, &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SalzS", &z_command, + &z_options, &z_timeout, &z_callback, + &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); command = ZSTR_VAL(z_command); @@ -2495,6 +2481,54 @@ API_FUNC(hook_connect) API_RETURN_STRING(result); } +struct t_hashtable * +weechat_php_api_hook_line_cb (const void *pointer, void *data, + struct t_hashtable *line) +{ + struct t_hashtable *rc; + void *func_argv[2]; + + func_argv[1] = line; + + weechat_php_cb (pointer, data, func_argv, "sh", + WEECHAT_SCRIPT_EXEC_HASHTABLE, &rc); + + return rc; +} + +API_FUNC(hook_line) +{ + zend_string *z_buffer_type, *z_buffer_name, *z_tags, *z_data; + zval *z_callback; + char *buffer_type, *buffer_name, *tags, *data; + const char *result; + + API_INIT_FUNC(1, "hook_line", API_RETURN_EMPTY); + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSzS", + &z_buffer_type, &z_buffer_name, &z_tags, + &z_callback, &z_data) == FAILURE) + API_WRONG_ARGS(API_RETURN_EMPTY); + + weechat_php_get_function_name (z_callback, callback_name); + buffer_type = ZSTR_VAL(z_buffer_type); + buffer_name = ZSTR_VAL(z_buffer_name); + tags = ZSTR_VAL(z_tags); + data = ZSTR_VAL(z_data); + + result = API_PTR2STR( + plugin_script_api_hook_line ( + weechat_php_plugin, + php_current_script, + (const char *)buffer_type, + (const char *)buffer_name, + (const char *)tags, + &weechat_php_api_hook_line_cb, + (const char *)callback_name, + (const char *)data)); + + API_RETURN_STRING(result); +} + static int weechat_php_api_hook_print_cb (const void *pointer, void *data, struct t_gui_buffer *buffer, time_t date, @@ -2531,9 +2565,8 @@ API_FUNC(hook_print) const char *result; API_INIT_FUNC(1, "hook_print", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSlzS", &z_buffer, &z_tags, &z_message, - &z_strip_colors, &z_callback, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSlzS", &z_buffer, &z_tags, + &z_message, &z_strip_colors, &z_callback, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -2547,7 +2580,8 @@ API_FUNC(hook_print) result = API_PTR2STR( plugin_script_api_hook_print ( weechat_php_plugin, - php_current_script, buffer, + php_current_script, + buffer, (const char *)tags, (const char *)message, strip_colors, @@ -2584,8 +2618,7 @@ API_FUNC(hook_signal) const char *result; API_INIT_FUNC(1, "hook_signal", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SzS", &z_signal, &z_callback, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SzS", &z_signal, &z_callback, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -2613,8 +2646,7 @@ API_FUNC(hook_signal_send) int result; API_INIT_FUNC(1, "hook_signal_send", API_RETURN_INT(WEECHAT_RC_ERROR)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_signal, &z_type_data, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_signal, &z_type_data, &z_signal_data) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(WEECHAT_RC_ERROR)); @@ -2652,8 +2684,7 @@ API_FUNC(hook_hsignal) const char *result; API_INIT_FUNC(1, "hook_hsignal", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SzS", &z_signal, &z_callback, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SzS", &z_signal, &z_callback, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -2682,8 +2713,8 @@ API_FUNC(hook_hsignal_send) int result; API_INIT_FUNC(1, "hook_hsignal_send", API_RETURN_INT(WEECHAT_RC_ERROR)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Sa", &z_signal, &z_hashtable) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Sa", &z_signal, + &z_hashtable) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(WEECHAT_RC_ERROR)); signal = ZSTR_VAL(z_signal); @@ -2721,8 +2752,7 @@ API_FUNC(hook_config) const char *result; API_INIT_FUNC(1, "hook_config", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SzS", &z_option, &z_callback, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SzS", &z_option, &z_callback, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -2769,9 +2799,8 @@ API_FUNC(hook_modifier) const char *result; API_INIT_FUNC(1, "hook_modifier", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SzS", &z_modifier, &z_callback, - &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SzS", &z_modifier, + &z_callback, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); modifier = ZSTR_VAL(z_modifier); @@ -2796,9 +2825,8 @@ API_FUNC(hook_modifier_exec) char *modifier, *modifier_data, *string, *result; API_INIT_FUNC(1, "hook_modifier_exec", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_modifier, &z_modifier_data, - &z_string) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_modifier, + &z_modifier_data, &z_string) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); modifier = ZSTR_VAL(z_modifier); @@ -2837,10 +2865,9 @@ API_FUNC(hook_info) const char *result; API_INIT_FUNC(1, "hook_info", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSzS", &z_info_name, &z_description, - &z_args_description, &z_callback, - &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSzS", &z_info_name, + &z_description, &z_args_description, + &z_callback, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); info_name = ZSTR_VAL(z_info_name); @@ -2890,10 +2917,10 @@ API_FUNC(hook_info_hashtable) const char *result; API_INIT_FUNC(1, "hook_info_hashtable", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSSSzS", &z_info_name, &z_description, - &z_args_description, &z_output_description, - &z_callback, &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSSSzS", &z_info_name, + &z_description, &z_args_description, + &z_output_description, &z_callback, + &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); info_name = ZSTR_VAL(z_info_name); @@ -2947,10 +2974,10 @@ API_FUNC(hook_infolist) const char *result; API_INIT_FUNC(1, "hook_infolist", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSSzS", &z_infolist_name, &z_description, - &z_pointer_description, &z_args_description, - &z_callback, &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSSzS", &z_infolist_name, + &z_description, &z_pointer_description, + &z_args_description, &z_callback, + &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); infolist_name = ZSTR_VAL(z_infolist_name); @@ -3107,10 +3134,9 @@ API_FUNC(buffer_new) const char *result; API_INIT_FUNC(1, "buffer_new", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SzSzS", &z_name, &z_input_callback, - &z_data_input, &z_close_callback, - &z_data_close) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SzSzS", &z_name, + &z_input_callback, &z_data_input, + &z_close_callback, &z_data_close) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); name = ZSTR_VAL(z_name); @@ -3141,8 +3167,8 @@ API_FUNC(buffer_search) const char *result; API_INIT_FUNC(1, "buffer_search", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_plugin, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_plugin, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); plugin = ZSTR_VAL(z_plugin); @@ -3218,8 +3244,8 @@ API_FUNC(buffer_merge) struct t_gui_buffer *target_buffer; API_INIT_FUNC(1, "buffer_merge", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_buffer, &z_target_buffer) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_buffer, + &z_target_buffer) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3237,8 +3263,8 @@ API_FUNC(buffer_unmerge) int number; API_INIT_FUNC(1, "buffer_unmerge", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Sl", &z_buffer, &z_number) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Sl", &z_buffer, + &z_number) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3256,8 +3282,8 @@ API_FUNC(buffer_get_integer) int result; API_INIT_FUNC(1, "buffer_get_integer", API_RETURN_INT(-1)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_buffer, &z_property) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_buffer, + &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(-1)); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3275,8 +3301,8 @@ API_FUNC(buffer_get_string) char *property; API_INIT_FUNC(1, "buffer_get_string", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_buffer, &z_property) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_buffer, + &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3294,8 +3320,8 @@ API_FUNC(buffer_get_pointer) const char *result; API_INIT_FUNC(1, "buffer_get_pointer", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_buffer, &z_property) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_buffer, + &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3314,8 +3340,7 @@ API_FUNC(buffer_set) char *property, *value; API_INIT_FUNC(1, "buffer_set", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_buffer, &z_property, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_buffer, &z_property, &z_value) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); @@ -3334,8 +3359,8 @@ API_FUNC(buffer_string_replace_local_var) char *string, *result; API_INIT_FUNC(1, "buffer_string_replace_local_var", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_buffer, &z_string) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_buffer, + &z_string) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3354,8 +3379,8 @@ API_FUNC(buffer_match_list) int result; API_INIT_FUNC(1, "buffer_match_list", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_buffer, &z_string) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_buffer, + &z_string) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3403,8 +3428,8 @@ API_FUNC(window_get_integer) int result; API_INIT_FUNC(1, "window_get_integer", API_RETURN_INT(-1)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_window, &z_property) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_window, + &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(-1)); window = (struct t_gui_window *)API_STR2PTR(ZSTR_VAL(z_window)); @@ -3422,8 +3447,8 @@ API_FUNC(window_get_string) const char *result; API_INIT_FUNC(1, "window_get_string", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_window, &z_property) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_window, + &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); window = (struct t_gui_window *)API_STR2PTR(ZSTR_VAL(z_window)); @@ -3441,8 +3466,8 @@ API_FUNC(window_get_pointer) const char *result; API_INIT_FUNC(1, "window_get_pointer", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_window, &z_property) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_window, + &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); window = (struct t_gui_window *)API_STR2PTR(ZSTR_VAL(z_window)); @@ -3480,9 +3505,9 @@ API_FUNC(nicklist_add_group) const char *result; API_INIT_FUNC(1, "nicklist_add_group", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSSl", &z_buffer, &z_parent_group, &z_name, - &z_color, &z_visible) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSSl", &z_buffer, + &z_parent_group, &z_name, &z_color, + &z_visible) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3509,9 +3534,8 @@ API_FUNC(nicklist_search_group) const char *result; API_INIT_FUNC(1, "nicklist_search_group", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_buffer, &z_from_group, - &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_buffer, + &z_from_group, &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3537,10 +3561,9 @@ API_FUNC(nicklist_add_nick) const char *result; API_INIT_FUNC(1, "nicklist_add_nick", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSSSSl", &z_buffer, &z_group, &z_name, - &z_color, &z_prefix, &z_prefix_color, - &z_visible) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSSSSl", &z_buffer, + &z_group, &z_name, &z_color, &z_prefix, + &z_prefix_color, &z_visible) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3573,9 +3596,8 @@ API_FUNC(nicklist_search_nick) const char *result; API_INIT_FUNC(1, "nicklist_search_nick", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_buffer, &z_from_group, - &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_buffer, + &z_from_group, &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3596,8 +3618,8 @@ API_FUNC(nicklist_remove_group) struct t_gui_nick_group *group; API_INIT_FUNC(1, "nicklist_remove_group", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_buffer, &z_group) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_buffer, + &z_group) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3614,8 +3636,8 @@ API_FUNC(nicklist_remove_nick) struct t_gui_nick *nick; API_INIT_FUNC(1, "nicklist_remove_nick", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_buffer, &z_nick) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_buffer, + &z_nick) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3649,8 +3671,7 @@ API_FUNC(nicklist_group_get_integer) int result; API_INIT_FUNC(1, "nicklist_group_get_integer", API_RETURN_INT(-1)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_buffer, &z_group, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_buffer, &z_group, &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(-1)); @@ -3673,8 +3694,7 @@ API_FUNC(nicklist_group_get_string) const char *result; API_INIT_FUNC(1, "nicklist_group_get_string", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_buffer, &z_group, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_buffer, &z_group, &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -3697,8 +3717,7 @@ API_FUNC(nicklist_group_get_pointer) const char *result; API_INIT_FUNC(1, "nicklist_group_get_pointer", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_buffer, &z_group, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_buffer, &z_group, &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -3722,9 +3741,8 @@ API_FUNC(nicklist_group_set) char *property, *value; API_INIT_FUNC(1, "nicklist_group_set", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSS", &z_buffer, &z_group, &z_property, - &z_value) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSS", &z_buffer, &z_group, + &z_property, &z_value) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3748,8 +3766,7 @@ API_FUNC(nicklist_nick_get_integer) int result; API_INIT_FUNC(1, "nicklist_nick_get_integer", API_RETURN_INT(-1)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_buffer, &z_nick, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_buffer, &z_nick, &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(-1)); @@ -3772,8 +3789,7 @@ API_FUNC(nicklist_nick_get_string) const char *result; API_INIT_FUNC(1, "nicklist_nick_get_string", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_buffer, &z_nick, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_buffer, &z_nick, &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -3796,8 +3812,7 @@ API_FUNC(nicklist_nick_get_pointer) const char *result; API_INIT_FUNC(1, "nicklist_nick_get_pointer", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_buffer, &z_nick, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_buffer, &z_nick, &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); @@ -3821,9 +3836,8 @@ API_FUNC(nicklist_nick_set) char *property, *value; API_INIT_FUNC(1, "nicklist_nick_set", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSS", &z_buffer, &z_nick, &z_property, - &z_value) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSS", &z_buffer, &z_nick, + &z_property, &z_value) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -3884,9 +3898,8 @@ API_FUNC(bar_item_new) const char *result; API_INIT_FUNC(1, "bar_item_new", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SzS", &z_name, &z_build_callback, - &z_data) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SzS", &z_name, + &z_build_callback, &z_data) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); name = ZSTR_VAL(z_name); @@ -4017,8 +4030,8 @@ API_FUNC(bar_set) int result; API_INIT_FUNC(1, "bar_set", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_bar, &z_property, &z_value) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_bar, &z_property, + &z_value) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); bar = (struct t_gui_bar *)API_STR2PTR(ZSTR_VAL(z_bar)); @@ -4067,8 +4080,8 @@ API_FUNC(command) int result; API_INIT_FUNC(1, "command", API_RETURN_INT(WEECHAT_RC_ERROR)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_buffer, &z_command) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_buffer, + &z_command) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(WEECHAT_RC_ERROR)); buffer = (struct t_gui_buffer *)API_STR2PTR(ZSTR_VAL(z_buffer)); @@ -4088,8 +4101,8 @@ API_FUNC(info_get) const char *result; API_INIT_FUNC(1, "info_get", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_info_name, &z_arguments) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_info_name, + &z_arguments) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); info_name = ZSTR_VAL(z_info_name); @@ -4108,8 +4121,8 @@ API_FUNC(info_get_hashtable) struct t_hashtable *hashtable, *result; API_INIT_FUNC(1, "info_get_hashtable", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "Sa", &z_info_name, &z_hashtable) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "Sa", &z_info_name, + &z_hashtable) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); info_name = ZSTR_VAL(z_info_name); @@ -4163,8 +4176,8 @@ API_FUNC(infolist_new_var_integer) const char *result; API_INIT_FUNC(1, "infolist_new_var_integer", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSl", &z_item, &z_name, &z_value) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSl", &z_item, &z_name, + &z_value) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); item = (struct t_infolist_item *)API_STR2PTR(ZSTR_VAL(z_item)); @@ -4186,8 +4199,8 @@ API_FUNC(infolist_new_var_string) const char *result; API_INIT_FUNC(1, "infolist_new_var_string", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_item, &z_name, &z_value) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_item, &z_name, + &z_value) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); item = (struct t_infolist_item *)API_STR2PTR(ZSTR_VAL(z_item)); @@ -4211,8 +4224,8 @@ API_FUNC(infolist_new_var_pointer) const char *result; API_INIT_FUNC(1, "infolist_new_var_pointer", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_item, &z_name, &z_pointer) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_item, &z_name, + &z_pointer) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); item = (struct t_infolist_item *)API_STR2PTR(ZSTR_VAL(z_item)); @@ -4237,8 +4250,8 @@ API_FUNC(infolist_new_var_time) const char *result; API_INIT_FUNC(1, "infolist_new_var_time", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSl", &z_item, &z_name, &z_time) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSl", &z_item, &z_name, + &z_time) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); item = (struct t_infolist_item *)API_STR2PTR(ZSTR_VAL(z_item)); @@ -4259,8 +4272,8 @@ API_FUNC(infolist_search_var) const char *result; API_INIT_FUNC(1, "infolist_search_var", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_infolist, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_infolist, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); infolist = (struct t_infolist *)API_STR2PTR(ZSTR_VAL(z_infolist)); @@ -4280,9 +4293,8 @@ API_FUNC(infolist_get) const char *result; API_INIT_FUNC(1, "infolist_get", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_infolist_name, &z_pointer, - &z_arguments) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_infolist_name, + &z_pointer, &z_arguments) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); infolist_name = ZSTR_VAL(z_infolist_name); @@ -4368,8 +4380,8 @@ API_FUNC(infolist_integer) int result; API_INIT_FUNC(1, "infolist_integer", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_infolist, &z_var) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_infolist, + &z_var) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); infolist = (struct t_infolist *)API_STR2PTR(ZSTR_VAL(z_infolist)); @@ -4387,8 +4399,8 @@ API_FUNC(infolist_string) const char *result; API_INIT_FUNC(1, "infolist_string", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_infolist, &z_var) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_infolist, + &z_var) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); infolist = (struct t_infolist *)API_STR2PTR(ZSTR_VAL(z_infolist)); @@ -4406,8 +4418,8 @@ API_FUNC(infolist_pointer) const char *result; API_INIT_FUNC(1, "infolist_pointer", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_infolist, &z_var) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_infolist, + &z_var) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); infolist = (struct t_infolist *)API_STR2PTR(ZSTR_VAL(z_infolist)); @@ -4427,8 +4439,8 @@ API_FUNC(infolist_time) time_t time; API_INIT_FUNC(1, "infolist_time", API_RETURN_LONG(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_infolist, &z_var) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_infolist, + &z_var) == FAILURE) API_WRONG_ARGS(API_RETURN_LONG(0)); infolist = (struct t_infolist *)API_STR2PTR(ZSTR_VAL(z_infolist)); @@ -4479,8 +4491,8 @@ API_FUNC(hdata_get_var_offset) int result; API_INIT_FUNC(1, "hdata_get_var_offset", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_hdata, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_hdata, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4498,8 +4510,8 @@ API_FUNC(hdata_get_var_type_string) const char *result; API_INIT_FUNC(1, "hdata_get_var_type_string", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_hdata, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_hdata, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4518,8 +4530,8 @@ API_FUNC(hdata_get_var_array_size) int result; API_INIT_FUNC(1, "hdata_get_var_array_size", API_RETURN_INT(-1)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_hdata, &z_pointer, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_hdata, &z_pointer, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(-1)); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4541,8 +4553,8 @@ API_FUNC(hdata_get_var_array_size_string) const char *result; API_INIT_FUNC(1, "hdata_get_var_array_size_string", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_hdata, &z_pointer, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_hdata, &z_pointer, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4563,8 +4575,8 @@ API_FUNC(hdata_get_var_hdata) const char *result; API_INIT_FUNC(1, "hdata_get_var_hdata", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_hdata, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_hdata, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4582,8 +4594,8 @@ API_FUNC(hdata_get_list) const char *result; API_INIT_FUNC(1, "hdata_get_list", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_hdata, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_hdata, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4603,8 +4615,8 @@ API_FUNC(hdata_check_pointer) int result; API_INIT_FUNC(1, "hdata_check_pointer", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_hdata, &z_list, &z_pointer) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_hdata, &z_list, + &z_pointer) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4625,8 +4637,8 @@ API_FUNC(hdata_move) const char *result; API_INIT_FUNC(1, "hdata_move", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSl", &z_hdata, &z_pointer, &z_count) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSl", &z_hdata, &z_pointer, + &z_count) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4649,9 +4661,8 @@ API_FUNC(hdata_search) const char *result; API_INIT_FUNC(1, "hdata_search", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSl", &z_hdata, &z_pointer, &z_search, - &z_move) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSl", &z_hdata, &z_pointer, + &z_search, &z_move) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4673,8 +4684,8 @@ API_FUNC(hdata_char) char *name, result; API_INIT_FUNC(1, "hdata_char", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_hdata, &z_pointer, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_hdata, &z_pointer, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4694,8 +4705,8 @@ API_FUNC(hdata_integer) int result; API_INIT_FUNC(1, "hdata_integer", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_hdata, &z_pointer, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_hdata, &z_pointer, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4715,8 +4726,8 @@ API_FUNC(hdata_long) long result; API_INIT_FUNC(1, "hdata_long", API_RETURN_LONG(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_hdata, &z_pointer, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_hdata, &z_pointer, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_LONG(0)); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4736,8 +4747,8 @@ API_FUNC(hdata_string) const char *result; API_INIT_FUNC(1, "hdata_string", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_hdata, &z_pointer, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_hdata, &z_pointer, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4757,8 +4768,8 @@ API_FUNC(hdata_pointer) const char *result; API_INIT_FUNC(1, "hdata_pointer", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_hdata, &z_pointer, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_hdata, &z_pointer, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4780,8 +4791,8 @@ API_FUNC(hdata_time) time_t result; API_INIT_FUNC(1, "hdata_time", API_RETURN_LONG(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_hdata, &z_pointer, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_hdata, &z_pointer, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_LONG(0)); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4801,8 +4812,8 @@ API_FUNC(hdata_hashtable) struct t_hashtable *result; API_INIT_FUNC(1, "hdata_hashtable", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSS", &z_hdata, &z_pointer, &z_name) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSS", &z_hdata, &z_pointer, + &z_name) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4823,9 +4834,9 @@ API_FUNC(hdata_compare) int case_sensitive, result; API_INIT_FUNC(1, "hdata_compare", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSSSl", &z_hdata, &z_pointer1, &z_pointer2, - &z_name, &z_case_sensitive) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSSSl", &z_hdata, &z_pointer1, + &z_pointer2, &z_name, + &z_case_sensitive) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4849,8 +4860,7 @@ API_FUNC(hdata_update) struct t_hashtable *hashtable; API_INIT_FUNC(1, "hdata_update", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SSa", &z_hdata, &z_pointer, + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SSa", &z_hdata, &z_pointer, &z_hashtable) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); @@ -4874,8 +4884,8 @@ API_FUNC(hdata_get_string) const char *result; API_INIT_FUNC(1, "hdata_get_string", API_RETURN_EMPTY); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SS", &z_hdata, &z_property) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SS", &z_hdata, + &z_property) == FAILURE) API_WRONG_ARGS(API_RETURN_EMPTY); hdata = (struct t_hdata *)API_STR2PTR(ZSTR_VAL(z_hdata)); @@ -4943,9 +4953,8 @@ API_FUNC(upgrade_write_object) int result; API_INIT_FUNC(1, "upgrade_write_object", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "SlS", &z_upgrade_file, &z_object_id, - &z_infolist) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "SlS", &z_upgrade_file, + &z_object_id, &z_infolist) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); upgrade_file = (struct t_upgrade_file *)API_STR2PTR(ZSTR_VAL(z_upgrade_file)); @@ -4963,8 +4972,8 @@ API_FUNC(upgrade_read) int result; API_INIT_FUNC(1, "upgrade_read", API_RETURN_INT(0)); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "S", &z_upgrade_file) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "S", + &z_upgrade_file) == FAILURE) API_WRONG_ARGS(API_RETURN_INT(0)); upgrade_file = (struct t_upgrade_file *)API_STR2PTR(ZSTR_VAL(z_upgrade_file)); @@ -4979,8 +4988,8 @@ API_FUNC(upgrade_close) struct t_upgrade_file *upgrade_file; API_INIT_FUNC(1, "upgrade_close", API_RETURN_ERROR); - if (zend_parse_parameters (ZEND_NUM_ARGS(), - "S", &z_upgrade_file) == FAILURE) + if (zend_parse_parameters (ZEND_NUM_ARGS(), "S", + &z_upgrade_file) == FAILURE) API_WRONG_ARGS(API_RETURN_ERROR); upgrade_file = (struct t_upgrade_file *)API_STR2PTR(ZSTR_VAL(z_upgrade_file)); diff --git a/src/plugins/php/weechat-php-api.h b/src/plugins/php/weechat-php-api.h index eb0e5db69..132340fee 100644 --- a/src/plugins/php/weechat-php-api.h +++ b/src/plugins/php/weechat-php-api.h @@ -135,6 +135,7 @@ PHP_FUNCTION(weechat_hook_fd); PHP_FUNCTION(weechat_hook_process); PHP_FUNCTION(weechat_hook_process_hashtable); PHP_FUNCTION(weechat_hook_connect); +PHP_FUNCTION(weechat_hook_line); PHP_FUNCTION(weechat_hook_print); PHP_FUNCTION(weechat_hook_signal); PHP_FUNCTION(weechat_hook_signal_send); diff --git a/src/plugins/php/weechat-php.c b/src/plugins/php/weechat-php.c index 1e2bdc6c8..159f5aad2 100644 --- a/src/plugins/php/weechat-php.c +++ b/src/plugins/php/weechat-php.c @@ -189,6 +189,7 @@ const zend_function_entry weechat_functions[] = { PHP_FE(weechat_hook_process, NULL) PHP_FE(weechat_hook_process_hashtable, NULL) PHP_FE(weechat_hook_connect, NULL) + PHP_FE(weechat_hook_line, NULL) PHP_FE(weechat_hook_print, NULL) PHP_FE(weechat_hook_signal, NULL) PHP_FE(weechat_hook_signal_send, NULL) diff --git a/src/plugins/plugin-script-api.c b/src/plugins/plugin-script-api.c index d922df411..cc91bc9ad 100644 --- a/src/plugins/plugin-script-api.c +++ b/src/plugins/plugin-script-api.c @@ -658,6 +658,48 @@ plugin_script_api_hook_connect (struct t_weechat_plugin *weechat_plugin, } /* + * Hooks a line. + * + * Returns pointer to new hook, NULL if error. + */ + +struct t_hook * +plugin_script_api_hook_line (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script, + const char *buffer_type, + const char *buffer_name, + const char *tags, + struct t_hashtable *(*callback)(const void *pointer, + void *data, + struct t_hashtable *line), + const char *function, + const char *data) +{ + char *function_and_data; + struct t_hook *new_hook; + + if (!script) + return NULL; + + function_and_data = plugin_script_build_function_and_data (function, data); + + new_hook = weechat_hook_line (buffer_type, buffer_name, tags, callback, + script, function_and_data); + + if (new_hook) + { + weechat_hook_set (new_hook, "subplugin", script->name); + } + else + { + if (function_and_data) + free (function_and_data); + } + + return new_hook; +} + +/* * Hooks a message printed by WeeChat. * * Returns pointer to new hook, NULL if error. diff --git a/src/plugins/plugin-script-api.h b/src/plugins/plugin-script-api.h index 58ef7edf6..d0c1e94af 100644 --- a/src/plugins/plugin-script-api.h +++ b/src/plugins/plugin-script-api.h @@ -203,6 +203,16 @@ extern struct t_hook *plugin_script_api_hook_connect (struct t_weechat_plugin *w const char *ip_address), const char *function, const char *data); +extern struct t_hook *plugin_script_api_hook_line (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script, + const char *buffer_type, + const char *buffer_name, + const char *tags, + struct t_hashtable *(*callback)(const void *pointer, + void *data, + struct t_hashtable *line), + const char *function, + const char *data); extern struct t_hook *plugin_script_api_hook_print (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *script, struct t_gui_buffer *buffer, diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 0a49aa4e3..e99c5a189 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -777,6 +777,7 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv) new_plugin->hook_process = &hook_process; new_plugin->hook_process_hashtable = &hook_process_hashtable; new_plugin->hook_connect = &hook_connect; + new_plugin->hook_line = &hook_line; new_plugin->hook_print = &hook_print; new_plugin->hook_signal = &hook_signal; new_plugin->hook_signal_send = &hook_signal_send; diff --git a/src/plugins/python/weechat-python-api.c b/src/plugins/python/weechat-python-api.c index 82399b494..68f983272 100644 --- a/src/plugins/python/weechat-python-api.c +++ b/src/plugins/python/weechat-python-api.c @@ -2510,6 +2510,67 @@ API_FUNC(hook_connect) API_RETURN_STRING(result); } +struct t_hashtable * +weechat_python_api_hook_line_cb (const void *pointer, void *data, + struct t_hashtable *line) +{ + struct t_plugin_script *script; + void *func_argv[2]; + char empty_arg[1] = { '\0' }; + const char *ptr_function, *ptr_data; + struct t_hashtable *ret_hashtable; + + script = (struct t_plugin_script *)pointer; + plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); + + if (ptr_function && ptr_function[0]) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + func_argv[1] = weechat_python_hashtable_to_dict (line); + + ret_hashtable = weechat_python_exec (script, + WEECHAT_SCRIPT_EXEC_HASHTABLE, + ptr_function, + "sO", func_argv); + + if (func_argv[1]) + { + Py_XDECREF((PyObject *)func_argv[1]); + } + + return ret_hashtable; + } + + return NULL; +} + +API_FUNC(hook_line) +{ + char *buffer_type, *buffer_name, *tags, *function, *data; + const char *result; + + API_INIT_FUNC(1, "hook_line", API_RETURN_EMPTY); + buffer_type = NULL; + buffer_name = NULL; + tags = NULL; + function = NULL; + data = NULL; + if (!PyArg_ParseTuple (args, "sssss", &buffer_type, &buffer_name, &tags, + &function, &data)) + API_WRONG_ARGS(API_RETURN_EMPTY); + + result = API_PTR2STR(plugin_script_api_hook_line (weechat_python_plugin, + python_current_script, + buffer_type, + buffer_name, + tags, + &weechat_python_api_hook_line_cb, + function, + data)); + + API_RETURN_STRING(result); +} + int weechat_python_api_hook_print_cb (const void *pointer, void *data, struct t_gui_buffer *buffer, @@ -5084,6 +5145,7 @@ PyMethodDef weechat_python_funcs[] = API_DEF_FUNC(hook_process), API_DEF_FUNC(hook_process_hashtable), API_DEF_FUNC(hook_connect), + API_DEF_FUNC(hook_line), API_DEF_FUNC(hook_print), API_DEF_FUNC(hook_signal), API_DEF_FUNC(hook_signal_send), diff --git a/src/plugins/ruby/weechat-ruby-api.c b/src/plugins/ruby/weechat-ruby-api.c index bfe889962..5f4f7a995 100644 --- a/src/plugins/ruby/weechat-ruby-api.c +++ b/src/plugins/ruby/weechat-ruby-api.c @@ -3033,6 +3033,69 @@ weechat_ruby_api_hook_connect (VALUE class, VALUE proxy, VALUE address, API_RETURN_STRING(result); } +struct t_hashtable * +weechat_ruby_api_hook_line_cb (const void *pointer, void *data, + struct t_hashtable *line) +{ + struct t_plugin_script *script; + void *func_argv[2]; + char empty_arg[1] = { '\0' }; + const char *ptr_function, *ptr_data; + + script = (struct t_plugin_script *)pointer; + plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); + + if (ptr_function && ptr_function[0]) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + func_argv[1] = line; + + return (struct t_hashtable *)weechat_ruby_exec ( + script, + WEECHAT_SCRIPT_EXEC_HASHTABLE, + ptr_function, + "sh", func_argv); + } + + return NULL; +} + +static VALUE +weechat_ruby_api_hook_line (VALUE class, VALUE buffer_type, VALUE buffer_name, + VALUE tags, VALUE function, VALUE data) +{ + char *c_buffer_type, *c_buffer_name, *c_tags, *c_function, *c_data; + const char *result; + + API_INIT_FUNC(1, "hook_line", API_RETURN_EMPTY); + if (NIL_P (buffer_type) || NIL_P (buffer_name) || NIL_P (tags) + || NIL_P (function) || NIL_P (data)) + API_WRONG_ARGS(API_RETURN_EMPTY); + + Check_Type (buffer_type, T_STRING); + Check_Type (buffer_name, T_STRING); + Check_Type (tags, T_STRING); + Check_Type (function, T_STRING); + Check_Type (data, T_STRING); + + c_buffer_type = StringValuePtr (buffer_type); + c_buffer_name = StringValuePtr (buffer_name); + c_tags = StringValuePtr (tags); + c_function = StringValuePtr (function); + c_data = StringValuePtr (data); + + result = API_PTR2STR(plugin_script_api_hook_line (weechat_ruby_plugin, + ruby_current_script, + c_buffer_type, + c_buffer_name, + c_tags, + &weechat_ruby_api_hook_line_cb, + c_function, + c_data)); + + API_RETURN_STRING(result); +} + int weechat_ruby_api_hook_print_cb (const void *pointer, void *data, struct t_gui_buffer *buffer, @@ -6236,6 +6299,7 @@ weechat_ruby_api_init (VALUE ruby_mWeechat) API_DEF_FUNC(hook_process, 4); API_DEF_FUNC(hook_process_hashtable, 5); API_DEF_FUNC(hook_connect, 8); + API_DEF_FUNC(hook_line, 5); API_DEF_FUNC(hook_print, 6); API_DEF_FUNC(hook_signal, 3); API_DEF_FUNC(hook_signal_send, 3); diff --git a/src/plugins/tcl/weechat-tcl-api.c b/src/plugins/tcl/weechat-tcl-api.c index 2159ec645..fe80fcd03 100644 --- a/src/plugins/tcl/weechat-tcl-api.c +++ b/src/plugins/tcl/weechat-tcl-api.c @@ -2763,6 +2763,62 @@ API_FUNC(hook_connect) API_RETURN_STRING(result); } +struct t_hashtable * +weechat_tcl_api_hook_line_cb (const void *pointer, void *data, + struct t_hashtable *line) +{ + struct t_plugin_script *script; + void *func_argv[2]; + char empty_arg[1] = { '\0' }; + const char *ptr_function, *ptr_data; + + script = (struct t_plugin_script *)pointer; + plugin_script_get_function_and_data (data, &ptr_function, &ptr_data); + + if (ptr_function && ptr_function[0]) + { + func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg; + func_argv[1] = line; + + return (struct t_hashtable *)weechat_tcl_exec ( + script, + WEECHAT_SCRIPT_EXEC_HASHTABLE, + ptr_function, + "sh", func_argv); + } + + return NULL; +} + +API_FUNC(hook_line) +{ + Tcl_Obj *objp; + char *buffer_type, *buffer_name, *tags, *function, *data; + const char *result; + int i; + + API_INIT_FUNC(1, "hook_line", API_RETURN_EMPTY); + if (objc < 6) + API_WRONG_ARGS(API_RETURN_EMPTY); + + buffer_type = Tcl_GetStringFromObj (objv[1], &i); + buffer_name = Tcl_GetStringFromObj (objv[2], &i); + tags = Tcl_GetStringFromObj (objv[3], &i); + function = Tcl_GetStringFromObj (objv[4], &i); + data = Tcl_GetStringFromObj (objv[5], &i); + + result = API_PTR2STR(plugin_script_api_hook_line (weechat_tcl_plugin, + tcl_current_script, + buffer_type, + buffer_name, + tags, + &weechat_tcl_api_hook_line_cb, + function, + data)); + + API_RETURN_STRING(result); +} + int weechat_tcl_api_hook_print_cb (const void *pointer, void *data, struct t_gui_buffer *buffer, @@ -5611,6 +5667,7 @@ void weechat_tcl_api_init (Tcl_Interp *interp) API_DEF_FUNC(hook_process); API_DEF_FUNC(hook_process_hashtable); API_DEF_FUNC(hook_connect); + API_DEF_FUNC(hook_line); API_DEF_FUNC(hook_print); API_DEF_FUNC(hook_signal); API_DEF_FUNC(hook_signal_send); diff --git a/src/plugins/trigger/trigger-callback.c b/src/plugins/trigger/trigger-callback.c index 2ed0909b4..0ef7cc279 100644 --- a/src/plugins/trigger/trigger-callback.c +++ b/src/plugins/trigger/trigger-callback.c @@ -227,6 +227,7 @@ void trigger_callback_replace_regex (struct t_trigger *trigger, struct t_hashtable *pointers, struct t_hashtable *extra_vars, + struct t_weelist *vars_updated, int display_monitor) { char *value; @@ -312,6 +313,11 @@ trigger_callback_replace_regex (struct t_trigger *trigger, weechat_color ("chat_delimiters")); } weechat_hashtable_set (extra_vars, ptr_key, value); + if (vars_updated) + { + weechat_list_add (vars_updated, ptr_key, WEECHAT_LIST_POS_END, + NULL); + } free (value); } } @@ -392,7 +398,8 @@ void trigger_callback_execute (struct t_trigger *trigger, struct t_gui_buffer *buffer, struct t_hashtable *pointers, - struct t_hashtable *extra_vars) + struct t_hashtable *extra_vars, + struct t_weelist *vars_updated) { int display_monitor; @@ -409,7 +416,7 @@ trigger_callback_execute (struct t_trigger *trigger, { /* replace text with regex */ trigger_callback_replace_regex (trigger, pointers, extra_vars, - display_monitor); + vars_updated, display_monitor); /* execute command(s) */ trigger_callback_run_command (trigger, buffer, pointers, extra_vars, @@ -521,7 +528,7 @@ trigger_callback_signal_cb (const void *pointer, void *data, weechat_hashtable_set (extra_vars, "tg_signal_data", ptr_signal_data); /* execute the trigger (conditions, regex, command) */ - trigger_callback_execute (trigger, NULL, pointers, extra_vars); + trigger_callback_execute (trigger, NULL, pointers, extra_vars, NULL); end: TRIGGER_CALLBACK_CB_END(trigger_rc); @@ -569,7 +576,7 @@ trigger_callback_hsignal_cb (const void *pointer, void *data, weechat_hashtable_set (extra_vars, "tg_signal", signal); /* execute the trigger (conditions, regex, command) */ - trigger_callback_execute (trigger, NULL, pointers, extra_vars); + trigger_callback_execute (trigger, NULL, pointers, extra_vars, NULL); end: TRIGGER_CALLBACK_CB_END(trigger_rc); @@ -753,7 +760,7 @@ trigger_callback_modifier_cb (const void *pointer, void *data, } /* execute the trigger (conditions, regex, command) */ - trigger_callback_execute (trigger, buffer, pointers, extra_vars); + trigger_callback_execute (trigger, buffer, pointers, extra_vars, NULL); end: ptr_string = weechat_hashtable_get (extra_vars, "tg_string"); @@ -769,6 +776,126 @@ end: } /* + * Callback for a line hooked. + */ + +struct t_hashtable * +trigger_callback_line_cb (const void *pointer, void *data, + struct t_hashtable *line) +{ + struct t_hashtable *hashtable; + struct t_gui_buffer *buffer; + struct t_weelist_item *ptr_item; + long unsigned int value; + const char *ptr_key, *ptr_value; + char **tags, *str_tags; + int rc, num_tags, length; + + TRIGGER_CALLBACK_CB_INIT(NULL); + + hashtable = NULL; + + TRIGGER_CALLBACK_CB_NEW_POINTERS; + TRIGGER_CALLBACK_CB_NEW_VARS_UPDATED; + + extra_vars = weechat_hashtable_dup (line); + + weechat_hashtable_remove (extra_vars, "buffer"); + weechat_hashtable_remove (extra_vars, "tags_count"); + weechat_hashtable_remove (extra_vars, "tags"); + + /* add data in hashtables used for conditions/replace/command */ + ptr_value = weechat_hashtable_get (line, "buffer"); + if (!ptr_value || (ptr_value[0] != '0') || (ptr_value[1] != 'x')) + goto end; + rc = sscanf (ptr_value + 2, "%lx", &value); + if ((rc == EOF) || (rc < 1)) + goto end; + buffer = (void *)value; + + weechat_hashtable_set (pointers, "buffer", buffer); + ptr_value = weechat_hashtable_get (line, "tags"); + tags = weechat_string_split ((ptr_value) ? ptr_value : "", ",", 0, 0, + &num_tags); + + /* build string with tags and commas around: ",tag1,tag2,tag3," */ + length = 1 + strlen ((ptr_value) ? ptr_value : "") + 1 + 1; + str_tags = malloc (length); + if (str_tags) + { + snprintf (str_tags, length, ",%s,", + (ptr_value) ? ptr_value : ""); + weechat_hashtable_set (extra_vars, "tg_tags", str_tags); + free (str_tags); + } + + if (!trigger_callback_set_tags (buffer, (const char **)tags, num_tags, + extra_vars)) + { + goto end; + } + + /* execute the trigger (conditions, regex, command) */ + trigger_callback_execute (trigger, buffer, pointers, extra_vars, + vars_updated); + + hashtable = weechat_hashtable_new (32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, NULL); + if (hashtable) + { + /* copy updated variables into the result "hashtable" */ + for (ptr_item = weechat_list_get (vars_updated, 0); ptr_item; + ptr_item = weechat_list_next (ptr_item)) + { + ptr_key = weechat_list_string (ptr_item); + if (weechat_hashtable_has_key (extra_vars, ptr_key)) + { + if (strcmp (ptr_key, "tg_tags") == 0) + { + /* + * remove commas at the beginning/end of tg_tags and + * rename the key to "tags" + */ + ptr_value = weechat_hashtable_get (extra_vars, ptr_key); + if (ptr_value && ptr_value[0]) + { + str_tags = strdup ( + (ptr_value[0] == ',') ? ptr_value + 1 : ptr_value); + if (str_tags) + { + if (str_tags[0] + && (str_tags[strlen (str_tags) - 1] == ',')) + { + str_tags[strlen (str_tags) - 1] = '\0'; + } + weechat_hashtable_set (hashtable, + "tags", str_tags); + free (str_tags); + } + } + else + { + weechat_hashtable_set (hashtable, "tags", ptr_value); + } + } + else + { + weechat_hashtable_set ( + hashtable, + ptr_key, + weechat_hashtable_get (extra_vars, ptr_key)); + } + } + } + } + +end: + TRIGGER_CALLBACK_CB_END(hashtable); +} + +/* * Callback for a print hooked. */ @@ -840,7 +967,7 @@ trigger_callback_print_cb (const void *pointer, void *data, goto end; /* execute the trigger (conditions, regex, command) */ - trigger_callback_execute (trigger, buffer, pointers, extra_vars); + trigger_callback_execute (trigger, buffer, pointers, extra_vars, NULL); end: TRIGGER_CALLBACK_CB_END(trigger_rc); @@ -874,7 +1001,7 @@ trigger_callback_command_cb (const void *pointer, void *data, } /* execute the trigger (conditions, regex, command) */ - trigger_callback_execute (trigger, buffer, pointers, extra_vars); + trigger_callback_execute (trigger, buffer, pointers, extra_vars, NULL); end: TRIGGER_CALLBACK_CB_END(trigger_rc); @@ -899,7 +1026,7 @@ trigger_callback_command_run_cb (const void *pointer, void *data, weechat_hashtable_set (extra_vars, "tg_command", command); /* execute the trigger (conditions, regex, command) */ - trigger_callback_execute (trigger, buffer, pointers, extra_vars); + trigger_callback_execute (trigger, buffer, pointers, extra_vars, NULL); end: TRIGGER_CALLBACK_CB_END(trigger_rc); @@ -949,7 +1076,7 @@ trigger_callback_timer_cb (const void *pointer, void *data, } /* execute the trigger (conditions, regex, command) */ - trigger_callback_execute (trigger, NULL, pointers, extra_vars); + trigger_callback_execute (trigger, NULL, pointers, extra_vars, NULL); end: TRIGGER_CALLBACK_CB_END(trigger_rc); @@ -972,7 +1099,7 @@ trigger_callback_config_cb (const void *pointer, void *data, weechat_hashtable_set (extra_vars, "tg_value", value); /* execute the trigger (conditions, regex, command) */ - trigger_callback_execute (trigger, NULL, pointers, extra_vars); + trigger_callback_execute (trigger, NULL, pointers, extra_vars, NULL); end: TRIGGER_CALLBACK_CB_END(trigger_rc); @@ -1011,7 +1138,7 @@ trigger_callback_focus_cb (const void *pointer, void *data, } /* execute the trigger (conditions, regex, command) */ - trigger_callback_execute (trigger, NULL, pointers, info); + trigger_callback_execute (trigger, NULL, pointers, info, NULL); end: TRIGGER_CALLBACK_CB_END(info); diff --git a/src/plugins/trigger/trigger-callback.h b/src/plugins/trigger/trigger-callback.h index 8eeec3171..f9081aa19 100644 --- a/src/plugins/trigger/trigger-callback.h +++ b/src/plugins/trigger/trigger-callback.h @@ -25,10 +25,13 @@ #define TRIGGER_CALLBACK_CB_INIT(__rc) \ struct t_trigger *trigger; \ struct t_hashtable *pointers, *extra_vars; \ + struct t_weelist *vars_updated; \ int trigger_rc; \ pointers = NULL; \ extra_vars = NULL; \ + vars_updated = NULL; \ (void) data; \ + (void) vars_updated; \ (void) trigger_rc; \ if (!trigger_enabled) \ return __rc; \ @@ -59,11 +62,18 @@ if (!extra_vars) \ goto end; +#define TRIGGER_CALLBACK_CB_NEW_VARS_UPDATED \ + vars_updated = weechat_list_new (); \ + if (!vars_updated) \ + goto end; + #define TRIGGER_CALLBACK_CB_END(__rc) \ if (pointers) \ weechat_hashtable_free (pointers); \ if (extra_vars) \ weechat_hashtable_free (extra_vars); \ + if (vars_updated) \ + weechat_list_free (vars_updated); \ trigger->hook_running = 0; \ switch (weechat_config_integer ( \ trigger->options[TRIGGER_OPTION_POST_ACTION])) \ @@ -93,6 +103,8 @@ extern char *trigger_callback_modifier_cb (const void *pointer, void *data, const char *modifier, const char *modifier_data, const char *string); +extern struct t_hashtable *trigger_callback_line_cb (const void *pointer, void *data, + struct t_hashtable *line); extern int trigger_callback_print_cb (const void *pointer, void *data, struct t_gui_buffer *buffer, time_t date, int tags_count, diff --git a/src/plugins/trigger/trigger-command.c b/src/plugins/trigger/trigger-command.c index 5de047bc1..b896d981a 100644 --- a/src/plugins/trigger/trigger-command.c +++ b/src/plugins/trigger/trigger-command.c @@ -1153,13 +1153,14 @@ trigger_command_init () " addoff: add a trigger (disabled)\n" " addreplace: add or replace an existing trigger\n" " name: name of trigger\n" - " hook: signal, hsignal, modifier, print, command, command_run, " - "timer, config, focus\n" + " hook: signal, hsignal, modifier, line, print, command, " + "command_run, timer, config, focus\n" " arguments: arguments for the hook, depending on hook (separated " "by semicolons):\n" " signal: name(s) of signal (required)\n" " hsignal: name(s) of hsignal (required)\n" " modifier: name(s) of modifier (required)\n" + " line: list of buffer masks, tags\n" " print: buffer, tags, message, strip colors\n" " command: command (required), description, arguments, " "description of arguments, completion\n" @@ -1212,7 +1213,7 @@ trigger_command_init () " 2. replace text using POSIX extended regular expression(s) (if " "defined in trigger)\n" " 3. execute command(s) (if defined in trigger)\n" - " 4. exit with a return code (except for modifiers and focus)\n" + " 4. exit with a return code (except for modifier, line and focus)\n" " 5. perform post action\n" "\n" "Examples (you can also look at default triggers with /trigger " diff --git a/src/plugins/trigger/trigger.c b/src/plugins/trigger/trigger.c index b088b1f0e..0dcf01473 100644 --- a/src/plugins/trigger/trigger.c +++ b/src/plugins/trigger/trigger.c @@ -49,10 +49,11 @@ char *trigger_option_default[TRIGGER_NUM_OPTIONS] = { "on", "signal", "", "", "", "", "ok", "none" }; char *trigger_hook_type_string[TRIGGER_NUM_HOOK_TYPES] = -{ "signal", "hsignal", "modifier", "print", "command", "command_run", "timer", - "config", "focus" }; +{ "signal", "hsignal", "modifier", "line", "print", "command", "command_run", + "timer", "config", "focus" }; char *trigger_hook_option_values = - "signal|hsignal|modifier|print|command|command_run|timer|config|focus"; + "signal|hsignal|modifier|line|print|command|command_run|timer|config|" + "focus"; char *trigger_hook_default_arguments[TRIGGER_NUM_HOOK_TYPES] = { "xxx", "xxx", "xxx", "", "cmd;desc;args;args_desc;%(buffers_names)", "/cmd", "60000;0;0", "xxx", "chat" }; @@ -262,7 +263,8 @@ trigger_unhook (struct t_trigger *trigger) void trigger_hook (struct t_trigger *trigger) { - char **argv, **argv_eol, *tags, *message, *error1, *error2, *error3; + char **argv, **argv_eol, *buffer_type, *buffer_name, *tags, *message; + char *error1, *error2, *error3; int i, argc, strip_colors; long interval, align_second, max_calls; @@ -329,6 +331,30 @@ trigger_hook (struct t_trigger *trigger) } } break; + case TRIGGER_HOOK_LINE: + buffer_type = NULL; + buffer_name = NULL; + tags = NULL; + if (argv && (argc >= 1)) + { + buffer_type = argv[0]; + if ((argc >= 2) && (strcmp (argv[1], "*") != 0)) + buffer_name = argv[1]; + if ((argc >= 3) && (strcmp (argv[2], "*") != 0)) + tags = argv[2]; + } + trigger->hooks = malloc (sizeof (trigger->hooks[0])); + if (trigger->hooks) + { + trigger->hooks_count = 1; + trigger->hooks[0] = weechat_hook_line ( + buffer_type, + buffer_name, + tags, + &trigger_callback_line_cb, + trigger, NULL); + } + break; case TRIGGER_HOOK_PRINT: tags = NULL; message = NULL; diff --git a/src/plugins/trigger/trigger.h b/src/plugins/trigger/trigger.h index 78984277b..d4b5119b4 100644 --- a/src/plugins/trigger/trigger.h +++ b/src/plugins/trigger/trigger.h @@ -48,6 +48,7 @@ enum t_trigger_hook_type TRIGGER_HOOK_SIGNAL = 0, TRIGGER_HOOK_HSIGNAL, TRIGGER_HOOK_MODIFIER, + TRIGGER_HOOK_LINE, TRIGGER_HOOK_PRINT, TRIGGER_HOOK_COMMAND, TRIGGER_HOOK_COMMAND_RUN, diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index f9a836065..e9416d2ce 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -67,7 +67,7 @@ struct timeval; * please change the date with current one; for a second change at same * date, increment the 01, otherwise please keep 01. */ -#define WEECHAT_PLUGIN_API_VERSION "20180520-01" +#define WEECHAT_PLUGIN_API_VERSION "20180812-01" /* macros for defining plugin infos */ #define WEECHAT_PLUGIN_NAME(__name) \ @@ -709,6 +709,15 @@ struct t_weechat_plugin const char *ip_address), const void *callback_pointer, void *callback_data); + struct t_hook *(*hook_line) (struct t_weechat_plugin *plugin, + const char *buffer_type, + const char *buffer_name, + const char *tags, + struct t_hashtable *(*callback)(const void *pointer, + void *data, + struct t_hashtable *line), + const void *callback_pointer, + void *callback_data); struct t_hook *(*hook_print) (struct t_weechat_plugin *plugin, struct t_gui_buffer *buffer, const char *tags, @@ -1645,6 +1654,11 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin); __gnutls_priorities, \ __local_hostname, \ __callback, __pointer, __data) +#define weechat_hook_line(_buffer_type, __buffer_name, __tags, \ + __callback, __pointer, __data) \ + (weechat_plugin->hook_line)(weechat_plugin, _buffer_type, \ + __buffer_name, __tags, __callback, \ + __pointer, __data) #define weechat_hook_print(__buffer, __tags, __msg, __strip__colors, \ __callback, __pointer, __data) \ (weechat_plugin->hook_print)(weechat_plugin, __buffer, __tags, \ |