diff options
author | Matthias Clasen <mclasen@redhat.com> | 2009-10-25 02:55:46 -0400 |
---|---|---|
committer | Emmanuel Fleury <emmanuel.fleury@gmail.com> | 2021-09-23 19:23:33 +0200 |
commit | a1bfe899abe2e0fab2e8697a5ec30da315117559 (patch) | |
tree | 2d90366426aeb3edaa4aa6eaf2cb83dfa1524e81 | |
parent | b4893986b07ee6651494f0edae836918e431a26e (diff) | |
download | glib-a1bfe899abe2e0fab2e8697a5ec30da315117559.tar.gz |
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.
-rw-r--r-- | gio/xdgmime/xdgmimecache.c | 49 | ||||
-rw-r--r-- | gio/xdgmime/xdgmimeglob.c | 42 |
2 files changed, 78 insertions, 13 deletions
diff --git a/gio/xdgmime/xdgmimecache.c b/gio/xdgmime/xdgmimecache.c index acaed9d47..58a845b15 100644 --- a/gio/xdgmime/xdgmimecache.c +++ b/gio/xdgmime/xdgmimecache.c @@ -428,11 +428,11 @@ cache_glob_lookup_fnmatch (const char *file_name, } } - if (n > 0) - return n; + if (n == n_mime_types) + break; } - - return 0; + + return n; } static int @@ -524,6 +524,7 @@ cache_glob_lookup_suffix (const char *file_name, { int i, n; + n = 0; for (i = 0; _caches[i]; i++) { XdgMimeCache *cache = _caches[i]; @@ -570,7 +571,35 @@ ascii_tolower (const char *str) } static int -cache_glob_lookup_file_name (const char *file_name, +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 +cache_glob_lookup_file_name (const char *file_name, const char *mime_types[], int n_mime_types) { @@ -603,14 +632,16 @@ cache_glob_lookup_file_name (const char *file_name, len = strlen (file_name); 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); + if (n < 2) + n += cache_glob_lookup_suffix (file_name, len, TRUE, mimes + n, n_mimes - n); /* Last, try fnmatch */ if (n == 0) n = cache_glob_lookup_fnmatch (lower_case, mimes, n_mimes, FALSE); - if (n == 0) - n = cache_glob_lookup_fnmatch (file_name, mimes, n_mimes, TRUE); + if (n < 2) + n += cache_glob_lookup_fnmatch (file_name, mimes + n, n_mimes - n, TRUE); + + n = filter_out_dupes (mimes, n); free (lower_case); diff --git a/gio/xdgmime/xdgmimeglob.c b/gio/xdgmime/xdgmimeglob.c index 5071418cc..6463837db 100644 --- a/gio/xdgmime/xdgmimeglob.c +++ b/gio/xdgmime/xdgmimeglob.c @@ -37,6 +37,10 @@ #include <string.h> #include <fnmatch.h> +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + #ifndef FALSE #define FALSE (0) #endif @@ -400,6 +404,34 @@ ascii_tolower (const char *str) 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 _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash, const char *file_name, @@ -446,11 +478,11 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash, len = strlen (file_name); 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, - mimes, n_mimes); + if (n < 2) + n += _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, TRUE, + 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) { @@ -464,6 +496,8 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash, } free (lower_case); + n = filter_out_dupes (mimes, n); + qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight); if (n_mime_types < n) |