mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-12 05:20:17 +00:00
Add a helper to make case-insensitive globs
This will be used in GtkFileFilter in the future. Tests included.
This commit is contained in:
parent
8981ba4bd2
commit
47400e4bd8
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user