summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/trigger/trigger-callback.c119
-rw-r--r--src/plugins/trigger/trigger-command.c14
-rw-r--r--src/plugins/trigger/trigger-config.c7
-rw-r--r--src/plugins/trigger/trigger.c206
-rw-r--r--src/plugins/trigger/trigger.h6
5 files changed, 195 insertions, 157 deletions
diff --git a/src/plugins/trigger/trigger-callback.c b/src/plugins/trigger/trigger-callback.c
index a40e83585..38dd3dc15 100644
--- a/src/plugins/trigger/trigger-callback.c
+++ b/src/plugins/trigger/trigger-callback.c
@@ -67,41 +67,66 @@ trigger_callback_check_conditions (struct t_trigger *trigger,
/*
* Replaces text using one or more regex in the trigger.
- *
- * Note: result must be freed after use.
*/
-char *
-trigger_callback_replace_regex (struct t_trigger *trigger, const char *name,
- const char *value)
+void
+trigger_callback_replace_regex (struct t_trigger *trigger,
+ struct t_hashtable *extra_vars)
{
- char *temp, *res;
+ char *value;
+ const char *ptr_key, *ptr_value;
int i;
if (trigger->regex_count == 0)
- return strdup (value);
-
- res = NULL;
+ return;
for (i = 0; i < trigger->regex_count; i++)
{
- temp = weechat_string_replace_regex ((res) ? res : value,
- trigger->regex[i].regex,
- trigger->regex[i].replace_eval);
- if (!temp)
- return res;
- res = temp;
+ ptr_key = (trigger->regex[i].variable) ?
+ trigger->regex[i].variable :
+ trigger_hook_regex_default_var[weechat_config_integer (trigger->options[TRIGGER_OPTION_HOOK])];
+ if (!ptr_key || !ptr_key[0])
+ {
+ if (trigger_buffer)
+ {
+ weechat_printf_tags (trigger_buffer, "no_trigger",
+ "\t regex %d: %s",
+ i + 1, _("no variable"));
+ }
+ continue;
+ }
+
+ ptr_value = weechat_hashtable_get (extra_vars, ptr_key);
+ if (!ptr_value)
+ {
+ if (trigger_buffer)
+ {
+ weechat_printf_tags (trigger_buffer, "no_trigger",
+ "\t regex %d (%s): %s",
+ i + 1, ptr_key, _("empty variable"));
+ }
+ continue;
+ }
+
+ value = weechat_string_replace_regex (ptr_value,
+ trigger->regex[i].regex,
+ trigger->regex[i].replace_eval);
+ if (!value)
+ continue;
/* display debug info on trigger buffer */
if (trigger_buffer)
{
weechat_printf_tags (trigger_buffer, "no_trigger",
- "\t %s (regex %d): \"%s%s\"",
- name, i + 1, res, weechat_color ("reset"));
+ "\t regex %d (%s): \"%s%s\"",
+ i + 1, ptr_key, value,
+ weechat_color ("reset"));
}
- }
- return res;
+ weechat_hashtable_set (extra_vars, ptr_key, value);
+
+ free (value);
+ }
}
/*
@@ -157,7 +182,7 @@ trigger_callback_signal_cb (void *data, const char *signal,
struct t_trigger *trigger;
struct t_hashtable *extra_vars;
const char *command, *ptr_signal_data;
- char str_data[128], *signal_data2;
+ char str_data[128];
int rc;
/* get trigger pointer, return immediately if not found or trigger running */
@@ -234,17 +259,7 @@ trigger_callback_signal_cb (void *data, const char *signal,
goto end;
/* replace text with regex */
- if (trigger->regex_count > 0)
- {
- signal_data2 = trigger_callback_replace_regex (trigger,
- "tg_signal_data",
- ptr_signal_data);
- if (signal_data2)
- {
- weechat_hashtable_set (extra_vars, "tg_signal_data", signal_data2);
- free (signal_data2);
- }
- }
+ trigger_callback_replace_regex (trigger, extra_vars);
/* execute command */
trigger_callback_run_command (trigger, NULL, NULL, extra_vars);
@@ -252,7 +267,9 @@ trigger_callback_signal_cb (void *data, const char *signal,
end:
if (extra_vars)
weechat_hashtable_free (extra_vars);
+
trigger->hook_running = 0;
+
return rc;
}
@@ -281,7 +298,7 @@ trigger_callback_modifier_cb (void *data, const char *modifier,
{
struct t_trigger *trigger;
struct t_hashtable *extra_vars;
- const char *command;
+ const char *command, *ptr_string;
char *string_modified, *pos, *pos2, *plugin_name, *buffer_name;
char *buffer_full_name, *tags;
int no_trigger, length;
@@ -297,7 +314,6 @@ trigger_callback_modifier_cb (void *data, const char *modifier,
trigger->hook_running = 1;
extra_vars = NULL;
- string_modified = NULL;
/*
* in a modifier, the only possible actions are regex or command;
@@ -400,29 +416,21 @@ trigger_callback_modifier_cb (void *data, const char *modifier,
goto end;
/* replace text with regex */
- if (trigger->regex_count > 0)
- {
- string_modified = trigger_callback_replace_regex (trigger, "tg_string",
- string);
- if (string_modified)
- {
- weechat_hashtable_set (extra_vars, "tg_string", string_modified);
- if (strcmp (string, string_modified) == 0)
- {
- /* regex did not change the string, ignore it */
- free (string_modified);
- string_modified = NULL;
- }
- }
- }
+ trigger_callback_replace_regex (trigger, extra_vars);
/* execute command */
trigger_callback_run_command (trigger, NULL, NULL, extra_vars);
end:
+ ptr_string = weechat_hashtable_get (extra_vars, "tg_string");
+ string_modified = (ptr_string && (strcmp (ptr_string, string) != 0)) ?
+ strdup (ptr_string) : NULL;
+
if (extra_vars)
weechat_hashtable_free (extra_vars);
+
trigger->hook_running = 0;
+
return string_modified;
}
@@ -439,7 +447,7 @@ trigger_callback_print_cb (void *data, struct t_gui_buffer *buffer,
struct t_trigger *trigger;
struct t_hashtable *pointers, *extra_vars;
const char *command, *localvar_type;
- char *message2, *str_tags, *str_tags2, str_temp[128];
+ char *str_tags, *str_tags2, str_temp[128];
int i, rc, length, tag_notify_private;
struct tm *date_tmp;
@@ -556,16 +564,7 @@ trigger_callback_print_cb (void *data, struct t_gui_buffer *buffer,
goto end;
/* replace text with regex */
- if (trigger->regex_count > 0)
- {
- message2 = trigger_callback_replace_regex (trigger, "tg_message",
- message);
- if (message2)
- {
- weechat_hashtable_set (extra_vars, "tg_message", message2);
- free (message2);
- }
- }
+ trigger_callback_replace_regex (trigger, extra_vars);
/* execute command */
trigger_callback_run_command (trigger, buffer, pointers, extra_vars);
@@ -575,7 +574,9 @@ end:
weechat_hashtable_free (pointers);
if (extra_vars)
weechat_hashtable_free (extra_vars);
+
trigger->hook_running = 0;
+
return rc;
}
diff --git a/src/plugins/trigger/trigger-command.c b/src/plugins/trigger/trigger-command.c
index bfba7b064..5fef8e632 100644
--- a/src/plugins/trigger/trigger-command.c
+++ b/src/plugins/trigger/trigger-command.c
@@ -102,13 +102,19 @@ trigger_command_trigger (void *data, struct t_gui_buffer *buffer, int argc,
for (i = 0; i < ptr_trigger->regex_count; i++)
{
weechat_printf_tags (NULL, "no_trigger",
- " regex %d: %s%s %s-->%s %s",
+ " regex %d%s%s%s: "
+ "%s\"%s%s%s\" --> \"%s%s%s\"",
i + 1,
+ (ptr_trigger->regex[i].variable) ? " (" : "",
+ (ptr_trigger->regex[i].variable) ? ptr_trigger->regex[i].variable : "",
+ (ptr_trigger->regex[i].variable) ? ")" : "",
+ weechat_color ("chat_delimiters"),
weechat_color (weechat_config_string (trigger_config_color_regex)),
ptr_trigger->regex[i].str_regex,
weechat_color ("chat_delimiters"),
weechat_color (weechat_config_string (trigger_config_color_replace)),
- ptr_trigger->regex[i].replace);
+ ptr_trigger->regex[i].replace,
+ weechat_color ("chat_delimiters"));
}
option = weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_COMMAND]);
if (option && option[0])
@@ -408,8 +414,8 @@ trigger_command_init ()
" add text attributes in *bold*, _underline_ and /italic/:\n"
" /trigger add effects modifier weechat_print\n"
" /trigger set effects regex "
- "==\\*(\\S+)\\*==*${color:bold}\\1${color:-bold}*"
- "==_(\\S+)_==_${color:underline}\\1${color:-underline}_"
+ "==\\*(\\S+)\\*==*${color:bold}\\1${color:-bold}*== "
+ "==_(\\S+)_==_${color:underline}\\1${color:-underline}_== "
"==/(\\S+)/==/${color:italic}\\1${color:-italic}/"),
"list"
" || add %(trigger_names) %(trigger_hooks)"
diff --git a/src/plugins/trigger/trigger-config.c b/src/plugins/trigger/trigger-config.c
index d78bbcb2a..3e5340bf5 100644
--- a/src/plugins/trigger/trigger-config.c
+++ b/src/plugins/trigger/trigger-config.c
@@ -173,7 +173,12 @@ trigger_config_create_option (const char *trigger_name, int index_option,
N_("replace text with a POSIX extended regular expression (it "
"is done only if conditions are OK, and before running the "
"command) (note: content is evaluated on trigger creation, "
- "see /help eval)"),
+ "see /help eval); format is: \"/regex/replace/var\" (var "
+ "is the hashtable variable to replace, it is optional), "
+ "many regex can be separated by a space, for example: "
+ "\"/regex1/replace1/var1 /regex2/replace2/var2\"; the "
+ "separator \"/\" can be replaced by any char (one or more "
+ "identical chars), except '\\' and parentheses"),
NULL, 0, 0, value, NULL, 0,
NULL, NULL, &trigger_config_change_regex, NULL, NULL, NULL);
break;
diff --git a/src/plugins/trigger/trigger.c b/src/plugins/trigger/trigger.c
index de1ee1797..315c58968 100644
--- a/src/plugins/trigger/trigger.c
+++ b/src/plugins/trigger/trigger.c
@@ -50,6 +50,9 @@ char *trigger_option_default[TRIGGER_NUM_OPTIONS] =
char *trigger_hook_type_string[TRIGGER_NUM_HOOK_TYPES] =
{ "signal", "hsignal", "modifier", "print", "timer" };
+char *trigger_hook_regex_default_var[TRIGGER_NUM_HOOK_TYPES] =
+{ "tg_signal_data", "", "tg_string", "tg_message", "" };
+
char *trigger_return_code_string[TRIGGER_NUM_RETURN_CODES] =
{ "ok", "ok_eat", "error" };
int trigger_return_code[TRIGGER_NUM_RETURN_CODES] =
@@ -199,6 +202,8 @@ trigger_free_regex (struct t_trigger *trigger)
{
for (i = 0; i < trigger->regex_count; i++)
{
+ if (trigger->regex[i].variable)
+ free (trigger->regex[i].variable);
if (trigger->regex[i].str_regex)
free (trigger->regex[i].str_regex);
if (trigger->regex[i].regex)
@@ -224,9 +229,11 @@ trigger_free_regex (struct t_trigger *trigger)
void
trigger_set_regex (struct t_trigger *trigger)
{
- const char *option_regex, *pos, *pos2;
+ const char *option_regex, *ptr_option, *pos, *pos_replace, *pos_replace_end;
+ const char *pos_next_regex;
char *delimiter;
- int i, length_delimiter, regex_count;
+ int index, length_delimiter;
+ struct t_trigger_regex *new_regex;
delimiter = NULL;
@@ -242,122 +249,133 @@ trigger_set_regex (struct t_trigger *trigger)
if (strlen (option_regex) < 3)
goto format_error;
- /* search the delimiter (which can be more than one char) */
- pos = weechat_utf8_next_char (option_regex);
- while (pos[0] && weechat_utf8_charcmp (option_regex, pos) == 0)
+ /* parse regular expressions in the option */
+ ptr_option = option_regex;
+ while (ptr_option && ptr_option[0])
{
- pos = weechat_utf8_next_char (pos);
- }
- if (!pos[0])
- goto format_error;
- delimiter = weechat_strndup (option_regex, pos - option_regex);
- if (!delimiter)
- goto memory_error;
- if (strcmp (delimiter, "\\") == 0)
- goto format_error;
-
- length_delimiter = strlen (delimiter);
+ if (delimiter)
+ {
+ free (delimiter);
+ delimiter = NULL;
+ }
- /* count the number of regex in the option */
- regex_count = 0;
- pos = option_regex;
- while (pos && pos[0])
- {
- /*
- * if option "regex" ends with a delimiter, just ignore it
- * and exit the loop
- */
- pos += length_delimiter;
+ /* search the delimiter (which can be more than one char) */
+ pos = weechat_utf8_next_char (ptr_option);
+ while (pos[0] && (weechat_utf8_charcmp (ptr_option, pos) == 0))
+ {
+ pos = weechat_utf8_next_char (pos);
+ }
if (!pos[0])
- break;
-
- /* search the start of replacement string */
- pos = strstr (pos + length_delimiter, delimiter);
- if (!pos)
+ goto format_error;
+ delimiter = weechat_strndup (ptr_option, pos - ptr_option);
+ if (!delimiter)
+ goto memory_error;
+ if ((strcmp (delimiter, "\\") == 0) || (strcmp (delimiter, "(") == 0))
goto format_error;
- regex_count++;
-
- /* search the start of next regex */
- pos = strstr (pos + length_delimiter, delimiter);
- }
-
- /* at least one regex is needed */
- if (regex_count == 0)
- goto format_error;
+ length_delimiter = strlen (delimiter);
- /* allocate with array of regex/replacement */
- trigger->regex = malloc (regex_count * sizeof (trigger->regex[0]));
- if (!trigger->regex)
- goto memory_error;
+ ptr_option = pos;
+ if (!ptr_option[0])
+ goto format_error;
- /* initialize regex */
- for (i = 0; i < trigger->regex_count; i++)
- {
- trigger->regex[i].str_regex = NULL;
- trigger->regex[i].regex = NULL;
- trigger->regex[i].replace = NULL;
- trigger->regex[i].replace_eval = NULL;
- }
- trigger->regex_count = regex_count;
+ /* search the start of replacement string */
+ pos_replace = strstr (ptr_option, delimiter);
+ if (!pos_replace)
+ goto format_error;
- /* allocate regex and replacement */
- i = 0;
- pos = option_regex;
- while (pos && pos[0])
- {
- pos += length_delimiter;
- if (!pos[0])
- break;
+ /* search the end of replacement string */
+ pos_replace_end = strstr (pos_replace + length_delimiter, delimiter);
- pos2 = strstr (pos + length_delimiter, delimiter);
- if (!pos)
- break;
+ new_regex = realloc (trigger->regex,
+ (trigger->regex_count + 1) * sizeof (trigger->regex[0]));
+ if (!new_regex)
+ goto memory_error;
- trigger->regex[i].str_regex = weechat_strndup (pos, pos2 - pos);
- if (!trigger->regex[i].str_regex)
+ trigger->regex = new_regex;
+ trigger->regex_count++;
+ index = trigger->regex_count - 1;
+
+ /* initialize new regex */
+ trigger->regex[index].variable = NULL;
+ trigger->regex[index].str_regex = NULL;
+ trigger->regex[index].regex = NULL;
+ trigger->regex[index].replace = NULL;
+ trigger->regex[index].replace_eval = NULL;
+
+ /* set string with regex */
+ trigger->regex[index].str_regex = weechat_strndup (ptr_option,
+ pos_replace - ptr_option);
+ if (!trigger->regex[index].str_regex)
goto memory_error;
- trigger->regex[i].regex = malloc (sizeof (*trigger->regex[i].regex));
- if (!trigger->regex[i].regex)
+
+ /* set regex */
+ trigger->regex[index].regex = malloc (sizeof (*trigger->regex[index].regex));
+ if (!trigger->regex[index].regex)
goto memory_error;
- if (weechat_string_regcomp (trigger->regex[i].regex,
- trigger->regex[i].str_regex,
+ if (weechat_string_regcomp (trigger->regex[index].regex,
+ trigger->regex[index].str_regex,
REG_EXTENDED | REG_ICASE) != 0)
{
weechat_printf (NULL,
_("%s%s: error compiling regular expression \"%s\""),
weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
- trigger->regex[i].str_regex);
- free (trigger->regex[i].regex);
- trigger->regex[i].regex = NULL;
+ trigger->regex[index].str_regex);
+ free (trigger->regex[index].regex);
+ trigger->regex[index].regex = NULL;
goto end;
}
- pos = pos2 + length_delimiter;
-
- pos2 = strstr (pos + length_delimiter, delimiter);
- trigger->regex[i].replace = (pos2) ?
- weechat_strndup (pos, pos2 - pos) : strdup (pos);
- if (!trigger->regex[i].replace)
+ /* set replace and replace_eval */
+ trigger->regex[index].replace = (pos_replace_end) ?
+ weechat_strndup (pos_replace + length_delimiter,
+ pos_replace_end - pos_replace - length_delimiter) :
+ strdup (pos_replace + length_delimiter);
+ if (!trigger->regex[index].replace)
goto memory_error;
- trigger->regex[i].replace_eval =
- weechat_string_eval_expression (trigger->regex[i].replace,
+ trigger->regex[index].replace_eval =
+ weechat_string_eval_expression (trigger->regex[index].replace,
NULL, NULL, NULL);
+ if (!trigger->regex[index].replace_eval)
+ goto memory_error;
- pos = pos2;
+ if (!pos_replace_end)
+ break;
+
+ /* set variable (optional) */
+ ptr_option = pos_replace_end + length_delimiter;
+ if (!ptr_option[0])
+ break;
+ if (ptr_option[0] == ' ')
+ pos_next_regex = ptr_option;
+ else
+ {
+ pos_next_regex = strchr (ptr_option, ' ');
+ trigger->regex[index].variable = (pos_next_regex) ?
+ weechat_strndup (ptr_option, pos_next_regex - ptr_option) :
+ strdup (ptr_option);
+ if (!trigger->regex[index].variable)
+ goto memory_error;
+ }
+ if (!pos_next_regex)
+ break;
- i++;
+ /* skip spaces before next regex */
+ ptr_option = pos_next_regex + 1;
+ while (ptr_option[0] == ' ')
+ {
+ ptr_option++;
+ }
}
goto end;
format_error:
weechat_printf (NULL,
- _("%s%s: invalid value for option \"replace\", format "
- "is: \"/regex/replace\" (the char '/' can be "
- "replaced by one or more identical chars, except '\\' "
- "which is used for matching groups)"),
- weechat_prefix ("error"), TRIGGER_PLUGIN_NAME);
+ _("%s%s: invalid value for option \"regex\", "
+ "see /help trigger.trigger.%s.regex"),
+ weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
+ trigger->name);
trigger_free_regex (trigger);
goto end;
@@ -792,10 +810,16 @@ trigger_print_log ()
weechat_log_printf (" regex . . . . . . . . . : 0x%lx", ptr_trigger->regex);
for (i = 0; i < ptr_trigger->regex_count; i++)
{
- weechat_log_printf (" regex[%03d].regex. . . : 0x%lx",
+ weechat_log_printf (" regex[%03d].variable . . : '%s'",
+ i, ptr_trigger->regex[i].variable);
+ weechat_log_printf (" regex[%03d].str_regex. . : '%s'",
+ i, ptr_trigger->regex[i].str_regex);
+ weechat_log_printf (" regex[%03d].regex. . . . : 0x%lx",
i, ptr_trigger->regex[i].regex);
- weechat_log_printf (" regex[%03d].replace. . : '%s'",
+ weechat_log_printf (" regex[%03d].replace. . . : '%s'",
i, ptr_trigger->regex[i].replace);
+ weechat_log_printf (" regex[%03d].replace_eval : '%s'",
+ i, ptr_trigger->regex[i].replace_eval);
}
weechat_log_printf (" hooks_count . . . . . . : %d", ptr_trigger->hooks_count);
weechat_log_printf (" hooks . . . . . . . . . : 0x%lx", ptr_trigger->hooks);
@@ -900,8 +924,8 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
(void) plugin;
trigger_config_write ();
+ trigger_free_all ();
trigger_config_free ();
-
trigger_callback_end ();
return WEECHAT_RC_OK;
diff --git a/src/plugins/trigger/trigger.h b/src/plugins/trigger/trigger.h
index 8b3cffc51..ed7a05b54 100644
--- a/src/plugins/trigger/trigger.h
+++ b/src/plugins/trigger/trigger.h
@@ -60,6 +60,7 @@ enum t_trigger_return_code
struct t_trigger_regex
{
+ char *variable; /* the hashtable key used */
char *str_regex; /* regex to search for replacement */
regex_t *regex; /* compiled regex */
char *replace; /* replacement text */
@@ -75,8 +76,8 @@ struct t_trigger
/* internal vars */
/* regular expressions with their replacement text */
- int regex_count; /* number of regex/replacement */
- struct t_trigger_regex *regex; /* array of regex/replacement */
+ int regex_count; /* number of regex */
+ struct t_trigger_regex *regex; /* array of regex */
/* hooks */
int hooks_count; /* number of hooks */
@@ -95,6 +96,7 @@ extern struct t_weechat_plugin *weechat_trigger_plugin;
extern char *trigger_option_string[];
extern char *trigger_option_default[];
extern char *trigger_hook_type_string[];
+extern char *trigger_hook_regex_default_var[];
extern int trigger_return_code[];
extern struct t_trigger *triggers;
extern struct t_trigger *last_trigger;