diff options
author | Jonathan Blandford <jrb@redhat.com> | 2004-11-09 07:04:30 +0000 |
---|---|---|
committer | Jonathan Blandford <jrb@redhat.com> | 2004-11-09 07:04:30 +0000 |
commit | 94f54528a2326ba623cbc73dfcae63fe7723d9e5 (patch) | |
tree | 572d4613c5006d4f5f70889fa1bc0dcfd3ca1e6f /update-mime-database.c | |
parent | f9c74af900469a419cb9c084d64c561d6f55be84 (diff) | |
download | shared-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.c | 146 |
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"); |