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