Index: base/third_party/xdg_mime/xdgmimeglob.c |
=================================================================== |
--- base/third_party/xdg_mime/xdgmimeglob.c (revision 150109) |
+++ base/third_party/xdg_mime/xdgmimeglob.c (working copy) |
@@ -26,7 +26,7 @@ |
*/ |
#ifdef HAVE_CONFIG_H |
-#include "config.h" |
+#include <config.h> |
#endif |
#include "xdgmimeglob.h" |
@@ -36,7 +36,6 @@ |
#include <assert.h> |
#include <string.h> |
#include <fnmatch.h> |
-#include <ctype.h> |
#ifndef FALSE |
#define FALSE (0) |
@@ -54,6 +53,7 @@ |
xdg_unichar_t character; |
const char *mime_type; |
int weight; |
+ int case_sensitive; |
XdgGlobHashNode *next; |
XdgGlobHashNode *child; |
}; |
@@ -62,6 +62,7 @@ |
const char *data; |
const char *mime_type; |
int weight; |
+ int case_sensitive; |
XdgGlobList *next; |
}; |
@@ -111,15 +112,27 @@ |
_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 +181,8 @@ |
_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 +246,11 @@ |
{ |
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 +268,7 @@ |
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 +279,12 @@ |
{ |
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 +294,8 @@ |
_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 +303,7 @@ |
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 +317,7 @@ |
_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 +329,6 @@ |
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 +341,15 @@ |
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 +358,9 @@ |
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; |
@@ -362,9 +381,25 @@ |
const MimeWeight *aa = (const MimeWeight *)a; |
const MimeWeight *bb = (const MimeWeight *)b; |
- return aa->weight - bb->weight; |
+ return bb->weight - aa->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 +411,7 @@ |
MimeWeight mimes[10]; |
int n_mimes = 10; |
int len; |
+ char *lower_case; |
/* First, check the literals */ |
@@ -383,17 +419,32 @@ |
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 +462,7 @@ |
} |
} |
} |
+ free (lower_case); |
qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight); |
@@ -493,7 +545,8 @@ |
_xdg_glob_hash_append_glob (XdgGlobHash *glob_hash, |
const char *glob, |
const char *mime_type, |
- int weight) |
+ int weight, |
+ int case_sensitive) |
{ |
XdgGlobType type; |
@@ -505,13 +558,13 @@ |
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; |
} |
} |
@@ -555,10 +608,12 @@ |
void |
_xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash, |
- const char *file_name) |
+ const char *file_name, |
+ int version_two) |
{ |
FILE *glob_file; |
char line[255]; |
+ char *p; |
glob_file = fopen (file_name, "r"); |
@@ -569,33 +624,67 @@ |
* Blah */ |
while (fgets (line, 255, glob_file) != NULL) |
{ |
- char *colon, *colon2; |
- char *mimetype, *glob; |
+ char *colon; |
+ char *mimetype, *glob, *end; |
int weight; |
+ int case_sensitive; |
- if (line[0] == '#') |
+ if (line[0] == '#' || line[0] == 0) |
continue; |
- colon = strchr (line, ':'); |
+ end = line + strlen(line) - 1; |
+ if (*end == '\n') |
+ *end = 0; |
+ |
+ p = line; |
+ if (version_two) |
+ { |
+ colon = strchr (p, ':'); |
+ if (colon == NULL) |
+ continue; |
+ *colon = 0; |
+ weight = atoi (p); |
+ p = colon + 1; |
+ } |
+ else |
+ weight = 50; |
+ |
+ colon = strchr (p, ':'); |
if (colon == NULL) |
continue; |
- *(colon++) = '\0'; |
- colon[strlen (colon) -1] = '\0'; |
- colon2 = strchr (colon, ':'); |
- if (colon2) |
- { |
- *(colon2++) = '\000'; |
- weight = atoi (line); |
- mimetype = colon; |
- glob = colon2; |
- } |
- else |
- { |
- weight = 50; |
- mimetype = line; |
- glob = colon; |
- } |
- _xdg_glob_hash_append_glob (glob_hash, glob, mimetype, weight); |
+ *colon = 0; |
+ |
+ mimetype = p; |
+ p = colon + 1; |
+ glob = p; |
+ case_sensitive = FALSE; |
+ |
+ colon = strchr (p, ':'); |
+ if (version_two && colon != NULL) |
+ { |
+ char *flag; |
+ |
+ /* We got flags */ |
+ *colon = 0; |
+ p = colon + 1; |
+ |
+ /* Flags end at next colon */ |
+ colon = strchr (p, ':'); |
+ if (colon != NULL) |
+ *colon = 0; |
+ |
+ flag = strstr (p, "cs"); |
+ if (flag != NULL && |
+ /* Start or after comma */ |
+ (flag == p || |
+ flag[-1] == ',') && |
+ /* ends with comma or end of string */ |
+ (flag[2] == 0 || |
+ flag[2] == ',')) |
+ case_sensitive = TRUE; |
+ } |
+ |
+ _xdg_glob_hash_append_glob (glob_hash, glob, mimetype, weight, case_sensitive); |
} |
fclose (glob_file); |