mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-04 23:31:19 +00:00
libnm-core/utils: add some special properties for the attributes
"no_value" indicates that the the attribute is a single word, not a key=value pair. If the type is BOOLEAN then the attribute is considered true, if it's a STRING then the key is used instead of a value. "consumes_rest" indicates that the particular key takes the unparseable tail of the string for a value. This allows parsing tc-style strings. Consider this filter: ,------ regular key/value pair ,-----'----. root handle 1234: matchall action simple foo bar baz | | `-----------.-----------' | | `- "", STRING, consumes_rest | `------------------- "kind", STRING, no_value `-------------------------------------- "root', BOOLEAN, no_value
This commit is contained in:
parent
48a619e62b
commit
47b1dc3828
|
@ -16,7 +16,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2007 - 2014 Red Hat, Inc.
|
||||
* Copyright 2007 - 2017 Red Hat, Inc.
|
||||
* Copyright 2007 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
@ -1238,7 +1238,7 @@ nm_ip_route_set_attribute (NMIPRoute *route, const char *name, GVariant *value)
|
|||
}
|
||||
|
||||
#define ATTR_SPEC_PTR(name, type, v4, v6, str_type) \
|
||||
&(NMVariantAttributeSpec) { name, type, v4, v6, str_type }
|
||||
&(NMVariantAttributeSpec) { name, type, v4, v6, FALSE, FALSE, str_type }
|
||||
|
||||
static const NMVariantAttributeSpec * const ip_route_attribute_spec[] = {
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_TABLE, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2005 - 2014 Red Hat, Inc.
|
||||
* Copyright 2005 - 2017 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_UTILS_PRIVATE_H__
|
||||
|
@ -33,6 +33,8 @@ struct _NMVariantAttributeSpec {
|
|||
const GVariantType *type;
|
||||
bool v4:1;
|
||||
bool v6:1;
|
||||
bool no_value:1;
|
||||
bool consumes_rest:1;
|
||||
char str_type;
|
||||
};
|
||||
|
||||
|
|
|
@ -5438,22 +5438,16 @@ nm_utils_parse_variant_attributes (const char *string,
|
|||
break;
|
||||
}
|
||||
|
||||
if (*sep != key_value_separator) {
|
||||
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
|
||||
_("missing key-value separator '%c'"), key_value_separator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The attribute and key/value separators are the same. Look for the next one. */
|
||||
if (ptr == sep)
|
||||
goto next;
|
||||
|
||||
name = attribute_unescape (start, sep);
|
||||
value = attribute_unescape (sep + 1, ptr);
|
||||
|
||||
for (s = spec; *s; s++) {
|
||||
if (g_hash_table_contains (ht, (*s)->name))
|
||||
continue;
|
||||
if (nm_streq (name, (*s)->name))
|
||||
break;
|
||||
if ( (*s)->no_value
|
||||
&& g_variant_type_equal ((*s)->type, G_VARIANT_TYPE_STRING))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!*s) {
|
||||
|
@ -5466,12 +5460,33 @@ nm_utils_parse_variant_attributes (const char *string,
|
|||
}
|
||||
}
|
||||
|
||||
if ((*s)->no_value) {
|
||||
if ((*s)->consumes_rest) {
|
||||
value = g_strdup (start);
|
||||
ptr = strchr (start, '\0');
|
||||
} else {
|
||||
value = g_steal_pointer (&name);
|
||||
}
|
||||
} else {
|
||||
if (*sep != key_value_separator) {
|
||||
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
|
||||
_("missing key-value separator '%c' after '%s'"), key_value_separator, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The attribute and key/value separators are the same. Look for the next one. */
|
||||
if (ptr == sep)
|
||||
goto next;
|
||||
|
||||
value = attribute_unescape (sep + 1, ptr);
|
||||
}
|
||||
|
||||
if (g_variant_type_equal ((*s)->type, G_VARIANT_TYPE_UINT32)) {
|
||||
gint64 num = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, -1);
|
||||
|
||||
if (num == -1) {
|
||||
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
|
||||
_("invalid uint32 value '%s' for attribute '%s'"), value, name);
|
||||
_("invalid uint32 value '%s' for attribute '%s'"), value, (*s)->name);
|
||||
return NULL;
|
||||
}
|
||||
variant = g_variant_new_uint32 (num);
|
||||
|
@ -5480,17 +5495,17 @@ nm_utils_parse_variant_attributes (const char *string,
|
|||
|
||||
if (num == -1) {
|
||||
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
|
||||
_("invalid uint8 value '%s' for attribute '%s'"), value, name);
|
||||
_("invalid uint8 value '%s' for attribute '%s'"), value, (*s)->name);
|
||||
return NULL;
|
||||
}
|
||||
variant = g_variant_new_byte ((guchar) num);
|
||||
} else if (g_variant_type_equal ((*s)->type, G_VARIANT_TYPE_BOOLEAN)) {
|
||||
int b;
|
||||
|
||||
b = _nm_utils_ascii_str_to_bool (value, -1);
|
||||
b = (*s)->no_value ? TRUE :_nm_utils_ascii_str_to_bool (value, -1);
|
||||
if (b == -1) {
|
||||
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
|
||||
_("invalid boolean value '%s' for attribute '%s'"), value, name);
|
||||
_("invalid boolean value '%s' for attribute '%s'"), value, (*s)->name);
|
||||
return NULL;
|
||||
}
|
||||
variant = g_variant_new_boolean (b);
|
||||
|
@ -5498,12 +5513,12 @@ nm_utils_parse_variant_attributes (const char *string,
|
|||
variant = g_variant_new_take_string (g_steal_pointer (&value));
|
||||
} else {
|
||||
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
|
||||
_("unsupported attribute '%s' of type '%s'"), name,
|
||||
_("unsupported attribute '%s' of type '%s'"), (*s)->name,
|
||||
(char *) (*s)->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_hash_table_insert (ht, g_steal_pointer (&name), variant);
|
||||
g_hash_table_insert (ht, g_strdup ((*s)->name), variant);
|
||||
start = NULL;
|
||||
}
|
||||
next:
|
||||
|
|
Loading…
Reference in a new issue