Use the new g_strv_contains
[platform/upstream/glib.git] / gio / xdgmime / xdgmimeparent.c
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 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 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "xdgmimeparent.h"
31 #include "xdgmimeint.h"
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <assert.h>
35 #include <string.h>
36 #include <fnmatch.h>
37
38 #ifndef FALSE
39 #define FALSE   (0)
40 #endif
41
42 #ifndef TRUE
43 #define TRUE    (!FALSE)
44 #endif
45
46 typedef struct XdgMimeParents XdgMimeParents;
47
48 struct XdgMimeParents
49 {
50   char *mime;
51   char **parents;
52   int n_parents;
53 };
54
55 struct XdgParentList
56 {
57   struct XdgMimeParents *parents;
58   int n_mimes;
59 };
60
61 XdgParentList *
62 _xdg_mime_parent_list_new (void)
63 {
64   XdgParentList *list;
65
66   list = malloc (sizeof (XdgParentList));
67
68   list->parents = NULL;
69   list->n_mimes = 0;
70
71   return list;
72 }
73
74 void         
75 _xdg_mime_parent_list_free (XdgParentList *list)
76 {
77   int i;
78   char **p;
79
80   if (list->parents)
81     {
82       for (i = 0; i < list->n_mimes; i++)
83         {
84           for (p = list->parents[i].parents; *p; p++)
85             free (*p);
86
87           free (list->parents[i].parents);
88           free (list->parents[i].mime);
89         }
90       free (list->parents);
91     }
92   free (list);
93 }
94
95 static int
96 parent_entry_cmp (const void *v1, const void *v2)
97 {
98   return strcmp (((XdgMimeParents *)v1)->mime, ((XdgMimeParents *)v2)->mime);
99 }
100
101 const char **
102 _xdg_mime_parent_list_lookup (XdgParentList *list,
103                               const char    *mime)
104 {
105   XdgMimeParents *entry;
106   XdgMimeParents key;
107
108   if (list->n_mimes > 0)
109     {
110       key.mime = (char *)mime;
111       key.parents = NULL;
112       key.n_parents = 0;
113
114       entry = bsearch (&key, list->parents, list->n_mimes,
115                        sizeof (XdgMimeParents), &parent_entry_cmp);
116       if (entry)
117         return (const char **)entry->parents;
118     }
119
120   return NULL;
121 }
122
123 void
124 _xdg_mime_parent_read_from_file (XdgParentList *list,
125                                  const char    *file_name)
126 {
127   FILE *file;
128   char line[255];
129   int i, alloc;
130   XdgMimeParents *entry;
131
132   file = fopen (file_name, "r");
133
134   if (file == NULL)
135     return;
136
137   /* FIXME: Not UTF-8 safe.  Doesn't work if lines are greater than 255 chars.
138    * Blah */
139   alloc = list->n_mimes + 16;
140   list->parents = realloc (list->parents, alloc * sizeof (XdgMimeParents));
141   while (fgets (line, 255, file) != NULL)
142     {
143       char *sep;
144       if (line[0] == '#')
145         continue;
146
147       sep = strchr (line, ' ');
148       if (sep == NULL)
149         continue;
150       *(sep++) = '\000';
151       sep[strlen (sep) -1] = '\000';
152       entry = NULL;
153       for (i = 0; i < list->n_mimes; i++)
154         {
155           if (strcmp (list->parents[i].mime, line) == 0)
156             {
157               entry = &(list->parents[i]);
158               break;
159             }
160         }
161       
162       if (!entry)
163         {
164           if (list->n_mimes == alloc)
165             {
166               alloc <<= 1;
167               list->parents = realloc (list->parents, 
168                                        alloc * sizeof (XdgMimeParents));
169             }
170           list->parents[list->n_mimes].mime = strdup (line);
171           list->parents[list->n_mimes].parents = NULL;
172           entry = &(list->parents[list->n_mimes]);
173           list->n_mimes++;
174         }
175
176       if (!entry->parents)
177         {
178           entry->n_parents = 1;
179           entry->parents = malloc ((entry->n_parents + 1) * sizeof (char *));
180         }
181       else
182         {
183           entry->n_parents += 1;
184           entry->parents = realloc (entry->parents, 
185                                     (entry->n_parents + 2) * sizeof (char *));
186         }
187       entry->parents[entry->n_parents - 1] = strdup (sep);
188       entry->parents[entry->n_parents] = NULL;
189     }
190
191   list->parents = realloc (list->parents, 
192                            list->n_mimes * sizeof (XdgMimeParents));
193
194   fclose (file);  
195   
196   if (list->n_mimes > 1)
197     qsort (list->parents, list->n_mimes, 
198            sizeof (XdgMimeParents), &parent_entry_cmp);
199 }
200
201 #ifdef NOT_USED_IN_GIO
202
203 void         
204 _xdg_mime_parent_list_dump (XdgParentList *list)
205 {
206   int i;
207   char **p;
208
209   if (list->parents)
210     {
211       for (i = 0; i < list->n_mimes; i++)
212         {
213           for (p = list->parents[i].parents; *p; p++)
214             printf ("%s %s\n", list->parents[i].mime, *p);
215         }
216     }
217 }
218
219 #endif
220