#include "autocmd.h"
#include "ascii.h"
#include "ex.h"
+#include "util.h"
typedef struct {
guint bits;
if (!(cmd->bits & bits)) {
continue;
}
- /* skip it pattern does not match - '*' matches everithing */
- if (strcmp(cmd->pattern, "*") && strcmp(cmd->pattern, pattern)) {
+ /* skip if pattern does not match - we check the pattern against
+ * another pattern */
+ if (!util_wildmatch(pattern, cmd->pattern)) {
continue;
}
/* remove the bits from the item */
if (!(bits & cmd->bits)) {
continue;
}
- /* TODO skip if pattern does not match */
+ /* check pattern only if uri was given */
+ /* skip if pattern does not match */
+ if (uri && !util_wildmatch(cmd->pattern, uri)) {
+ continue;
+ }
/* run the command */
- /* TODO shoult hte result be tested for RESULT_COMPLETE? */
+ /* TODO shoult the result be tested for RESULT_COMPLETE? */
ex_run_string(cmd->excmd);
}
}
return expanded;
}
+/**
+ * Compares given string against also given pattern.
+ * * matches any sequence of characters
+ * ? matches any single character except of /
+ * \? matches a ?
+ * . matches a .
+ * ~ matches a ~
+ */
+gboolean util_wildmatch(const char *pattern, const char *string)
+{
+ int i;
+ char ul, pl;
+ const char *p, *s;
+
+ p = pattern;
+ s = string;
+
+ while (*p) {
+ switch (*p) {
+ case '?':
+ /* match single char except of / or end */
+ if (*s == '/' || !*s) {
+ return false;
+ }
+ break;
+
+ case '\\':
+ /* \ escapes next * or ? char */
+ if (*(p + 1) == '*' || *(p + 1) == '?') {
+ p++;
+ if (*p != *s) {
+ return false;
+ }
+ }
+ break;
+
+ case '*':
+ /* Try to match as much as possible. Try to match the complete
+ * uri, if that fails move forward in uri and chack for a
+ * match. */
+ i = strlen(s);
+ while (i >= 0 && !util_wildmatch(p + 1, s + i)) {
+ i--;
+ }
+ return i >= 0;
+
+ default:
+ ul = *s;
+ if (VB_IS_UPPER(ul)) {
+ ul += 'a' - 'A';
+ }
+ pl = *p;
+ if (VB_IS_UPPER(pl)) {
+ pl += 'a' - 'A';
+ }
+ if (ul != pl) {
+ return false;
+ }
+ break;
+ }
+ p++;
+ s++;
+ }
+
+ /* if there is uri left on pattern end - this is no match */
+ if (!*p) {
+ return !*s;
+ }
+
+ return false;
+}
+
/**
* Fills the given list store by matching data of also given src list.
*/
g_free(value);
}
+static void test_wildmatch_simple(void)
+{
+ g_assert_true(util_wildmatch("", ""));
+ g_assert_true(util_wildmatch("w", "w"));
+ g_assert_true(util_wildmatch(".", "."));
+ g_assert_true(util_wildmatch("~", "~"));
+ g_assert_true(util_wildmatch("wildmatch", "WildMatch"));
+ g_assert_true(util_wildmatch("wild\\match", "wild\\match"));
+
+ /* no special meaning of . and ~ in pattern */
+ g_assert_false(util_wildmatch(".", "w"));
+ g_assert_false(util_wildmatch("~", "w"));
+ g_assert_false(util_wildmatch("wild", "wild "));
+ g_assert_false(util_wildmatch("wild", " wild"));
+ g_assert_false(util_wildmatch("wild", "\\ wild"));
+ g_assert_false(util_wildmatch("wild", "\\wild"));
+ g_assert_false(util_wildmatch("wild", "wild\\"));
+ g_assert_false(util_wildmatch("wild\\1", "wild\\2"));
+}
+
+static void test_wildmatch_questionmark(void)
+{
+ g_assert_true(util_wildmatch("wild?atch", "wildmatch"));
+ g_assert_true(util_wildmatch("wild?atch", "wildBatch"));
+ g_assert_true(util_wildmatch("wild?atch", "wild?atch"));
+ g_assert_true(util_wildmatch("?ild?atch", "MildBatch"));
+ g_assert_true(util_wildmatch("foo\\?bar", "foo?bar"));
+ g_assert_true(util_wildmatch("???", "foo"));
+ g_assert_true(util_wildmatch("???", "bar"));
+
+ g_assert_false(util_wildmatch("foo\\?bar", "foorbar"));
+ g_assert_false(util_wildmatch("?", ""));
+}
+
+static void test_wildmatch_wildcard(void)
+{
+ g_assert_true(util_wildmatch("*", ""));
+ g_assert_true(util_wildmatch("*", "Match as much as possible"));
+ g_assert_true(util_wildmatch("*match", "prefix match"));
+ g_assert_true(util_wildmatch("match*", "match suffix"));
+ g_assert_true(util_wildmatch("match*", "match*"));
+ g_assert_true(util_wildmatch("match\\*", "match*"));
+ g_assert_true(util_wildmatch("do * match", "do a infix match"));
+ g_assert_true(util_wildmatch("*://*.io/*", "http://fanglingsu.github.io/vimb/"));
+
+ g_assert_false(util_wildmatch("match\\*", "match fail"));
+}
+
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
g_test_add_func("/test-util/expand-spacial", test_expand_speacial);
g_test_add_func("/test-util/strcasestr", test_strcasestr);
g_test_add_func("/test-util/str_replace", test_str_replace);
+ g_test_add_func("/test-util/wildmatch-simple", test_wildmatch_simple);
+ g_test_add_func("/test-util/wildmatch-questionmark", test_wildmatch_questionmark);
+ g_test_add_func("/test-util/wildmatch-wildcard", test_wildmatch_wildcard);
return g_test_run();
}