Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/lib/xdgmimeglob.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xdgmimeglob.c')
-rw-r--r--lib/xdgmimeglob.c547
1 files changed, 0 insertions, 547 deletions
diff --git a/lib/xdgmimeglob.c b/lib/xdgmimeglob.c
deleted file mode 100644
index 95d9587..0000000
--- a/lib/xdgmimeglob.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu" -*- */
-/* xdgmimeglob.c: Private file. Datastructure for storing the globs.
- *
- * More info can be found at http://www.freedesktop.org/standards/
- *
- * Copyright (C) 2003 Red Hat, Inc.
- * Copyright (C) 2003 Jonathan Blandford <jrb@alum.mit.edu>
- *
- * Licensed under the Academic Free License version 2.0
- * Or under the following terms:
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "xdgmimeglob.h"
-#include "xdgmimeint.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-#include <fnmatch.h>
-
-#ifndef FALSE
-#define FALSE (0)
-#endif
-
-#ifndef TRUE
-#define TRUE (!FALSE)
-#endif
-
-typedef struct XdgGlobHashNode XdgGlobHashNode;
-typedef struct XdgGlobList XdgGlobList;
-
-struct XdgGlobHashNode
-{
- xdg_unichar_t character;
- const char *mime_type;
- XdgGlobHashNode *next;
- XdgGlobHashNode *child;
-};
-struct XdgGlobList
-{
- const char *data;
- const char *mime_type;
- XdgGlobList *next;
-};
-
-struct XdgGlobHash
-{
- XdgGlobList *literal_list;
- XdgGlobHashNode *simple_node;
- XdgGlobList *full_list;
-};
-
-
-/* XdgGlobList
- */
-static XdgGlobList *
-_xdg_glob_list_new (void)
-{
- XdgGlobList *new_element;
-
- new_element = calloc (1, sizeof (XdgGlobList));
-
- return new_element;
-}
-
-/* Frees glob_list and all of it's children */
-static void
-_xdg_glob_list_free (XdgGlobList *glob_list)
-{
- XdgGlobList *ptr, *next;
-
- ptr = glob_list;
-
- while (ptr != NULL)
- {
- next = ptr->next;
-
- if (ptr->data)
- free ((void *) ptr->data);
- if (ptr->mime_type)
- free ((void *) ptr->mime_type);
- free (ptr);
-
- ptr = next;
- }
-}
-
-static XdgGlobList *
-_xdg_glob_list_append (XdgGlobList *glob_list,
- void *data,
- const char *mime_type)
-{
- XdgGlobList *new_element;
- XdgGlobList *tmp_element;
-
- new_element = _xdg_glob_list_new ();
- new_element->data = data;
- new_element->mime_type = mime_type;
- if (glob_list == NULL)
- return new_element;
-
- tmp_element = glob_list;
- while (tmp_element->next != NULL)
- tmp_element = tmp_element->next;
-
- tmp_element->next = new_element;
-
- return glob_list;
-}
-
-#if 0
-static XdgGlobList *
-_xdg_glob_list_prepend (XdgGlobList *glob_list,
- void *data,
- const char *mime_type)
-{
- XdgGlobList *new_element;
-
- new_element = _xdg_glob_list_new ();
- new_element->data = data;
- new_element->next = glob_list;
- new_element->mime_type = mime_type;
-
- return new_element;
-}
-#endif
-
-/* XdgGlobHashNode
- */
-
-static XdgGlobHashNode *
-_xdg_glob_hash_node_new (void)
-{
- XdgGlobHashNode *glob_hash_node;
-
- glob_hash_node = calloc (1, sizeof (XdgGlobHashNode));
-
- return glob_hash_node;
-}
-
-static void
-_xdg_glob_hash_node_dump (XdgGlobHashNode *glob_hash_node,
- int depth)
-{
- int i;
- for (i = 0; i < depth; i++)
- printf (" ");
-
- printf ("%c", (char)glob_hash_node->character);
- if (glob_hash_node->mime_type)
- printf (" - %s\n", glob_hash_node->mime_type);
- else
- printf ("\n");
- if (glob_hash_node->child)
- _xdg_glob_hash_node_dump (glob_hash_node->child, depth + 1);
- if (glob_hash_node->next)
- _xdg_glob_hash_node_dump (glob_hash_node->next, depth);
-}
-
-static XdgGlobHashNode *
-_xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
- const char *text,
- const char *mime_type)
-{
- XdgGlobHashNode *node;
- xdg_unichar_t character;
-
- character = _xdg_utf8_to_ucs4 (text);
-
- if ((glob_hash_node == NULL) ||
- (character < glob_hash_node->character))
- {
- node = _xdg_glob_hash_node_new ();
- node->character = character;
- node->next = glob_hash_node;
- glob_hash_node = node;
- }
- else if (character == glob_hash_node->character)
- {
- node = glob_hash_node;
- }
- else
- {
- XdgGlobHashNode *prev_node;
- int found_node = FALSE;
-
- /* Look for the first character of text in glob_hash_node, and insert it if we
- * have to.*/
- prev_node = glob_hash_node;
- node = prev_node->next;
-
- while (node != NULL)
- {
- if (character < node->character)
- {
- node = _xdg_glob_hash_node_new ();
- node->character = character;
- node->next = prev_node->next;
- prev_node->next = node;
-
- found_node = TRUE;
- break;
- }
- else if (character == node->character)
- {
- found_node = TRUE;
- break;
- }
- prev_node = node;
- node = node->next;
- }
-
- if (! found_node)
- {
- node = _xdg_glob_hash_node_new ();
- node->character = character;
- node->next = prev_node->next;
- prev_node->next = node;
- }
- }
-
- text = _xdg_utf8_next_char (text);
- if (*text == '\000')
- {
- if (node->mime_type)
- {
- if (strcmp (node->mime_type, mime_type))
- {
- XdgGlobHashNode *child;
- int found_node = FALSE;
-
- child = node->child;
- while (child && child->character == '\0')
- {
- if (strcmp (child->mime_type, mime_type) == 0)
- {
- found_node = TRUE;
- break;
- }
- child = child->next;
- }
-
- if (!found_node)
- {
- child = _xdg_glob_hash_node_new ();
- child->character = '\000';
- child->mime_type = mime_type;
- child->child = NULL;
- child->next = node->child;
- node->child = child;
- }
- }
- }
- else
- {
- node->mime_type = mime_type;
- }
- }
- else
- {
- node->child = _xdg_glob_hash_insert_text (node->child, text, mime_type);
- }
- return glob_hash_node;
-}
-
-static int
-_xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
- const char *file_name,
- int ignore_case,
- const char *mime_types[],
- int n_mime_types)
-{
- int n;
- XdgGlobHashNode *node;
- xdg_unichar_t character;
-
- if (glob_hash_node == NULL)
- return 0;
-
- character = _xdg_utf8_to_ucs4 (file_name);
- if (ignore_case)
- character = _xdg_ucs4_to_lower(character);
-
- for (node = glob_hash_node; node && character >= node->character; node = node->next)
- {
- if (character == node->character)
- {
- file_name = _xdg_utf8_next_char (file_name);
- if (*file_name == '\000')
- {
- n = 0;
- if (node->mime_type)
- mime_types[n++] = node->mime_type;
- node = node->child;
- while (n < n_mime_types && node && node->character == 0)
- {
- if (node->mime_type)
- mime_types[n++] = node->mime_type;
- node = node->next;
- }
- }
- else
- {
- n = _xdg_glob_hash_node_lookup_file_name (node->child,
- file_name,
- ignore_case,
- mime_types,
- n_mime_types);
- }
- return n;
- }
- }
-
- return 0;
-}
-
-int
-_xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
- const char *file_name,
- const char *mime_types[],
- int n_mime_types)
-{
- XdgGlobList *list;
- const char *ptr;
- char stopchars[128];
- int i, n;
- XdgGlobHashNode *node;
-
- /* First, check the literals */
-
- assert (file_name != NULL && n_mime_types > 0);
-
- 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;
- return 1;
- }
- }
-
- i = 0;
- for (node = glob_hash->simple_node; node; node = node->next)
- {
- if (node->character < 128)
- stopchars[i++] = (char)node->character;
- }
- stopchars[i] = '\0';
-
- ptr = strpbrk (file_name, stopchars);
- while (ptr)
- {
- n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, ptr, FALSE,
- mime_types, n_mime_types);
- if (n > 0)
- return n;
-
- n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, ptr, TRUE,
- mime_types, n_mime_types);
- if (n > 0)
- return n;
-
- ptr = strpbrk (ptr + 1, stopchars);
- }
-
- /* FIXME: Not UTF-8 safe */
- n = 0;
- for (list = glob_hash->full_list; list && n < n_mime_types; list = list->next)
- {
- if (fnmatch ((const char *)list->data, file_name, 0) == 0)
- mime_types[n++] = list->mime_type;
- }
-
- return n;
-}
-
-
-
-/* XdgGlobHash
- */
-
-XdgGlobHash *
-_xdg_glob_hash_new (void)
-{
- XdgGlobHash *glob_hash;
-
- glob_hash = calloc (1, sizeof (XdgGlobHash));
-
- return glob_hash;
-}
-
-
-static void
-_xdg_glob_hash_free_nodes (XdgGlobHashNode *node)
-{
- if (node)
- {
- if (node->child)
- _xdg_glob_hash_free_nodes (node->child);
- if (node->next)
- _xdg_glob_hash_free_nodes (node->next);
- if (node->mime_type)
- free ((void *) node->mime_type);
- free (node);
- }
-}
-
-void
-_xdg_glob_hash_free (XdgGlobHash *glob_hash)
-{
- _xdg_glob_list_free (glob_hash->literal_list);
- _xdg_glob_list_free (glob_hash->full_list);
- _xdg_glob_hash_free_nodes (glob_hash->simple_node);
- free (glob_hash);
-}
-
-XdgGlobType
-_xdg_glob_determine_type (const char *glob)
-{
- const char *ptr;
- int maybe_in_simple_glob = FALSE;
- int first_char = TRUE;
-
- ptr = glob;
-
- while (*ptr != '\000')
- {
- if (*ptr == '*' && first_char)
- maybe_in_simple_glob = TRUE;
- else if (*ptr == '\\' || *ptr == '[' || *ptr == '?' || *ptr == '*')
- return XDG_GLOB_FULL;
-
- first_char = FALSE;
- ptr = _xdg_utf8_next_char (ptr);
- }
- if (maybe_in_simple_glob)
- return XDG_GLOB_SIMPLE;
- else
- return XDG_GLOB_LITERAL;
-}
-
-/* glob must be valid UTF-8 */
-void
-_xdg_glob_hash_append_glob (XdgGlobHash *glob_hash,
- const char *glob,
- const char *mime_type)
-{
- XdgGlobType type;
-
- assert (glob_hash != NULL);
- assert (glob != NULL);
-
- type = _xdg_glob_determine_type (glob);
-
- switch (type)
- {
- case XDG_GLOB_LITERAL:
- glob_hash->literal_list = _xdg_glob_list_append (glob_hash->literal_list, strdup (glob), strdup (mime_type));
- break;
- case XDG_GLOB_SIMPLE:
- glob_hash->simple_node = _xdg_glob_hash_insert_text (glob_hash->simple_node, glob + 1, strdup (mime_type));
- break;
- case XDG_GLOB_FULL:
- glob_hash->full_list = _xdg_glob_list_append (glob_hash->full_list, strdup (glob), strdup (mime_type));
- break;
- }
-}
-
-void
-_xdg_glob_hash_dump (XdgGlobHash *glob_hash)
-{
- XdgGlobList *list;
- printf ("LITERAL STRINGS\n");
- if (glob_hash->literal_list == NULL)
- {
- printf (" None\n");
- }
- else
- {
- for (list = glob_hash->literal_list; list; list = list->next)
- printf (" %s - %s\n", (char *)list->data, list->mime_type);
- }
- printf ("\nSIMPLE GLOBS\n");
- _xdg_glob_hash_node_dump (glob_hash->simple_node, 4);
-
- printf ("\nFULL GLOBS\n");
- if (glob_hash->full_list == NULL)
- {
- printf (" None\n");
- }
- else
- {
- for (list = glob_hash->full_list; list; list = list->next)
- printf (" %s - %s\n", (char *)list->data, list->mime_type);
- }
-}
-
-
-void
-_xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash,
- const char *file_name)
-{
- FILE *glob_file;
- char line[255];
-
- glob_file = fopen (file_name, "r");
-
- if (glob_file == NULL)
- return;
-
- /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars.
- * Blah */
- while (fgets (line, 255, glob_file) != NULL)
- {
- char *colon;
- if (line[0] == '#')
- continue;
-
- colon = strchr (line, ':');
- if (colon == NULL)
- continue;
- *(colon++) = '\000';
- colon[strlen (colon) -1] = '\000';
- _xdg_glob_hash_append_glob (glob_hash, colon, line);
- }
-
- fclose (glob_file);
-}