From 68ff71a0cbf9c11a9be8878146bf485be9bd8f87 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 15 Oct 2007 13:39:07 +0000 Subject: Split part of the sugar library to sugar-base --- (limited to 'lib/xdgmimeglob.c') 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 - * - * 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 -#endif - -#include "xdgmimeglob.h" -#include "xdgmimeint.h" -#include -#include -#include -#include -#include - -#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); -} -- cgit v0.9.1