• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* xdgmimealias.c: Private file.  Datastructure for storing the hierarchy.
3  *
4  * More info can be found at http://www.freedesktop.org/standards/
5  *
6  * Copyright (C) 2004  Red Hat, Inc.
7  * Copyright (C) 2004  Matthias Clasen <mclasen@redhat.com>
8  *
9  * Licensed under the Academic Free License version 2.0
10  * Or under the following terms:
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 #include "config.h"
27 
28 #include "xdgmimeparent.h"
29 #include "xdgmimeint.h"
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <assert.h>
33 #include <string.h>
34 #include <fnmatch.h>
35 
36 #ifndef	FALSE
37 #define	FALSE	(0)
38 #endif
39 
40 #ifndef	TRUE
41 #define	TRUE	(!FALSE)
42 #endif
43 
44 typedef struct XdgMimeParents XdgMimeParents;
45 
46 struct XdgMimeParents
47 {
48   char *mime;
49   char **parents;
50   int n_parents;
51 };
52 
53 struct XdgParentList
54 {
55   struct XdgMimeParents *parents;
56   int n_mimes;
57 };
58 
59 XdgParentList *
_xdg_mime_parent_list_new(void)60 _xdg_mime_parent_list_new (void)
61 {
62   XdgParentList *list;
63 
64   list = malloc (sizeof (XdgParentList));
65 
66   list->parents = NULL;
67   list->n_mimes = 0;
68 
69   return list;
70 }
71 
72 void
_xdg_mime_parent_list_free(XdgParentList * list)73 _xdg_mime_parent_list_free (XdgParentList *list)
74 {
75   int i;
76   char **p;
77 
78   if (list->parents)
79     {
80       for (i = 0; i < list->n_mimes; i++)
81 	{
82 	  for (p = list->parents[i].parents; *p; p++)
83 	    free (*p);
84 
85 	  free (list->parents[i].parents);
86 	  free (list->parents[i].mime);
87 	}
88       free (list->parents);
89     }
90   free (list);
91 }
92 
93 static int
parent_entry_cmp(const void * v1,const void * v2)94 parent_entry_cmp (const void *v1, const void *v2)
95 {
96   return strcmp (((XdgMimeParents *)v1)->mime, ((XdgMimeParents *)v2)->mime);
97 }
98 
99 const char **
_xdg_mime_parent_list_lookup(XdgParentList * list,const char * mime)100 _xdg_mime_parent_list_lookup (XdgParentList *list,
101 			      const char    *mime)
102 {
103   XdgMimeParents *entry;
104   XdgMimeParents key;
105 
106   if (list->n_mimes > 0)
107     {
108       key.mime = (char *)mime;
109       key.parents = NULL;
110       key.n_parents = 0;
111 
112       entry = bsearch (&key, list->parents, list->n_mimes,
113 		       sizeof (XdgMimeParents), &parent_entry_cmp);
114       if (entry)
115         return (const char **)entry->parents;
116     }
117 
118   return NULL;
119 }
120 
121 void
_xdg_mime_parent_read_from_file(XdgParentList * list,const char * file_name)122 _xdg_mime_parent_read_from_file (XdgParentList *list,
123 				 const char    *file_name)
124 {
125   FILE *file;
126   char line[255];
127   int i, alloc;
128   XdgMimeParents *entry;
129 
130   file = fopen (file_name, "r");
131 
132   if (file == NULL)
133     return;
134 
135   /* FIXME: Not UTF-8 safe.  Doesn't work if lines are greater than 255 chars.
136    * Blah */
137   alloc = list->n_mimes + 16;
138   list->parents = realloc (list->parents, alloc * sizeof (XdgMimeParents));
139   while (fgets (line, 255, file) != NULL)
140     {
141       char *sep;
142       if (line[0] == '#')
143 	continue;
144 
145       sep = strchr (line, ' ');
146       if (sep == NULL)
147 	continue;
148       *(sep++) = '\000';
149       sep[strlen (sep) -1] = '\000';
150       entry = NULL;
151       for (i = 0; i < list->n_mimes; i++)
152 	{
153 	  if (strcmp (list->parents[i].mime, line) == 0)
154 	    {
155 	      entry = &(list->parents[i]);
156 	      break;
157 	    }
158 	}
159 
160       if (!entry)
161 	{
162 	  if (list->n_mimes == alloc)
163 	    {
164 	      alloc <<= 1;
165 	      list->parents = realloc (list->parents,
166 				       alloc * sizeof (XdgMimeParents));
167 	    }
168 	  list->parents[list->n_mimes].mime = strdup (line);
169 	  list->parents[list->n_mimes].parents = NULL;
170 	  entry = &(list->parents[list->n_mimes]);
171 	  list->n_mimes++;
172 	}
173 
174       if (!entry->parents)
175 	{
176 	  entry->n_parents = 1;
177 	  entry->parents = malloc ((entry->n_parents + 1) * sizeof (char *));
178 	}
179       else
180 	{
181 	  entry->n_parents += 1;
182 	  entry->parents = realloc (entry->parents,
183 				    (entry->n_parents + 2) * sizeof (char *));
184 	}
185       entry->parents[entry->n_parents - 1] = strdup (sep);
186       entry->parents[entry->n_parents] = NULL;
187     }
188 
189   list->parents = realloc (list->parents,
190 			   list->n_mimes * sizeof (XdgMimeParents));
191 
192   fclose (file);
193 
194   if (list->n_mimes > 1)
195     qsort (list->parents, list->n_mimes,
196            sizeof (XdgMimeParents), &parent_entry_cmp);
197 }
198 
199 #ifdef NOT_USED_IN_GIO
200 
201 void
_xdg_mime_parent_list_dump(XdgParentList * list)202 _xdg_mime_parent_list_dump (XdgParentList *list)
203 {
204   int i;
205   char **p;
206 
207   if (list->parents)
208     {
209       for (i = 0; i < list->n_mimes; i++)
210 	{
211 	  for (p = list->parents[i].parents; *p; p++)
212 	    printf ("%s %s\n", list->parents[i].mime, *p);
213 	}
214     }
215 }
216 
217 #endif
218