From 33ec6851e8eece9d9bf4a17c8be065e9790b8a5f Mon Sep 17 00:00:00 2001 From: Kalev Lember Date: Fri, 6 Jan 2017 10:46:28 +0100 Subject: WIP: Keep an array with source files for each app Instead of one source file, allow setting multiple source files so that we can have the desktop file, appdata file and appstream file all marked as a source for one app. This is supposed to fix https://bugzilla.gnome.org/show_bug.cgi?id=775814 but something is still not right there and this needs a bit more investigation. --- libappstream-glib/as-app.c | 95 +++++++++++++++++++++++++++++++++++++++----- libappstream-glib/as-app.h | 5 +++ libappstream-glib/as-store.c | 6 ++- 3 files changed, 94 insertions(+), 12 deletions(-) diff --git a/libappstream-glib/as-app.c b/libappstream-glib/as-app.c index 1d6fbe5..8e385f9 100644 --- a/libappstream-glib/as-app.c +++ b/libappstream-glib/as-app.c @@ -86,6 +86,7 @@ typedef struct GPtrArray *content_ratings; /* of AsContentRating */ GPtrArray *icons; /* of AsIcon */ GPtrArray *bundles; /* of AsBundle */ + GPtrArray *source_files; /* of AsRefString */ GPtrArray *translations; /* of AsTranslation */ GPtrArray *suggests; /* of AsSuggest */ GPtrArray *requires; /* of AsRequire */ @@ -108,7 +109,6 @@ typedef struct AsRefString *update_contact; gchar *unique_id; gboolean unique_id_valid; - AsRefString *source_file; AsRefString *branch; gint priority; gsize token_cache_valid; @@ -484,8 +484,6 @@ as_app_finalize (GObject *object) if (priv->update_contact != NULL) as_ref_string_unref (priv->update_contact); g_free (priv->unique_id); - if (priv->source_file != NULL) - as_ref_string_unref (priv->source_file); if (priv->branch != NULL) as_ref_string_unref (priv->branch); g_hash_table_unref (priv->comments); @@ -516,6 +514,7 @@ as_app_finalize (GObject *object) g_ptr_array_unref (priv->translations); g_ptr_array_unref (priv->suggests); g_ptr_array_unref (priv->requires); + g_ptr_array_unref (priv->source_files); g_ptr_array_unref (priv->vetos); G_OBJECT_CLASS (as_app_parent_class)->finalize (object); @@ -547,6 +546,7 @@ as_app_init (AsApp *app) priv->translations = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->suggests = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->requires = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + priv->source_files = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); priv->vetos = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref); priv->comments = g_hash_table_new_full (g_str_hash, g_str_equal, @@ -1983,7 +1983,11 @@ const gchar * as_app_get_source_file (AsApp *app) { AsAppPrivate *priv = GET_PRIVATE (app); - return priv->source_file; + + if (priv->source_files->len == 0) + return NULL; + + return g_ptr_array_index (priv->source_files, 0); } /** @@ -2345,6 +2349,76 @@ as_app_set_source_pkgname (AsApp *app, as_ref_string_assign_safe (&priv->source_pkgname, source_pkgname); } +/** + * as_app_has_source_file: + * @app: a #AsApp instance. + * @source_file: the filename. + * + * Searches the source file list for a specific filename. + * + * Returns: %TRUE if the application has got the specified source file + * + * Since: 0.6.7 + */ +gboolean +as_app_has_source_file (AsApp *app, const gchar *source_file) +{ + AsAppPrivate *priv = GET_PRIVATE (app); + + if (as_ptr_array_find_string (priv->source_files, source_file)) + return TRUE; + return FALSE; +} + +/** + * as_app_get_source_files: + * @app: a #AsApp instance. + * + * Gets all the source filenames the instance was populated from. + * + * NOTE: these are not set for %AS_APP_SOURCE_KIND_APPSTREAM entries. + * + * Returns: (element-type utf8) (transfer none): an array + * + * Since: 0.6.7 + **/ +GPtrArray * +as_app_get_source_files (AsApp *app) +{ + AsAppPrivate *priv = GET_PRIVATE (app); + return priv->source_files; +} + +/** + * as_app_add_source_file: + * @app: a #AsApp instance. + * @source_file: the filename. + * + * Adds a file that the instance was sourced from. + * + * Since: 0.6.7 + **/ +void +as_app_add_source_file (AsApp *app, const gchar *source_file) +{ + AsAppPrivate *priv = GET_PRIVATE (app); + + g_return_if_fail (source_file != NULL); + + /* handle untrusted */ + if ((priv->trust_flags & AS_APP_TRUST_FLAG_CHECK_VALID_UTF8) > 0 && + !as_app_validate_utf8 (source_file)) { + priv->problems |= AS_APP_PROBLEM_NOT_VALID_UTF8; + return; + } + if ((priv->trust_flags & AS_APP_TRUST_FLAG_CHECK_DUPLICATES) > 0 && + as_ptr_array_find_string (priv->source_files, source_file)) { + return; + } + + g_ptr_array_add (priv->source_files, as_ref_string_new (source_file)); +} + /** * as_app_set_source_file: * @app: a #AsApp instance. @@ -2357,8 +2431,7 @@ as_app_set_source_pkgname (AsApp *app, void as_app_set_source_file (AsApp *app, const gchar *source_file) { - AsAppPrivate *priv = GET_PRIVATE (app); - as_ref_string_assign_safe (&priv->source_file, source_file); + as_app_add_source_file (app, source_file); } /** @@ -3816,10 +3889,12 @@ as_app_subsume_private (AsApp *app, AsApp *donor, AsAppSubsumeFlags flags) if (flags & AS_APP_SUBSUME_FLAG_KEYWORDS) as_app_subsume_keywords (app, donor, flags); - /* source */ + /* source files */ if (flags & AS_APP_SUBSUME_FLAG_SOURCE_FILE) { - if (priv->source_file != NULL) - as_app_set_source_file (app, priv->source_file); + for (i = 0; i < priv->source_files->len; i++) { + tmp = g_ptr_array_index (priv->source_files, i); + as_app_add_source_file (app, tmp); + } } /* branch */ @@ -5766,7 +5841,7 @@ as_app_parse_file (AsApp *app, AS_APP_TRUST_FLAG_CHECK_VALID_UTF8); /* set the source location */ - as_app_set_source_file (app, filename); + as_app_add_source_file (app, filename); /* parse */ switch (priv->source_kind) { diff --git a/libappstream-glib/as-app.h b/libappstream-glib/as-app.h index ca62e36..2a7b6b0 100644 --- a/libappstream-glib/as-app.h +++ b/libappstream-glib/as-app.h @@ -496,6 +496,7 @@ GPtrArray *as_app_get_reviews (AsApp *app); GPtrArray *as_app_get_content_ratings (AsApp *app); GPtrArray *as_app_get_icons (AsApp *app); GPtrArray *as_app_get_bundles (AsApp *app); +GPtrArray *as_app_get_source_files (AsApp *app); GPtrArray *as_app_get_translations (AsApp *app); GPtrArray *as_app_get_suggests (AsApp *app); GPtrArray *as_app_get_requires (AsApp *app); @@ -547,6 +548,8 @@ gboolean as_app_has_compulsory_for_desktop (AsApp *app, const gchar *desktop); gboolean as_app_has_quirk (AsApp *app, AsAppQuirk quirk); +gboolean as_app_has_source_file (AsApp *app, + const gchar *source_file); /* setters */ void as_app_set_id (AsApp *app, @@ -591,6 +594,8 @@ void as_app_set_description (AsApp *app, const gchar *description); void as_app_set_source_file (AsApp *app, const gchar *source_file); +void as_app_add_source_file (AsApp *app, + const gchar *source_file); void as_app_set_branch (AsApp *app, const gchar *branch); void as_app_set_priority (AsApp *app, diff --git a/libappstream-glib/as-store.c b/libappstream-glib/as-store.c index e8ac300..d2cc0a8 100644 --- a/libappstream-glib/as-store.c +++ b/libappstream-glib/as-store.c @@ -1511,7 +1511,7 @@ as_store_from_root (AsStore *store, if (origin_str != NULL) as_app_set_origin (app, origin_str); if (source_filename_str != NULL) - as_app_set_source_file (app, source_filename_str); + as_app_add_source_file (app, source_filename_str); as_store_add_app (store, app); } @@ -1630,8 +1630,10 @@ as_store_remove_by_source_file (AsStore *store, const gchar *filename) ids = g_ptr_array_new_with_free_func (g_free); apps = as_store_get_apps (store); for (i = 0; i < apps->len; i++) { + GPtrArray *source_files; app = g_ptr_array_index (apps, i); - if (g_strcmp0 (as_app_get_source_file (app), filename) != 0) + source_files = as_app_get_source_files (app); + if (!as_ptr_array_find_string (source_files, filename)) continue; g_ptr_array_add (ids, g_strdup (as_app_get_id (app))); } -- cgit v1.2.1