summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Schwan <carl.schwan@gnupg.com>2023-09-01 12:17:04 +0200
committerDavid Faure <faure@kde.org>2023-10-07 10:55:36 +0000
commit5a82e95878473ac7114f0e7fde68a188f0895983 (patch)
tree0aed2041ea82a063f33edc778ccfccd9d022cc57 /src
parent4dd51563bafc2f3d088db55449a22f1dbdd3c70e (diff)
Make update-mime-database compatible with MSVC
- Port to C++ compatible code (use explicit static_cast) - Replace dirent/opendir implementation with std::filesystem - Disable check_in_path_xdg_data on windows as xdg_data doesn't exist on windows - Simplify getopt handling on windows to just handle -v
Diffstat (limited to 'src')
-rw-r--r--src/meson.build2
-rw-r--r--src/update-mime-database.cpp (renamed from src/update-mime-database.c)172
2 files changed, 86 insertions, 88 deletions
diff --git a/src/meson.build b/src/meson.build
index 5da9ddf..d5d8f31 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -5,7 +5,7 @@ configure_file(
)
update_mime_database = executable('update-mime-database',
- 'update-mime-database.c',
+ 'update-mime-database.cpp',
dependencies: [
glib2,
libxml,
diff --git a/src/update-mime-database.c b/src/update-mime-database.cpp
index a8d2967..733ba06 100644
--- a/src/update-mime-database.c
+++ b/src/update-mime-database.cpp
@@ -6,19 +6,28 @@
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
+#ifndef _MSC_VER
#include <unistd.h>
+#include <dirent.h>
+#endif
#include <stdio.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <glib/gstdio.h>
#include <errno.h>
-#include <dirent.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
+#include <algorithm>
+#include <filesystem>
+#include <vector>
+#include <optional>
+
+namespace fs = std::filesystem;
+
#define XML_NS XML_XML_NAMESPACE
#define XMLNS_NS "http://www.w3.org/2000/xmlns/"
#define FREE_NS (xmlChar *)"http://www.freedesktop.org/standards/shared-mime-info"
@@ -166,7 +175,7 @@ static GHashTable *icon_hash = NULL;
static GHashTable *generic_icon_hash = NULL;
/* Lists enabled log levels */
-static GLogLevelFlags enabled_log_levels = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING;
+static GLogLevelFlags enabled_log_levels = static_cast<GLogLevelFlags>(G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
/* Static prototypes */
static Magic *magic_new(xmlNode *node, Type *type, GError **error);
@@ -218,9 +227,9 @@ static void free_type(gpointer data)
*/
static char *my_xmlGetNsProp (xmlNodePtr node,
const char *name,
- const xmlChar *namespace)
+ const xmlChar *nameSpace)
{
- return (char *)xmlGetNsProp (node, (xmlChar *)name, namespace);
+ return (char *)xmlGetNsProp (node, (xmlChar *)name, nameSpace);
}
/* If we've seen this type before, return the existing object.
@@ -244,7 +253,7 @@ static Type *get_type(const char *name, GError **error)
return NULL;
}
- type = g_hash_table_lookup(types, name);
+ type = static_cast<Type *>(g_hash_table_lookup(types, name));
if (type)
return type;
@@ -416,7 +425,7 @@ static gboolean process_freedesktop_node(Type *type, xmlNode *field,
{
Glob *glob;
char *pat = case_sensitive ? g_strdup (pattern) : g_ascii_strdown (pattern, -1);
- GList *list = g_hash_table_lookup (globs_hash, pat);
+ auto list = static_cast<GList *>(g_hash_table_lookup (globs_hash, pat));
glob = g_new0 (Glob, 1);
glob->pattern = pat;
@@ -440,7 +449,7 @@ static gboolean process_freedesktop_node(Type *type, xmlNode *field,
else if (strcmp((char *)field->name, "glob-deleteall") == 0)
{
Glob *glob;
- GList *list = g_hash_table_lookup (globs_hash, NOGLOBS);
+ auto list = static_cast<GList *>(g_hash_table_lookup (globs_hash, NOGLOBS));
glob = g_new0 (Glob, 1);
glob->pattern = g_strdup (NOGLOBS);
@@ -511,9 +520,9 @@ static gboolean process_freedesktop_node(Type *type, xmlNode *field,
valid = other_type && strchr(other_type, '/');
if (valid)
{
- char *typename;
+ char *typeName;
- typename = g_strdup_printf("%s/%s",
+ typeName = g_strdup_printf("%s/%s",
type->media,
type->subtype);
@@ -523,13 +532,13 @@ static gboolean process_freedesktop_node(Type *type, xmlNode *field,
else
{
- list = g_hash_table_lookup(subclass_hash, typename);
+ list = static_cast<GSList *>(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_strdup(typeName), nlist);
}
- g_free(typename);
+ g_free(typeName);
xmlFree(other_type);
copy_to_xml = TRUE; /* Copy through */
@@ -560,22 +569,22 @@ static gboolean process_freedesktop_node(Type *type, xmlNode *field,
strcmp((char *)field->name, "icon") == 0)
{
char *icon;
- char *typename;
+ char *typeName;
icon = my_xmlGetNsProp(field, "name", NULL);
if (icon)
{
- typename = g_strdup_printf("%s/%s",
+ typeName = g_strdup_printf("%s/%s",
type->media,
type->subtype);
if (strcmp((char *)field->name, "icon") == 0)
g_hash_table_insert(icon_hash,
- typename, g_strdup (icon));
+ typeName, g_strdup (icon));
else
g_hash_table_insert(generic_icon_hash,
- typename, g_strdup (icon));
+ typeName, g_strdup (icon));
xmlFree (icon);
@@ -611,18 +620,18 @@ static gboolean has_lang(xmlNode *node, const char *lang)
/* We're about to add 'new' to the list of fields to be output for the
* type. Remove any existing nodes which it replaces.
*/
-static void remove_old(Type *type, xmlNode *new)
+static void remove_old(Type *type, xmlNode *newNode)
{
xmlNode *field, *fields;
char *lang;
- if (new->ns == NULL || xmlStrcmp(new->ns->href, FREE_NS) != 0)
+ if (newNode->ns == NULL || xmlStrcmp(newNode->ns->href, FREE_NS) != 0)
return; /* No idea what we're doing -- leave it in! */
- if (strcmp((char *)new->name, "comment") != 0)
+ if (strcmp((char *)newNode->name, "comment") != 0)
return;
- lang = my_xmlGetNsProp(new, "lang", XML_NS);
+ lang = my_xmlGetNsProp(newNode, "lang", XML_NS);
fields = xmlDocGetRootElement(type->output);
for (field = fields->xmlChildrenNode; field; field = field->next)
@@ -789,53 +798,35 @@ static gint strcmp2(gconstpointer a, gconstpointer b)
*/
static void scan_source_dir(const char *path)
{
- DIR *dir;
- struct dirent *ent;
- char *filename;
- GPtrArray *files;
- int i;
- gboolean have_override = FALSE;
-
- dir = opendir(path);
- if (!dir)
- {
+ if (!fs::is_directory(fs::status(path))) {
perror("scan_source_dir");
exit(EXIT_FAILURE);
}
- files = g_ptr_array_new();
- while ((ent = readdir(dir)))
- {
- int l;
- l = strlen(ent->d_name);
- if (l < 4 || strcmp(ent->d_name + l - 4, ".xml") != 0)
+ const fs::path dir{path};
+ std::vector<fs::path> files;
+ std::optional<fs::path> file_override;
+ for (auto const& dir_entry : std::filesystem::directory_iterator{dir}) {
+ if (dir_entry.path().extension() != ".xml") {
continue;
- if (strcmp(ent->d_name, "Override.xml") == 0)
- {
- have_override = TRUE;
+ }
+
+ if (dir_entry.path().filename() == "Override.xml") {
+ file_override = dir_entry.path();
continue;
}
- g_ptr_array_add(files, g_strdup(ent->d_name));
- }
- closedir(dir);
- g_ptr_array_sort(files, strcmp2);
+ files.push_back(dir_entry.path());
+ }
- if (have_override)
- g_ptr_array_add(files, g_strdup("Override.xml"));
+ std::sort(files.begin(), files.end());
- for (i = 0; i < files->len; i++)
- {
- gchar *leaf = (gchar *) files->pdata[i];
+ if (file_override)
+ files.push_back(file_override.value());
- filename = g_strconcat(path, "/", leaf, NULL);
- load_source_file(filename);
- g_free(filename);
+ for (const auto &file : files) {
+ load_source_file(file.string().c_str());
}
-
- for (i = 0; i < files->len; i++)
- g_free(files->pdata[i]);
- g_ptr_array_free(files, TRUE);
}
static gboolean save_xml_file(xmlDocPtr doc, const gchar *filename, GError **error)
@@ -919,7 +910,7 @@ static void write_out_glob2(GList *globs, FILE *stream)
static void collect_glob2(gpointer key, gpointer value, gpointer data)
{
- GList **listp = data;
+ auto listp = static_cast<GList**>(data);
*listp = g_list_concat (*listp, g_list_copy ((GList *)value));
}
@@ -1035,7 +1026,7 @@ static void write_out_type(gpointer key, gpointer value, gpointer data)
media = g_strconcat(mime_dir, "/", lower, NULL);
g_free(lower);
#ifdef _WIN32
- mkdir(media);
+ fs::create_directory(media);
#else
mkdir(media, 0755);
#endif
@@ -1969,26 +1960,20 @@ static void delete_old_types(const gchar *mime_dir)
for (i = 0; i < G_N_ELEMENTS(media_types); i++)
{
- gchar *media_dir;
- DIR *dir;
- struct dirent *ent;
-
- media_dir = g_strconcat(mime_dir, "/", media_types[i], NULL);
- dir = opendir(media_dir);
- g_free(media_dir);
- if (!dir)
+ const fs::path media_dir = g_strconcat(mime_dir, "/", media_types[i], NULL);
+
+ if (!fs::is_directory(fs::status(media_dir)))
continue;
- while ((ent = readdir(dir)))
+ std::vector<fs::path> files;
+ std::optional<fs::path> file_override;
+ for (auto const& dir_entry : std::filesystem::directory_iterator{media_dir})
{
- char *type_name;
- int l;
- l = strlen(ent->d_name);
- if (l < 4 || strcmp(ent->d_name + l - 4, ".xml") != 0)
+ if (dir_entry.path().extension() != ".xml")
continue;
- type_name = g_strconcat(media_types[i], "/",
- ent->d_name, NULL);
+ char *type_name = g_strconcat(media_types[i], "/",
+ dir_entry.path().filename().string().c_str(), NULL);
type_name[strlen(type_name) - 4] = '\0';
if (!g_hash_table_lookup(types, type_name))
{
@@ -2003,9 +1988,7 @@ static void delete_old_types(const gchar *mime_dir)
g_free(path);
}
g_free(type_name);
- }
-
- closedir(dir);
+ }
}
}
@@ -2048,14 +2031,14 @@ static void write_namespaces(FILE *stream)
static void write_subclass(gpointer key, gpointer value, gpointer data)
{
- GSList *list = value;
- FILE *stream = data;
+ auto list = static_cast<GSList *>(value);
+ auto stream = static_cast<FILE *>(data);
GSList *l;
char *line;
for (l = list; l; l = l->next)
{
- line = g_strconcat (key, " ", l->data, "\n", NULL);
+ line = g_strconcat (static_cast<const gchar *>(key), " ", l->data, "\n", NULL);
fwrite(line, 1, strlen(line), stream);
g_free (line);
}
@@ -2157,6 +2140,7 @@ static void write_icons(GHashTable *icons, FILE *stream)
/* Issue a warning if 'path' won't be found by applications */
static void check_in_path_xdg_data(const char *mime_path)
{
+#ifndef _MSC_VER
struct stat path_info, dir_info;
const char *env;
char **dirs;
@@ -2213,11 +2197,12 @@ static void check_in_path_xdg_data(const char *mime_path)
g_free(dirs);
out:
g_free(path);
+#endif
}
static void free_string_list(gpointer data)
{
- GSList *list = data;
+ auto list = static_cast<GSList *>(data);
g_slist_foreach(list, (GFunc)g_free, NULL);
g_slist_free(list);
@@ -2235,7 +2220,7 @@ write_data (FILE *cache, const gchar *n, gint len)
l = ALIGN_VALUE (len, 4);
- s = g_malloc0 (l);
+ s = static_cast<gchar *>(g_malloc0(l));
memcpy (s, n, len);
i = fwrite (s, l, 1, cache);
@@ -2333,7 +2318,7 @@ write_map_entry (gpointer key,
guint offset, i;
guint weight;
- values = (* map_data->get_value) (map_data->data, key);
+ values = (* map_data->get_value) (map_data->data, static_cast<gchar *>(key));
for (i = 0; values[i]; i++)
{
if (map_data->weighted && (i % 3 == 2))
@@ -2394,7 +2379,7 @@ count_map_entry (gpointer key,
CountData *count_data = (CountData *)data;
gchar **values;
- values = (* count_data->get_value) (count_data->data, key);
+ values = (* count_data->get_value) (count_data->data, static_cast<gchar *>(key));
count_data->count += g_strv_length (values) / (count_data->weighted ? 3 : 2);
g_strfreev (values);
}
@@ -3649,6 +3634,7 @@ int main(int argc, char **argv)
/* Install the filtering log handler */
g_log_set_default_handler(g_log_handler, NULL);
+ #ifndef _MSC_VER
while ((opt = getopt(argc, argv, "hvVn")) != -1)
{
switch (opt)
@@ -3665,8 +3651,8 @@ int main(int argc, char **argv)
VERSION "\n" COPYING);
return EXIT_SUCCESS;
case 'V':
- enabled_log_levels |= G_LOG_LEVEL_MESSAGE
- | G_LOG_LEVEL_INFO;
+ enabled_log_levels = static_cast<GLogLevelFlags>(enabled_log_levels | G_LOG_LEVEL_MESSAGE
+ | G_LOG_LEVEL_INFO);
break;
case 'n':
if_newer = TRUE;
@@ -3676,15 +3662,27 @@ int main(int argc, char **argv)
}
}
+
if (optind != argc - 1)
{
usage(argv[0]);
return EXIT_FAILURE;
}
- LIBXML_TEST_VERSION;
mime_dir = argv[optind];
+#else
+ if (strcmp(argv[argc - 1], "v")) {
+ g_fprintf(stderr,
+ "update-mime-database (" PACKAGE ") "
+ VERSION "\n" COPYING);
+ return EXIT_SUCCESS;
+ }
+
+ mime_dir = argv[argc - 1];
+#endif
+
+ LIBXML_TEST_VERSION;
/* Strip trailing / characters */
{
@@ -3698,7 +3696,7 @@ int main(int argc, char **argv)
package_dir = g_strconcat(mime_dir, "/packages", NULL);
- if (access(mime_dir, F_OK))
+ if (!fs::exists(mime_dir) && !fs::is_directory(fs::status(mime_dir)))
{
g_warning(_("Directory '%s' does not exist!"), package_dir);
return EXIT_FAILURE;
@@ -3706,7 +3704,7 @@ int main(int argc, char **argv)
g_message("Updating MIME database in %s...\n", mime_dir);
- if (access(package_dir, F_OK))
+ if (!fs::exists(package_dir) && !fs::is_directory(fs::status(package_dir)))
{
g_fprintf(stderr,
_("Directory '%s' does not exist!\n"), package_dir);