summaryrefslogtreecommitdiff
path: root/update-mime-database.c
diff options
context:
space:
mode:
authorJonathan Blandford <jrb@redhat.com>2004-11-09 07:04:30 +0000
committerJonathan Blandford <jrb@redhat.com>2004-11-09 07:04:30 +0000
commit94f54528a2326ba623cbc73dfcae63fe7723d9e5 (patch)
tree572d4613c5006d4f5f70889fa1bc0dcfd3ca1e6f /update-mime-database.c
parentf9c74af900469a419cb9c084d64c561d6f55be84 (diff)
downloadshared-mime-info-94f54528a2326ba623cbc73dfcae63fe7723d9e5.tar.gz
Tue Nov 9 01:52:52 2004 Jonathan Blandford <jrb@redhat.com>
* update-mime-database.c: Patch from Matthias Clasen to generate subclass and alias files. * shared-mime-info-spec.xml.in: update the spec to mention the subclasses and aliases files.
Diffstat (limited to 'update-mime-database.c')
-rw-r--r--update-mime-database.c146
1 files changed, 142 insertions, 4 deletions
diff --git a/update-mime-database.c b/update-mime-database.c
index ff87494a..bb1f8021 100644
--- a/update-mime-database.c
+++ b/update-mime-database.c
@@ -94,6 +94,12 @@ static GHashTable *globs_hash = NULL;
/* 'magic' nodes */
static GPtrArray *magic_array = NULL;
+/* Maps MIME type names to superclass names */
+static GHashTable *subclass_hash = NULL;
+
+/* Maps aliases to Types */
+static GHashTable *alias_hash = NULL;
+
/* Static prototypes */
static Magic *magic_new(xmlNode *node, Type *type, GError **error);
@@ -295,12 +301,37 @@ static gboolean process_freedesktop_node(Type *type, xmlNode *field,
{
char *other_type;
gboolean valid;
+ GSList *list, *nlist;
+
other_type = xmlGetNsProp(field, "type", NULL);
valid = other_type && strchr(other_type, '/');
- xmlFree(other_type);
if (valid)
+ {
+ char *typename;
+
+ typename = g_strdup_printf("%s/%s",
+ type->media,
+ type->subtype);
+
+ if (strcmp(field->name, "alias") == 0)
+ g_hash_table_insert(alias_hash,
+ g_strdup(other_type), type);
+
+ else
+ {
+ list = g_hash_table_lookup(subclass_hash, typename);
+ nlist = g_slist_append (list, g_strdup(other_type));
+ if (list == NULL)
+ g_hash_table_insert(subclass_hash,
+ g_strdup(typename), nlist);
+ }
+ g_free(typename);
+ xmlFree(other_type);
+
return FALSE; /* Copy through */
-
+ }
+
+ xmlFree(other_type);
g_set_error(error, MIME_ERROR, 0,
_("Incorrect or missing 'type' attribute "
"in <%s>"), field->name);
@@ -1310,6 +1341,66 @@ static void write_namespaces(FILE *stream)
g_ptr_array_free(lines, TRUE);
}
+static void write_subclass(gpointer key, gpointer value, gpointer data)
+{
+ GSList *list = value;
+ FILE *stream = data;
+ GSList *l;
+ char *line;
+
+ for (l = list; l; l = l->next)
+ {
+ line = g_strconcat (key, " ", l->data, "\n", NULL);
+ fwrite(line, 1, strlen(line), stream);
+ g_free (line);
+ }
+}
+
+/* Write all the collected subclass information to 'subclasses' */
+static void write_subclasses(FILE *stream)
+{
+ g_hash_table_foreach(subclass_hash, write_subclass, stream);
+}
+
+/* Extract one entry from alias_hash and put it in the GPtrArray so
+ * we can sort it.
+ */
+static void add_alias(gpointer key, gpointer value, gpointer data)
+{
+ GPtrArray *lines = (GPtrArray *) data;
+ const guchar *alias = (guchar *) key;
+ Type *type = (Type *) value;
+
+ g_ptr_array_add(lines, g_strconcat(alias, " ", type->media,
+ "/", type->subtype, "\n",
+ NULL));
+}
+
+/* Write all the collected aliases */
+static void write_aliases(FILE *stream)
+{
+ GPtrArray *lines;
+ int i;
+
+ lines = g_ptr_array_new();
+
+ g_hash_table_foreach(alias_hash, add_alias, lines);
+
+ g_ptr_array_sort(lines, strcmp2);
+
+ for (i = 0; i < lines->len; i++)
+ {
+ char *line = (char *) lines->pdata[i];
+
+ fwrite(line, 1, strlen(line), stream);
+
+ g_free(line);
+ }
+
+ g_ptr_array_free(lines, TRUE);
+}
+
+
/* Issue a warning if 'path' won't be found by applications */
static void check_in_path_xdg_data(const char *mime_path)
{
@@ -1371,6 +1462,14 @@ out:
g_free(path);
}
+static void free_string_list(gpointer data)
+{
+ GSList *list = data;
+
+ g_slist_foreach(list, (GFunc)g_free, NULL);
+ g_slist_free(list);
+}
+
int main(int argc, char **argv)
{
char *mime_dir = NULL;
@@ -1442,7 +1541,11 @@ int main(int argc, char **argv)
namespace_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, NULL);
magic_array = g_ptr_array_new();
-
+ subclass_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, free_string_list);
+ alias_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+
scan_source_dir(package_dir);
g_free(package_dir);
@@ -1494,7 +1597,7 @@ int main(int argc, char **argv)
atomic_update(magic_path);
g_free(magic_path);
}
-
+
{
FILE *stream;
char *ns_path;
@@ -1510,12 +1613,47 @@ int main(int argc, char **argv)
atomic_update(ns_path);
g_free(ns_path);
}
+
+ {
+ FILE *stream;
+ char *path;
+
+ path = g_strconcat(mime_dir, "/subclasses.new", NULL);
+ stream = fopen(path, "wb");
+ if (!stream)
+ g_error("Failed to open '%s' for writing\n",
+ path);
+
+ write_subclasses(stream);
+
+ atomic_update(path);
+ g_free(path);
+ }
+
+ {
+ FILE *stream;
+ char *path;
+
+ path = g_strconcat(mime_dir, "/aliases.new", NULL);
+ stream = fopen(path, "wb");
+ if (!stream)
+ g_error("Failed to open '%s' for writing\n",
+ path);
+
+ write_aliases(stream);
+
+ atomic_update(path);
+ g_free(path);
+ }
+
g_ptr_array_free(magic_array, TRUE);
g_hash_table_destroy(types);
g_hash_table_destroy(globs_hash);
g_hash_table_destroy(namespace_hash);
+ g_hash_table_destroy(subclass_hash);
+ g_hash_table_destroy(alias_hash);
g_print("***\n");