mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-01 17:40:14 +01:00
libnm/keyfile: sort keyfile entries and nm_connection_for_each_setting_value()
Fix the order for keyfile writer. It is nicer to have a fixed, sensible
order with [connection] first.
Do this by sorting the order in nm_connection_for_each_setting_value()
and nm_setting_enumerate_values().
This is a partial backport of merge 89c88f2480
https://mail.gnome.org/archives/networkmanager-list/2015-March/msg00050.html
This commit is contained in:
commit
9fa5e9af58
3 changed files with 90 additions and 13 deletions
|
|
@ -32,6 +32,7 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include "nm-utils.h"
|
||||
#include "nm-utils-internal.h"
|
||||
#include "nm-glib-compat.h"
|
||||
#include "gsystem-local-alloc.h"
|
||||
|
||||
|
|
@ -84,13 +85,13 @@ nmtst_initialized (void)
|
|||
return !!__nmtst_internal.rand0;
|
||||
}
|
||||
|
||||
#define __NMTST_LOG(cmd, fmt, ...) \
|
||||
#define __NMTST_LOG(cmd, ...) \
|
||||
G_STMT_START { \
|
||||
g_assert (nmtst_initialized ()); \
|
||||
if (!__nmtst_internal.assert_logging || __nmtst_internal.no_expect_message) { \
|
||||
cmd (fmt, __VA_ARGS__); \
|
||||
cmd (__VA_ARGS__); \
|
||||
} else { \
|
||||
printf (fmt "\n", __VA_ARGS__); \
|
||||
printf (_NM_UTILS_MACRO_FIRST (__VA_ARGS__) "\n" _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
||||
|
|
@ -836,18 +837,21 @@ nmtst_assert_connection_equals (NMConnection *a, gboolean normalize_a, NMConnect
|
|||
b = b2 = nmtst_connection_duplicate_and_normalize (b);
|
||||
|
||||
compare = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_settings);
|
||||
if (!compare && out_settings) {
|
||||
if (!compare || out_settings) {
|
||||
const char *name, *pname;
|
||||
GHashTable *setting;
|
||||
GHashTableIter iter, iter2;
|
||||
|
||||
g_hash_table_iter_init (&iter, out_settings);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &setting)) {
|
||||
__NMTST_LOG (g_message, ">>> differences in setting '%s':", name);
|
||||
__NMTST_LOG (g_message, ">>> ASSERTION nmtst_assert_connection_equals() fails");
|
||||
if (out_settings) {
|
||||
g_hash_table_iter_init (&iter, out_settings);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &setting)) {
|
||||
__NMTST_LOG (g_message, ">>> differences in setting '%s':", name);
|
||||
|
||||
g_hash_table_iter_init (&iter2, out_settings);
|
||||
while (g_hash_table_iter_next (&iter2, (gpointer *) &pname, NULL))
|
||||
__NMTST_LOG (g_message, ">>> differences in setting '%s.%s':", name, pname);
|
||||
g_hash_table_iter_init (&iter2, setting);
|
||||
while (g_hash_table_iter_next (&iter2, (gpointer *) &pname, NULL))
|
||||
__NMTST_LOG (g_message, ">>> differences in setting '%s.%s'", name, pname);
|
||||
}
|
||||
}
|
||||
}
|
||||
g_assert (compare);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "nm-utils.h"
|
||||
#include "nm-setting-private.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "gsystem-local-alloc.h"
|
||||
|
||||
/**
|
||||
* SECTION:nm-connection
|
||||
|
|
@ -1306,6 +1307,19 @@ nm_connection_is_type (NMConnection *connection, const char *type)
|
|||
return (g_strcmp0 (type2, type) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
_for_each_sort (NMSetting **p_a, NMSetting **p_b, void *unused)
|
||||
{
|
||||
NMSetting *a = *p_a;
|
||||
NMSetting *b = *p_b;
|
||||
int c;
|
||||
|
||||
c = _nm_setting_compare_priority (a, b);
|
||||
if (c != 0)
|
||||
return c;
|
||||
return strcmp (nm_setting_get_name (a), nm_setting_get_name (b));
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_connection_for_each_setting_value:
|
||||
* @connection: the #NMConnection
|
||||
|
|
@ -1320,15 +1334,39 @@ nm_connection_for_each_setting_value (NMConnection *connection,
|
|||
NMSettingValueIterFn func,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMConnectionPrivate *priv;
|
||||
gs_free NMSetting **arr_free = NULL;
|
||||
NMSetting *arr_temp[20], **arr;
|
||||
GHashTableIter iter;
|
||||
gpointer value;
|
||||
guint i, size;
|
||||
|
||||
g_return_if_fail (NM_IS_CONNECTION (connection));
|
||||
g_return_if_fail (func != NULL);
|
||||
|
||||
g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
nm_setting_enumerate_values (NM_SETTING (value), func, user_data);
|
||||
priv = NM_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
size = g_hash_table_size (priv->settings);
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
if (size > G_N_ELEMENTS (arr_temp))
|
||||
arr = arr_free = g_new (NMSetting *, size);
|
||||
else
|
||||
arr = arr_temp;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->settings);
|
||||
for (i = 0; g_hash_table_iter_next (&iter, NULL, &value); i++)
|
||||
arr[i] = NM_SETTING (value);
|
||||
g_assert (i == size);
|
||||
|
||||
/* sort the settings. This has an effect on the order in which keyfile
|
||||
* prints them. */
|
||||
if (size > 1)
|
||||
g_qsort_with_data (arr, size, sizeof (NMSetting *), (GCompareDataFunc) _for_each_sort, NULL);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
nm_setting_enumerate_values (arr[i], func, user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue