This commit adds the whole machinery needed for dealing with Guest Features for an Os object. Signed-off-by: Fabiano Fidêncio <fidencio@xxxxxxxxxx> --- osinfo/libosinfo.syms | 2 + osinfo/osinfo_os.c | 140 ++++++++++++++++++++++++++++++++++++++++++ osinfo/osinfo_os.h | 4 ++ 3 files changed, 146 insertions(+) diff --git a/osinfo/libosinfo.syms b/osinfo/libosinfo.syms index 30bab43..99a7843 100644 --- a/osinfo/libosinfo.syms +++ b/osinfo/libosinfo.syms @@ -562,9 +562,11 @@ LIBOSINFO_1.3.0 { osinfo_media_supports_installer_script; + osinfo_os_add_feature; osinfo_os_add_image; osinfo_os_add_maximum_resources; osinfo_os_get_all_device_links; + osinfo_os_get_feature_list; osinfo_os_get_image_list; osinfo_os_get_maximum_resources; diff --git a/osinfo/osinfo_os.c b/osinfo/osinfo_os.c index 01d2e01..c29ffd2 100644 --- a/osinfo/osinfo_os.c +++ b/osinfo/osinfo_os.c @@ -29,6 +29,7 @@ #include "osinfo/osinfo_product_private.h" #include "osinfo/osinfo_os_private.h" #include "osinfo/osinfo_resources_private.h" +#include "osinfo/osinfo_feature_private.h" #include <glib/gi18n-lib.h> G_DEFINE_TYPE(OsinfoOs, osinfo_os, OSINFO_TYPE_PRODUCT); @@ -59,6 +60,7 @@ struct _OsinfoOsPrivate OsinfoResourcesList *minimum; OsinfoResourcesList *recommended; OsinfoResourcesList *maximum; + OsinfoFeatureList *features; OsinfoInstallScriptList *scripts; @@ -119,6 +121,7 @@ osinfo_os_finalize(GObject *object) g_object_unref(os->priv->minimum); g_object_unref(os->priv->recommended); g_object_unref(os->priv->maximum); + g_object_unref(os->priv->features); g_object_unref(os->priv->scripts); @@ -186,6 +189,7 @@ osinfo_os_init(OsinfoOs *os) os->priv->minimum = osinfo_resourceslist_new(); os->priv->recommended = osinfo_resourceslist_new(); os->priv->maximum = osinfo_resourceslist_new(); + os->priv->features = osinfo_featurelist_new(); os->priv->scripts = osinfo_install_scriptlist_new(); os->priv->device_drivers = osinfo_device_driverlist_new(); } @@ -553,6 +557,142 @@ OsinfoDeviceLink *osinfo_os_add_device(OsinfoOs *os, OsinfoDevice *dev) return devlink; } +static gboolean feature_exists_in_list(const gchar *name, + OsinfoList *list) +{ + gssize len, i; + + if (list == NULL) + return FALSE; + + len = osinfo_list_get_length(list); + for (i = 0; i < len; i++) { + OsinfoFeature *f; + + f = OSINFO_FEATURE(osinfo_list_get_nth(list, i)); + + if (g_str_equal(name, osinfo_feature_get_name(f))) + return TRUE; + } + + return FALSE; +} + +struct GetAllFeaturesData { + OsinfoOs *os; + OsinfoFilter *filter; + OsinfoFeatureList *feature_list; + OsinfoFeatureList *unsupported_list; +}; + +static void get_all_features_cb(OsinfoProduct *product, gpointer user_data) +{ + OsinfoFeatureList *filtered; + OsinfoFeatureList *filtered_arch; + OsinfoFeatureList *filtered_all; + OsinfoOs *os; + OsinfoFilter *filter; + struct GetAllFeaturesData *foreach_data = (struct GetAllFeaturesData *)user_data; + gsize featurelist_len; + gsize i; + + g_return_if_fail(OSINFO_IS_OS(product)); + os = OSINFO_OS(product); + + filter = osinfo_filter_new(); + osinfo_filter_add_constraint(filter, OSINFO_FEATURE_PROP_ARCHITECTURE, "all"); + filtered_all = OSINFO_FEATURELIST(osinfo_list_new_filtered(OSINFO_LIST(os->priv->features), + filter)); + filtered_arch = OSINFO_FEATURELIST(osinfo_list_new_filtered(OSINFO_LIST(os->priv->features), + foreach_data->filter)); + + filtered = OSINFO_FEATURELIST(osinfo_list_new_union(OSINFO_LIST(filtered_arch), + OSINFO_LIST(filtered_all))); + + featurelist_len = osinfo_list_get_length(OSINFO_LIST(filtered)); + + for (i = 0; i < featurelist_len; i++) { + OsinfoFeature *feature; + const gchar *name; + + feature = OSINFO_FEATURE(osinfo_list_get_nth(OSINFO_LIST(filtered), i)); + name = osinfo_feature_get_name(feature); + + if (!osinfo_feature_get_supported(feature) && + !feature_exists_in_list(name, OSINFO_LIST(foreach_data->unsupported_list))) + osinfo_list_add(OSINFO_LIST(foreach_data->unsupported_list), OSINFO_ENTITY(feature)); + } + + for (i = 0; i < featurelist_len; i++) { + OsinfoFeature *feature; + const gchar *name; + + feature = OSINFO_FEATURE(osinfo_list_get_nth(OSINFO_LIST(filtered), i)); + name = osinfo_feature_get_name(feature); + + if (!feature_exists_in_list(name, OSINFO_LIST(foreach_data->unsupported_list)) && + !feature_exists_in_list(name, OSINFO_LIST(foreach_data->feature_list))) + osinfo_list_add(OSINFO_LIST(foreach_data->feature_list), OSINFO_ENTITY(feature)); + } + + g_object_unref(filtered); + g_object_unref(filtered_all); + g_object_unref(filtered_arch); + g_object_unref(filter); +} + +/** + * osinfo_os_get_feature_list: + * @os: an operating system + * @arch: the target architecture + * + * Get all features matching a given filter and taking into consideration + * all features previous set in all OSes from which @os derived and/or cloned. + * + * Returns: (transfer full): A list of OsinfoFeature + */ +OsinfoFeatureList *osinfo_os_get_feature_list(OsinfoOs *os, const gchar *arch) +{ + struct GetAllFeaturesData foreach_data = { + .os = os, + .filter = osinfo_filter_new(), + .feature_list = osinfo_featurelist_new(), + .unsupported_list = osinfo_featurelist_new(), + }; + + g_return_val_if_fail(OSINFO_IS_OS(os), NULL); + g_return_val_if_fail(arch != NULL, NULL); + + osinfo_filter_add_constraint(foreach_data.filter, + OSINFO_FEATURE_PROP_ARCHITECTURE, + arch); + + osinfo_product_foreach_related(OSINFO_PRODUCT(os), + OSINFO_PRODUCT_FOREACH_FLAG_DERIVES_FROM | + OSINFO_PRODUCT_FOREACH_FLAG_CLONES, + get_all_features_cb, + &foreach_data); + + g_object_unref(foreach_data.filter); + g_object_unref(foreach_data.unsupported_list); + + return foreach_data.feature_list; +} + +/** osinfo_os_add_feature: + * @os: an operating system + * @feature: (transfer none): the feature to associate with + * + * Adds @feature to list of features of operating system @os. + */ +void osinfo_os_add_feature(OsinfoOs *os, OsinfoFeature *feature) +{ + g_return_if_fail(OSINFO_IS_OS(os)); + g_return_if_fail(OSINFO_IS_FEATURE(feature)); + + osinfo_list_add(OSINFO_LIST(os->priv->features), OSINFO_ENTITY(feature)); +} + /** * osinfo_os_get_family: * @os: an #OsinfoOs diff --git a/osinfo/osinfo_os.h b/osinfo/osinfo_os.h index 4eb4b1b..6ea825d 100644 --- a/osinfo/osinfo_os.h +++ b/osinfo/osinfo_os.h @@ -34,6 +34,7 @@ #include <osinfo/osinfo_tree.h> #include <osinfo/osinfo_resources.h> #include <osinfo/osinfo_resourceslist.h> +#include <osinfo/osinfo_feature.h> #include <osinfo/osinfo_image.h> #include <osinfo/osinfo_imagelist.h> @@ -137,6 +138,9 @@ void osinfo_os_add_install_script(OsinfoOs *os, OsinfoInstallScript *script); OsinfoDeviceDriverList *osinfo_os_get_device_drivers(OsinfoOs *os); void osinfo_os_add_device_driver(OsinfoOs *os, OsinfoDeviceDriver *driver); +OsinfoFeatureList *osinfo_os_get_feature_list(OsinfoOs *os, const gchar *arch); +void osinfo_os_add_feature(OsinfoOs *os, OsinfoFeature *feature); + #endif /* __OSINFO_OS_H__ */ /* * Local variables: -- 2.19.2 _______________________________________________ Libosinfo mailing list Libosinfo@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libosinfo