Don't give up too early when collecting mime types

Since returning exactly one match has special significance, don't
give up matching before we've found at least 2 types. Also, make
sure that we don't return the same mime type more than once.
Bug 541236.
This commit is contained in:
Matthias Clasen 2009-10-25 02:55:46 -04:00 committed by Emmanuel Fleury
parent b4893986b0
commit a1bfe899ab
2 changed files with 78 additions and 13 deletions

View File

@ -428,11 +428,11 @@ cache_glob_lookup_fnmatch (const char *file_name,
} }
} }
if (n > 0) if (n == n_mime_types)
return n; break;
} }
return 0; return n;
} }
static int static int
@ -524,6 +524,7 @@ cache_glob_lookup_suffix (const char *file_name,
{ {
int i, n; int i, n;
n = 0;
for (i = 0; _caches[i]; i++) for (i = 0; _caches[i]; i++)
{ {
XdgMimeCache *cache = _caches[i]; XdgMimeCache *cache = _caches[i];
@ -569,6 +570,34 @@ ascii_tolower (const char *str)
return lower; return lower;
} }
static int
filter_out_dupes (MimeWeight mimes[], int n_mimes)
{
int last;
int i, j;
last = n_mimes;
for (i = 0; i < last; i++)
{
j = i + 1;
while (j < last)
{
if (strcmp (mimes[i].mime, mimes[j].mime) == 0)
{
mimes[i].weight = MAX (mimes[i].weight, mimes[j].weight);
last--;
mimes[j].mime = mimes[last].mime;
mimes[j].weight = mimes[last].weight;
}
else
j++;
}
}
return last;
}
static int static int
cache_glob_lookup_file_name (const char *file_name, cache_glob_lookup_file_name (const char *file_name,
const char *mime_types[], const char *mime_types[],
@ -603,14 +632,16 @@ cache_glob_lookup_file_name (const char *file_name,
len = strlen (file_name); len = strlen (file_name);
n = cache_glob_lookup_suffix (lower_case, len, FALSE, mimes, n_mimes); n = cache_glob_lookup_suffix (lower_case, len, FALSE, mimes, n_mimes);
if (n == 0) if (n < 2)
n = cache_glob_lookup_suffix (file_name, len, TRUE, mimes, n_mimes); n += cache_glob_lookup_suffix (file_name, len, TRUE, mimes + n, n_mimes - n);
/* Last, try fnmatch */ /* Last, try fnmatch */
if (n == 0) if (n == 0)
n = cache_glob_lookup_fnmatch (lower_case, mimes, n_mimes, FALSE); n = cache_glob_lookup_fnmatch (lower_case, mimes, n_mimes, FALSE);
if (n == 0) if (n < 2)
n = cache_glob_lookup_fnmatch (file_name, mimes, n_mimes, TRUE); n += cache_glob_lookup_fnmatch (file_name, mimes + n, n_mimes - n, TRUE);
n = filter_out_dupes (mimes, n);
free (lower_case); free (lower_case);

View File

@ -37,6 +37,10 @@
#include <string.h> #include <string.h>
#include <fnmatch.h> #include <fnmatch.h>
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef FALSE #ifndef FALSE
#define FALSE (0) #define FALSE (0)
#endif #endif
@ -400,6 +404,34 @@ ascii_tolower (const char *str)
return lower; return lower;
} }
static int
filter_out_dupes (MimeWeight mimes[], int n_mimes)
{
int last;
int i, j;
last = n_mimes;
for (i = 0; i < last; i++)
{
j = i + 1;
while (j < last)
{
if (strcmp (mimes[i].mime, mimes[j].mime) == 0)
{
mimes[i].weight = MAX (mimes[i].weight, mimes[j].weight);
last--;
mimes[j].mime = mimes[last].mime;
mimes[j].weight = mimes[last].weight;
}
else
j++;
}
}
return last;
}
int int
_xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash, _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
const char *file_name, const char *file_name,
@ -446,11 +478,11 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
len = strlen (file_name); len = strlen (file_name);
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, lower_case, len, FALSE, n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, lower_case, len, FALSE,
mimes, n_mimes); mimes, n_mimes);
if (n == 0) if (n < 2)
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, TRUE, n += _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, TRUE,
mimes, n_mimes); mimes + n, n_mimes - n);
if (n == 0) if (n < 2)
{ {
for (list = glob_hash->full_list; list && n < n_mime_types; list = list->next) for (list = glob_hash->full_list; list && n < n_mime_types; list = list->next)
{ {
@ -464,6 +496,8 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
} }
free (lower_case); free (lower_case);
n = filter_out_dupes (mimes, n);
qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight); qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight);
if (n_mime_types < n) if (n_mime_types < n)