mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-30 20:10:10 +01:00
libnm-core: add enum conversion utilities
Add functions nm_utils_enum_to_str() and nm_utils_enum_from_str()
which can be used to perform conversions between enum values and
strings, passing the GType automatically generated for every enum by
glib-mkenums.
(cherry picked from commit 8be9814793)
This commit is contained in:
parent
3b3f5fa755
commit
f4ce6760e0
7 changed files with 265 additions and 2 deletions
|
|
@ -53,7 +53,8 @@ IGNORE_HFILES= \
|
|||
nm-setting-private.h \
|
||||
nm-types.h \
|
||||
nm-utils-private.h \
|
||||
nm-vpn-plugin-old.h
|
||||
nm-vpn-plugin-old.h \
|
||||
nm-core-tests-enum-types.h
|
||||
|
||||
# Images to copy into HTML directory.
|
||||
HTML_IMAGES = libnm.png
|
||||
|
|
|
|||
|
|
@ -3639,3 +3639,122 @@ _nm_dbus_error_has_name (GError *error,
|
|||
return has_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_enum_to_str
|
||||
* @type: the %GType of the enum
|
||||
* @value: the value to be translated
|
||||
*
|
||||
* Converts an enum value to its string representation. If the enum is a
|
||||
* %G_TYPE_FLAGS the function returns a comma-separated list of matching values.
|
||||
* If the enum is a %G_TYPE_ENUM and the given value is not valid the
|
||||
* function returns %NULL.
|
||||
*
|
||||
* Returns: a newly allocated string or %NULL
|
||||
*
|
||||
* Since: 1.0.6
|
||||
*/
|
||||
char *nm_utils_enum_to_str (GType type, int value)
|
||||
{
|
||||
GTypeClass *class;
|
||||
char *ret;
|
||||
|
||||
class = g_type_class_ref (type);
|
||||
|
||||
if (G_IS_ENUM_CLASS (class)) {
|
||||
GEnumValue *enum_value;
|
||||
|
||||
enum_value = g_enum_get_value (G_ENUM_CLASS (class), value);
|
||||
ret = enum_value ? strdup (enum_value->value_nick) : NULL;
|
||||
} else if (G_IS_FLAGS_CLASS (class)) {
|
||||
GFlagsValue *flags_value;
|
||||
GString *str = g_string_new ("");
|
||||
gboolean first = TRUE;
|
||||
|
||||
while (value) {
|
||||
flags_value = g_flags_get_first_value (G_FLAGS_CLASS (class), value);
|
||||
if (!flags_value)
|
||||
break;
|
||||
|
||||
if (!first)
|
||||
g_string_append_c (str, ',');
|
||||
g_string_append (str, flags_value->value_nick);
|
||||
|
||||
value &= ~flags_value->value;
|
||||
first = FALSE;
|
||||
}
|
||||
ret = g_string_free (str, FALSE);
|
||||
} else
|
||||
g_return_if_reached ();
|
||||
|
||||
g_type_class_unref (class);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_enum_from_str
|
||||
* @type: the %GType of the enum
|
||||
* @str: the input string
|
||||
* @out_value: (out) (allow-none) the output value
|
||||
* @err_token: (out) (allow-none) location to store the first unrecognized token
|
||||
*
|
||||
* Converts a string to the matching enum value.
|
||||
*
|
||||
* If the enum is a %G_TYPE_FLAGS the function returns the logical OR of values
|
||||
* matching the comma-separated tokens in the string; if an unknown token is found
|
||||
* the function returns %FALSE and stores a pointer to a newly allocated string
|
||||
* containing the unrecognized token in @err_token.
|
||||
*
|
||||
* Returns: %TRUE if the conversion was successful, %FALSE otherwise
|
||||
*
|
||||
* Since: 1.0.6
|
||||
*/
|
||||
gboolean nm_utils_enum_from_str (GType type, const char *str,
|
||||
int *out_value, char **err_token)
|
||||
{
|
||||
GTypeClass *class;
|
||||
gboolean ret = FALSE;
|
||||
int value = 0;
|
||||
|
||||
g_return_val_if_fail (str, FALSE);
|
||||
class = g_type_class_ref (type);
|
||||
|
||||
if (G_IS_ENUM_CLASS (class)) {
|
||||
GEnumValue *enum_value;
|
||||
|
||||
enum_value = g_enum_get_value_by_nick (G_ENUM_CLASS (class), str);
|
||||
if (enum_value) {
|
||||
value = enum_value->value;
|
||||
ret = TRUE;
|
||||
}
|
||||
} else if (G_IS_FLAGS_CLASS (class)) {
|
||||
GFlagsValue *flags_value;
|
||||
gs_strfreev char **strv = NULL;
|
||||
int i;
|
||||
|
||||
strv = g_strsplit (str, ",", 0);
|
||||
for (i = 0; strv[i]; i++) {
|
||||
if (!strv[i][0])
|
||||
continue;
|
||||
|
||||
flags_value = g_flags_get_value_by_nick (G_FLAGS_CLASS (class), strv[i]);
|
||||
if (!flags_value)
|
||||
break;
|
||||
|
||||
value |= flags_value->value;
|
||||
}
|
||||
|
||||
if (strv[i]) {
|
||||
if (err_token)
|
||||
*err_token = strdup (strv[i]);
|
||||
value = 0;
|
||||
} else
|
||||
ret = TRUE;
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
|
||||
if (out_value)
|
||||
*out_value = value;
|
||||
|
||||
g_type_class_unref (class);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,6 +189,12 @@ gboolean nm_utils_ipaddr_valid (int family, const char *ip);
|
|||
|
||||
gboolean nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_type);
|
||||
|
||||
NM_AVAILABLE_IN_1_0_6
|
||||
char *nm_utils_enum_to_str (GType type, int value);
|
||||
|
||||
NM_AVAILABLE_IN_1_0_6
|
||||
gboolean nm_utils_enum_from_str (GType type, const char *str, int *out_value, char **err_token);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_UTILS_H__ */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
if ENABLE_TESTS
|
||||
|
||||
include $(GLIB_MAKEFILE)
|
||||
|
||||
GLIB_GENERATED = nm-core-tests-enum-types.h nm-core-tests-enum-types.c
|
||||
nm_core_tests_enum_types_sources = test-general-enums.h
|
||||
GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM
|
||||
GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM
|
||||
|
||||
BUILT_SOURCES = $(GLIB_GENERATED)
|
||||
|
||||
certsdir = $(srcdir)/certs
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
|
|
@ -28,6 +37,12 @@ LDADD = \
|
|||
@VALGRIND_RULES@
|
||||
TESTS = $(noinst_PROGRAMS)
|
||||
|
||||
test_general_SOURCES = \
|
||||
test-general.c \
|
||||
test-general-enums.h \
|
||||
nm-core-tests-enum-types.c \
|
||||
nm-core-tests-enum-types.h
|
||||
|
||||
endif
|
||||
|
||||
# test-cert.p12 created with:
|
||||
|
|
|
|||
46
libnm-core/tests/test-general-enums.h
Normal file
46
libnm-core/tests/test-general-enums.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _NM_TEST_GENERAL_ENUMS_H_
|
||||
#define _NM_TEST_GENERAL_ENUMS_H_
|
||||
|
||||
typedef enum {
|
||||
NM_TEST_GENERAL_BOOL_ENUM_NO = 0,
|
||||
NM_TEST_GENERAL_BOOL_ENUM_YES = 1,
|
||||
NM_TEST_GENERAL_BOOL_ENUM_MAYBE = 2,
|
||||
NM_TEST_GENERAL_BOOL_ENUM_UNKNOWN = 3,
|
||||
NM_TEST_GENERAL_BOOL_ENUM_INVALID = 4, /*< skip >*/
|
||||
} NMTestGeneralBoolEnum;
|
||||
|
||||
typedef enum {
|
||||
NM_TEST_GENERAL_META_FLAGS_NONE = 0,
|
||||
NM_TEST_GENERAL_META_FLAGS_FOO = (1 << 0),
|
||||
NM_TEST_GENERAL_META_FLAGS_BAR = (1 << 1),
|
||||
NM_TEST_GENERAL_META_FLAGS_BAZ = (1 << 2),
|
||||
} NMTestGeneralMetaFlags;
|
||||
|
||||
typedef enum { /*< flags >*/
|
||||
NM_TEST_GENERAL_COLOR_FLAGS_WHITE = 1, /*< skip >*/
|
||||
NM_TEST_GENERAL_COLOR_FLAGS_BLUE = 2,
|
||||
NM_TEST_GENERAL_COLOR_FLAGS_RED = 4,
|
||||
NM_TEST_GENERAL_COLOR_FLAGS_GREEN = 8,
|
||||
} NMTestGeneralColorFlags;
|
||||
|
||||
#endif /* _NM_TEST_GENERAL_ENUMS_H_ */
|
||||
|
|
@ -32,6 +32,7 @@
|
|||
#include "nm-setting-private.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-core-tests-enum-types.h"
|
||||
|
||||
#include "nm-setting-8021x.h"
|
||||
#include "nm-setting-adsl.h"
|
||||
|
|
@ -62,6 +63,7 @@
|
|||
#include "nm-glib-compat.h"
|
||||
|
||||
#include "nm-test-utils.h"
|
||||
#include "test-general-enums.h"
|
||||
|
||||
static void
|
||||
vpn_check_func (const char *key, const char *value, gpointer user_data)
|
||||
|
|
@ -4536,6 +4538,77 @@ test_nm_in_set (void)
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
static void
|
||||
test_nm_utils_enum_from_str_do (GType type, const char *str,
|
||||
gboolean exp_result, int exp_flags,
|
||||
const char *exp_err_token)
|
||||
{
|
||||
int flags = 1;
|
||||
char *err_token = NULL;
|
||||
gboolean result;
|
||||
|
||||
result = nm_utils_enum_from_str (type, str, &flags, &err_token);
|
||||
|
||||
g_assert (result == exp_result);
|
||||
g_assert_cmpint (flags, ==, exp_flags);
|
||||
g_assert_cmpstr (err_token, ==, exp_err_token);
|
||||
|
||||
g_free (err_token);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nm_utils_enum_to_str_do (GType type, int flags, const char *exp_str)
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = nm_utils_enum_to_str (type, flags);
|
||||
g_assert_cmpstr (str, ==, exp_str);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
static void test_nm_utils_enum (void)
|
||||
{
|
||||
GType bool_enum = nm_test_general_bool_enum_get_type();
|
||||
GType meta_flags = nm_test_general_meta_flags_get_type();
|
||||
GType color_flags = nm_test_general_color_flags_get_type();
|
||||
|
||||
test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_YES, "yes");
|
||||
test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_UNKNOWN, "unknown");
|
||||
test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_INVALID, NULL);
|
||||
|
||||
test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_NONE, "");
|
||||
test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_BAZ, "baz");
|
||||
test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_FOO |
|
||||
NM_TEST_GENERAL_META_FLAGS_BAR |
|
||||
NM_TEST_GENERAL_META_FLAGS_BAZ, "foo,bar,baz");
|
||||
|
||||
test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_RED, "red");
|
||||
test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_WHITE, "");
|
||||
test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_RED |
|
||||
NM_TEST_GENERAL_COLOR_FLAGS_GREEN, "red,green");
|
||||
|
||||
test_nm_utils_enum_from_str_do (bool_enum, "", FALSE, 0, NULL);
|
||||
test_nm_utils_enum_from_str_do (bool_enum, "invalid", FALSE, 0, NULL);
|
||||
test_nm_utils_enum_from_str_do (bool_enum, "yes", TRUE, NM_TEST_GENERAL_BOOL_ENUM_YES, NULL);
|
||||
test_nm_utils_enum_from_str_do (bool_enum, "no", TRUE, NM_TEST_GENERAL_BOOL_ENUM_NO, NULL);
|
||||
test_nm_utils_enum_from_str_do (bool_enum, "yes,no", FALSE, 0, NULL);
|
||||
|
||||
test_nm_utils_enum_from_str_do (meta_flags, "", TRUE, 0, NULL);
|
||||
test_nm_utils_enum_from_str_do (meta_flags, "foo", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO, NULL);
|
||||
test_nm_utils_enum_from_str_do (meta_flags, "foo,baz", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO |
|
||||
NM_TEST_GENERAL_META_FLAGS_BAZ, NULL);
|
||||
test_nm_utils_enum_from_str_do (meta_flags, "foo,,bar", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO |
|
||||
NM_TEST_GENERAL_META_FLAGS_BAR, NULL);
|
||||
test_nm_utils_enum_from_str_do (meta_flags, "foo,baz,quux,bar", FALSE, 0, "quux");
|
||||
|
||||
test_nm_utils_enum_from_str_do (color_flags, "green", TRUE, NM_TEST_GENERAL_COLOR_FLAGS_GREEN, NULL);
|
||||
test_nm_utils_enum_from_str_do (color_flags, "blue,red", TRUE, NM_TEST_GENERAL_COLOR_FLAGS_BLUE |
|
||||
NM_TEST_GENERAL_COLOR_FLAGS_RED, NULL);
|
||||
test_nm_utils_enum_from_str_do (color_flags, "blue,white", FALSE, 0, "white");
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
||||
int main (int argc, char **argv)
|
||||
|
|
@ -4641,6 +4714,8 @@ int main (int argc, char **argv)
|
|||
g_test_add_func ("/core/general/_glib_compat_g_ptr_array_insert", test_g_ptr_array_insert);
|
||||
g_test_add_func ("/core/general/_nm_utils_ptrarray_find_binary_search", test_nm_utils_ptrarray_find_binary_search);
|
||||
|
||||
g_test_add_func ("/core/general/test_nm_utils_enum", test_nm_utils_enum);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -859,7 +859,8 @@ global:
|
|||
nm_device_wifi_request_scan_options_async;
|
||||
nm_metered_get_type;
|
||||
nm_setting_connection_get_metered;
|
||||
nm_utils_enum_from_str;
|
||||
nm_utils_enum_to_str;
|
||||
nm_utils_wifi_2ghz_freqs;
|
||||
nm_utils_wifi_5ghz_freqs;
|
||||
} libnm_1_0_4;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue