/
githubmirror
/
libmodulemd
Обзор
Документация
Войти
/
githubmirror
/
libmodulemd
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
2.13.0
modulemd/modulemd-service-level.c
474 строки
12 KB
Stephen Gallagher
Apply clang-tidy formatting
18 окт 2019, 03:24
18 окт 2019, 03:24
028aa0b
Код
Авторство
О чём код?
/* * This file is part of libmodulemd * Copyright (C) 2017-2018 Stephen Gallagher * * Fedora-License-Identifier: MIT * SPDX-2.0-License-Identifier: MIT * SPDX-3.0-License-Identifier: MIT * * This program is free software. * For more information on the license, see COPYING. * For more information on free software, see <https://www.gnu.org/philosophy/free-sw.en.html>. */ #include <glib.h> #include <yaml.h> #include "modulemd-service-level.h" #include "private/glib-extensions.h" #include "private/modulemd-service-level-private.h" #include "private/modulemd-util.h" #include "private/modulemd-yaml.h" #define SL_DEFAULT_STRING "__NAME_UNSET__" struct _ModulemdServiceLevel { GObject parent_instance; gchar *name; GDate *eol; }; G_DEFINE_TYPE (ModulemdServiceLevel, modulemd_service_level, G_TYPE_OBJECT) enum { PROP_0, PROP_NAME, N_PROPS }; static GParamSpec *properties[N_PROPS]; ModulemdServiceLevel * modulemd_service_level_new (const gchar *name) { // clang-format off return g_object_new (MODULEMD_TYPE_SERVICE_LEVEL, "name", name, NULL); // clang-format on } gboolean modulemd_service_level_equals_wrapper (const void *a, const void *b) { g_return_val_if_fail (MODULEMD_IS_SERVICE_LEVEL ((ModulemdServiceLevel *)a), FALSE); g_return_val_if_fail (MODULEMD_IS_SERVICE_LEVEL ((ModulemdServiceLevel *)b), FALSE); return modulemd_service_level_equals ((ModulemdServiceLevel *)a, (ModulemdServiceLevel *)b); } gboolean modulemd_service_level_equals (ModulemdServiceLevel *self_1, ModulemdServiceLevel *self_2) { if (!self_1 && !self_2) { return TRUE; } if (!self_1 || !self_2) { return FALSE; } g_return_val_if_fail (MODULEMD_IS_SERVICE_LEVEL (self_1), FALSE); g_return_val_if_fail (MODULEMD_IS_SERVICE_LEVEL (self_2), FALSE); if (g_strcmp0 (modulemd_service_level_get_name (self_1), modulemd_service_level_get_name (self_2)) != 0) { return FALSE; } /*if both eols are invalid, its equivalent*/ if (!g_date_valid (self_1->eol) && !g_date_valid (self_2->eol)) { return TRUE; } if (!g_date_valid (self_1->eol) || !g_date_valid (self_2->eol)) { return FALSE; } if (g_date_compare (self_1->eol, self_2->eol) != 0) { return FALSE; } return TRUE; } ModulemdServiceLevel * modulemd_service_level_copy (ModulemdServiceLevel *self) { g_autoptr (ModulemdServiceLevel) sl = NULL; g_return_val_if_fail (MODULEMD_IS_SERVICE_LEVEL (self), NULL); sl = modulemd_service_level_new (modulemd_service_level_get_name (self)); modulemd_service_level_set_eol (sl, modulemd_service_level_get_eol (self)); return g_object_ref (sl); } static void modulemd_service_level_finalize (GObject *object) { ModulemdServiceLevel *self = (ModulemdServiceLevel *)object; g_clear_pointer (&self->name, g_free); g_clear_pointer (&self->eol, g_date_free); G_OBJECT_CLASS (modulemd_service_level_parent_class)->finalize (object); } static void modulemd_service_level_set_name (ModulemdServiceLevel *self, const gchar *name) { g_return_if_fail (MODULEMD_IS_SERVICE_LEVEL (self)); /* It is a coding error if we ever get a NULL name here */ g_return_if_fail (name); /* It is a coding error if we ever get the default name here */ g_return_if_fail (g_strcmp0 (name, SL_DEFAULT_STRING)); g_clear_pointer (&self->name, g_free); self->name = g_strdup (name); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_NAME]); } const gchar * modulemd_service_level_get_name (ModulemdServiceLevel *self) { g_return_val_if_fail (MODULEMD_IS_SERVICE_LEVEL (self), NULL); return self->name; } void modulemd_service_level_set_eol (ModulemdServiceLevel *self, GDate *date) { g_return_if_fail (MODULEMD_IS_SERVICE_LEVEL (self)); if (!date || !g_date_valid (date)) { g_date_clear (self->eol, 1); return; } if (!g_date_valid (self->eol) || g_date_compare (date, self->eol) != 0) { /* Date is changing. Update it */ g_date_set_year (self->eol, g_date_get_year (date)); g_date_set_month (self->eol, g_date_get_month (date)); g_date_set_day (self->eol, g_date_get_day (date)); } } void modulemd_service_level_set_eol_ymd (ModulemdServiceLevel *self, GDateYear year, GDateMonth month, GDateDay day) { g_autoptr (GDate) date = NULL; g_return_if_fail (MODULEMD_IS_SERVICE_LEVEL (self)); if (!g_date_valid_dmy (day, month, year)) { /* Treat invalid dates as NULL */ return modulemd_service_level_set_eol (self, NULL); } date = g_date_new_dmy (day, month, year); return modulemd_service_level_set_eol (self, date); } void modulemd_service_level_remove_eol (ModulemdServiceLevel *self) { return modulemd_service_level_set_eol (self, NULL); } GDate * modulemd_service_level_get_eol (ModulemdServiceLevel *self) { g_return_val_if_fail (MODULEMD_IS_SERVICE_LEVEL (self), NULL); if (self->eol && g_date_valid (self->eol)) { return self->eol; } return NULL; } gchar * modulemd_service_level_get_eol_as_string (ModulemdServiceLevel *self) { if (self->eol && g_date_valid (self->eol)) { return g_strdup_printf ("%.4d-%.2d-%.2d", g_date_get_year (self->eol), g_date_get_month (self->eol), g_date_get_day (self->eol)); } return NULL; } static void modulemd_service_level_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { ModulemdServiceLevel *self = MODULEMD_SERVICE_LEVEL (object); switch (prop_id) { case PROP_NAME: g_value_set_string (value, modulemd_service_level_get_name (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void modulemd_service_level_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { ModulemdServiceLevel *self = MODULEMD_SERVICE_LEVEL (object); switch (prop_id) { case PROP_NAME: modulemd_service_level_set_name (self, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void modulemd_service_level_class_init (ModulemdServiceLevelClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = modulemd_service_level_finalize; object_class->get_property = modulemd_service_level_get_property; object_class->set_property = modulemd_service_level_set_property; properties[PROP_NAME] = g_param_spec_string ( "name", "Name", "A human-readable name for this servicelevel", SL_DEFAULT_STRING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties (object_class, N_PROPS, properties); } static void modulemd_service_level_init (ModulemdServiceLevel *self) { self->eol = g_date_new (); } /* === YAML Functions === */ ModulemdServiceLevel * modulemd_service_level_parse_yaml (yaml_parser_t *parser, const gchar *name, gboolean strict, GError **error) { MODULEMD_INIT_TRACE (); MMD_INIT_YAML_EVENT (event); gboolean done = FALSE; gboolean in_map = FALSE; g_autoptr (ModulemdServiceLevel) sl = NULL; GDate *eol = NULL; g_autoptr (GError) nested_error = NULL; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); sl = modulemd_service_level_new (name); /* Read in any supplementary attributes of the service level, * such as 'eol' */ while (!done) { YAML_PARSER_PARSE_WITH_EXIT (parser, &event, error); switch (event.type) { case YAML_MAPPING_START_EVENT: /* This is the start of the service level content. */ in_map = TRUE; break; case YAML_MAPPING_END_EVENT: if (!in_map) { MMD_YAML_ERROR_EVENT_EXIT ( error, event, "Unexpected MAPPING_END in service level"); break; } /* We're done processing the service level content */ in_map = FALSE; done = TRUE; break; case YAML_SCALAR_EVENT: if (!in_map) { /* We must be in the map before we handle scalars */ MMD_YAML_ERROR_EVENT_EXIT ( error, event, "Missing mapping in service level"); break; } /* Only "eol" is supported right now */ if (!g_strcmp0 ((const gchar *)event.data.scalar.value, "eol")) { /* Get the EOL date */ eol = modulemd_yaml_parse_date (parser, &nested_error); if (!eol) { MMD_YAML_ERROR_EVENT_EXIT ( error, event, "Failed to parse EOL date in service level: %s", nested_error->message); } modulemd_service_level_set_eol (sl, eol); g_date_free (eol); } else { /* Unknown field in service level */ SKIP_UNKNOWN (parser, FALSE, "Unexpected key in service level body: %s", (const gchar *)event.data.scalar.value); } break; default: /* We received a YAML event we shouldn't expect at this level */ MMD_YAML_ERROR_EVENT_EXIT ( error, event, "Unexpected YAML event in service level"); break; } yaml_event_delete (&event); } return g_object_ref (sl); } gboolean modulemd_service_level_emit_yaml (ModulemdServiceLevel *self, yaml_emitter_t *emitter, GError **error) { MODULEMD_INIT_TRACE (); int ret; g_autoptr (GError) nested_error = NULL; g_autofree gchar *eol_string = NULL; MMD_INIT_YAML_EVENT (event); /* Emit the Service Level Name */ ret = mmd_emitter_scalar (emitter, modulemd_service_level_get_name (self), YAML_PLAIN_SCALAR_STYLE, &nested_error); if (!ret) { g_propagate_prefixed_error (error, g_steal_pointer (&nested_error), "Failed to emit service level name: "); return FALSE; } /* Start the mapping for additional attributes of this service level */ ret = mmd_emitter_start_mapping ( emitter, YAML_BLOCK_MAPPING_STYLE, &nested_error); if (!ret) { g_propagate_prefixed_error (error, g_steal_pointer (&nested_error), "Failed to start service level mapping: "); return FALSE; } /* Add service level attributes if available */ if (modulemd_service_level_get_eol (self) != NULL) { ret = mmd_emitter_scalar ( emitter, "eol", YAML_PLAIN_SCALAR_STYLE, &nested_error); if (!ret) { g_propagate_prefixed_error (error, g_steal_pointer (&nested_error), "Failed to emit EOL key: "); return FALSE; } eol_string = modulemd_service_level_get_eol_as_string (self); ret = mmd_emitter_scalar ( emitter, eol_string, YAML_PLAIN_SCALAR_STYLE, &nested_error); if (!ret) { g_propagate_prefixed_error (error, g_steal_pointer (&nested_error), "Failed to emit EOL string [%s]: ", eol_string); return FALSE; } } /* End the mapping */ ret = mmd_emitter_end_mapping (emitter, &nested_error); if (!ret) { g_propagate_prefixed_error (error, g_steal_pointer (&nested_error), "Failed to end service level mapping: "); return FALSE; } return TRUE; }