From eb0cfefe52eff57d5a803dd8ace92647dcabf4df Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 19 Mar 2019 19:29:23 +0100 Subject: [PATCH] cli: allow resetting all values via set_fcn() property handler Previously, set_fcn() could only append values. Now, pass on the modifier so that it may append, set all, or reset the default. These operations are strongly related and should be handled by the same set_fcn() function. --- clients/cli/settings.c | 52 +----- clients/common/nm-meta-setting-desc.c | 257 +++++++++++++++----------- clients/common/nm-meta-setting-desc.h | 1 + 3 files changed, 159 insertions(+), 151 deletions(-) diff --git a/clients/cli/settings.c b/clients/cli/settings.c index 837431da0..8a1279bcb 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -517,12 +517,8 @@ nmc_setting_set_property (NMClient *client, const char *value, GError **error) { - nm_auto_unset_gvalue GValue gvalue_old = G_VALUE_INIT; const NMMetaPropertyInfo *property_info; gs_free char *value_to_free = NULL; - /* FIXME: any mentioning of GParamSpec only works for GObject base properties. That is - * wrong, the property meta-data must handle all properties. */ - GParamSpec *param_spec = NULL; g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); @@ -562,47 +558,13 @@ nmc_setting_set_property (NMClient *client, } } - if ( modifier == '\0' - || value == NULL) { - /* FIXME: reset the value. By default, "set_fcn" adds values (don't ask). */ - - param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), prop); - if (param_spec) { - nm_auto_unset_gvalue GValue gvalue = G_VALUE_INIT; - - /* get the current value, to restore it on failure below. */ - g_value_init (&gvalue_old, G_PARAM_SPEC_VALUE_TYPE (param_spec)); - g_object_get_property (G_OBJECT (setting), prop, &gvalue_old); - } - - if (!property_info->property_type->set_fcn (property_info, - nmc_meta_environment, - nmc_meta_environment_arg, - setting, - NULL, - error)) { - return FALSE; - } - } - - if (value) { - if (!property_info->property_type->set_fcn (property_info, - nmc_meta_environment, - nmc_meta_environment_arg, - setting, - value, - error)) { - if ( modifier == '\0' - && param_spec) { - /* restore the previous value. */ - g_object_set_property (G_OBJECT (setting), prop, &gvalue_old); - } - - return FALSE; - } - } - - return TRUE; + return property_info->property_type->set_fcn (property_info, + nmc_meta_environment, + nmc_meta_environment_arg, + setting, + modifier, + value, + error); out_fail_read_only: nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, _("the property can't be changed")); diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index b312e5c8a..72da617cd 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -626,7 +626,7 @@ _env_warn_fcn (const NMMetaEnvironment *environment, const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, NMMetaAccessorGetOutFlags *out_flags, gboolean *out_is_default, gpointer *out_to_free #define ARGS_SET_FCN \ - const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, GError **error + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, char modifier, const char *value, GError **error #define ARGS_REMOVE_FCN \ const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, GError **error @@ -640,8 +640,23 @@ _env_warn_fcn (const NMMetaEnvironment *environment, #define ARGS_SETTING_INIT_FCN \ const NMMetaSettingInfoEditor *setting_info, NMSetting *setting, NMMetaAccessorSettingInitType init_type -#define _SET_FCN_DO_RESET_DEFAULT(value) \ - ((value) == NULL) +static gboolean +_SET_FCN_DO_RESET_DEFAULT (char modifier, const char *value) +{ + nm_assert (NM_IN_SET (modifier, '\0', '+')); + nm_assert (value || modifier == '\0'); + + return value == NULL; +} + +static gboolean +_SET_FCN_DO_SET_ALL (char modifier, const char *value) +{ + nm_assert (NM_IN_SET (modifier, '\0', '+')); + nm_assert (value); + + return modifier == '\0'; +} #define RETURN_UNSUPPORTED_GET_TYPE() \ G_STMT_START { \ @@ -1031,7 +1046,7 @@ _set_fcn_gobject_string (ARGS_SET_FCN) { gs_free char *to_free = NULL; - if (_SET_FCN_DO_RESET_DEFAULT (value)) + if (_SET_FCN_DO_RESET_DEFAULT (modifier, value)) return _gobject_property_reset_default (setting, property_info->property_name); if (property_info->property_typ_data) { @@ -1056,7 +1071,7 @@ _set_fcn_gobject_bool (ARGS_SET_FCN) { gboolean val_bool; - if (_SET_FCN_DO_RESET_DEFAULT (value)) + if (_SET_FCN_DO_RESET_DEFAULT (modifier, value)) return _gobject_property_reset_default (setting, property_info->property_name); if (!nmc_string_to_bool (value, &val_bool, error)) @@ -1080,7 +1095,7 @@ _set_fcn_gobject_int (ARGS_SET_FCN) guint base = 10; const NMMetaUtilsIntValueInfo *value_infos; - if (_SET_FCN_DO_RESET_DEFAULT (value)) + if (_SET_FCN_DO_RESET_DEFAULT (modifier, value)) return _gobject_property_reset_default (setting, property_info->property_name); pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), property_info->property_name); @@ -1219,7 +1234,7 @@ _set_fcn_gobject_mtu (ARGS_SET_FCN) const GParamSpec *pspec; gint64 v; - if (_SET_FCN_DO_RESET_DEFAULT (value)) + if (_SET_FCN_DO_RESET_DEFAULT (modifier, value)) return _gobject_property_reset_default (setting, property_info->property_name); if (nm_streq (value, "auto")) @@ -1260,7 +1275,7 @@ _set_fcn_gobject_mac (ARGS_SET_FCN) NMMetaPropertyTypeMacMode mode; gboolean valid; - if (_SET_FCN_DO_RESET_DEFAULT (value)) + if (_SET_FCN_DO_RESET_DEFAULT (modifier, value)) return _gobject_property_reset_default (setting, property_info->property_name); if (property_info->property_typ_data) @@ -1298,7 +1313,7 @@ _set_fcn_gobject_enum (ARGS_SET_FCN) gboolean is_flags; int v; - if (_SET_FCN_DO_RESET_DEFAULT (value)) + if (_SET_FCN_DO_RESET_DEFAULT (modifier, value)) return _gobject_property_reset_default (setting, property_info->property_name); if (property_info->property_typ_data) { @@ -1665,9 +1680,9 @@ static gboolean _set_fcn_multilist (ARGS_SET_FCN) { gs_free const char **strv = NULL; - gsize i, j; + gsize i, nstrv; - if (_SET_FCN_DO_RESET_DEFAULT (value)) + if (_SET_FCN_DO_RESET_DEFAULT (modifier, value)) return _gobject_property_reset_default (setting, property_info->property_name); if (property_info->property_typ_data->subtype.multilist.with_escaped_spaces) @@ -1675,9 +1690,8 @@ _set_fcn_multilist (ARGS_SET_FCN) else strv = nm_utils_strsplit_set (value, " \t,", FALSE); + nstrv = 0; if (strv) { - - j = 0; for (i = 0; strv[i]; i++) { const char *item = strv[i]; @@ -1694,16 +1708,18 @@ _set_fcn_multilist (ARGS_SET_FCN) if (!item) return FALSE; - strv[j++] = item; + strv[nstrv++] = item; } - strv[j] = NULL; + } - for (i = 0; strv[i]; i++) { - if (property_info->property_typ_data->subtype.multilist.add2_fcn) - property_info->property_typ_data->subtype.multilist.add2_fcn (setting, strv[i]); - else - property_info->property_typ_data->subtype.multilist.add_fcn (setting, strv[i]); - } + if (_SET_FCN_DO_SET_ALL (modifier, value)) + _gobject_property_reset_default (setting, property_info->property_name); + + for (i = 0; i < nstrv; i++) { + if (property_info->property_typ_data->subtype.multilist.add2_fcn) + property_info->property_typ_data->subtype.multilist.add2_fcn (setting, strv[i]); + else + property_info->property_typ_data->subtype.multilist.add_fcn (setting, strv[i]); } return TRUE; } @@ -1748,78 +1764,93 @@ static gboolean _set_fcn_optionlist (ARGS_SET_FCN) { gs_free const char **strv = NULL; - const char **iter; + gs_free const char **strv_val = NULL; + gsize i, nstrv; nm_assert (!error || !*error); - if (_SET_FCN_DO_RESET_DEFAULT (value)) + if (_SET_FCN_DO_RESET_DEFAULT (modifier, value)) return _gobject_property_reset_default (setting, property_info->property_name); + nstrv = 0; strv = nm_utils_strsplit_set (value, ",", FALSE); - for (iter = strv; iter && *iter; iter++) { - const char *opt_name; - const char *opt_value; - char *left; - char *right; + if (strv) { + strv_val = g_new (const char *, NM_PTRARRAY_LEN (strv)); + for (i = 0; strv[i]; i++) { + const char *opt_name; + const char *opt_value; + char *left; + char *right; - left = (char *) nm_str_skip_leading_spaces (*iter); + left = (char *) nm_str_skip_leading_spaces (strv[i]); - /* FIXME: support backslash escaping for the option list. */ - right = strchr (left, '='); + /* FIXME: support backslash escaping for the option list. */ + right = strchr (left, '='); - if ( !right - || left == right) { - nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("'%s' is not valid; use