mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-06 10:18:03 +02:00
cli: support list of indexes for removing objlist property
$ nmcli connection modify "$PROFILE" -ipv4.addresses 1,3 Already before, nmcli would support removing items by index. But only one number was supported. - indexes are zero based (as before). - duplicate indexes or indexes out of bounds are silently ignored. Maybe certain properties should not support removal by index.
This commit is contained in:
parent
28f0153350
commit
70bad5c74d
1 changed files with 116 additions and 14 deletions
|
|
@ -76,6 +76,95 @@ _gtype_property_get_gtype (GType gtype, const char *property_name)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
_int64_cmp_desc (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer user_data)
|
||||
{
|
||||
NM_CMP_DIRECT (*((const gint64 *) b), *((const gint64 *) a));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint64 *
|
||||
_value_str_as_index_list (const char *value, gsize *out_len)
|
||||
{
|
||||
gs_free char *str_clone_free = NULL;
|
||||
gboolean str_cloned = FALSE;
|
||||
char *str;
|
||||
gsize i, j;
|
||||
gsize n_alloc;
|
||||
gsize len;
|
||||
gs_free gint64 *arr = NULL;
|
||||
|
||||
*out_len = 0;
|
||||
|
||||
if (!value)
|
||||
return NULL;
|
||||
|
||||
str = (char *) value;
|
||||
n_alloc = 0;
|
||||
len = 0;
|
||||
while (TRUE) {
|
||||
gint64 i64;
|
||||
const char *s;
|
||||
gsize good;
|
||||
|
||||
good = strcspn (str, ","NM_ASCII_SPACES);
|
||||
if (good == 0) {
|
||||
if (str[0] == '\0')
|
||||
break;
|
||||
str++;
|
||||
continue;
|
||||
}
|
||||
if (str[good] == '\0') {
|
||||
s = str;
|
||||
str += good;
|
||||
} else {
|
||||
if (!str_cloned) {
|
||||
str_cloned = TRUE;
|
||||
str = nm_strndup_a (200, str, strlen (str), &str_clone_free);
|
||||
}
|
||||
s = str;
|
||||
str[good] = '\0';
|
||||
str += good + 1;
|
||||
}
|
||||
|
||||
i64 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXINT64, -1);
|
||||
if (i64 == -1)
|
||||
return NULL;
|
||||
|
||||
if (len >= n_alloc) {
|
||||
if (n_alloc > 0) {
|
||||
n_alloc = n_alloc * 2;
|
||||
arr = g_realloc (arr, n_alloc * sizeof (gint64));
|
||||
} else {
|
||||
n_alloc = 4;
|
||||
arr = g_new (gint64, n_alloc);
|
||||
}
|
||||
}
|
||||
arr[len++] = i64;
|
||||
}
|
||||
|
||||
if (len > 1) {
|
||||
/* sort the list of indexes descendingly, and drop duplicates. */
|
||||
g_qsort_with_data (arr,
|
||||
len,
|
||||
sizeof (gint64),
|
||||
_int64_cmp_desc,
|
||||
NULL);
|
||||
j = 1;
|
||||
for (i = 1; i < len; i++) {
|
||||
nm_assert (arr[i - 1] >= arr[i]);
|
||||
if (arr[i - 1] > arr[i])
|
||||
arr[j++] = arr[i];
|
||||
}
|
||||
len = j;
|
||||
}
|
||||
|
||||
*out_len = len;
|
||||
return g_steal_pointer (&arr);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
VALUE_STRSPLIT_MODE_STRIPPED,
|
||||
VALUE_STRSPLIT_MODE_OBJLIST,
|
||||
|
|
@ -1738,20 +1827,26 @@ _set_fcn_multilist (ARGS_SET_FCN)
|
|||
if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (property_info, modifier, value))
|
||||
return _gobject_property_reset_default (setting, property_info->property_name);
|
||||
|
||||
if (_SET_FCN_DO_REMOVE (modifier, value)) {
|
||||
gint64 idx;
|
||||
if ( _SET_FCN_DO_REMOVE (modifier, value)
|
||||
&& ( property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32
|
||||
|| property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s
|
||||
|| property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u)) {
|
||||
gs_free gint64 *indexes = NULL;
|
||||
|
||||
/* FIXME: support a list of numbers. */
|
||||
idx = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT64, -1);
|
||||
if (idx != -1) {
|
||||
guint num;
|
||||
indexes = _value_str_as_index_list (value, &nstrv);
|
||||
if (indexes) {
|
||||
gint64 num;
|
||||
|
||||
if (property_info->property_typ_data->subtype.multilist.get_num_fcn_u32)
|
||||
num = property_info->property_typ_data->subtype.multilist.get_num_fcn_u32 (setting);
|
||||
else
|
||||
num = property_info->property_typ_data->subtype.multilist.get_num_fcn_u (setting);
|
||||
for (i = 0; i < nstrv; i++) {
|
||||
gint64 idx = indexes[i];
|
||||
|
||||
if (idx >= num)
|
||||
continue;
|
||||
|
||||
if (idx < (gint64) num) {
|
||||
if (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32)
|
||||
property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32 (setting, idx);
|
||||
else if (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s)
|
||||
|
|
@ -3098,15 +3193,21 @@ _set_fcn_objlist (ARGS_SET_FCN)
|
|||
return _gobject_property_reset_default (setting, property_info->property_name);
|
||||
}
|
||||
|
||||
if (_SET_FCN_DO_REMOVE (modifier, value)) {
|
||||
gint64 idx;
|
||||
gint64 num;
|
||||
if ( _SET_FCN_DO_REMOVE (modifier, value)
|
||||
&& ( property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_u
|
||||
|| property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_s)) {
|
||||
gs_free gint64 *indexes = NULL;
|
||||
|
||||
indexes = _value_str_as_index_list (value, &nstrv);
|
||||
if (indexes) {
|
||||
gint64 num;
|
||||
|
||||
/* FIXME: support list of values. */
|
||||
idx = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT64, -1);
|
||||
if (idx != -1) {
|
||||
num = property_info->property_typ_data->subtype.objlist.get_num_fcn (setting);
|
||||
if (idx < num) {
|
||||
for (i = 0; i < nstrv; i++) {
|
||||
gint64 idx = indexes[i];
|
||||
|
||||
if (idx >= num)
|
||||
continue;
|
||||
if (property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_u)
|
||||
property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_u (setting, idx);
|
||||
else
|
||||
|
|
@ -6011,6 +6112,7 @@ static const NMMetaPropertyInfo *const property_infos_SRIOV[] = {
|
|||
.clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingSriov, nm_setting_sriov_clear_vfs),
|
||||
.obj_to_str_fcn = _objlist_obj_to_str_fcn_sriov_vfs,
|
||||
.set_fcn = _objlist_set_fcn_sriov_vfs,
|
||||
/* FIXME: removing by index is ambigous and should maybe be prevented. */
|
||||
.remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingSriov, nm_setting_sriov_remove_vf),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue