diff --git a/src/xdgmimecache.c b/src/xdgmimecache.c index acaed9d470edf3536f6acb46db0761e7fcde29e8..5cbd3a807afd377ff7c5c172986130a1fbdd236f 100644 --- a/src/xdgmimecache.c +++ b/src/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]; @@ -532,17 +533,17 @@ cache_glob_lookup_suffix (const char *file_name, xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset); xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4); - n = cache_glob_node_lookup_suffix (cache, - n_entries, offset, - file_name, len, - ignore_case, - mime_types, - n_mime_types); - if (n > 0) - return n; + n += cache_glob_node_lookup_suffix (cache, + n_entries, offset, + file_name, len, + ignore_case, + mime_types + n, + n_mime_types - n); + if (n == n_mime_types) + break; } - return 0; + return n; } static int compare_mime_weight (const void *a, const void *b) @@ -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/src/xdgmimeglob.c b/src/xdgmimeglob.c index 5071418cc4a79d17f51b8168d2a21ec630b48dd8..6463837db5f6ac8a66c5f5db4778ef88add2eb5b 100644 --- a/src/xdgmimeglob.c +++ b/src/xdgmimeglob.c @@ -37,6 +37,10 @@ #include #include +#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)