diff options
author | Thomas Haller <thaller@redhat.com> | 2015-03-13 16:35:23 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2015-03-20 13:19:20 +0100 |
commit | 58f08c8c9ce3602f31d2fdfaa2cc9ecca4713532 (patch) | |
tree | eedd9bedb25046b5b7d94c56ff8e644fe9e7b979 | |
parent | e50fbe466b01823e97540d91a1452d994cfcb11e (diff) | |
download | NetworkManager-58f08c8c9ce3602f31d2fdfaa2cc9ecca4713532.tar.gz |
libnm: sort properties for nm_setting_enumerate_values()
The sort order of nm_setting_enumerate_values() affects the
order in which keyfile writer serializes the properties.
Have a defined, stable sort order by sorting the properties
by name (with prefering id,uuid,type for NMSettingConnection).
-rw-r--r-- | libnm-core/nm-setting.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index 2730742654..a292bfca6e 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -1314,6 +1314,33 @@ nm_setting_diff (NMSetting *a, return !(*results); } +#define CMP_AND_RETURN(n_a, n_b, name) \ + G_STMT_START { \ + gboolean _is = (strcmp (n_a, ""name) == 0); \ + \ + if (_is || (strcmp (n_b, ""name) == 0)) \ + return _is ? -1 : 1; \ + } G_STMT_END; + +static int +_enumerate_values_sort (GParamSpec **p_a, GParamSpec **p_b, GType *p_type) +{ + const char *n_a = (*p_a)->name; + const char *n_b = (*p_b)->name; + int c = strcmp (n_a, n_b); + + if (c) { + if (*p_type == NM_TYPE_SETTING_CONNECTION) { + /* for [connection], report first id, uuid, type in that order. */ + CMP_AND_RETURN (n_a, n_b, NM_SETTING_CONNECTION_ID); + CMP_AND_RETURN (n_a, n_b, NM_SETTING_CONNECTION_UUID); + CMP_AND_RETURN (n_a, n_b, NM_SETTING_CONNECTION_TYPE); + } + } + return c; +} +#undef CMP_AND_RETURN + /** * nm_setting_enumerate_values: * @setting: the #NMSetting @@ -1331,11 +1358,19 @@ nm_setting_enumerate_values (NMSetting *setting, GParamSpec **property_specs; guint n_property_specs; int i; + GType type; g_return_if_fail (NM_IS_SETTING (setting)); g_return_if_fail (func != NULL); property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + + /* sort the properties. This has an effect on the order in which keyfile + * prints them. */ + type = G_OBJECT_TYPE (setting); + g_qsort_with_data (property_specs, n_property_specs, sizeof (gpointer), + (GCompareDataFunc) _enumerate_values_sort, &type); + for (i = 0; i < n_property_specs; i++) { GParamSpec *prop_spec = property_specs[i]; GValue value = G_VALUE_INIT; |