OLD | NEW |
1 /* -*- mode: C; c-file-style: "gnu" -*- */ | 1 /* -*- mode: C; c-file-style: "gnu" -*- */ |
2 /* xdgmimeglob.c: Private file. Datastructure for storing the globs. | 2 /* xdgmimeglob.c: Private file. Datastructure for storing the globs. |
3 * | 3 * |
4 * More info can be found at http://www.freedesktop.org/standards/ | 4 * More info can be found at http://www.freedesktop.org/standards/ |
5 * | 5 * |
6 * Copyright (C) 2003 Red Hat, Inc. | 6 * Copyright (C) 2003 Red Hat, Inc. |
7 * Copyright (C) 2003 Jonathan Blandford <jrb@alum.mit.edu> | 7 * Copyright (C) 2003 Jonathan Blandford <jrb@alum.mit.edu> |
8 * | 8 * |
9 * Licensed under the Academic Free License version 2.0 | 9 * Licensed under the Academic Free License version 2.0 |
10 * Or under the following terms: | 10 * Or under the following terms: |
11 * | 11 * |
12 * This library is free software; you can redistribute it and/or | 12 * This library is free software; you can redistribute it and/or |
13 * modify it under the terms of the GNU Lesser General Public | 13 * modify it under the terms of the GNU Lesser General Public |
14 * License as published by the Free Software Foundation; either | 14 * License as published by the Free Software Foundation; either |
15 * version 2 of the License, or (at your option) any later version. | 15 * version 2 of the License, or (at your option) any later version. |
16 * | 16 * |
17 * This library is distributed in the hope that it will be useful, | 17 * This library is distributed in the hope that it will be useful, |
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
20 * Lesser General Public License for more details. | 20 * Lesser General Public License for more details. |
21 * | 21 * |
22 * You should have received a copy of the GNU Lesser General Public | 22 * You should have received a copy of the GNU Lesser General Public |
23 * License along with this library; if not, write to the | 23 * License along with this library; if not, write to the |
24 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 24 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
25 * Boston, MA 02111-1307, USA. | 25 * Boston, MA 02111-1307, USA. |
26 */ | 26 */ |
27 | 27 |
28 #ifdef HAVE_CONFIG_H | 28 #ifdef HAVE_CONFIG_H |
29 #include "config.h" | 29 #include <config.h> |
30 #endif | 30 #endif |
31 | 31 |
32 #include "xdgmimeglob.h" | 32 #include "xdgmimeglob.h" |
33 #include "xdgmimeint.h" | 33 #include "xdgmimeint.h" |
34 #include <stdlib.h> | 34 #include <stdlib.h> |
35 #include <stdio.h> | 35 #include <stdio.h> |
36 #include <assert.h> | 36 #include <assert.h> |
37 #include <string.h> | 37 #include <string.h> |
38 #include <fnmatch.h> | 38 #include <fnmatch.h> |
39 #include <ctype.h> | |
40 | 39 |
41 #ifndef FALSE | 40 #ifndef FALSE |
42 #define FALSE (0) | 41 #define FALSE (0) |
43 #endif | 42 #endif |
44 | 43 |
45 #ifndef TRUE | 44 #ifndef TRUE |
46 #define TRUE (!FALSE) | 45 #define TRUE (!FALSE) |
47 #endif | 46 #endif |
48 | 47 |
49 typedef struct XdgGlobHashNode XdgGlobHashNode; | 48 typedef struct XdgGlobHashNode XdgGlobHashNode; |
50 typedef struct XdgGlobList XdgGlobList; | 49 typedef struct XdgGlobList XdgGlobList; |
51 | 50 |
52 struct XdgGlobHashNode | 51 struct XdgGlobHashNode |
53 { | 52 { |
54 xdg_unichar_t character; | 53 xdg_unichar_t character; |
55 const char *mime_type; | 54 const char *mime_type; |
56 int weight; | 55 int weight; |
| 56 int case_sensitive; |
57 XdgGlobHashNode *next; | 57 XdgGlobHashNode *next; |
58 XdgGlobHashNode *child; | 58 XdgGlobHashNode *child; |
59 }; | 59 }; |
60 struct XdgGlobList | 60 struct XdgGlobList |
61 { | 61 { |
62 const char *data; | 62 const char *data; |
63 const char *mime_type; | 63 const char *mime_type; |
64 int weight; | 64 int weight; |
| 65 int case_sensitive; |
65 XdgGlobList *next; | 66 XdgGlobList *next; |
66 }; | 67 }; |
67 | 68 |
68 struct XdgGlobHash | 69 struct XdgGlobHash |
69 { | 70 { |
70 XdgGlobList *literal_list; | 71 XdgGlobList *literal_list; |
71 XdgGlobHashNode *simple_node; | 72 XdgGlobHashNode *simple_node; |
72 XdgGlobList *full_list; | 73 XdgGlobList *full_list; |
73 }; | 74 }; |
74 | 75 |
(...skipping 29 matching lines...) Expand all Loading... |
104 free (ptr); | 105 free (ptr); |
105 | 106 |
106 ptr = next; | 107 ptr = next; |
107 } | 108 } |
108 } | 109 } |
109 | 110 |
110 static XdgGlobList * | 111 static XdgGlobList * |
111 _xdg_glob_list_append (XdgGlobList *glob_list, | 112 _xdg_glob_list_append (XdgGlobList *glob_list, |
112 void *data, | 113 void *data, |
113 const char *mime_type, | 114 const char *mime_type, |
114 » » int weight) | 115 » » int weight, |
| 116 » » int case_sensitive) |
115 { | 117 { |
116 XdgGlobList *new_element; | 118 XdgGlobList *new_element; |
117 XdgGlobList *tmp_element; | 119 XdgGlobList *tmp_element; |
118 | 120 |
| 121 tmp_element = glob_list; |
| 122 while (tmp_element != NULL) |
| 123 { |
| 124 if (strcmp (tmp_element->data, data) == 0 && |
| 125 strcmp (tmp_element->mime_type, mime_type) == 0) |
| 126 return glob_list; |
| 127 |
| 128 tmp_element = tmp_element->next; |
| 129 } |
| 130 |
119 new_element = _xdg_glob_list_new (); | 131 new_element = _xdg_glob_list_new (); |
120 new_element->data = data; | 132 new_element->data = data; |
121 new_element->mime_type = mime_type; | 133 new_element->mime_type = mime_type; |
122 new_element->weight = weight; | 134 new_element->weight = weight; |
| 135 new_element->case_sensitive = case_sensitive; |
123 if (glob_list == NULL) | 136 if (glob_list == NULL) |
124 return new_element; | 137 return new_element; |
125 | 138 |
126 tmp_element = glob_list; | 139 tmp_element = glob_list; |
127 while (tmp_element->next != NULL) | 140 while (tmp_element->next != NULL) |
128 tmp_element = tmp_element->next; | 141 tmp_element = tmp_element->next; |
129 | 142 |
130 tmp_element->next = new_element; | 143 tmp_element->next = new_element; |
131 | 144 |
132 return glob_list; | 145 return glob_list; |
(...skipping 28 matching lines...) Expand all Loading... |
161 if (glob_hash_node->child) | 174 if (glob_hash_node->child) |
162 _xdg_glob_hash_node_dump (glob_hash_node->child, depth + 1); | 175 _xdg_glob_hash_node_dump (glob_hash_node->child, depth + 1); |
163 if (glob_hash_node->next) | 176 if (glob_hash_node->next) |
164 _xdg_glob_hash_node_dump (glob_hash_node->next, depth); | 177 _xdg_glob_hash_node_dump (glob_hash_node->next, depth); |
165 } | 178 } |
166 | 179 |
167 static XdgGlobHashNode * | 180 static XdgGlobHashNode * |
168 _xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node, | 181 _xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node, |
169 xdg_unichar_t *text, | 182 xdg_unichar_t *text, |
170 const char *mime_type, | 183 const char *mime_type, |
171 » » » int weight) | 184 » » » int weight, |
| 185 » » » int case_sensitive) |
172 { | 186 { |
173 XdgGlobHashNode *node; | 187 XdgGlobHashNode *node; |
174 xdg_unichar_t character; | 188 xdg_unichar_t character; |
175 | 189 |
176 character = text[0]; | 190 character = text[0]; |
177 | 191 |
178 if ((glob_hash_node == NULL) || | 192 if ((glob_hash_node == NULL) || |
179 (character < glob_hash_node->character)) | 193 (character < glob_hash_node->character)) |
180 { | 194 { |
181 node = _xdg_glob_hash_node_new (); | 195 node = _xdg_glob_hash_node_new (); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 node->next = prev_node->next; | 239 node->next = prev_node->next; |
226 prev_node->next = node; | 240 prev_node->next = node; |
227 } | 241 } |
228 } | 242 } |
229 | 243 |
230 text++; | 244 text++; |
231 if (*text == 0) | 245 if (*text == 0) |
232 { | 246 { |
233 if (node->mime_type) | 247 if (node->mime_type) |
234 { | 248 { |
235 » if (strcmp (node->mime_type, mime_type)) | 249 » if (strcmp (node->mime_type, mime_type) != 0) |
236 { | 250 { |
237 XdgGlobHashNode *child; | 251 XdgGlobHashNode *child; |
238 int found_node = FALSE; | 252 int found_node = FALSE; |
239 » | 253 |
240 child = node->child; | 254 child = node->child; |
241 while (child && child->character == 0) | 255 while (child && child->character == 0) |
242 { | 256 { |
243 if (strcmp (child->mime_type, mime_type) == 0) | 257 if (strcmp (child->mime_type, mime_type) == 0) |
244 { | 258 { |
245 found_node = TRUE; | 259 found_node = TRUE; |
246 break; | 260 break; |
247 } | 261 } |
248 child = child->next; | 262 child = child->next; |
249 } | 263 } |
250 | 264 |
251 if (!found_node) | 265 if (!found_node) |
252 { | 266 { |
253 child = _xdg_glob_hash_node_new (); | 267 child = _xdg_glob_hash_node_new (); |
254 child->character = 0; | 268 child->character = 0; |
255 child->mime_type = strdup (mime_type); | 269 child->mime_type = strdup (mime_type); |
256 child->weight = weight; | 270 child->weight = weight; |
| 271 child->case_sensitive = case_sensitive; |
257 child->child = NULL; | 272 child->child = NULL; |
258 child->next = node->child; | 273 child->next = node->child; |
259 node->child = child; | 274 node->child = child; |
260 } | 275 } |
261 } | 276 } |
262 } | 277 } |
263 else | 278 else |
264 { | 279 { |
265 node->mime_type = strdup (mime_type); | 280 node->mime_type = strdup (mime_type); |
266 node->weight = weight; | 281 node->weight = weight; |
| 282 node->case_sensitive = case_sensitive; |
267 } | 283 } |
268 } | 284 } |
269 else | 285 else |
270 { | 286 { |
271 node->child = _xdg_glob_hash_insert_ucs4 (node->child, text, mime_type, we
ight); | 287 node->child = _xdg_glob_hash_insert_ucs4 (node->child, text, mime_type, we
ight, case_sensitive); |
272 } | 288 } |
273 return glob_hash_node; | 289 return glob_hash_node; |
274 } | 290 } |
275 | 291 |
276 /* glob must be valid UTF-8 */ | 292 /* glob must be valid UTF-8 */ |
277 static XdgGlobHashNode * | 293 static XdgGlobHashNode * |
278 _xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node, | 294 _xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node, |
279 const char *text, | 295 const char *text, |
280 const char *mime_type, | 296 const char *mime_type, |
281 » » » int weight) | 297 » » » int weight, |
| 298 » » » int case_sensitive) |
282 { | 299 { |
283 XdgGlobHashNode *node; | 300 XdgGlobHashNode *node; |
284 xdg_unichar_t *unitext; | 301 xdg_unichar_t *unitext; |
285 int len; | 302 int len; |
286 | 303 |
287 unitext = _xdg_convert_to_ucs4 (text, &len); | 304 unitext = _xdg_convert_to_ucs4 (text, &len); |
288 _xdg_reverse_ucs4 (unitext, len); | 305 _xdg_reverse_ucs4 (unitext, len); |
289 node = _xdg_glob_hash_insert_ucs4 (glob_hash_node, unitext, mime_type, weight)
; | 306 node = _xdg_glob_hash_insert_ucs4 (glob_hash_node, unitext, mime_type, weight,
case_sensitive); |
290 free (unitext); | 307 free (unitext); |
291 return node; | 308 return node; |
292 } | 309 } |
293 | 310 |
294 typedef struct { | 311 typedef struct { |
295 const char *mime; | 312 const char *mime; |
296 int weight; | 313 int weight; |
297 } MimeWeight; | 314 } MimeWeight; |
298 | 315 |
299 static int | 316 static int |
300 _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node, | 317 _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node, |
301 const char *file_name, | 318 const char *file_name, |
302 int len, | 319 int len, |
303 » » » » int ignore_case, | 320 » » » » int case_sensitive_check, |
304 MimeWeight mime_types[], | 321 MimeWeight mime_types[], |
305 int n_mime_types) | 322 int n_mime_types) |
306 { | 323 { |
307 int n; | 324 int n; |
308 XdgGlobHashNode *node; | 325 XdgGlobHashNode *node; |
309 xdg_unichar_t character; | 326 xdg_unichar_t character; |
310 | 327 |
311 if (glob_hash_node == NULL) | 328 if (glob_hash_node == NULL) |
312 return 0; | 329 return 0; |
313 | 330 |
314 character = file_name[len - 1]; | 331 character = file_name[len - 1]; |
315 if (ignore_case) | |
316 character = tolower(character); | |
317 | 332 |
318 for (node = glob_hash_node; node && character >= node->character; node = node-
>next) | 333 for (node = glob_hash_node; node && character >= node->character; node = node-
>next) |
319 { | 334 { |
320 if (character == node->character) | 335 if (character == node->character) |
321 { | 336 { |
322 len--; | 337 len--; |
323 n = 0; | 338 n = 0; |
324 if (len > 0) | 339 if (len > 0) |
325 { | 340 { |
326 n = _xdg_glob_hash_node_lookup_file_name (node->child, | 341 n = _xdg_glob_hash_node_lookup_file_name (node->child, |
327 file_name, | 342 file_name, |
328 len, | 343 len, |
329 » » » » » » » ignore_case, | 344 » » » » » » » case_sensitive_check, |
330 mime_types, | 345 mime_types, |
331 n_mime_types); | 346 n_mime_types); |
332 } | 347 } |
333 if (n == 0) | 348 if (n == 0) |
334 { | 349 { |
335 if (node->mime_type) | 350 if (node->mime_type && |
| 351 » » (case_sensitive_check || |
| 352 » » !node->case_sensitive)) |
336 { | 353 { |
337 mime_types[n].mime = node->mime_type; | 354 mime_types[n].mime = node->mime_type; |
338 mime_types[n].weight = node->weight; | 355 mime_types[n].weight = node->weight; |
339 n++; | 356 n++; |
340 } | 357 } |
341 node = node->child; | 358 node = node->child; |
342 while (n < n_mime_types && node && node->character == 0) | 359 while (n < n_mime_types && node && node->character == 0) |
343 { | 360 { |
344 if (node->mime_type) | 361 if (node->mime_type && |
| 362 » » (case_sensitive_check || |
| 363 » » !node->case_sensitive)) |
345 { | 364 { |
346 mime_types[n].mime = node->mime_type; | 365 mime_types[n].mime = node->mime_type; |
347 mime_types[n].weight = node->weight; | 366 mime_types[n].weight = node->weight; |
348 n++; | 367 n++; |
349 } | 368 } |
350 node = node->next; | 369 node = node->next; |
351 } | 370 } |
352 } | 371 } |
353 return n; | 372 return n; |
354 } | 373 } |
355 } | 374 } |
356 | 375 |
357 return 0; | 376 return 0; |
358 } | 377 } |
359 | 378 |
360 static int compare_mime_weight (const void *a, const void *b) | 379 static int compare_mime_weight (const void *a, const void *b) |
361 { | 380 { |
362 const MimeWeight *aa = (const MimeWeight *)a; | 381 const MimeWeight *aa = (const MimeWeight *)a; |
363 const MimeWeight *bb = (const MimeWeight *)b; | 382 const MimeWeight *bb = (const MimeWeight *)b; |
364 | 383 |
365 return aa->weight - bb->weight; | 384 return bb->weight - aa->weight; |
| 385 } |
| 386 |
| 387 #define ISUPPER(c)» » ((c) >= 'A' && (c) <= 'Z') |
| 388 static char * |
| 389 ascii_tolower (const char *str) |
| 390 { |
| 391 char *p, *lower; |
| 392 |
| 393 lower = strdup (str); |
| 394 p = lower; |
| 395 while (*p != 0) |
| 396 { |
| 397 char c = *p; |
| 398 *p++ = ISUPPER (c) ? c - 'A' + 'a' : c; |
| 399 } |
| 400 return lower; |
366 } | 401 } |
367 | 402 |
368 int | 403 int |
369 _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash, | 404 _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash, |
370 const char *file_name, | 405 const char *file_name, |
371 const char *mime_types[], | 406 const char *mime_types[], |
372 int n_mime_types) | 407 int n_mime_types) |
373 { | 408 { |
374 XdgGlobList *list; | 409 XdgGlobList *list; |
375 int i, n; | 410 int i, n; |
376 MimeWeight mimes[10]; | 411 MimeWeight mimes[10]; |
377 int n_mimes = 10; | 412 int n_mimes = 10; |
378 int len; | 413 int len; |
| 414 char *lower_case; |
379 | 415 |
380 /* First, check the literals */ | 416 /* First, check the literals */ |
381 | 417 |
382 assert (file_name != NULL && n_mime_types > 0); | 418 assert (file_name != NULL && n_mime_types > 0); |
383 | 419 |
384 n = 0; | 420 n = 0; |
385 | 421 |
| 422 lower_case = ascii_tolower (file_name); |
| 423 |
386 for (list = glob_hash->literal_list; list; list = list->next) | 424 for (list = glob_hash->literal_list; list; list = list->next) |
387 { | 425 { |
388 if (strcmp ((const char *)list->data, file_name) == 0) | 426 if (strcmp ((const char *)list->data, file_name) == 0) |
389 { | 427 { |
390 mime_types[0] = list->mime_type; | 428 mime_types[0] = list->mime_type; |
| 429 free (lower_case); |
391 return 1; | 430 return 1; |
392 } | 431 } |
393 } | 432 } |
394 | 433 |
| 434 for (list = glob_hash->literal_list; list; list = list->next) |
| 435 { |
| 436 if (!list->case_sensitive && |
| 437 strcmp ((const char *)list->data, lower_case) == 0) |
| 438 { |
| 439 mime_types[0] = list->mime_type; |
| 440 free (lower_case); |
| 441 return 1; |
| 442 } |
| 443 } |
| 444 |
| 445 |
395 len = strlen (file_name); | 446 len = strlen (file_name); |
396 n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, l
en, FALSE, | 447 n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, lower_case,
len, FALSE, |
397 mimes, n_mimes); | 448 mimes, n_mimes); |
398 if (n == 0) | 449 if (n == 0) |
399 n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name,
len, TRUE, | 450 n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name,
len, TRUE, |
400 mimes, n_mimes); | 451 mimes, n_mimes); |
401 | 452 |
402 if (n == 0) | 453 if (n == 0) |
403 { | 454 { |
404 for (list = glob_hash->full_list; list && n < n_mime_types; list = list->n
ext) | 455 for (list = glob_hash->full_list; list && n < n_mime_types; list = list->n
ext) |
405 { | 456 { |
406 if (fnmatch ((const char *)list->data, file_name, 0) == 0) | 457 if (fnmatch ((const char *)list->data, file_name, 0) == 0) |
407 { | 458 { |
408 mimes[n].mime = list->mime_type; | 459 mimes[n].mime = list->mime_type; |
409 mimes[n].weight = list->weight; | 460 mimes[n].weight = list->weight; |
410 n++; | 461 n++; |
411 } | 462 } |
412 } | 463 } |
413 } | 464 } |
| 465 free (lower_case); |
414 | 466 |
415 qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight); | 467 qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight); |
416 | 468 |
417 if (n_mime_types < n) | 469 if (n_mime_types < n) |
418 n = n_mime_types; | 470 n = n_mime_types; |
419 | 471 |
420 for (i = 0; i < n; i++) | 472 for (i = 0; i < n; i++) |
421 mime_types[i] = mimes[i].mime; | 473 mime_types[i] = mimes[i].mime; |
422 | 474 |
423 return n; | 475 return n; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 return XDG_GLOB_SIMPLE; | 538 return XDG_GLOB_SIMPLE; |
487 else | 539 else |
488 return XDG_GLOB_LITERAL; | 540 return XDG_GLOB_LITERAL; |
489 } | 541 } |
490 | 542 |
491 /* glob must be valid UTF-8 */ | 543 /* glob must be valid UTF-8 */ |
492 void | 544 void |
493 _xdg_glob_hash_append_glob (XdgGlobHash *glob_hash, | 545 _xdg_glob_hash_append_glob (XdgGlobHash *glob_hash, |
494 const char *glob, | 546 const char *glob, |
495 const char *mime_type, | 547 const char *mime_type, |
496 » » » int weight) | 548 » » » int weight, |
| 549 » » » int case_sensitive) |
497 { | 550 { |
498 XdgGlobType type; | 551 XdgGlobType type; |
499 | 552 |
500 assert (glob_hash != NULL); | 553 assert (glob_hash != NULL); |
501 assert (glob != NULL); | 554 assert (glob != NULL); |
502 | 555 |
503 type = _xdg_glob_determine_type (glob); | 556 type = _xdg_glob_determine_type (glob); |
504 | 557 |
505 switch (type) | 558 switch (type) |
506 { | 559 { |
507 case XDG_GLOB_LITERAL: | 560 case XDG_GLOB_LITERAL: |
508 glob_hash->literal_list = _xdg_glob_list_append (glob_hash->literal_list,
strdup (glob), strdup (mime_type), weight); | 561 glob_hash->literal_list = _xdg_glob_list_append (glob_hash->literal_list,
strdup (glob), strdup (mime_type), weight, case_sensitive); |
509 break; | 562 break; |
510 case XDG_GLOB_SIMPLE: | 563 case XDG_GLOB_SIMPLE: |
511 glob_hash->simple_node = _xdg_glob_hash_insert_text (glob_hash->simple_nod
e, glob + 1, mime_type, weight); | 564 glob_hash->simple_node = _xdg_glob_hash_insert_text (glob_hash->simple_nod
e, glob + 1, mime_type, weight, case_sensitive); |
512 break; | 565 break; |
513 case XDG_GLOB_FULL: | 566 case XDG_GLOB_FULL: |
514 glob_hash->full_list = _xdg_glob_list_append (glob_hash->full_list, strdup
(glob), strdup (mime_type), weight); | 567 glob_hash->full_list = _xdg_glob_list_append (glob_hash->full_list, strdup
(glob), strdup (mime_type), weight, case_sensitive); |
515 break; | 568 break; |
516 } | 569 } |
517 } | 570 } |
518 | 571 |
519 void | 572 void |
520 _xdg_glob_hash_dump (XdgGlobHash *glob_hash) | 573 _xdg_glob_hash_dump (XdgGlobHash *glob_hash) |
521 { | 574 { |
522 XdgGlobList *list; | 575 XdgGlobList *list; |
523 printf ("LITERAL STRINGS\n"); | 576 printf ("LITERAL STRINGS\n"); |
524 if (!glob_hash || glob_hash->literal_list == NULL) | 577 if (!glob_hash || glob_hash->literal_list == NULL) |
(...skipping 23 matching lines...) Expand all Loading... |
548 else | 601 else |
549 { | 602 { |
550 for (list = glob_hash->full_list; list; list = list->next) | 603 for (list = glob_hash->full_list; list; list = list->next) |
551 printf (" %s - %s %d\n", (char *)list->data, list->mime_type, list->w
eight); | 604 printf (" %s - %s %d\n", (char *)list->data, list->mime_type, list->w
eight); |
552 } | 605 } |
553 } | 606 } |
554 | 607 |
555 | 608 |
556 void | 609 void |
557 _xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash, | 610 _xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash, |
558 » » » const char *file_name) | 611 » » » const char *file_name, |
| 612 » » » int version_two) |
559 { | 613 { |
560 FILE *glob_file; | 614 FILE *glob_file; |
561 char line[255]; | 615 char line[255]; |
| 616 char *p; |
562 | 617 |
563 glob_file = fopen (file_name, "r"); | 618 glob_file = fopen (file_name, "r"); |
564 | 619 |
565 if (glob_file == NULL) | 620 if (glob_file == NULL) |
566 return; | 621 return; |
567 | 622 |
568 /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. | 623 /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. |
569 * Blah */ | 624 * Blah */ |
570 while (fgets (line, 255, glob_file) != NULL) | 625 while (fgets (line, 255, glob_file) != NULL) |
571 { | 626 { |
572 char *colon, *colon2; | 627 char *colon; |
573 char *mimetype, *glob; | 628 char *mimetype, *glob, *end; |
574 int weight; | 629 int weight; |
| 630 int case_sensitive; |
575 | 631 |
576 if (line[0] == '#') | 632 if (line[0] == '#' || line[0] == 0) |
577 continue; | 633 continue; |
578 | 634 |
579 colon = strchr (line, ':'); | 635 end = line + strlen(line) - 1; |
| 636 if (*end == '\n') |
| 637 » *end = 0; |
| 638 |
| 639 p = line; |
| 640 if (version_two) |
| 641 » { |
| 642 » colon = strchr (p, ':'); |
| 643 » if (colon == NULL) |
| 644 » continue; |
| 645 » *colon = 0; |
| 646 weight = atoi (p); |
| 647 » p = colon + 1; |
| 648 » } |
| 649 else |
| 650 » weight = 50; |
| 651 |
| 652 colon = strchr (p, ':'); |
580 if (colon == NULL) | 653 if (colon == NULL) |
581 continue; | 654 continue; |
582 *(colon++) = '\0'; | 655 *colon = 0; |
583 colon[strlen (colon) -1] = '\0'; | 656 |
584 colon2 = strchr (colon, ':'); | 657 mimetype = p; |
585 if (colon2) | 658 p = colon + 1; |
586 { | 659 glob = p; |
587 *(colon2++) = '\000'; | 660 case_sensitive = FALSE; |
588 weight = atoi (line); | 661 |
589 mimetype = colon; | 662 colon = strchr (p, ':'); |
590 glob = colon2; | 663 if (version_two && colon != NULL) |
591 } | 664 » { |
592 else | 665 » char *flag; |
593 { | 666 |
594 weight = 50; | 667 » /* We got flags */ |
595 mimetype = line; | 668 » *colon = 0; |
596 glob = colon; | 669 » p = colon + 1; |
597 } | 670 |
598 _xdg_glob_hash_append_glob (glob_hash, glob, mimetype, weight); | 671 » /* Flags end at next colon */ |
| 672 » colon = strchr (p, ':'); |
| 673 » if (colon != NULL) |
| 674 » *colon = 0; |
| 675 |
| 676 » flag = strstr (p, "cs"); |
| 677 » if (flag != NULL && |
| 678 » /* Start or after comma */ |
| 679 » (flag == p || |
| 680 » flag[-1] == ',') && |
| 681 » /* ends with comma or end of string */ |
| 682 » (flag[2] == 0 || |
| 683 » flag[2] == ',')) |
| 684 » case_sensitive = TRUE; |
| 685 » } |
| 686 |
| 687 _xdg_glob_hash_append_glob (glob_hash, glob, mimetype, weight, case_sensit
ive); |
599 } | 688 } |
600 | 689 |
601 fclose (glob_file); | 690 fclose (glob_file); |
602 } | 691 } |
OLD | NEW |