diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index e3c6b80be..5e920de48 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4120,3 +4120,55 @@ NM_BACKPORT_SYMBOL (libnm_1_0_6, gboolean, nm_utils_enum_from_str, (GType type, const char *str, int *out_value, char **err_token), (type, str, out_value, err_token)); +/** + * nm_utils_enum_get_values: + * @type: the %GType of the enum + * @from: the first element to be returned + * @to: the last element to be returned + * + * Returns the list of possible values for a given enum. + * + * Returns: a NULL-terminated dynamically-allocated array of static strings + * or %NULL on error + * + * Since: 1.2 + */ +const char **nm_utils_enum_get_values (GType type, gint from, gint to) +{ + GTypeClass *class; + GPtrArray *array; + gint i; + + class = g_type_class_ref (type); + array = g_ptr_array_new (); + + if (G_IS_ENUM_CLASS (class)) { + GEnumClass *enum_class = G_ENUM_CLASS (class); + GEnumValue *enum_value; + + for (i = 0; i < enum_class->n_values; i++) { + enum_value = &enum_class->values[i]; + if (enum_value->value >= from && enum_value->value <= to) + g_ptr_array_add (array, (gpointer) enum_value->value_nick); + } + } else if (G_IS_FLAGS_CLASS (class)) { + GFlagsClass *flags_class = G_FLAGS_CLASS (class); + GFlagsValue *flags_value; + + for (i = 0; i < flags_class->n_values; i++) { + flags_value = &flags_class->values[i]; + if (flags_value->value >= from && flags_value->value <= to) + g_ptr_array_add (array, (gpointer) flags_value->value_nick); + } + } else { + g_type_class_unref (class); + g_ptr_array_free (array, TRUE); + g_return_val_if_reached (NULL); + } + + g_type_class_unref (class); + g_ptr_array_add (array, NULL); + + return (const char **) g_ptr_array_free (array, FALSE); +} + diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h index 4be58e09a..407c14e2c 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -203,6 +203,9 @@ char *nm_utils_enum_to_str (GType type, int value); NM_AVAILABLE_IN_1_2 gboolean nm_utils_enum_from_str (GType type, const char *str, int *out_value, char **err_token); +NM_AVAILABLE_IN_1_2 +const char **nm_utils_enum_get_values (GType type, gint from, gint to); + G_END_DECLS #endif /* __NM_UTILS_H__ */ diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index f4dec283c..e8eb0bafb 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -4740,6 +4740,21 @@ test_nm_utils_enum_to_str_do (GType type, int flags, const char *exp_str) g_free (str); } +static void +test_nm_utils_enum_get_values_do (GType type, int from, int to, const char *exp_str) +{ + const char **strv; + char *str; + + strv = nm_utils_enum_get_values (type, from, to); + g_assert (strv); + str = g_strjoinv (",", (char **) strv); + g_assert_cmpstr (str, ==, exp_str); + g_free (str); + g_free (strv); +} + + static void test_nm_utils_enum (void) { GType bool_enum = nm_test_general_bool_enum_get_type(); @@ -4783,6 +4798,12 @@ static void test_nm_utils_enum (void) 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"); + + test_nm_utils_enum_get_values_do (bool_enum, 0, G_MAXINT, "no,yes,maybe,unknown"); + test_nm_utils_enum_get_values_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_YES, + NM_TEST_GENERAL_BOOL_ENUM_MAYBE, "yes,maybe"); + test_nm_utils_enum_get_values_do (meta_flags, 0, G_MAXINT, "none,foo,bar,baz"); + test_nm_utils_enum_get_values_do (color_flags, 0, G_MAXINT, "blue,red,green"); } /******************************************************************************/ diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 865cc328d..81321f7af 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -925,6 +925,7 @@ global: nm_utils_bond_mode_string_to_int; nm_utils_enum_from_str; nm_utils_enum_to_str; + nm_utils_enum_get_values; nm_utils_wifi_2ghz_freqs; nm_utils_wifi_5ghz_freqs; nm_vpn_editor_plugin_load_from_file;