libnm: handler numeric values more gracefully in nm_utils_enum_from_str()

nm_utils_enum_to_str() may also output numeric values if there is no
corresponding "nick" for the enum/flag value.

For enums the value is in decimal and for flags the value is hexadecimal
(with a "0x" prefix).

The same was already supported by nm_utils_enum_from_str() when reading
the value. However, previously, reading a flag would only support hex
numbers and reading a enum would only support decimal numbers.

Extend that, to allow passing numbers in any base. For nm_utils_enum_to_str()
also make sure to never output nicks that may be misinterpreted as
numbers.
This commit is contained in:
Thomas Haller 2017-03-29 18:05:00 +02:00
parent 112f09cf4b
commit e26a81cf35

View file

@ -4260,12 +4260,20 @@ _is_hex_string (const char *str)
&& NM_STRCHAR_ALL (&str[2], ch, g_ascii_isxdigit (ch));
}
static gboolean
_is_dec_string (const char *str)
{
return str[0]
&& NM_STRCHAR_ALL (&str[0], ch, g_ascii_isdigit (ch));
}
static gboolean
_enum_is_valid_enum_nick (const char *str)
{
return str[0]
&& !NM_STRCHAR_ANY (str, ch, g_ascii_isspace (ch))
&& !NM_STRCHAR_ALL (str, ch, g_ascii_isdigit (ch));
&& !_is_dec_string (str)
&& !_is_hex_string (str);
}
static gboolean
@ -4273,6 +4281,7 @@ _enum_is_valid_flags_nick (const char *str)
{
return str[0]
&& !NM_STRCHAR_ANY (str, ch, IS_FLAGS_SEPARATOR (ch))
&& !_is_dec_string (str)
&& !_is_hex_string (str);
}
@ -4390,8 +4399,14 @@ nm_utils_enum_from_str (GType type, const char *str,
GEnumValue *enum_value;
if (s[0]) {
if (NM_STRCHAR_ALL (s, ch, g_ascii_isdigit (ch))) {
v64 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXINT, -1);
if (_is_hex_string (s)) {
v64 = _nm_utils_ascii_str_to_int64 (s, 16, 0, G_MAXUINT, -1);
if (v64 != -1) {
value = (int) v64;
ret = TRUE;
}
} else if (_is_dec_string (s)) {
v64 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXUINT, -1);
if (v64 != -1) {
value = (int) v64;
ret = TRUE;
@ -4428,6 +4443,13 @@ nm_utils_enum_from_str (GType type, const char *str,
break;
}
uvalue |= (unsigned) v64;
} else if (_is_dec_string (s)) {
v64 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXUINT, -1);
if (v64 == -1) {
ret = FALSE;
break;
}
uvalue |= (unsigned) v64;
} else {
flags_value = g_flags_get_value_by_nick (G_FLAGS_CLASS (class), s);
if (!flags_value) {