From ba956bd499c1798e57fdfafa9d87710cf3704e37 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 12 Apr 2019 12:00:48 +0200 Subject: [PATCH] cli: add new style for tokenizing/concatenating list options in nmcli nmcli supports list options (optlist and multilist properties). These commonly are individual items, concatenated by a delimiter. It should be generally possibly to express every value. That means, we need some for of escaping mechanism for delimiters. Currently this is all inconsistent or no escaping is supported. I intend to fix that (which will be a change in behavior). For now, just add yet another style of tokenzing/concatenating list items in nmcli. This is the style to replace all other styles. --- clients/common/nm-meta-setting-desc.c | 28 ++++++++++++++++++++------- clients/common/nm-meta-setting-desc.h | 2 ++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 83959ec653..aa2bcd4f6f 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -167,12 +167,16 @@ _value_str_as_index_list (const char *value, gsize *out_len) #define MULTILIST_WITH_ESCAPE_CHARS NM_ASCII_SPACES"," +#define ESCAPED_TOKENS_DELIMTER ',' +#define ESCAPED_TOKENS_DELIMTERS "," + typedef enum { VALUE_STRSPLIT_MODE_STRIPPED, VALUE_STRSPLIT_MODE_OBJLIST, VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE, VALUE_STRSPLIT_MODE_MULTILIST, VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE, + VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, } ValueStrsplitMode; static const char * @@ -211,6 +215,10 @@ _value_strsplit (const char *value, case VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE: strv = nm_utils_strsplit_set_full (value, MULTILIST_WITH_ESCAPE_CHARS, NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING); break; + case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS: + strv = nm_utils_escaped_tokens_split (value, ESCAPED_TOKENS_DELIMTERS); + NM_SET_OUT (out_len, NM_PTRARRAY_LEN (strv)); + return g_steal_pointer (&strv); default: nm_assert_not_reached (); break; @@ -1882,9 +1890,11 @@ _set_fcn_multilist (ARGS_SET_FCN) } strv = _value_strsplit (value, - property_info->property_typ_data->subtype.multilist.strsplit_with_escape - ? VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE - : VALUE_STRSPLIT_MODE_MULTILIST, + property_info->property_typ_data->subtype.multilist.strsplit_escaped_tokens + ? VALUE_STRSPLIT_MODE_ESCAPED_TOKENS + : ( property_info->property_typ_data->subtype.multilist.strsplit_with_escape + ? VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE + : VALUE_STRSPLIT_MODE_OBJLIST), &nstrv); j = 0; @@ -3061,8 +3071,10 @@ _get_fcn_objlist (ARGS_GET_FCN) if ( get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY && property_info->property_typ_data->subtype.objlist.delimit_pretty_with_semicolon) g_string_append (str, "; "); - else + else { + G_STATIC_ASSERT_EXPR (ESCAPED_TOKENS_DELIMTER == ','); g_string_append (str, ", "); + } } start_offset = str->len; @@ -3271,9 +3283,11 @@ _set_fcn_objlist (ARGS_SET_FCN) } strv = _value_strsplit (value, - property_info->property_typ_data->subtype.objlist.strsplit_with_escape - ? VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE - : VALUE_STRSPLIT_MODE_OBJLIST, + property_info->property_typ_data->subtype.objlist.strsplit_escaped_tokens + ? VALUE_STRSPLIT_MODE_ESCAPED_TOKENS + : ( property_info->property_typ_data->subtype.objlist.strsplit_with_escape + ? VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE + : VALUE_STRSPLIT_MODE_OBJLIST), &nstrv); if (_SET_FCN_DO_SET_ALL (modifier, value)) { diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 15c0e81eb0..44a6827b7e 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -281,6 +281,7 @@ struct _NMMetaPropertyTypData { void (*remove_by_idx_fcn_s) (NMSetting *setting, int idx); gboolean (*remove_by_value_fcn) (NMSetting *setting, const char *item); bool strsplit_with_escape:1; + bool strsplit_escaped_tokens:1; } multilist; struct { guint (*get_num_fcn) (NMSetting *setting); @@ -297,6 +298,7 @@ struct _NMMetaPropertyTypData { void (*remove_by_idx_fcn_s) (NMSetting *setting, int idx); bool delimit_pretty_with_semicolon:1; bool strsplit_with_escape:1; + bool strsplit_escaped_tokens:1; } objlist; struct { gboolean (*set_fcn) (NMSetting *setting,