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