mirror of
https://github.com/weechat/weechat.git
synced 2026-07-05 09:13:14 +02:00
api: allow wildcard "*" inside the mask in function string_match
This commit is contained in:
@@ -5593,8 +5593,7 @@ command_set_display_option_lists (char **argv, int arg_start, int arg_end,
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sOption \"%s\" not found (tip: you can use "
|
||||
"\"*\" at beginning and/or end of option to "
|
||||
"see a sublist)"),
|
||||
"wildcard \"*\" in option to see a sublist)"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
argv[i]);
|
||||
}
|
||||
@@ -7070,12 +7069,12 @@ command_init ()
|
||||
"freenode.#weechat\")\n"
|
||||
" - \"*\" means all buffers\n"
|
||||
" - a name starting with '!' is excluded\n"
|
||||
" - name can start or end with '*' to match many buffers\n"
|
||||
" - wildcard \"*\" is allowed\n"
|
||||
" tags: comma separated list of tags, for example \"irc_join,"
|
||||
"irc_part,irc_quit\"\n"
|
||||
" - logical \"and\": use \"+\" between tags (for example: "
|
||||
"\"nick_toto+irc_action\")\n"
|
||||
" - tags can start or end with '*'\n"
|
||||
" - wildcard \"*\" is allowed\n"
|
||||
" regex: POSIX extended regular expression to search in line\n"
|
||||
" - use '\\t' to separate prefix from message, special chars "
|
||||
"like '|' must be escaped: '\\|'\n"
|
||||
@@ -7271,7 +7270,7 @@ command_init ()
|
||||
" bar(xxx): bar \"xxx\"\n"
|
||||
" item(*): any bar item\n"
|
||||
" item(xxx): bar item \"xxx\"\n"
|
||||
"The key can start or end with '*' to match many mouse events.\n"
|
||||
"Wildcard \"*\" is allowed in key to match many mouse events.\n"
|
||||
"A special value for command with format \"hsignal:name\" can be "
|
||||
"used for context mouse, this will send the hsignal \"name\" with "
|
||||
"the focus hashtable as argument.\n"
|
||||
@@ -7591,8 +7590,7 @@ command_init ()
|
||||
NULL, "set",
|
||||
N_("set config options"),
|
||||
N_("[<option> [<value>]] || diff [<option> [<option>...]]"),
|
||||
N_("option: name of an option (can start or end with '*' to list many "
|
||||
"options)\n"
|
||||
N_("option: name of an option (wildcard \"*\" is allowed)\n"
|
||||
" value: new value for option\n"
|
||||
" diff: display only changed options\n"
|
||||
"\n"
|
||||
@@ -7621,8 +7619,8 @@ command_init ()
|
||||
NULL, "unset",
|
||||
N_("unset/reset config options"),
|
||||
N_("<option>"),
|
||||
N_("option: name of an option (may begin or end with \"*\" to "
|
||||
"mass-reset options, use carefully!)\n"
|
||||
N_("option: name of an option (wildcard \"*\" is allowed to mass-reset "
|
||||
"options, use carefully!)\n"
|
||||
"\n"
|
||||
"According to option, it's reset (for standard options) or removed "
|
||||
"(for optional settings, like server values).\n"
|
||||
|
||||
@@ -2289,11 +2289,11 @@ config_weechat_init_options ()
|
||||
weechat_config_file, ptr_section,
|
||||
"highlight_tags", "string",
|
||||
N_("comma separated list of tags to highlight; case insensitive "
|
||||
"comparison; each tag can start or end with \"*\" to match more "
|
||||
"than one tag; many tags can be separated by \"+\" to make a "
|
||||
"logical \"and\" between tags; examples: \"nick_flashcode\" for "
|
||||
"messages from nick \"FlashCode\", \"irc_notice+nick_toto*\" for "
|
||||
"notices from a nick starting with \"toto\""),
|
||||
"comparison; wildcard \"*\" is allowed in each tag; many tags can "
|
||||
"be separated by \"+\" to make a logical \"and\" between tags; "
|
||||
"examples: \"nick_flashcode\" for messages from nick \"FlashCode\", "
|
||||
"\"irc_notice+nick_toto*\" for notices from a nick starting with "
|
||||
"\"toto\""),
|
||||
NULL, 0, 0, "", NULL, 0, NULL, NULL, &config_change_highlight_tags, NULL, NULL, NULL);
|
||||
config_look_hotlist_add_conditions = config_file_new_option (
|
||||
weechat_config_file, ptr_section,
|
||||
@@ -3324,8 +3324,8 @@ config_weechat_init_options ()
|
||||
N_("comma separated list of plugins to load automatically "
|
||||
"at startup, \"*\" means all plugins found, a name beginning with "
|
||||
"\"!\" is a negative value to prevent a plugin from being loaded, "
|
||||
"names can start or end with \"*\" to match several plugins "
|
||||
"(examples: \"*\" or \"*,!lua,!tcl\")"),
|
||||
"wildcard \"*\" is allowed in names (examples: \"*\" or "
|
||||
"\"*,!lua,!tcl\")"),
|
||||
NULL, 0, 0, "*", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
config_plugin_debug = config_file_new_option (
|
||||
weechat_config_file, ptr_section,
|
||||
|
||||
+83
-68
@@ -363,7 +363,8 @@ string_strcasestr (const char *string, const char *search)
|
||||
/*
|
||||
* Checks if a string matches a mask.
|
||||
*
|
||||
* Mask can begin or end with "*", no other "*" are allowed inside mask.
|
||||
* The mask can contain wildcards ("*"), each wildcard matches 0 or more chars
|
||||
* in the string.
|
||||
*
|
||||
* Returns:
|
||||
* 1: string matches mask
|
||||
@@ -373,78 +374,92 @@ string_strcasestr (const char *string, const char *search)
|
||||
int
|
||||
string_match (const char *string, const char *mask, int case_sensitive)
|
||||
{
|
||||
char last, *mask2;
|
||||
int len_string, len_mask, rc;
|
||||
const char *ptr_string, *ptr_mask, *pos_word, *pos_end;
|
||||
char *word;
|
||||
int wildcard, length_word;
|
||||
|
||||
if (!mask || !mask[0])
|
||||
if (!string || !mask || !mask[0])
|
||||
return 0;
|
||||
|
||||
/* if mask is "*", then any string matches */
|
||||
if (strcmp (mask, "*") == 0)
|
||||
ptr_string = string;
|
||||
ptr_mask = mask;
|
||||
|
||||
while (ptr_mask[0])
|
||||
{
|
||||
wildcard = 0;
|
||||
|
||||
/* if we are on a wildcard, set the wildcard flag and skip it */
|
||||
if (ptr_mask[0] == '*')
|
||||
{
|
||||
wildcard = 1;
|
||||
ptr_mask++;
|
||||
while (ptr_mask[0] == '*')
|
||||
{
|
||||
ptr_mask++;
|
||||
}
|
||||
if (!ptr_mask[0])
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* no match if some mask without string */
|
||||
if (!string[0])
|
||||
return 0;
|
||||
|
||||
/* search the next wildcard (after the word) */
|
||||
pos_end = strchr (ptr_mask, '*');
|
||||
|
||||
/* extract the word before the wildcard (or the end of mask) */
|
||||
if (pos_end)
|
||||
{
|
||||
length_word = pos_end - ptr_mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
length_word = strlen (ptr_mask);
|
||||
pos_end = ptr_mask + length_word;
|
||||
}
|
||||
word = string_strndup (ptr_mask, length_word);
|
||||
if (!word)
|
||||
return 0;
|
||||
|
||||
/* check if the word is matching */
|
||||
if (wildcard)
|
||||
{
|
||||
/* search the word anywhere in the string (from current position) */
|
||||
pos_word = (case_sensitive) ?
|
||||
strstr (ptr_string, word) : string_strcasestr (ptr_string, word);
|
||||
if (!pos_word)
|
||||
{
|
||||
free (word);
|
||||
return 0;
|
||||
}
|
||||
ptr_string = pos_word + length_word;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* check if word is at beginning of string */
|
||||
if ((case_sensitive
|
||||
&& (strncmp (ptr_string, word, length_word) != 0))
|
||||
|| (!case_sensitive
|
||||
&& (string_strncasecmp (ptr_string, word,
|
||||
utf8_strlen (word)) != 0)))
|
||||
{
|
||||
free (word);
|
||||
return 0;
|
||||
}
|
||||
ptr_string += length_word;
|
||||
}
|
||||
|
||||
free (word);
|
||||
|
||||
ptr_mask = pos_end;
|
||||
}
|
||||
|
||||
/* match if no more string/mask */
|
||||
if (!ptr_string[0] && !ptr_mask[0])
|
||||
return 1;
|
||||
|
||||
len_string = strlen (string);
|
||||
len_mask = strlen (mask);
|
||||
|
||||
last = mask[len_mask - 1];
|
||||
|
||||
/* mask begins with "*" */
|
||||
if ((mask[0] == '*') && (last != '*'))
|
||||
{
|
||||
/* not enough chars in string to match */
|
||||
if (len_string < len_mask - 1)
|
||||
return 0;
|
||||
/* check if end of string matches */
|
||||
if ((case_sensitive && (strcmp (string + len_string - (len_mask - 1),
|
||||
mask + 1) == 0))
|
||||
|| (!case_sensitive && (string_strcasecmp (string + len_string - (len_mask - 1),
|
||||
mask + 1) == 0)))
|
||||
return 1;
|
||||
/* no match */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* mask ends with "*" */
|
||||
if ((mask[0] != '*') && (last == '*'))
|
||||
{
|
||||
/* not enough chars in string to match */
|
||||
if (len_string < len_mask - 1)
|
||||
return 0;
|
||||
/* check if beginning of string matches */
|
||||
if ((case_sensitive && (strncmp (string, mask, len_mask - 1) == 0))
|
||||
|| (!case_sensitive && (string_strncasecmp (string,
|
||||
mask,
|
||||
len_mask - 1) == 0)))
|
||||
return 1;
|
||||
/* no match */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* mask begins and ends with "*" */
|
||||
if ((mask[0] == '*') && (last == '*'))
|
||||
{
|
||||
/* not enough chars in string to match */
|
||||
if (len_string < len_mask - 2)
|
||||
return 0;
|
||||
/* keep only relevant chars in mask for searching string */
|
||||
mask2 = string_strndup (mask + 1, len_mask - 2);
|
||||
if (!mask2)
|
||||
return 0;
|
||||
/* search string */
|
||||
rc = ((case_sensitive && strstr (string, mask2))
|
||||
|| (!case_sensitive && string_strcasestr (string, mask2))) ?
|
||||
1 : 0;
|
||||
/* free and return */
|
||||
free (mask2);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* no "*" at all, compare strings */
|
||||
if ((case_sensitive && (strcmp (string, mask) == 0))
|
||||
|| (!case_sensitive && (string_strcasecmp (string, mask) == 0)))
|
||||
return 1;
|
||||
|
||||
/* no match */
|
||||
/* no match in other cases */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user