[gtk/ci-file-filters: 20/21] Add a helper to make case-insensitive globs
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/ci-file-filters: 20/21] Add a helper to make case-insensitive globs
- Date: Fri, 4 Jun 2021 21:59:25 +0000 (UTC)
commit 980150c7f79995a3ff0dce8190a6b40cf41e3eb7
Author: Matthias Clasen <mclasen redhat com>
Date: Thu Jun 3 23:50:09 2021 -0400
Add a helper to make case-insensitive globs
This will be used in GtkFileFilter in the future.
Tests included.
gtk/fnmatch.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++
gtk/gtkprivate.h | 3 +++
testsuite/gtk/fnmatch.c | 37 ++++++++++++++++++++++++++++
3 files changed, 104 insertions(+)
---
diff --git a/gtk/fnmatch.c b/gtk/fnmatch.c
index 0ad1cd8992..9b51df208d 100644
--- a/gtk/fnmatch.c
+++ b/gtk/fnmatch.c
@@ -253,3 +253,67 @@ _gtk_fnmatch (const char *pattern,
{
return gtk_fnmatch_intern (pattern, string, TRUE, no_leading_period, casefold);
}
+
+/* Turn a glob pattern into a case-insensitive one, by replacing
+ * alphabetic characters by [xX] ranges.
+ */
+char *
+_gtk_make_ci_glob_pattern (const char *pattern)
+{
+ GString *s;
+ gboolean in_range = FALSE;
+
+ s = g_string_new ("");
+ for (const char *p = pattern; *p; p = g_utf8_next_char (p))
+ {
+ gunichar c = g_utf8_get_char (p);
+ if (in_range)
+ {
+ g_string_append_unichar (s, c);
+ if (c == ']')
+ in_range = FALSE;
+ continue;
+ }
+
+#if DO_ESCAPE
+ if (c == '\\')
+ {
+ g_string_append (s, "\\");
+ p = g_utf8_next_char (p);
+ if (*p == '\0')
+ break;
+
+ c = g_utf8_get_char (p);
+ g_string_append_unichar (s, c);
+ continue;
+ }
+#endif
+
+ if (c == '[')
+ {
+ g_string_append (s, "[");
+ p = g_utf8_next_char (p);
+ if (*p == '\0')
+ break;
+
+ c = g_utf8_get_char (p);
+ g_string_append_unichar (s, c);
+
+ in_range = TRUE;
+ continue;
+ }
+ else if (g_unichar_isalpha (c))
+ {
+ g_string_append (s, "[");
+ g_string_append_unichar (s, g_unichar_tolower (c));
+ g_string_append_unichar (s, g_unichar_toupper (c));
+ g_string_append (s, "]");
+ }
+ else
+ {
+ g_string_append_unichar (s, c);
+ }
+ }
+
+ return g_string_free (s, FALSE);
+}
diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h
index d24c272065..8cb11c761c 100644
--- a/gtk/gtkprivate.h
+++ b/gtk/gtkprivate.h
@@ -64,6 +64,9 @@ gboolean _gtk_fnmatch (const char *pattern,
gboolean no_leading_period,
gboolean casefold);
+char * _gtk_make_ci_glob_pattern (const char *pattern);
+
+
char * _gtk_get_lc_ctype (void);
void _gtk_ensure_resources (void);
diff --git a/testsuite/gtk/fnmatch.c b/testsuite/gtk/fnmatch.c
index a614c1f99b..e16bdae016 100644
--- a/testsuite/gtk/fnmatch.c
+++ b/testsuite/gtk/fnmatch.c
@@ -125,6 +125,37 @@ test_fnmatch (gconstpointer data)
g_assert_true (_gtk_fnmatch (test->pat, test->str, test->no_leading_period, test->ci) == test->result);
}
+typedef struct {
+ const char *glob;
+ const char *ci;
+} CITest;
+
+static CITest citests[] = {
+ { "*.txt", "*.[tT][xX][tT]" },
+ { "*.TXT", "*.[tT][xX][tT]" },
+ { "*?[]-abc]t", "*?[]-abc][tT]" },
+#ifdef DO_ESCAPE
+ /* Tests of escaping */
+ { "\\\\", "\\\\" },
+ { "\\??", "\\??" },
+ { "\\**", "\\**" },
+ { "\\[", "\\[" },
+ { "\\[a-", "\\[[aA]-" },
+ { "\\[]", "\\[]" },
+#endif
+};
+
+static void
+test_ci_glob (gconstpointer data)
+{
+ const CITest *test = data;
+ char *ci;
+
+ ci = _gtk_make_ci_glob_pattern (test->glob);
+ g_assert_cmpstr (ci, ==, test->ci);
+ g_free (ci);
+}
+
int
main (int argc, char *argv[])
{
@@ -136,5 +167,11 @@ main (int argc, char *argv[])
g_test_add_data_func (path, &tests[i], test_fnmatch);
}
+ for (int i = 0; i < G_N_ELEMENTS (citests); i++)
+ {
+ char *path = g_strdup_printf ("/ci-glob/test%d", i);
+ g_test_add_data_func (path, &citests[i], test_ci_glob);
+ }
+
return g_test_run ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]