summaryrefslogtreecommitdiff
path: root/libnm-core
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-03-29 18:40:32 +0200
committerThomas Haller <thaller@redhat.com>2017-03-30 13:09:58 +0200
commita8730c51c8915d7cd4209c0420734bf446b902d3 (patch)
tree54921d4fd634c13b05a4b9b1b04307621542bfb9 /libnm-core
parent63c4760cd5eb84061a90f87dfeed2b36abf7625d (diff)
downloadNetworkManager-a8730c51c8915d7cd4209c0420734bf446b902d3.tar.gz
libnm: move enum utils to new shared file shared/nm-utils/nm-enum-utils.h
libnm contains the public function nm_utils_enum_from_str() et al. The function is not flexible enough for nmcli's usecase. So, I would need another public function like nm_utils_enum_from_str_full() that has an extended API. That was already required previously for ifcfg-rh writer, but in that case I could just add it as internal API as libnm-core is linked statically with NetworkManager. I don't want to commit to a public API for an utility function. So move the code instead to the shared directory, so that nmcli may link statically against it and use the internal API.
Diffstat (limited to 'libnm-core')
-rw-r--r--libnm-core/nm-core-internal.h2
-rw-r--r--libnm-core/nm-utils.c286
2 files changed, 1 insertions, 287 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index ac292bfc18..176c0600f9 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -204,8 +204,6 @@ gboolean _nm_utils_check_module_file (const char *name,
gpointer user_data,
GError **error);
-char *_nm_utils_enum_to_str_full (GType type, int value, const char *sep);
-
#define NM_UTILS_UUID_TYPE_LEGACY 0
#define NM_UTILS_UUID_TYPE_VARIANT3 1
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index 56f9497f2a..5c5b94c667 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -37,6 +37,7 @@
#include <jansson.h>
#endif
+#include "nm-utils/nm-enum-utils.h"
#include "nm-common-macros.h"
#include "nm-utils-private.h"
#include "nm-setting-private.h"
@@ -4249,291 +4250,6 @@ int _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option)
return -1;
}
-#define IS_FLAGS_SEPARATOR(ch) (NM_IN_SET ((ch), ' ', '\t', ',', '\n', '\r'))
-
-static gboolean
-_is_hex_string (const char *str)
-{
- return str[0] == '0'
- && str[1] == 'x'
- && str[2]
- && 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))
- && !_is_dec_string (str)
- && !_is_hex_string (str);
-}
-
-static gboolean
-_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);
-}
-
-char *
-_nm_utils_enum_to_str_full (GType type,
- int value,
- const char *flags_separator)
-{
- GTypeClass *class;
- char *ret;
-
- if ( flags_separator
- && ( !flags_separator[0]
- || NM_STRCHAR_ANY (flags_separator, ch, !IS_FLAGS_SEPARATOR (ch))))
- g_return_val_if_reached (NULL);
-
- 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);
- if ( !enum_value
- || !_enum_is_valid_enum_nick (enum_value->value_nick))
- ret = g_strdup_printf ("%d", value);
- else
- ret = strdup (enum_value->value_nick);
- } else if (G_IS_FLAGS_CLASS (class)) {
- GFlagsValue *flags_value;
- GString *str = g_string_new ("");
- unsigned uvalue = (unsigned) value;
-
- flags_separator = flags_separator ?: " ";
-
- do {
- flags_value = g_flags_get_first_value (G_FLAGS_CLASS (class), uvalue);
- if (str->len)
- g_string_append (str, flags_separator);
- if ( !flags_value
- || !_enum_is_valid_flags_nick (flags_value->value_nick)) {
- if (uvalue)
- g_string_append_printf (str, "0x%x", uvalue);
- break;
- }
- g_string_append (str, flags_value->value_nick);
- uvalue &= ~flags_value->value;
- } while (uvalue);
- ret = g_string_free (str, FALSE);
- } else
- g_return_val_if_reached (NULL);
-
- g_type_class_unref (class);
- return ret;
-}
-
-/**
- * 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 value has no corresponding string representation, it is converted
- * to a number. For enums it is converted to a decimal number, for flags
- * to an (unsigned) hex number.
- *
- * Returns: a newly allocated string or %NULL
- *
- * Since: 1.2
- */
-char *
-nm_utils_enum_to_str (GType type, int value)
-{
- return _nm_utils_enum_to_str_full (type, value, ", ");
-}
-
-/**
- * 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) (transfer full): 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.2
- */
-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;
- gs_free char *str_clone = NULL;
- char *s;
- gint64 v64;
-
- g_return_val_if_fail (str, FALSE);
-
- str_clone = strdup (str);
- s = nm_str_skip_leading_spaces (str_clone);
- g_strchomp (s);
-
- class = g_type_class_ref (type);
-
- if (G_IS_ENUM_CLASS (class)) {
- GEnumValue *enum_value;
-
- if (s[0]) {
- 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;
- }
- } else {
- enum_value = g_enum_get_value_by_nick (G_ENUM_CLASS (class), s);
- if (enum_value) {
- value = enum_value->value;
- ret = TRUE;
- }
- }
- }
- } else if (G_IS_FLAGS_CLASS (class)) {
- GFlagsValue *flags_value;
- unsigned uvalue = 0;
-
- ret = TRUE;
- while (s[0]) {
- char *s_end;
-
- for (s_end = s; s_end[0]; s_end++) {
- if (IS_FLAGS_SEPARATOR (s_end[0])) {
- s_end[0] = '\0';
- s_end++;
- break;
- }
- }
-
- if (s[0]) {
- if (_is_hex_string (s)) {
- v64 = _nm_utils_ascii_str_to_int64 (&s[2], 16, 0, G_MAXUINT, -1);
- if (v64 == -1) {
- ret = FALSE;
- 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) {
- ret = FALSE;
- break;
- }
- uvalue |= flags_value->value;
- }
- }
-
- s = s_end;
- }
-
- value = (int) uvalue;
- } else
- g_return_val_if_reached (FALSE);
-
- NM_SET_OUT (err_token, !ret && s[0] ? g_strdup (s) : NULL);
- NM_SET_OUT (out_value, ret ? value : 0);
- g_type_class_unref (class);
- return ret;
-}
-
-/**
- * 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: (transfer container): 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;
- char sbuf[64];
-
- 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) {
- if (_enum_is_valid_enum_nick (enum_value->value_nick))
- g_ptr_array_add (array, (gpointer) enum_value->value_nick);
- else
- g_ptr_array_add (array, (gpointer) g_intern_string (nm_sprintf_buf (sbuf, "%d", enum_value->value)));
- }
- }
- } 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) {
- if (_enum_is_valid_flags_nick (flags_value->value_nick))
- g_ptr_array_add (array, (gpointer) flags_value->value_nick);
- else
- g_ptr_array_add (array, (gpointer) g_intern_string (nm_sprintf_buf (sbuf, "0x%x", (unsigned) flags_value->value)));
- }
- }
- } 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);
-}
-
#if WITH_JANSSON
/**
* nm_utils_is_json_object: