summaryrefslogtreecommitdiff
path: root/src/core/wee-hook.c
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2010-08-11 18:42:38 +0200
committerSebastien Helleu <flashcode@flashtux.org>2010-08-11 18:42:38 +0200
commit6317dba7904c0e4f42ea9a6c7cdd623f1408a023 (patch)
treea2575205ecad90049da80c156801af618805b0ed /src/core/wee-hook.c
parentd59d099e82378669a2bea5aac5c9d9862438f51e (diff)
downloadweechat-6317dba7904c0e4f42ea9a6c7cdd623f1408a023.zip
Add priority for hooks (task #10550)
Diffstat (limited to 'src/core/wee-hook.c')
-rw-r--r--src/core/wee-hook.c222
1 files changed, 161 insertions, 61 deletions
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c
index 44b6eedfd..174a0ea69 100644
--- a/src/core/wee-hook.c
+++ b/src/core/wee-hook.c
@@ -103,29 +103,46 @@ hook_search_type (const char *type)
}
/*
- * hook_find_pos: find position for new hook (keeping command list sorted)
+ * hook_find_pos: find position for new hook:
+ * - for type command: sort on command name, then priority
+ * - for all other types: sort on priority
*/
struct t_hook *
hook_find_pos (struct t_hook *hook)
{
struct t_hook *ptr_hook;
+ int rc_cmp;
- /* if it's not command hook, then add to the end of list */
- if (hook->type != HOOK_TYPE_COMMAND)
- return NULL;
-
- /* for command hook, keep list sorted */
- for (ptr_hook = weechat_hooks[hook->type]; ptr_hook;
- ptr_hook = ptr_hook->next_hook)
+ if (hook->type == HOOK_TYPE_COMMAND)
{
- if (!ptr_hook->deleted
- && (string_strcasecmp (HOOK_COMMAND(hook, command),
- HOOK_COMMAND(ptr_hook, command)) <= 0))
- return ptr_hook;
+ /* for command hook, sort on command name */
+ for (ptr_hook = weechat_hooks[hook->type]; ptr_hook;
+ ptr_hook = ptr_hook->next_hook)
+ {
+ if (!ptr_hook->deleted)
+ {
+ rc_cmp = string_strcasecmp (HOOK_COMMAND(hook, command),
+ HOOK_COMMAND(ptr_hook, command));
+ if (rc_cmp < 0)
+ return ptr_hook;
+ if ((rc_cmp == 0) && (hook->priority >= ptr_hook->priority))
+ return ptr_hook;
+ }
+ }
+ }
+ else
+ {
+ /* for other types, sort on priority */
+ for (ptr_hook = weechat_hooks[hook->type]; ptr_hook;
+ ptr_hook = ptr_hook->next_hook)
+ {
+ if (!ptr_hook->deleted && (hook->priority >= ptr_hook->priority))
+ return ptr_hook;
+ }
}
- /* position not found, best position is at the end */
+ /* position not found, add at the end */
return NULL;
}
@@ -143,7 +160,7 @@ hook_add_to_list (struct t_hook *new_hook)
pos_hook = hook_find_pos (new_hook);
if (pos_hook)
{
- /* add hook somewhere in the list */
+ /* add hook before "pos_hook" */
new_hook->prev_hook = pos_hook->prev_hook;
new_hook->next_hook = pos_hook;
if (pos_hook->prev_hook)
@@ -230,26 +247,71 @@ hook_remove_deleted ()
}
/*
+ * hook_get_priority_and_name: get priority (integer) and pointer to start of
+ * name, from argument "name"
+ * name may be:
+ * - a simple name like "test":
+ * => priority = 1000 (default), ptr_name = "test"
+ * - a priority + "|" + name, like "500|test":
+ * => priority = 500, ptr_name = "test"
+ */
+
+void
+hook_get_priority_and_name (const char *name,
+ int *priority, const char **ptr_name)
+{
+ char *pos, *str_priority, *error;
+ long number;
+
+ if (priority)
+ *priority = HOOK_PRIORITY_DEFAULT;
+ if (ptr_name)
+ *ptr_name = name;
+
+ pos = strchr (name, '|');
+ if (pos)
+ {
+ str_priority = string_strndup (name, pos - name);
+ if (str_priority)
+ {
+ error = NULL;
+ number = strtol (str_priority, &error, 10);
+ if (error && !error[0])
+ {
+ if (priority)
+ *priority = number;
+ if (ptr_name)
+ *ptr_name = pos + 1;
+ }
+ free (str_priority);
+ }
+ }
+}
+
+/*
* hook_init_data: init data a new hook with default values
*/
void
hook_init_data (struct t_hook *hook, struct t_weechat_plugin *plugin,
- int type, void *callback_data)
+ int type, int priority, void *callback_data)
{
hook->plugin = plugin;
hook->type = type;
hook->deleted = 0;
hook->running = 0;
+ hook->priority = priority;
hook->callback_data = callback_data;
hook->hook_data = NULL;
-
+
if (weechat_debug_core >= 2)
{
gui_chat_printf (NULL,
- "debug: adding hook: type=%d (%s), plugin=%lx (%s)",
+ "debug: adding hook: type=%d (%s), plugin=%lx (%s), "
+ "priority=%d",
hook->type, hook_type_string[hook->type],
- hook->plugin, plugin_get_name (hook->plugin));
+ hook->plugin, plugin_get_name (hook->plugin),
+ hook->priority);
}
}
@@ -505,6 +567,8 @@ hook_command (struct t_weechat_plugin *plugin, const char *command,
{
struct t_hook *new_hook;
struct t_hook_command *new_hook_command;
+ int priority;
+ const char *ptr_command;
if (!callback)
return NULL;
@@ -530,20 +594,19 @@ hook_command (struct t_weechat_plugin *plugin, const char *command,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_COMMAND, callback_data);
+ hook_get_priority_and_name (command, &priority, &ptr_command);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_COMMAND, priority,
+ callback_data);
new_hook->hook_data = new_hook_command;
new_hook_command->callback = callback;
- new_hook_command->command = (command) ?
- strdup (command) : strdup ("");
- new_hook_command->description = (description) ?
- strdup (description) : strdup ("");
- new_hook_command->args = (args) ?
- strdup (args) : strdup ("");
- new_hook_command->args_description = (args_description) ?
- strdup (args_description) : strdup ("");
- new_hook_command->completion = (completion) ?
- strdup (completion) : strdup ("");
+ new_hook_command->command = strdup ((ptr_command) ? ptr_command :
+ ((command) ? command : ""));
+ new_hook_command->description = strdup ((description) ? description : "");
+ new_hook_command->args = strdup ((args) ? args : "");
+ new_hook_command->args_description = strdup ((args_description) ?
+ args_description : "");
+ new_hook_command->completion = strdup ((completion) ? completion : "");
/* build completion variables for command */
new_hook_command->cplt_num_templates = 0;
@@ -687,6 +750,8 @@ hook_command_run (struct t_weechat_plugin *plugin, const char *command,
{
struct t_hook *new_hook;
struct t_hook_command_run *new_hook_command_run;
+ int priority;
+ const char *ptr_command;
if (!callback)
return NULL;
@@ -701,12 +766,14 @@ hook_command_run (struct t_weechat_plugin *plugin, const char *command,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_COMMAND_RUN, callback_data);
+ hook_get_priority_and_name (command, &priority, &ptr_command);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_COMMAND_RUN, priority,
+ callback_data);
new_hook->hook_data = new_hook_command_run;
new_hook_command_run->callback = callback;
- new_hook_command_run->command = (command) ?
- strdup (command) : strdup ("");
+ new_hook_command_run->command = strdup ((ptr_command) ? ptr_command :
+ ((command) ? command : ""));
hook_add_to_list (new_hook);
@@ -865,7 +932,8 @@ hook_timer (struct t_weechat_plugin *plugin, long interval, int align_second,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_TIMER, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_TIMER, HOOK_PRIORITY_DEFAULT,
+ callback_data);
new_hook->hook_data = new_hook_timer;
new_hook_timer->callback = callback;
@@ -1095,7 +1163,8 @@ hook_fd (struct t_weechat_plugin *plugin, int fd, int flag_read,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_FD, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_FD, HOOK_PRIORITY_DEFAULT,
+ callback_data);
new_hook->hook_data = new_hook_fd;
new_hook_fd->callback = callback;
@@ -1216,7 +1285,8 @@ hook_process (struct t_weechat_plugin *plugin,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_PROCESS, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_PROCESS, HOOK_PRIORITY_DEFAULT,
+ callback_data);
new_hook->hook_data = new_hook_process;
new_hook_process->callback = callback;
@@ -1520,7 +1590,8 @@ hook_connect (struct t_weechat_plugin *plugin, const char *proxy, const char *ad
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_CONNECT, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_CONNECT, HOOK_PRIORITY_DEFAULT,
+ callback_data);
new_hook->hook_data = new_hook_connect;
new_hook_connect->callback = callback;
@@ -1609,7 +1680,8 @@ hook_print (struct t_weechat_plugin *plugin, struct t_gui_buffer *buffer,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_PRINT, callback_data);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_PRINT, HOOK_PRIORITY_DEFAULT,
+ callback_data);
new_hook->hook_data = new_hook_print;
new_hook_print->callback = callback;
@@ -1740,6 +1812,8 @@ hook_signal (struct t_weechat_plugin *plugin, const char *signal,
{
struct t_hook *new_hook;
struct t_hook_signal *new_hook_signal;
+ int priority;
+ const char *ptr_signal;
if (!signal || !signal[0] || !callback)
return NULL;
@@ -1754,11 +1828,13 @@ hook_signal (struct t_weechat_plugin *plugin, const char *signal,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_SIGNAL, callback_data);
+ hook_get_priority_and_name (signal, &priority, &ptr_signal);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_SIGNAL, priority,
+ callback_data);
new_hook->hook_data = new_hook_signal;
new_hook_signal->callback = callback;
- new_hook_signal->signal = strdup (signal);
+ new_hook_signal->signal = strdup ((ptr_signal) ? ptr_signal : signal);
hook_add_to_list (new_hook);
@@ -1807,6 +1883,8 @@ hook_config (struct t_weechat_plugin *plugin, const char *option,
{
struct t_hook *new_hook;
struct t_hook_config *new_hook_config;
+ int priority;
+ const char *ptr_option;
if (!callback)
return NULL;
@@ -1821,11 +1899,14 @@ hook_config (struct t_weechat_plugin *plugin, const char *option,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_CONFIG, callback_data);
+ hook_get_priority_and_name (option, &priority, &ptr_option);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_CONFIG, priority,
+ callback_data);
new_hook->hook_data = new_hook_config;
new_hook_config->callback = callback;
- new_hook_config->option = (option) ? strdup (option) : strdup ("");
+ new_hook_config->option = strdup ((ptr_option) ? ptr_option :
+ ((option) ? option : ""));
hook_add_to_list (new_hook);
@@ -1876,6 +1957,8 @@ hook_completion (struct t_weechat_plugin *plugin, const char *completion_item,
{
struct t_hook *new_hook;
struct t_hook_completion *new_hook_completion;
+ int priority;
+ const char *ptr_completion_item;
if (!completion_item || !completion_item[0]
|| strchr (completion_item, ' ') || !callback)
@@ -1891,13 +1974,16 @@ hook_completion (struct t_weechat_plugin *plugin, const char *completion_item,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_COMPLETION, callback_data);
+ hook_get_priority_and_name (completion_item, &priority, &ptr_completion_item);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_COMPLETION, priority,
+ callback_data);
new_hook->hook_data = new_hook_completion;
new_hook_completion->callback = callback;
- new_hook_completion->completion_item = strdup (completion_item);
- new_hook_completion->description =
- (description) ? strdup (description) : strdup ("");
+ new_hook_completion->completion_item = strdup ((ptr_completion_item) ?
+ ptr_completion_item : completion_item);
+ new_hook_completion->description = strdup ((description) ?
+ description : "");
hook_add_to_list (new_hook);
@@ -1965,6 +2051,8 @@ hook_modifier (struct t_weechat_plugin *plugin, const char *modifier,
{
struct t_hook *new_hook;
struct t_hook_modifier *new_hook_modifier;
+ int priority;
+ const char *ptr_modifier;
if (!modifier || !modifier[0] || !callback)
return NULL;
@@ -1979,11 +2067,13 @@ hook_modifier (struct t_weechat_plugin *plugin, const char *modifier,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_MODIFIER, callback_data);
+ hook_get_priority_and_name (modifier, &priority, &ptr_modifier);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_MODIFIER, priority,
+ callback_data);
new_hook->hook_data = new_hook_modifier;
new_hook_modifier->callback = callback;
- new_hook_modifier->modifier = strdup (modifier);
+ new_hook_modifier->modifier = strdup ((ptr_modifier) ? ptr_modifier : modifier);
hook_add_to_list (new_hook);
@@ -2065,6 +2155,8 @@ hook_info (struct t_weechat_plugin *plugin, const char *info_name,
{
struct t_hook *new_hook;
struct t_hook_info *new_hook_info;
+ int priority;
+ const char *ptr_info_name;
if (!info_name || !info_name[0] || !callback)
return NULL;
@@ -2079,15 +2171,16 @@ hook_info (struct t_weechat_plugin *plugin, const char *info_name,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_INFO, callback_data);
+ hook_get_priority_and_name (info_name, &priority, &ptr_info_name);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_INFO, priority, callback_data);
new_hook->hook_data = new_hook_info;
new_hook_info->callback = callback;
- new_hook_info->info_name = strdup (info_name);
- new_hook_info->description = (description) ?
- strdup (description) : strdup ("");
- new_hook_info->args_description = (args_description) ?
- strdup (args_description) : strdup ("");
+ new_hook_info->info_name = strdup ((ptr_info_name) ?
+ ptr_info_name : info_name);
+ new_hook_info->description = strdup ((description) ? description : "");
+ new_hook_info->args_description = strdup ((args_description) ?
+ args_description : "");
hook_add_to_list (new_hook);
@@ -2153,6 +2246,8 @@ hook_infolist (struct t_weechat_plugin *plugin, const char *infolist_name,
{
struct t_hook *new_hook;
struct t_hook_infolist *new_hook_infolist;
+ int priority;
+ const char *ptr_infolist_name;
if (!infolist_name || !infolist_name[0] || !callback)
return NULL;
@@ -2167,17 +2262,19 @@ hook_infolist (struct t_weechat_plugin *plugin, const char *infolist_name,
return NULL;
}
- hook_init_data (new_hook, plugin, HOOK_TYPE_INFOLIST, callback_data);
+ hook_get_priority_and_name (infolist_name, &priority, &ptr_infolist_name);
+ hook_init_data (new_hook, plugin, HOOK_TYPE_INFOLIST, priority,
+ callback_data);
new_hook->hook_data = new_hook_infolist;
new_hook_infolist->callback = callback;
- new_hook_infolist->infolist_name = strdup (infolist_name);
- new_hook_infolist->description = (description) ?
- strdup (description) : strdup ("");
- new_hook_infolist->pointer_description = (pointer_description) ?
- strdup (pointer_description) : strdup ("");
- new_hook_infolist->args_description = (args_description) ?
- strdup (args_description) : strdup ("");
+ new_hook_infolist->infolist_name = strdup ((ptr_infolist_name) ?
+ ptr_infolist_name : infolist_name);
+ new_hook_infolist->description = strdup ((description) ? description : "");
+ new_hook_infolist->pointer_description = strdup ((pointer_description) ?
+ pointer_description : "");
+ new_hook_infolist->args_description = strdup ((args_description) ?
+ args_description : "");
hook_add_to_list (new_hook);
@@ -2494,6 +2591,8 @@ hook_add_to_infolist_type (struct t_infolist *infolist,
return 0;
if (!infolist_new_var_integer (ptr_item, "running", ptr_hook->running))
return 0;
+ if (!infolist_new_var_integer (ptr_item, "priority", ptr_hook->priority))
+ return 0;
switch (ptr_hook->type)
{
case HOOK_TYPE_COMMAND:
@@ -2807,6 +2906,7 @@ hook_print_log ()
ptr_hook->plugin, plugin_get_name (ptr_hook->plugin));
log_printf (" deleted . . . . . . . . : %d", ptr_hook->deleted);
log_printf (" running . . . . . . . . : %d", ptr_hook->running);
+ log_printf (" priority. . . . . . . . : %d", ptr_hook->priority);
log_printf (" type. . . . . . . . . . : %d (%s)",
ptr_hook->type, hook_type_string[ptr_hook->type]);
log_printf (" callback_data . . . . . : 0x%lx", ptr_hook->callback_data);