summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2009-10-25 02:55:46 -0400
committerEmmanuel Fleury <emmanuel.fleury@gmail.com>2021-09-23 19:23:33 +0200
commita1bfe899abe2e0fab2e8697a5ec30da315117559 (patch)
tree2d90366426aeb3edaa4aa6eaf2cb83dfa1524e81
parentb4893986b07ee6651494f0edae836918e431a26e (diff)
downloadglib-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.c49
-rw-r--r--gio/xdgmime/xdgmimeglob.c42
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)