mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
xdgmime - support the new case sensitive flag
This commit is contained in:
parent
7c27df1fee
commit
e1643fd76d
@ -361,7 +361,8 @@ typedef struct {
|
||||
static int
|
||||
cache_glob_lookup_literal (const char *file_name,
|
||||
const char *mime_types[],
|
||||
int n_mime_types)
|
||||
int n_mime_types,
|
||||
int case_sensitive_check)
|
||||
{
|
||||
const char *ptr;
|
||||
int i, min, max, mid, cmp;
|
||||
@ -382,17 +383,25 @@ cache_glob_lookup_literal (const char *file_name,
|
||||
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid);
|
||||
ptr = cache->buffer + offset;
|
||||
cmp = strcmp (ptr, file_name);
|
||||
|
||||
|
||||
if (cmp < 0)
|
||||
min = mid + 1;
|
||||
else if (cmp > 0)
|
||||
max = mid - 1;
|
||||
else
|
||||
{
|
||||
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid + 4);
|
||||
mime_types[0] = (const char *)(cache->buffer + offset);
|
||||
|
||||
return 1;
|
||||
int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid + 8);
|
||||
int case_sensitive = weight & 0x100;
|
||||
weight = weight & 0xff;
|
||||
|
||||
if (case_sensitive_check || !case_sensitive)
|
||||
{
|
||||
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid + 4);
|
||||
mime_types[0] = (const char *)(cache->buffer + offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -423,6 +432,7 @@ cache_glob_lookup_fnmatch (const char *file_name,
|
||||
xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j);
|
||||
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 4);
|
||||
int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 8);
|
||||
weight = weight & 0xff;
|
||||
ptr = cache->buffer + offset;
|
||||
mime_type = cache->buffer + mimetype_offset;
|
||||
|
||||
@ -448,7 +458,7 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
|
||||
xdg_uint32_t offset,
|
||||
const char *file_name,
|
||||
int len,
|
||||
int ignore_case,
|
||||
int case_sensitive_check,
|
||||
MimeWeight mime_types[],
|
||||
int n_mime_types)
|
||||
{
|
||||
@ -458,12 +468,11 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
|
||||
xdg_uint32_t n_children;
|
||||
xdg_uint32_t child_offset;
|
||||
int weight;
|
||||
int case_sensitive;
|
||||
|
||||
int min, max, mid, n, i;
|
||||
|
||||
character = file_name[len - 1];
|
||||
if (ignore_case)
|
||||
character = tolower (character);
|
||||
|
||||
assert (character != 0);
|
||||
|
||||
@ -489,7 +498,7 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
|
||||
n = cache_glob_node_lookup_suffix (cache,
|
||||
n_children, child_offset,
|
||||
file_name, len,
|
||||
ignore_case,
|
||||
case_sensitive_check,
|
||||
mime_types,
|
||||
n_mime_types);
|
||||
}
|
||||
@ -504,10 +513,15 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
|
||||
|
||||
mimetype_offset = GET_UINT32 (cache->buffer, child_offset + 12 * i + 4);
|
||||
weight = GET_UINT32 (cache->buffer, child_offset + 12 * i + 8);
|
||||
case_sensitive = weight & 0x100;
|
||||
weight = weight & 0xff;
|
||||
|
||||
mime_types[n].mime = cache->buffer + mimetype_offset;
|
||||
mime_types[n].weight = weight;
|
||||
n++;
|
||||
if (case_sensitive_check || !case_sensitive)
|
||||
{
|
||||
mime_types[n].mime = cache->buffer + mimetype_offset;
|
||||
mime_types[n].weight = weight;
|
||||
n++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -555,6 +569,22 @@ static int compare_mime_weight (const void *a, const void *b)
|
||||
return aa->weight - bb->weight;
|
||||
}
|
||||
|
||||
#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z')
|
||||
static char *
|
||||
ascii_tolower (const char *str)
|
||||
{
|
||||
char *p, *lower;
|
||||
|
||||
lower = strdup (str);
|
||||
p = lower;
|
||||
while (*p != 0)
|
||||
{
|
||||
char c = *p;
|
||||
*p++ = ISUPPER (c) ? c - 'A' + 'a' : c;
|
||||
}
|
||||
return lower;
|
||||
}
|
||||
|
||||
static int
|
||||
cache_glob_lookup_file_name (const char *file_name,
|
||||
const char *mime_types[],
|
||||
@ -565,20 +595,36 @@ cache_glob_lookup_file_name (const char *file_name,
|
||||
int n_mimes = 10;
|
||||
int i;
|
||||
int len;
|
||||
|
||||
char *lower_case;
|
||||
int try_lower_case;
|
||||
|
||||
assert (file_name != NULL && n_mime_types > 0);
|
||||
|
||||
/* First, check the literals */
|
||||
n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types);
|
||||
|
||||
lower_case = ascii_tolower (file_name);
|
||||
|
||||
n = cache_glob_lookup_literal (lower_case, mime_types, n_mime_types, FALSE);
|
||||
if (n > 0)
|
||||
return n;
|
||||
{
|
||||
free (lower_case);
|
||||
return n;
|
||||
}
|
||||
|
||||
n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types, TRUE);
|
||||
if (n > 0)
|
||||
{
|
||||
free (lower_case);
|
||||
return n;
|
||||
}
|
||||
|
||||
len = strlen (file_name);
|
||||
n = cache_glob_lookup_suffix (file_name, len, FALSE, mimes, n_mimes);
|
||||
|
||||
n = cache_glob_lookup_suffix (lower_case, len, FALSE, mimes, n_mimes);
|
||||
if (n == 0)
|
||||
n = cache_glob_lookup_suffix (file_name, len, TRUE, mimes, n_mimes);
|
||||
|
||||
|
||||
free (lower_case);
|
||||
|
||||
/* Last, try fnmatch */
|
||||
if (n == 0)
|
||||
n = cache_glob_lookup_fnmatch (file_name, mimes, n_mimes);
|
||||
|
@ -54,6 +54,7 @@ struct XdgGlobHashNode
|
||||
xdg_unichar_t character;
|
||||
const char *mime_type;
|
||||
int weight;
|
||||
int case_sensitive;
|
||||
XdgGlobHashNode *next;
|
||||
XdgGlobHashNode *child;
|
||||
};
|
||||
@ -62,6 +63,7 @@ struct XdgGlobList
|
||||
const char *data;
|
||||
const char *mime_type;
|
||||
int weight;
|
||||
int case_sensitive;
|
||||
XdgGlobList *next;
|
||||
};
|
||||
|
||||
@ -111,15 +113,27 @@ static XdgGlobList *
|
||||
_xdg_glob_list_append (XdgGlobList *glob_list,
|
||||
void *data,
|
||||
const char *mime_type,
|
||||
int weight)
|
||||
int weight,
|
||||
int case_sensitive)
|
||||
{
|
||||
XdgGlobList *new_element;
|
||||
XdgGlobList *tmp_element;
|
||||
|
||||
tmp_element = glob_list;
|
||||
while (tmp_element != NULL)
|
||||
{
|
||||
if (strcmp (tmp_element->data, data) == 0 &&
|
||||
strcmp (tmp_element->mime_type, mime_type) == 0)
|
||||
return glob_list;
|
||||
|
||||
tmp_element = tmp_element->next;
|
||||
}
|
||||
|
||||
new_element = _xdg_glob_list_new ();
|
||||
new_element->data = data;
|
||||
new_element->mime_type = mime_type;
|
||||
new_element->weight = weight;
|
||||
new_element->case_sensitive = case_sensitive;
|
||||
if (glob_list == NULL)
|
||||
return new_element;
|
||||
|
||||
@ -168,7 +182,8 @@ static XdgGlobHashNode *
|
||||
_xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node,
|
||||
xdg_unichar_t *text,
|
||||
const char *mime_type,
|
||||
int weight)
|
||||
int weight,
|
||||
int case_sensitive)
|
||||
{
|
||||
XdgGlobHashNode *node;
|
||||
xdg_unichar_t character;
|
||||
@ -232,11 +247,11 @@ _xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node,
|
||||
{
|
||||
if (node->mime_type)
|
||||
{
|
||||
if (strcmp (node->mime_type, mime_type))
|
||||
if (strcmp (node->mime_type, mime_type) != 0)
|
||||
{
|
||||
XdgGlobHashNode *child;
|
||||
int found_node = FALSE;
|
||||
|
||||
|
||||
child = node->child;
|
||||
while (child && child->character == 0)
|
||||
{
|
||||
@ -254,6 +269,7 @@ _xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node,
|
||||
child->character = 0;
|
||||
child->mime_type = strdup (mime_type);
|
||||
child->weight = weight;
|
||||
child->case_sensitive = case_sensitive;
|
||||
child->child = NULL;
|
||||
child->next = node->child;
|
||||
node->child = child;
|
||||
@ -264,11 +280,12 @@ _xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node,
|
||||
{
|
||||
node->mime_type = strdup (mime_type);
|
||||
node->weight = weight;
|
||||
node->case_sensitive = case_sensitive;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
node->child = _xdg_glob_hash_insert_ucs4 (node->child, text, mime_type, weight);
|
||||
node->child = _xdg_glob_hash_insert_ucs4 (node->child, text, mime_type, weight, case_sensitive);
|
||||
}
|
||||
return glob_hash_node;
|
||||
}
|
||||
@ -278,7 +295,8 @@ static XdgGlobHashNode *
|
||||
_xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
||||
const char *text,
|
||||
const char *mime_type,
|
||||
int weight)
|
||||
int weight,
|
||||
int case_sensitive)
|
||||
{
|
||||
XdgGlobHashNode *node;
|
||||
xdg_unichar_t *unitext;
|
||||
@ -286,7 +304,7 @@ _xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
|
||||
|
||||
unitext = _xdg_convert_to_ucs4 (text, &len);
|
||||
_xdg_reverse_ucs4 (unitext, len);
|
||||
node = _xdg_glob_hash_insert_ucs4 (glob_hash_node, unitext, mime_type, weight);
|
||||
node = _xdg_glob_hash_insert_ucs4 (glob_hash_node, unitext, mime_type, weight, case_sensitive);
|
||||
free (unitext);
|
||||
return node;
|
||||
}
|
||||
@ -300,7 +318,7 @@ static int
|
||||
_xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
|
||||
const char *file_name,
|
||||
int len,
|
||||
int ignore_case,
|
||||
int case_sensitive_check,
|
||||
MimeWeight mime_types[],
|
||||
int n_mime_types)
|
||||
{
|
||||
@ -312,8 +330,6 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
|
||||
return 0;
|
||||
|
||||
character = file_name[len - 1];
|
||||
if (ignore_case)
|
||||
character = tolower(character);
|
||||
|
||||
for (node = glob_hash_node; node && character >= node->character; node = node->next)
|
||||
{
|
||||
@ -326,13 +342,15 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
|
||||
n = _xdg_glob_hash_node_lookup_file_name (node->child,
|
||||
file_name,
|
||||
len,
|
||||
ignore_case,
|
||||
case_sensitive_check,
|
||||
mime_types,
|
||||
n_mime_types);
|
||||
}
|
||||
if (n == 0)
|
||||
{
|
||||
if (node->mime_type)
|
||||
if (node->mime_type &&
|
||||
(case_sensitive_check ||
|
||||
!node->case_sensitive))
|
||||
{
|
||||
mime_types[n].mime = node->mime_type;
|
||||
mime_types[n].weight = node->weight;
|
||||
@ -341,7 +359,9 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
|
||||
node = node->child;
|
||||
while (n < n_mime_types && node && node->character == 0)
|
||||
{
|
||||
if (node->mime_type)
|
||||
if (node->mime_type &&
|
||||
(case_sensitive_check ||
|
||||
!node->case_sensitive))
|
||||
{
|
||||
mime_types[n].mime = node->mime_type;
|
||||
mime_types[n].weight = node->weight;
|
||||
@ -365,6 +385,22 @@ static int compare_mime_weight (const void *a, const void *b)
|
||||
return aa->weight - bb->weight;
|
||||
}
|
||||
|
||||
#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z')
|
||||
static char *
|
||||
ascii_tolower (const char *str)
|
||||
{
|
||||
char *p, *lower;
|
||||
|
||||
lower = strdup (str);
|
||||
p = lower;
|
||||
while (*p != 0)
|
||||
{
|
||||
char c = *p;
|
||||
*p++ = ISUPPER (c) ? c - 'A' + 'a' : c;
|
||||
}
|
||||
return lower;
|
||||
}
|
||||
|
||||
int
|
||||
_xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
||||
const char *file_name,
|
||||
@ -376,6 +412,8 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
||||
MimeWeight mimes[10];
|
||||
int n_mimes = 10;
|
||||
int len;
|
||||
char *lower_case;
|
||||
int try_lower_case;
|
||||
|
||||
/* First, check the literals */
|
||||
|
||||
@ -383,17 +421,32 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
||||
|
||||
n = 0;
|
||||
|
||||
lower_case = ascii_tolower (file_name);
|
||||
|
||||
for (list = glob_hash->literal_list; list; list = list->next)
|
||||
{
|
||||
if (strcmp ((const char *)list->data, file_name) == 0)
|
||||
{
|
||||
mime_types[0] = list->mime_type;
|
||||
free (lower_case);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (list = glob_hash->literal_list; list; list = list->next)
|
||||
{
|
||||
if (!list->case_sensitive &&
|
||||
strcmp ((const char *)list->data, lower_case) == 0)
|
||||
{
|
||||
mime_types[0] = list->mime_type;
|
||||
free (lower_case);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
len = strlen (file_name);
|
||||
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, FALSE,
|
||||
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, lower_case, len, FALSE,
|
||||
mimes, n_mimes);
|
||||
if (n == 0)
|
||||
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, TRUE,
|
||||
@ -411,6 +464,7 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
|
||||
}
|
||||
}
|
||||
}
|
||||
free (lower_case);
|
||||
|
||||
qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight);
|
||||
|
||||
@ -506,13 +560,13 @@ _xdg_glob_hash_append_glob (XdgGlobHash *glob_hash,
|
||||
switch (type)
|
||||
{
|
||||
case XDG_GLOB_LITERAL:
|
||||
glob_hash->literal_list = _xdg_glob_list_append (glob_hash->literal_list, strdup (glob), strdup (mime_type), weight);
|
||||
glob_hash->literal_list = _xdg_glob_list_append (glob_hash->literal_list, strdup (glob), strdup (mime_type), weight, case_sensitive);
|
||||
break;
|
||||
case XDG_GLOB_SIMPLE:
|
||||
glob_hash->simple_node = _xdg_glob_hash_insert_text (glob_hash->simple_node, glob + 1, mime_type, weight);
|
||||
glob_hash->simple_node = _xdg_glob_hash_insert_text (glob_hash->simple_node, glob + 1, mime_type, weight, case_sensitive);
|
||||
break;
|
||||
case XDG_GLOB_FULL:
|
||||
glob_hash->full_list = _xdg_glob_list_append (glob_hash->full_list, strdup (glob), strdup (mime_type), weight);
|
||||
glob_hash->full_list = _xdg_glob_list_append (glob_hash->full_list, strdup (glob), strdup (mime_type), weight, case_sensitive);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user