1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-02 15:53:12 +02:00

trigger: add support of variable in regex option

Examples with new format:
  /regex/text/
  /regex/text/var
  /regex1/text1/ /regex2/text2/
  /regex1/text1/var /regex2/text2/var
This commit is contained in:
Sebastien Helleu
2014-01-26 19:59:55 +01:00
parent bcff9162a7
commit be8e32dd1b
5 changed files with 196 additions and 158 deletions
+116 -92
View File
@@ -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;
if (delimiter)
{
free (delimiter);
delimiter = NULL;
}
length_delimiter = strlen (delimiter);
/* 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++;
length_delimiter = strlen (delimiter);
/* search the start of next regex */
pos = strstr (pos + length_delimiter, delimiter);
}
ptr_option = pos;
if (!ptr_option[0])
goto format_error;
/* at least one regex is needed */
if (regex_count == 0)
goto format_error;
/* search the start of replacement string */
pos_replace = strstr (ptr_option, delimiter);
if (!pos_replace)
goto format_error;
/* allocate with array of regex/replacement */
trigger->regex = malloc (regex_count * sizeof (trigger->regex[0]));
if (!trigger->regex)
goto memory_error;
/* search the end of replacement string */
pos_replace_end = strstr (pos_replace + length_delimiter, delimiter);
/* 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;
/* allocate regex and replacement */
i = 0;
pos = option_regex;
while (pos && pos[0])
{
pos += length_delimiter;
if (!pos[0])
break;
pos2 = strstr (pos + length_delimiter, delimiter);
if (!pos)
break;
trigger->regex[i].str_regex = weechat_strndup (pos, pos2 - pos);
if (!trigger->regex[i].str_regex)
new_regex = realloc (trigger->regex,
(trigger->regex_count + 1) * sizeof (trigger->regex[0]));
if (!new_regex)
goto memory_error;
trigger->regex[i].regex = malloc (sizeof (*trigger->regex[i].regex));
if (!trigger->regex[i].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;
if (weechat_string_regcomp (trigger->regex[i].regex,
trigger->regex[i].str_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[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;
i++;
/* 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;
/* 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;