[network-manager-openvpn/th/tmp: 1/2] shared: reimport shared files from NetworkManager's master
- From: Thomas Haller <thaller src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-openvpn/th/tmp: 1/2] shared: reimport shared files from NetworkManager's master
- Date: Fri, 19 May 2017 10:04:23 +0000 (UTC)
commit 0965a0e3a133f3d884ccda63acccd54c316b8feb
Author: Thomas Haller <thaller redhat com>
Date: Fri May 19 11:21:35 2017 +0200
shared: reimport shared files from NetworkManager's master
m4/compiler_options.m4 | 8 ++
shared/nm-utils/nm-glib.h | 8 +-
shared/nm-utils/nm-macros-internal.h | 142 ++++++++++++++++++++++++----
shared/nm-utils/nm-shared-utils.c | 171 ++++++++++++++++++++++++++++++++++
shared/nm-utils/nm-shared-utils.h | 27 ++++++
shared/nm-utils/nm-test-utils.h | 151 +++++++++++++++++++-----------
6 files changed, 431 insertions(+), 76 deletions(-)
---
diff --git a/m4/compiler_options.m4 b/m4/compiler_options.m4
index 5275281..ccb51f5 100644
--- a/m4/compiler_options.m4
+++ b/m4/compiler_options.m4
@@ -70,11 +70,13 @@ if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then
-Wimplicit-fallthrough \
-Wimplicit-function-declaration \
-Winit-self \
+ -Wlogical-op \
-Wmissing-declarations \
-Wmissing-include-dirs \
-Wmissing-prototypes \
-Wpointer-arith \
-Wshadow \
+ -Wshift-negative-value \
-Wstrict-prototypes \
-Wundef \
-Wno-duplicate-decl-specifier \
@@ -119,6 +121,12 @@ if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then
[int f () { int i = yolo; yolo; return i; }]
)
+ dnl clang 3.9 would like to see "{ { 0 } }" here, but that does not
+ dnl look too wise.
+ NM_COMPILER_WARNING([missing-braces],
+ [union { int a[1]; int b[2]; } c = { 0 }]
+ )
+
CFLAGS="$CFLAGS_MORE_WARNINGS $CFLAGS"
else
AC_MSG_RESULT(no)
diff --git a/shared/nm-utils/nm-glib.h b/shared/nm-utils/nm-glib.h
index 03251ca..dd18756 100644
--- a/shared/nm-utils/nm-glib.h
+++ b/shared/nm-utils/nm-glib.h
@@ -134,7 +134,7 @@ __g_type_ensure (GType type)
/* Rumtime check for glib version. First do a compile time check which
* (if satisfied) shortcuts the runtime check. */
-inline static gboolean
+static inline gboolean
nm_glib_check_version (guint major, guint minor, guint micro)
{
return GLIB_CHECK_VERSION (major, minor, micro)
@@ -147,7 +147,7 @@ nm_glib_check_version (guint major, guint minor, guint micro)
}
/* g_test_skip() is only available since glib 2.38. Add a compatibility wrapper. */
-inline static void
+static inline void
__nmtst_g_test_skip (const gchar *msg)
{
#if GLIB_CHECK_VERSION (2, 38, 0)
@@ -162,7 +162,7 @@ __nmtst_g_test_skip (const gchar *msg)
/* g_test_add_data_func_full() is only available since glib 2.34. Add a compatibility wrapper. */
-inline static void
+static inline void
__g_test_add_data_func_full (const char *testpath,
gpointer test_data,
GTestDataFunc test_func,
@@ -278,7 +278,7 @@ _nm_g_ptr_array_insert (GPtrArray *array,
#if !GLIB_CHECK_VERSION (2, 40, 0)
-inline static gboolean
+static inline gboolean
_g_key_file_save_to_file (GKeyFile *key_file,
const gchar *filename,
GError **error)
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h
index 2548665..cde257e 100644
--- a/shared/nm-utils/nm-macros-internal.h
+++ b/shared/nm-utils/nm-macros-internal.h
@@ -56,6 +56,14 @@ _nm_auto_unset_gvalue_impl (GValue *v)
#define nm_auto_unset_gvalue nm_auto(_nm_auto_unset_gvalue_impl)
static inline void
+_nm_auto_unref_gtypeclass (GTypeClass **v)
+{
+ if (v && *v)
+ g_type_class_unref (*v);
+}
+#define nm_auto_unref_gtypeclass nm_auto(_nm_auto_unref_gtypeclass)
+
+static inline void
_nm_auto_free_gstring_impl (GString **str)
{
if (*str)
@@ -106,12 +114,14 @@ _nm_auto_protect_errno (int *p_saved_errno)
#define __NM_UTILS_MACRO_REST_HELPER_ONE(first)
#define __NM_UTILS_MACRO_REST_HELPER_TWOORMORE(first, ...) , __VA_ARGS__
#define __NM_UTILS_MACRO_REST_NUM(...) \
- __NM_UTILS_MACRO_REST_SELECT_20TH(__VA_ARGS__, \
+ __NM_UTILS_MACRO_REST_SELECT_30TH(__VA_ARGS__, \
+ TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
+ TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway)
-#define __NM_UTILS_MACRO_REST_SELECT_20TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
a16, a17, a18, a19, a20, ...) a20
+#define __NM_UTILS_MACRO_REST_SELECT_30TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, ...) a30
/*****************************************************************************/
@@ -178,7 +188,7 @@ _nm_auto_protect_errno (int *p_saved_errno)
/**
* NM_G_ERROR_MSG:
- * @error: (allow none): the #GError instance
+ * @error: (allow-none): the #GError instance
*
* All functions must follow the convention that when they
* return a failure, they must also set the GError to a valid
@@ -199,6 +209,23 @@ NM_G_ERROR_MSG (GError *error)
/* macro to return strlen() of a compile time string. */
#define NM_STRLEN(str) ( sizeof ("" str) - 1 )
+/* returns the length of a NULL terminated array of pointers,
+ * like g_strv_length() does. The difference is:
+ * - it operats on arrays of pointers (of any kind, requiring no cast).
+ * - it accepts NULL to return zero. */
+#define NM_PTRARRAY_LEN(array) \
+ ({ \
+ typeof (*(array)) *const _array = (array); \
+ gsize _n = 0; \
+ \
+ if (_array) { \
+ _nm_unused typeof (*(_array[0])) *_array_check = _array[0]; \
+ while (_array[_n]) \
+ _n++; \
+ } \
+ _n; \
+ })
+
/* Note: @value is only evaluated when *out_val is present.
* Thus,
* NM_SET_OUT (out_str, g_strdup ("hallo"));
@@ -233,21 +260,34 @@ NM_G_ERROR_MSG (GError *error)
#define _NM_IN_SET_EVAL_16(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_15 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_N2(op, _x, n, ...) (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__))
-#define _NM_IN_SET_EVAL_N(op, x, n, ...) \
+#define _NM_IN_SET_EVAL_N(op, type, x, n, ...) \
({ \
- typeof(x) _x = (x); \
+ type _x = (x); \
+ \
+ /* trigger a -Wenum-compare warning */ \
+ nm_assert (TRUE || _x == (x)); \
+ \
!!_NM_IN_SET_EVAL_N2(op, _x, n, __VA_ARGS__); \
})
+#define _NM_IN_SET(op, type, x, ...) _NM_IN_SET_EVAL_N(op, type, x, NM_NARG (__VA_ARGS__),
__VA_ARGS__)
+
/* Beware that this does short-circuit evaluation (use "||" instead of "|")
* which has a possibly unexpected non-function-like behavior.
* Use NM_IN_SET_SE if you need all arguments to be evaluted. */
-#define NM_IN_SET(x, ...) _NM_IN_SET_EVAL_N(||, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
+#define NM_IN_SET(x, ...) _NM_IN_SET(||, typeof (x), x, __VA_ARGS__)
/* "SE" stands for "side-effect". Contrary to NM_IN_SET(), this does not do
* short-circuit evaluation, which can make a difference if the arguments have
* side-effects. */
-#define NM_IN_SET_SE(x, ...) _NM_IN_SET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
+#define NM_IN_SET_SE(x, ...) _NM_IN_SET(|, typeof (x), x, __VA_ARGS__)
+
+/* the *_TYPED forms allow to explicitly select the type of "x". This is useful
+ * if "x" doesn't support typeof (bitfields) or you want to gracefully convert
+ * a type using automatic type conversion rules (but not forcing the conversion
+ * with a cast). */
+#define NM_IN_SET_TYPED(type, x, ...) _NM_IN_SET(||, type, x, __VA_ARGS__)
+#define NM_IN_SET_SE_TYPED(type, x, ...) _NM_IN_SET(|, type, x, __VA_ARGS__)
/*****************************************************************************/
@@ -278,8 +318,8 @@ _NM_IN_STRSET_streq (const char *x, const char *s)
#define _NM_IN_STRSET_EVAL_N(op, x, n, ...) \
({ \
const char *_x = (x); \
- ( ((_x == NULL) && _NM_IN_SET_EVAL_N2 (op, (const char *) NULL, n, __VA_ARGS__)) \
- || ((_x != NULL) && _NM_IN_STRSET_EVAL_N2 (op, _x, n, __VA_ARGS__)) \
+ ( ((_x == NULL) && _NM_IN_SET_EVAL_N2 (op, ((const char *) NULL), n, __VA_ARGS__)) \
+ || ((_x != NULL) && _NM_IN_STRSET_EVAL_N2 (op, _x, n, __VA_ARGS__)) \
); \
})
@@ -469,6 +509,9 @@ _notify (obj_type *obj, _PropertyEnums prop) \
/*****************************************************************************/
+/* these are implemented as a macro, because they accept self
+ * as both (type*) and (const type*), and return a const
+ * private pointer accordingly. */
#define __NM_GET_PRIVATE(self, type, is_check, result_cmd) \
({ \
/* preserve the const-ness of self. Unfortunately, that
@@ -476,7 +519,7 @@ _notify (obj_type *obj, _PropertyEnums prop) \
typeof (self) _self = (self); \
\
/* Get compiler error if variable is of wrong type */ \
- _nm_unused const type *_self2 = (_self); \
+ _nm_unused const type *const _self2 = (_self); \
\
nm_assert (is_check (_self)); \
( result_cmd ); \
@@ -485,6 +528,21 @@ _notify (obj_type *obj, _PropertyEnums prop) \
#define _NM_GET_PRIVATE(self, type, is_check) __NM_GET_PRIVATE(self, type, is_check, &_self->_priv)
#define _NM_GET_PRIVATE_PTR(self, type, is_check) __NM_GET_PRIVATE(self, type, is_check, _self->_priv)
+#define __NM_GET_PRIVATE_VOID(self, type, is_check, result_cmd) \
+ ({ \
+ /* (self) can be any non-const pointer. It will be cast to "type *".
+ * We don't explicitly cast but assign first to (void *) which
+ * will fail if @self is pointing to const. */ \
+ void *const _self1 = (self); \
+ type *const _self = _self1; \
+ \
+ nm_assert (is_check (_self)); \
+ ( result_cmd ); \
+ })
+
+#define _NM_GET_PRIVATE_VOID(self, type, is_check) __NM_GET_PRIVATE_VOID(self, type, is_check,
&_self->_priv)
+#define _NM_GET_PRIVATE_PTR_VOID(self, type, is_check) __NM_GET_PRIVATE_VOID(self, type, is_check,
_self->_priv)
+
/*****************************************************************************/
static inline gpointer
@@ -577,25 +635,69 @@ nm_clear_g_cancellable (GCancellable **cancellable)
/* Determine whether @x is a power of two (@x being an integer type).
* For the special cases @x equals zero or one, it also returns true.
- * For negative @x, always returns FALSE. That only applies, if the data
- * type of @x is signed. */
+ * In case @x being a signed type, for negative @x always return FALSE. */
#define nm_utils_is_power_of_two(x) ({ \
typeof(x) __x = (x); \
\
/* Check if the value is negative. In that case, return FALSE.
* The first expression is a compile time constant, depending on whether
* the type is signed. The second expression is a clumsy way for (__x >= 0),
- * which causes a compiler warning for unsigned types. */ \
- ( ( ((typeof(__x)) -1) > ((typeof(__x)) 0) ) || (__x > 0) || (__x == 0) ) \
+ * which otherwise causes a compiler warning for unsigned types. */ \
+ ( (((typeof(__x)) -1) > ((typeof(__x)) 0)) \
+ || (__x > 0 || __x == 0) ) \
&& ((__x & (__x - 1)) == 0); \
})
/*****************************************************************************/
+#define NM_UTILS_LOOKUP_DEFAULT(v) return (v)
+#define NM_UTILS_LOOKUP_DEFAULT_WARN(v) g_return_val_if_reached (v)
+#define NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT(v) { nm_assert_not_reached (); return (v); }
+#define NM_UTILS_LOOKUP_ITEM(v, n) (void) 0; case v: return (n); (void) 0
+#define NM_UTILS_LOOKUP_STR_ITEM(v, n) NM_UTILS_LOOKUP_ITEM(v, ""n"")
+#define NM_UTILS_LOOKUP_ITEM_IGNORE(v) (void) 0; case v: break; (void) 0
+#define NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER() (void) 0; default: break; (void) 0
+
+#define _NM_UTILS_LOOKUP_DEFINE(scope, fcn_name, lookup_type, result_type, unknown_val, ...) \
+scope result_type \
+fcn_name (lookup_type val) \
+{ \
+ switch (val) { \
+ (void) 0, \
+ __VA_ARGS__ \
+ (void) 0; \
+ }; \
+ { unknown_val; } \
+}
+
+#define NM_UTILS_LOOKUP_STR_DEFINE(fcn_name, lookup_type, unknown_val, ...) \
+ _NM_UTILS_LOOKUP_DEFINE (, fcn_name, lookup_type, const char *, unknown_val, __VA_ARGS__)
+#define NM_UTILS_LOOKUP_STR_DEFINE_STATIC(fcn_name, lookup_type, unknown_val, ...) \
+ _NM_UTILS_LOOKUP_DEFINE (static, fcn_name, lookup_type, const char *, unknown_val, __VA_ARGS__)
+
+/* Call the string-lookup-table function @fcn_name. If the function returns
+ * %NULL, the numeric index is converted to string using a alloca() buffer.
+ * Beware: this macro uses alloca(). */
+#define NM_UTILS_LOOKUP_STR(fcn_name, idx) \
+ ({ \
+ typeof (idx) _idx = (idx); \
+ const char *_s; \
+ \
+ _s = fcn_name (_idx); \
+ if (!_s) { \
+ _s = g_alloca (30); \
+ \
+ g_snprintf ((char *) _s, 30, "(%lld)", (long long) _idx); \
+ } \
+ _s; \
+ })
+
+/*****************************************************************************/
+
/* check if @flags has exactly one flag (@check) set. You should call this
* only with @check being a compile time constant and a power of two. */
#define NM_FLAGS_HAS(flags, check) \
- ( (G_STATIC_ASSERT_EXPR ( ((check) != 0) && ((check) & ((check)-1)) == 0 )), (NM_FLAGS_ANY ((flags),
(check))) )
+ ( G_STATIC_ASSERT_EXPR ((check) > 0 && ((check) & ((check) - 1)) == 0), NM_FLAGS_ANY ((flags), (check)) )
#define NM_FLAGS_ANY(flags, check) ( ( ((flags) & (check)) != 0 ) ? TRUE : FALSE )
#define NM_FLAGS_ALL(flags, check) ( ( ((flags) & (check)) == (check) ) ? TRUE : FALSE )
@@ -748,13 +850,15 @@ nm_cmp_uint32_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_d
/*****************************************************************************/
static inline guint
-nm_encode_version (guint major, guint minor, guint micro) {
+nm_encode_version (guint major, guint minor, guint micro)
+{
/* analog to the preprocessor macro NM_ENCODE_VERSION(). */
return (major << 16) | (minor << 8) | micro;
}
static inline void
-nm_decode_version (guint version, guint *major, guint *minor, guint *micro) {
+nm_decode_version (guint version, guint *major, guint *minor, guint *micro)
+{
*major = (version & 0xFFFF0000u) >> 16;
*minor = (version & 0x0000FF00u) >> 8;
*micro = (version & 0x000000FFu);
@@ -802,7 +906,8 @@ nm_decode_version (guint version, guint *major, guint *minor, guint *micro) {
: "(null)"); \
})
-#define nm_sprintf_buf(buf, format, ...) ({ \
+#define nm_sprintf_buf(buf, format, ...) \
+ ({ \
char * _buf = (buf); \
int _buf_len; \
\
@@ -901,7 +1006,6 @@ nm_decode_version (guint version, guint *major, guint *minor, guint *micro) {
#define _G_BOOLEAN_EXPR(expr) __NM_G_BOOLEAN_EXPR_IMPL (NM_UNIQ, expr)
#endif
-
/*****************************************************************************/
#endif /* __NM_MACROS_INTERNAL_H__ */
diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c
index 413526d..9a87536 100644
--- a/shared/nm-utils/nm-shared-utils.c
+++ b/shared/nm-utils/nm-shared-utils.c
@@ -27,6 +27,10 @@
/*****************************************************************************/
+const void *const _NM_PTRARRAY_EMPTY[1] = { NULL };
+
+/*****************************************************************************/
+
void
nm_utils_strbuf_append_c (char **buf, gsize *len, char c)
{
@@ -204,6 +208,35 @@ nm_utils_strv_find_first (char **list, gssize len, const char *needle)
return -1;
}
+char **
+_nm_utils_strv_cleanup (char **strv,
+ gboolean strip_whitespace,
+ gboolean skip_empty,
+ gboolean skip_repeated)
+{
+ guint i, j;
+
+ if (!strv || !*strv)
+ return strv;
+
+ if (strip_whitespace) {
+ for (i = 0; strv[i]; i++)
+ g_strstrip (strv[i]);
+ }
+ if (!skip_empty && !skip_repeated)
+ return strv;
+ j = 0;
+ for (i = 0; strv[i]; i++) {
+ if ( (skip_empty && !*strv[i])
+ || (skip_repeated && nm_utils_strv_find_first (strv, j, strv[i]) >= 0))
+ g_free (strv[i]);
+ else
+ strv[j++] = strv[i];
+ }
+ strv[j] = NULL;
+ return strv;
+}
+
/*****************************************************************************/
gint
@@ -364,3 +397,141 @@ nm_g_object_set_property (GObject *object,
}
/*****************************************************************************/
+
+static void
+_str_append_escape (GString *s, char ch)
+{
+ g_string_append_c (s, '\\');
+ g_string_append_c (s, '0' + ((((guchar) ch) >> 6) & 07));
+ g_string_append_c (s, '0' + ((((guchar) ch) >> 3) & 07));
+ g_string_append_c (s, '0' + ( ((guchar) ch) & 07));
+}
+
+/**
+ * nm_utils_str_utf8safe_escape:
+ * @str: NUL terminated input string, possibly in utf-8 encoding
+ * @flags: #NMUtilsStrUtf8SafeFlags flags
+ * @to_free: (out): return the pointer location of the string
+ * if a copying was necessary.
+ *
+ * Returns the possible non-UTF-8 NUL terminated string @str
+ * and uses backslash escaping (C escaping, like g_strescape())
+ * to sanitize non UTF-8 characters. The result is valid
+ * UTF-8.
+ *
+ * The operation can be reverted with g_strcompress() or
+ * nm_utils_str_utf8safe_unescape().
+ *
+ * Depending on @flags, valid UTF-8 characters are not escaped at all
+ * (except the escape character '\\'). This is the difference to g_strescape(),
+ * which escapes all non-ASCII characters. This allows to pass on
+ * valid UTF-8 characters as-is and can be directly shown to the user
+ * as UTF-8 -- with exception of the backslash escape character,
+ * invalid UTF-8 sequences, and other (depending on @flags).
+ *
+ * Returns: the escaped input string, as valid UTF-8. If no escaping
+ * is necessary, it returns the input @str. Otherwise, an allocated
+ * string @to_free is returned which must be freed by the caller
+ * with g_free. The escaping can be reverted by g_strcompress().
+ **/
+const char *
+nm_utils_str_utf8safe_escape (const char *str, NMUtilsStrUtf8SafeFlags flags, char **to_free)
+{
+ const char *p = NULL;
+ GString *s;
+
+ g_return_val_if_fail (to_free, NULL);
+
+ *to_free = NULL;
+ if (!str || !str[0])
+ return str;
+
+ if ( g_utf8_validate (str, -1, &p)
+ && !NM_STRCHAR_ANY (str, ch,
+ ( ch == '\\' \
+ || ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) \
+ && ch < ' ') \
+ || ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) \
+ && ((guchar) ch) >= 127))))
+ return str;
+
+ s = g_string_sized_new ((p - str) + strlen (p) + 5);
+
+ do {
+ for (; str < p; str++) {
+ char ch = str[0];
+
+ if (ch == '\\')
+ g_string_append (s, "\\\\");
+ else if ( ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) \
+ && ch < ' ') \
+ || ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) \
+ && ((guchar) ch) >= 127))
+ _str_append_escape (s, ch);
+ else
+ g_string_append_c (s, ch);
+ }
+
+ if (p[0] == '\0')
+ break;
+ _str_append_escape (s, p[0]);
+
+ str = &p[1];
+ g_utf8_validate (str, -1, &p);
+ } while (TRUE);
+
+ *to_free = g_string_free (s, FALSE);
+ return *to_free;
+}
+
+const char *
+nm_utils_str_utf8safe_unescape (const char *str, char **to_free)
+{
+ g_return_val_if_fail (to_free, NULL);
+
+ if (!str || !strchr (str, '\\')) {
+ *to_free = NULL;
+ return str;
+ }
+ return (*to_free = g_strcompress (str));
+}
+
+/**
+ * nm_utils_str_utf8safe_escape_cp:
+ * @str: NUL terminated input string, possibly in utf-8 encoding
+ * @flags: #NMUtilsStrUtf8SafeFlags flags
+ *
+ * Like nm_utils_str_utf8safe_escape(), except the returned value
+ * is always a copy of the input and must be freed by the caller.
+ *
+ * Returns: the escaped input string in UTF-8 encoding. The returned
+ * value should be freed with g_free().
+ * The escaping can be reverted by g_strcompress().
+ **/
+char *
+nm_utils_str_utf8safe_escape_cp (const char *str, NMUtilsStrUtf8SafeFlags flags)
+{
+ char *s;
+
+ nm_utils_str_utf8safe_escape (str, flags, &s);
+ return s ?: g_strdup (str);
+}
+
+char *
+nm_utils_str_utf8safe_unescape_cp (const char *str)
+{
+ return str ? g_strcompress (str) : NULL;
+}
+
+char *
+nm_utils_str_utf8safe_escape_take (char *str, NMUtilsStrUtf8SafeFlags flags)
+{
+ char *str_to_free;
+
+ nm_utils_str_utf8safe_escape (str, flags, &str_to_free);
+ if (str_to_free) {
+ g_free (str);
+ return str_to_free;
+ }
+ return str;
+}
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index f1f9f51..438a7a9 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -24,6 +24,10 @@
/*****************************************************************************/
+extern const void *const _NM_PTRARRAY_EMPTY[1];
+
+#define NM_PTRARRAY_EMPTY(type) ((type const*) _NM_PTRARRAY_EMPTY)
+
static inline void
_nm_utils_strbuf_init (char *buf, gsize len, char **p_buf_ptr, gsize *p_buf_len)
{
@@ -45,6 +49,11 @@ void nm_utils_strbuf_append_str (char **buf, gsize *len, const char *str);
gssize nm_utils_strv_find_first (char **list, gssize len, const char *needle);
+char **_nm_utils_strv_cleanup (char **strv,
+ gboolean strip_whitespace,
+ gboolean skip_empty,
+ gboolean skip_repeated);
+
/*****************************************************************************/
gint64 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback);
@@ -62,10 +71,12 @@ gint _nm_utils_ascii_str_to_bool (const char *str,
* error reason. Depending on the usage, this might indicate a bug because
* usually the target object should stay alive as long as there are pending
* operations.
+ * @NM_UTILS_ERROR_INVALID_ARGUMENT: invalid argument.
*/
typedef enum {
NM_UTILS_ERROR_UNKNOWN = 0, /*< nick=Unknown >*/
NM_UTILS_ERROR_CANCELLED_DISPOSING, /*< nick=CancelledDisposing >*/
+ NM_UTILS_ERROR_INVALID_ARGUMENT, /*< nick=InvalidArgument >*/
} NMUtilsError;
#define NM_UTILS_ERROR (nm_utils_error_quark ())
@@ -86,4 +97,20 @@ gboolean nm_g_object_set_property (GObject *object,
/*****************************************************************************/
+typedef enum {
+ NM_UTILS_STR_UTF8_SAFE_FLAG_NONE = 0,
+ NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL = 0x0001,
+ NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII = 0x0002,
+} NMUtilsStrUtf8SafeFlags;
+
+const char *nm_utils_str_utf8safe_escape (const char *str, NMUtilsStrUtf8SafeFlags flags, char **to_free);
+const char *nm_utils_str_utf8safe_unescape (const char *str, char **to_free);
+
+char *nm_utils_str_utf8safe_escape_cp (const char *str, NMUtilsStrUtf8SafeFlags flags);
+char *nm_utils_str_utf8safe_unescape_cp (const char *str);
+
+char *nm_utils_str_utf8safe_escape_take (char *str, NMUtilsStrUtf8SafeFlags flags);
+
+/*****************************************************************************/
+
#endif /* __NM_SHARED_UTILS_H__ */
diff --git a/shared/nm-utils/nm-test-utils.h b/shared/nm-utils/nm-test-utils.h
index 7be7e25..0dfdfce 100644
--- a/shared/nm-utils/nm-test-utils.h
+++ b/shared/nm-utils/nm-test-utils.h
@@ -198,7 +198,7 @@ _nmtst_exit (void) \
}
-inline static gboolean
+static inline gboolean
nmtst_initialized (void)
{
return !!__nmtst_internal.rand0;
@@ -219,7 +219,7 @@ nmtst_initialized (void)
*
* The caller must g_free() the returned argv array.
**/
-inline static char **
+static inline char **
nmtst_str_split (char *str, const char *delimiters)
{
const char *d;
@@ -265,7 +265,7 @@ BREAK_INNER_LOOPS:
/* free instances allocated by nmtst (especially nmtst_init()) on shutdown
* to release memory. After nmtst_free(), the test is uninitialized again. */
-inline static void
+static inline void
nmtst_free (void)
{
if (!nmtst_initialized ())
@@ -280,7 +280,7 @@ nmtst_free (void)
memset (&__nmtst_internal, 0, sizeof (__nmtst_internal));
}
-inline static void
+static inline void
__nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_level, const char
*log_domains, gboolean *out_set_logging)
{
const char *nmtst_debug;
@@ -592,21 +592,21 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_
}
#ifndef _NMTST_INSIDE_CORE
-inline static void
+static inline void
nmtst_init (int *argc, char ***argv, gboolean assert_logging)
{
__nmtst_init (argc, argv, assert_logging, NULL, NULL, NULL);
}
#endif
-inline static gboolean
+static inline gboolean
nmtst_is_debug (void)
{
g_assert (nmtst_initialized ());
return __nmtst_internal.is_debug;
}
-inline static gboolean
+static inline gboolean
nmtst_test_quick (void)
{
g_assert (nmtst_initialized ());
@@ -656,7 +656,7 @@ struct _NmtstTestData {
gpointer args[1];
};
-inline static void
+static inline void
_nmtst_test_data_unpack (const NmtstTestData *test_data, gsize n_args, ...)
{
gsize i;
@@ -677,7 +677,7 @@ _nmtst_test_data_unpack (const NmtstTestData *test_data, gsize n_args, ...)
}
#define nmtst_test_data_unpack(test_data, ...) _nmtst_test_data_unpack(test_data, NM_NARG (__VA_ARGS__),
##__VA_ARGS__)
-inline static void
+static inline void
_nmtst_test_data_free (gpointer data)
{
NmtstTestData *test_data = data;
@@ -691,7 +691,7 @@ _nmtst_test_data_free (gpointer data)
g_free (test_data);
}
-inline static void
+static inline void
_nmtst_add_test_func_full (const char *testpath, GTestDataFunc test_func, NmtstTestDataRelease fcn_release,
gsize n_args, ...)
{
gsize i;
@@ -719,14 +719,14 @@ _nmtst_add_test_func_full (const char *testpath, GTestDataFunc test_func, NmtstT
/*****************************************************************************/
-inline static GRand *
+static inline GRand *
nmtst_get_rand0 (void)
{
g_assert (nmtst_initialized ());
return __nmtst_internal.rand0;
}
-inline static GRand *
+static inline GRand *
nmtst_get_rand (void)
{
g_assert (nmtst_initialized ());
@@ -757,13 +757,13 @@ nmtst_get_rand (void)
return __nmtst_internal.rand;
}
-inline static guint32
+static inline guint32
nmtst_get_rand_int (void)
{
return g_rand_int (nmtst_get_rand ());
}
-inline static gpointer
+static inline gpointer
nmtst_rand_buf (GRand *rand, gpointer buffer, gsize buffer_length)
{
guint32 v;
@@ -791,7 +791,7 @@ nmtst_rand_buf (GRand *rand, gpointer buffer, gsize buffer_length)
return buffer;
}
-inline static void *
+static inline void *
nmtst_rand_perm (GRand *rand, void *dst, const void *src, gsize elmt_size, gsize n_elmt)
{
gsize i, j;
@@ -832,7 +832,7 @@ nmtst_rand_perm (GRand *rand, void *dst, const void *src, gsize elmt_size, gsize
return dst;
}
-inline static GSList *
+static inline GSList *
nmtst_rand_perm_gslist (GRand *rand, GSList *list)
{
GSList *result;
@@ -859,7 +859,7 @@ nmtst_rand_perm_gslist (GRand *rand, GSList *list)
/*****************************************************************************/
-inline static gboolean
+static inline gboolean
_nmtst_main_loop_run_timeout (gpointer user_data)
{
GMainLoop **p_loop = user_data;
@@ -873,7 +873,7 @@ _nmtst_main_loop_run_timeout (gpointer user_data)
return G_SOURCE_REMOVE;
}
-inline static gboolean
+static inline gboolean
nmtst_main_loop_run (GMainLoop *loop, int timeout_ms)
{
GSource *source = NULL;
@@ -894,7 +894,7 @@ nmtst_main_loop_run (GMainLoop *loop, int timeout_ms)
return loopx != NULL;
}
-inline static void
+static inline void
_nmtst_main_loop_quit_on_notify (GObject *object, GParamSpec *pspec, gpointer user_data)
{
GMainLoop *loop = user_data;
@@ -908,14 +908,14 @@ _nmtst_main_loop_quit_on_notify (GObject *object, GParamSpec *pspec, gpointer us
/*****************************************************************************/
-inline static const char *
+static inline const char *
nmtst_get_sudo_cmd (void)
{
g_assert (nmtst_initialized ());
return __nmtst_internal.sudo_cmd;
}
-inline static void
+static inline void
nmtst_reexec_sudo (void)
{
char *str;
@@ -945,7 +945,7 @@ nmtst_reexec_sudo (void)
/*****************************************************************************/
-inline static gsize
+static inline gsize
nmtst_find_all_indexes (gpointer *elements,
gsize n_elements,
gpointer *needles,
@@ -987,7 +987,7 @@ next:
/*****************************************************************************/
#define __define_nmtst_static(NUM,SIZE) \
-inline static const char * \
+static inline const char * \
nmtst_static_##SIZE##_##NUM (const char *str) \
{ \
gsize l; \
@@ -1008,7 +1008,7 @@ __define_nmtst_static(03, 1024)
gs_free char *_nmtst_hidden_##uuid = nm_utils_uuid_generate (); \
const char *const uuid = _nmtst_hidden_##uuid
-inline static const char *
+static inline const char *
nmtst_uuid_generate (void)
{
static char u[37];
@@ -1039,7 +1039,7 @@ nmtst_uuid_generate (void)
g_error ("%s:%d: Expects \"%s\" but got \"%s\"", __FILE__, __LINE__, __substr,
__str); \
} G_STMT_END
-inline static guint32
+static inline guint32
nmtst_inet4_from_string (const char *str)
{
guint32 addr;
@@ -1055,7 +1055,7 @@ nmtst_inet4_from_string (const char *str)
return addr;
}
-inline static const struct in6_addr *
+static inline const struct in6_addr *
nmtst_inet6_from_string (const char *str)
{
static struct in6_addr addr;
@@ -1071,7 +1071,7 @@ nmtst_inet6_from_string (const char *str)
return &addr;
}
-inline static void
+static inline void
_nmtst_assert_ip4_address (const char *file, int line, in_addr_t addr, const char *str_expected)
{
if (nmtst_inet4_from_string (str_expected) != addr) {
@@ -1084,7 +1084,7 @@ _nmtst_assert_ip4_address (const char *file, int line, in_addr_t addr, const cha
}
#define nmtst_assert_ip4_address(addr, str_expected) _nmtst_assert_ip4_address (__FILE__, __LINE__, addr,
str_expected)
-inline static void
+static inline void
_nmtst_assert_ip6_address (const char *file, int line, const struct in6_addr *addr, const char *str_expected)
{
struct in6_addr any = in6addr_any;
@@ -1104,9 +1104,9 @@ _nmtst_assert_ip6_address (const char *file, int line, const struct in6_addr *ad
#define nmtst_spawn_sync(working_directory, standard_out, standard_err, assert_exit_status, ...) \
__nmtst_spawn_sync (working_directory, standard_out, standard_err, assert_exit_status, ##__VA_ARGS__,
NULL)
-inline static gint
+static inline gint
__nmtst_spawn_sync (const char *working_directory, char **standard_out, char **standard_err, int
assert_exit_status, ...) G_GNUC_NULL_TERMINATED;
-inline static gint
+static inline gint
__nmtst_spawn_sync (const char *working_directory, char **standard_out, char **standard_err, int
assert_exit_status, ...)
{
gint exit_status = 0;
@@ -1154,7 +1154,7 @@ __nmtst_spawn_sync (const char *working_directory, char **standard_out, char **s
/*****************************************************************************/
-inline static char *
+static inline char *
nmtst_file_resolve_relative_path (const char *rel, const char *cwd)
{
gs_free char *cwd_free = NULL;
@@ -1169,7 +1169,7 @@ nmtst_file_resolve_relative_path (const char *rel, const char *cwd)
return g_build_filename (cwd, rel, NULL);
}
-inline static char *
+static inline char *
nmtst_file_get_contents (const char *filename)
{
GError *error = NULL;
@@ -1185,7 +1185,7 @@ nmtst_file_get_contents (const char *filename)
/*****************************************************************************/
-inline static void
+static inline void
nmtst_file_unlink_if_exists (const char *name)
{
int errsv;
@@ -1199,7 +1199,7 @@ nmtst_file_unlink_if_exists (const char *name)
}
}
-inline static void
+static inline void
nmtst_file_unlink (const char *name)
{
int errsv;
@@ -1212,7 +1212,7 @@ nmtst_file_unlink (const char *name)
}
}
-inline static void
+static inline void
_nmtst_auto_unlinkfile (char **p_name)
{
if (*p_name) {
@@ -1225,7 +1225,7 @@ _nmtst_auto_unlinkfile (char **p_name)
/*****************************************************************************/
-inline static void
+static inline void
_nmtst_assert_resolve_relative_path_equals (const char *f1, const char *f2, const char *file, int line)
{
gs_free char *p1 = NULL, *p2 = NULL;
@@ -1244,7 +1244,7 @@ _nmtst_assert_resolve_relative_path_equals (const char *f1, const char *f2, cons
/*****************************************************************************/
#ifdef NM_SETTING_IP_CONFIG_H
-inline static void
+static inline void
nmtst_setting_ip_config_add_address (NMSettingIPConfig *s_ip,
const char *address,
guint prefix)
@@ -1267,7 +1267,7 @@ nmtst_setting_ip_config_add_address (NMSettingIPConfig *s_ip,
nm_ip_address_unref (addr);
}
-inline static void
+static inline void
nmtst_setting_ip_config_add_route (NMSettingIPConfig *s_ip,
const char *dest,
guint prefix,
@@ -1291,11 +1291,55 @@ nmtst_setting_ip_config_add_route (NMSettingIPConfig *s_ip,
g_assert (nm_setting_ip_config_add_route (s_ip, route));
nm_ip_route_unref (route);
}
+
+static inline void
+nmtst_assert_route_attribute_string (NMIPRoute *route, const char *name, const char *value)
+{
+ GVariant *variant;
+
+ variant = nm_ip_route_get_attribute (route, name);
+ g_assert (variant);
+ g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING));
+ g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, value);
+}
+
+static inline void
+nmtst_assert_route_attribute_byte (NMIPRoute *route, const char *name, guchar value)
+{
+ GVariant *variant;
+
+ variant = nm_ip_route_get_attribute (route, name);
+ g_assert (variant);
+ g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTE));
+ g_assert_cmpint (g_variant_get_byte (variant), ==, value);
+}
+
+static inline void
+nmtst_assert_route_attribute_uint32 (NMIPRoute *route, const char *name, guint32 value)
+{
+ GVariant *variant;
+
+ variant = nm_ip_route_get_attribute (route, name);
+ g_assert (variant);
+ g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32));
+ g_assert_cmpint (g_variant_get_uint32 (variant), ==, value);
+}
+
+static inline void
+nmtst_assert_route_attribute_boolean (NMIPRoute *route, const char *name, gboolean value)
+{
+ GVariant *variant;
+
+ variant = nm_ip_route_get_attribute (route, name);
+ g_assert (variant);
+ g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN));
+ g_assert_cmpint (g_variant_get_boolean (variant), ==, value);
+}
#endif /* NM_SETTING_IP_CONFIG_H */
#if (defined(__NM_SIMPLE_CONNECTION_H__) && defined(__NM_SETTING_CONNECTION_H__)) ||
(defined(NM_CONNECTION_H))
-inline static NMConnection *
+static inline NMConnection *
nmtst_clone_connection (NMConnection *connection)
{
g_assert (NM_IS_CONNECTION (connection));
@@ -1307,7 +1351,7 @@ nmtst_clone_connection (NMConnection *connection)
#endif
}
-inline static NMConnection *
+static inline NMConnection *
nmtst_create_minimal_connection (const char *id, const char *uuid, const char *type, NMSettingConnection
**out_s_con)
{
NMConnection *con;
@@ -1360,7 +1404,7 @@ nmtst_create_minimal_connection (const char *id, const char *uuid, const char *t
return con;
}
-inline static gboolean
+static inline gboolean
_nmtst_connection_normalize_v (NMConnection *connection, va_list args)
{
GError *error = NULL;
@@ -1390,7 +1434,7 @@ _nmtst_connection_normalize_v (NMConnection *connection, va_list args)
return was_modified;
}
-inline static gboolean
+static inline gboolean
_nmtst_connection_normalize (NMConnection *connection, ...)
{
gboolean was_modified;
@@ -1405,7 +1449,7 @@ _nmtst_connection_normalize (NMConnection *connection, ...)
#define nmtst_connection_normalize(connection, ...) \
_nmtst_connection_normalize(connection, ##__VA_ARGS__, NULL)
-inline static NMConnection *
+static inline NMConnection *
_nmtst_connection_duplicate_and_normalize (NMConnection *connection, ...)
{
gboolean was_modified;
@@ -1422,7 +1466,7 @@ _nmtst_connection_duplicate_and_normalize (NMConnection *connection, ...)
#define nmtst_connection_duplicate_and_normalize(connection, ...) \
_nmtst_connection_duplicate_and_normalize(connection, ##__VA_ARGS__, NULL)
-inline static void
+static inline void
nmtst_assert_connection_equals (NMConnection *a, gboolean normalize_a, NMConnection *b, gboolean normalize_b)
{
gboolean compare;
@@ -1481,7 +1525,7 @@ nmtst_assert_connection_equals (NMConnection *a, gboolean normalize_a, NMConnect
g_assert (compare);
}
-inline static void
+static inline void
nmtst_assert_connection_verifies (NMConnection *con)
{
/* assert that the connection does verify, it might be normaliziable or not */
@@ -1495,7 +1539,7 @@ nmtst_assert_connection_verifies (NMConnection *con)
g_assert (success);
}
-inline static void
+static inline void
nmtst_assert_connection_verifies_without_normalization (NMConnection *con)
{
/* assert that the connection verifies and does not need any normalization */
@@ -1515,7 +1559,7 @@ nmtst_assert_connection_verifies_without_normalization (NMConnection *con)
g_assert (!was_modified);
}
-inline static void
+static inline void
nmtst_assert_connection_verifies_and_normalizable (NMConnection *con)
{
/* assert that the connection does verify, but normalization still modifies it */
@@ -1537,7 +1581,7 @@ nmtst_assert_connection_verifies_and_normalizable (NMConnection *con)
nmtst_assert_connection_verifies_without_normalization (clone);
}
-inline static void
+static inline void
nmtst_assert_connection_verifies_after_normalization (NMConnection *con,
GQuark expect_error_domain,
gint expect_error_code)
@@ -1564,7 +1608,7 @@ nmtst_assert_connection_verifies_after_normalization (NMConnection *con,
nmtst_assert_connection_verifies_without_normalization (clone);
}
-inline static void
+static inline void
nmtst_assert_connection_unnormalizable (NMConnection *con,
GQuark expect_error_domain,
gint expect_error_code)
@@ -1591,7 +1635,7 @@ nmtst_assert_connection_unnormalizable (NMConnection *con,
g_clear_error (&error);
}
-inline static void
+static inline void
nmtst_assert_setting_verifies (NMSetting *setting)
{
/* assert that the setting verifies without an error */
@@ -1606,7 +1650,7 @@ nmtst_assert_setting_verifies (NMSetting *setting)
g_assert (success);
}
-inline static void
+static inline void
nmtst_assert_setting_verify_fails (NMSetting *setting,
GQuark expect_error_domain,
gint expect_error_code)
@@ -1661,9 +1705,10 @@ nmtst_assert_hwaddr_equals (gconstpointer hwaddr1, gssize hwaddr1_len, const cha
nmtst_assert_hwaddr_equals (hwaddr1, hwaddr1_len, expected, __FILE__, __LINE__)
#endif
+
#if defined(__NM_SIMPLE_CONNECTION_H__) && defined(__NM_SETTING_CONNECTION_H__) &&
defined(__NM_KEYFILE_INTERNAL_H__)
-inline static NMConnection *
+static inline NMConnection *
nmtst_create_connection_from_keyfile (const char *keyfile_str, const char *keyfile_name, const char
*base_dir)
{
GKeyFile *keyfile;
@@ -1693,7 +1738,7 @@ nmtst_create_connection_from_keyfile (const char *keyfile_str, const char *keyfi
#ifdef __NM_CONNECTION_H__
-inline static GVariant *
+static inline GVariant *
_nmtst_variant_new_vardict (int dummy, ...)
{
GVariantBuilder builder;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]