+/* Match STRING against the filename pattern PATTERN, returning zero if
+ * it matches, nonzero if not.
+ *
+ * GTK+ used to use a old version of GNU fnmatch() that was buggy
+ * in various ways and didn't handle UTF-8. The following is
+ * converted to UTF-8. To simplify the process of making it
+ * correct, this is special-cased to the combinations of flags
+ * that gtkfilesel.c uses.
+ *
+ * FNM_FILE_NAME - always set
+ * FNM_LEADING_DIR - never set
+ * FNM_NOESCAPE - set only on windows
+ * FNM_CASEFOLD - set only on windows
+ */
+gboolean
+_gtk_fnmatch (const char *pattern,
+ const char *string,
+ gboolean no_leading_period)
+{
+ return gtk_fnmatch_intern (pattern, string, TRUE, no_leading_period);
+}
+
+#undef FNMATCH_TEST_CASES
+#ifdef FNMATCH_TEST_CASES
+
+#define TEST(pat, str, no_leading_period, result) \
+ g_assert (_gtk_fnmatch ((pat), (str), (no_leading_period)) == result)
+
+int main (int argc, char **argv)
+{
+ TEST ("[a-]", "-", TRUE, TRUE);
+
+ TEST ("a", "a", TRUE, TRUE);
+ TEST ("a", "b", TRUE, FALSE);
+
+ /* Test what ? matches */
+ TEST ("?", "a", TRUE, TRUE);
+ TEST ("?", ".", TRUE, FALSE);
+ TEST ("a?", "a.", TRUE, TRUE);
+ TEST ("a/?", "a/b", TRUE, TRUE);
+ TEST ("a/?", "a/.", TRUE, FALSE);
+ TEST ("?", "/", TRUE, FALSE);
+
+ /* Test what * matches */
+ TEST ("*", "a", TRUE, TRUE);
+ TEST ("*", ".", TRUE, FALSE);
+ TEST ("a*", "a.", TRUE, TRUE);
+ TEST ("a/*", "a/b", TRUE, TRUE);
+ TEST ("a/*", "a/.", TRUE, FALSE);
+ TEST ("*", "/", TRUE, FALSE);
+
+ /* Range tests */
+ TEST ("[ab]", "a", TRUE, TRUE);
+ TEST ("[ab]", "c", TRUE, FALSE);
+ TEST ("[^ab]", "a", TRUE, FALSE);
+ TEST ("[!ab]", "a", TRUE, FALSE);
+ TEST ("[^ab]", "c", TRUE, TRUE);
+ TEST ("[!ab]", "c", TRUE, TRUE);
+ TEST ("[a-c]", "b", TRUE, TRUE);
+ TEST ("[a-c]", "d", TRUE, FALSE);
+ TEST ("[a-]", "-", TRUE, TRUE);
+ TEST ("[]]", "]", TRUE, TRUE);
+ TEST ("[^]]", "a", TRUE, TRUE);
+ TEST ("[!]]", "a", TRUE, TRUE);
+
+ /* Various unclosed ranges */
+ TEST ("[ab", "a", TRUE, FALSE);
+ TEST ("[a-", "a", TRUE, FALSE);
+ TEST ("[ab", "c", TRUE, FALSE);
+ TEST ("[a-", "c", TRUE, FALSE);
+ TEST ("[^]", "a", TRUE, FALSE);
+
+ /* Ranges and special no-wildcard matches */
+ TEST ("[.]", ".", TRUE, FALSE);
+ TEST ("a[.]", "a.", TRUE, TRUE);
+ TEST ("a/[.]", "a/.", TRUE, FALSE);
+ TEST ("[/]", "/", TRUE, FALSE);
+ TEST ("[^/]", "a", TRUE, TRUE);
+
+ /* Basic tests of * (and combinations of * and ?) */
+ TEST ("a*b", "ab", TRUE, TRUE);
+ TEST ("a*b", "axb", TRUE, TRUE);
+ TEST ("a*b", "axxb", TRUE, TRUE);
+ TEST ("a**b", "ab", TRUE, TRUE);
+ TEST ("a**b", "axb", TRUE, TRUE);
+ TEST ("a**b", "axxb", TRUE, TRUE);
+ TEST ("a*?*b", "ab", TRUE, FALSE);
+ TEST ("a*?*b", "axb", TRUE, TRUE);
+ TEST ("a*?*b", "axxb", TRUE, TRUE);
+
+ /* Test of *[range] */
+ TEST ("a*[cd]", "ac", TRUE, TRUE);
+ TEST ("a*[cd]", "axc", TRUE, TRUE);
+ TEST ("a*[cd]", "axx", TRUE, FALSE);
+
+ TEST ("a/[.]", "a/.", TRUE, FALSE);
+ TEST ("a*[.]", "a/.", TRUE, FALSE);
+
+ /* Test of UTF-8 */
+
+ TEST ("ä", "ä", TRUE, TRUE); /* TEST ("ä", "ä", TRUE); */
+ TEST ("?", "ä", TRUE, TRUE); /* TEST ("?", "ä", TRUE); */
+ TEST ("*ö", "äö", TRUE, TRUE); /* TEST ("*ö", "äö", TRUE); */
+ TEST ("*ö", "ääö", TRUE, TRUE); /* TEST ("*ö", "ääö", TRUE); */
+ TEST ("[ä]", "ä", TRUE, TRUE); /* TEST ("[ä]", "ä", TRUE); */
+ TEST ("[ä-ö]", "é", TRUE, TRUE); /* TEST ("[ä-ö]", "é", TRUE); */
+ TEST ("[ä-ö]", "a", TRUE, FALSE); /* TEST ("[ä-ö]", "a", FALSE); */
+
+#ifdef DO_ESCAPE
+ /* Tests of escaping */
+ TEST ("\\\\", "\\", TRUE, TRUE);
+ TEST ("\\?", "?", TRUE, TRUE);
+ TEST ("\\?", "a", TRUE, FALSE);
+ TEST ("\\*", "*", TRUE, TRUE);
+ TEST ("\\*", "a", TRUE, FALSE);
+ TEST ("\\[a-b]", "[a-b]", TRUE, TRUE);
+ TEST ("[\\\\]", "\\", TRUE, TRUE);
+ TEST ("[\\^a]", "a", TRUE, TRUE);
+ TEST ("[a\\-c]", "b", TRUE, FALSE);
+ TEST ("[a\\-c]", "-", TRUE, TRUE);
+ TEST ("[a\\]", "a", TRUE, FALSE);
+#endif /* DO_ESCAPE */
+
+ return 0;