Blame shared/nm-utils/nm-macros-internal.h

Packit Service d328f3
/* NetworkManager -- Network link manager
Packit Service d328f3
 *
Packit Service d328f3
 * This library is free software; you can redistribute it and/or
Packit Service d328f3
 * modify it under the terms of the GNU Lesser General Public
Packit Service d328f3
 * License as published by the Free Software Foundation; either
Packit Service d328f3
 * version 2 of the License, or (at your option) any later version.
Packit Service d328f3
 *
Packit Service d328f3
 * This library is distributed in the hope that it will be useful,
Packit Service d328f3
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d328f3
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service d328f3
 * Lesser General Public License for more details.
Packit Service d328f3
 *
Packit Service d328f3
 * You should have received a copy of the GNU Lesser General Public
Packit Service d328f3
 * License along with this library; if not, write to the
Packit Service d328f3
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit Service d328f3
 * Boston, MA 02110-1301 USA.
Packit Service d328f3
 *
Packit Service d328f3
 * (C) Copyright 2014 Red Hat, Inc.
Packit Service d328f3
 */
Packit Service d328f3
Packit Service d328f3
#ifndef __NM_MACROS_INTERNAL_H__
Packit Service d328f3
#define __NM_MACROS_INTERNAL_H__
Packit Service d328f3
Packit Service d328f3
#include <stdio.h>
Packit Service d328f3
#include <stdlib.h>
Packit Service d328f3
#include <errno.h>
Packit Service d328f3
Packit Service d328f3
#define _nm_packed           __attribute__ ((packed))
Packit Service d328f3
#define _nm_unused           __attribute__ ((unused))
Packit Service d328f3
#define _nm_pure             __attribute__ ((pure))
Packit Service d328f3
#define _nm_const            __attribute__ ((const))
Packit Service d328f3
#define _nm_printf(a,b)      __attribute__ ((__format__ (__printf__, a, b)))
Packit Service d328f3
#define _nm_align(s)         __attribute__ ((aligned (s)))
Packit Service d328f3
#define _nm_alignof(type)    __alignof (type)
Packit Service d328f3
#define _nm_alignas(type)    _nm_align (_nm_alignof (type))
Packit Service d328f3
Packit Service d328f3
#if __GNUC__ >= 7
Packit Service d328f3
#define _nm_fallthrough      __attribute__ ((fallthrough))
Packit Service d328f3
#else
Packit Service d328f3
#define _nm_fallthrough
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#ifdef thread_local
Packit Service d328f3
#define _nm_thread_local thread_local
Packit Service d328f3
/*
Packit Service d328f3
 * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
Packit Service d328f3
 * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
Packit Service d328f3
 */
Packit Service d328f3
#elif __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
Packit Service d328f3
#define _nm_thread_local _Thread_local
Packit Service d328f3
#else
Packit Service d328f3
#define _nm_thread_local __thread
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#include "nm-glib.h"
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#define nm_offsetofend(t,m) (G_STRUCT_OFFSET (t,m) + sizeof (((t *) NULL)->m))
Packit Service d328f3
Packit Service d328f3
#define nm_auto(fcn) __attribute__ ((cleanup(fcn)))
Packit Service d328f3
Packit Service d328f3
static inline int nm_close (int fd);
Packit Service d328f3
Packit Service d328f3
/**
Packit Service d328f3
 * nm_auto_free:
Packit Service d328f3
 *
Packit Service d328f3
 * Call free() on a variable location when it goes out of scope.
Packit Service d328f3
 */
Packit Service d328f3
#define nm_auto_free nm_auto(_nm_auto_free_impl)
Packit Service d328f3
GS_DEFINE_CLEANUP_FUNCTION(void*, _nm_auto_free_impl, free)
Packit Service d328f3
Packit Service d328f3
static inline void
Packit Service d328f3
nm_free_secret (char *secret)
Packit Service d328f3
{
Packit Service d328f3
	if (secret) {
Packit Service d328f3
		memset (secret, 0, strlen (secret));
Packit Service d328f3
		g_free (secret);
Packit Service d328f3
	}
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static inline void
Packit Service d328f3
_nm_auto_free_secret_impl (char **v)
Packit Service d328f3
{
Packit Service d328f3
	nm_free_secret (*v);
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/**
Packit Service d328f3
 * nm_auto_free_secret:
Packit Service d328f3
 *
Packit Service d328f3
 * Call g_free() on a variable location when it goes out of scope.
Packit Service d328f3
 * Also, previously, calls memset(loc, 0, strlen(loc)) to clear out
Packit Service d328f3
 * the secret.
Packit Service d328f3
 */
Packit Service d328f3
#define nm_auto_free_secret nm_auto(_nm_auto_free_secret_impl)
Packit Service d328f3
Packit Service d328f3
static inline void
Packit Service d328f3
_nm_auto_unset_gvalue_impl (GValue *v)
Packit Service d328f3
{
Packit Service d328f3
	g_value_unset (v);
Packit Service d328f3
}
Packit Service d328f3
#define nm_auto_unset_gvalue nm_auto(_nm_auto_unset_gvalue_impl)
Packit Service d328f3
Packit Service d328f3
static inline void
Packit Service d328f3
_nm_auto_unref_gtypeclass (gpointer v)
Packit Service d328f3
{
Packit Service d328f3
	if (v && *((gpointer *) v))
Packit Service d328f3
		g_type_class_unref (*((gpointer *) v));
Packit Service d328f3
}
Packit Service d328f3
#define nm_auto_unref_gtypeclass nm_auto(_nm_auto_unref_gtypeclass)
Packit Service d328f3
Packit Service d328f3
static inline void
Packit Service d328f3
_nm_auto_free_gstring_impl (GString **str)
Packit Service d328f3
{
Packit Service d328f3
	if (*str)
Packit Service d328f3
		g_string_free (*str, TRUE);
Packit Service d328f3
}
Packit Service d328f3
#define nm_auto_free_gstring nm_auto(_nm_auto_free_gstring_impl)
Packit Service d328f3
Packit Service d328f3
static inline void
Packit Service d328f3
_nm_auto_close_impl (int *pfd)
Packit Service d328f3
{
Packit Service d328f3
	if (*pfd >= 0) {
Packit Service d328f3
		int errsv = errno;
Packit Service d328f3
Packit Service d328f3
		(void) nm_close (*pfd);
Packit Service d328f3
		errno = errsv;
Packit Service d328f3
	}
Packit Service d328f3
}
Packit Service d328f3
#define nm_auto_close nm_auto(_nm_auto_close_impl)
Packit Service d328f3
Packit Service d328f3
static inline void
Packit Service d328f3
_nm_auto_fclose_impl (FILE **pfd)
Packit Service d328f3
{
Packit Service d328f3
	if (*pfd) {
Packit Service d328f3
		int errsv = errno;
Packit Service d328f3
Packit Service d328f3
		(void) fclose (*pfd);
Packit Service d328f3
		errno = errsv;
Packit Service d328f3
	}
Packit Service d328f3
}
Packit Service d328f3
#define nm_auto_fclose nm_auto(_nm_auto_fclose_impl)
Packit Service d328f3
Packit Service d328f3
static inline void
Packit Service d328f3
_nm_auto_protect_errno (int *p_saved_errno)
Packit Service d328f3
{
Packit Service d328f3
	errno = *p_saved_errno;
Packit Service d328f3
}
Packit Service d328f3
#define NM_AUTO_PROTECT_ERRNO(errsv_saved) nm_auto(_nm_auto_protect_errno) _nm_unused const int errsv_saved = (errno)
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/* http://stackoverflow.com/a/11172679 */
Packit Service d328f3
#define  _NM_UTILS_MACRO_FIRST(...)                           __NM_UTILS_MACRO_FIRST_HELPER(__VA_ARGS__, throwaway)
Packit Service d328f3
#define __NM_UTILS_MACRO_FIRST_HELPER(first, ...)             first
Packit Service d328f3
Packit Service d328f3
#define  _NM_UTILS_MACRO_REST(...)                            __NM_UTILS_MACRO_REST_HELPER(__NM_UTILS_MACRO_REST_NUM(__VA_ARGS__), __VA_ARGS__)
Packit Service d328f3
#define __NM_UTILS_MACRO_REST_HELPER(qty, ...)                __NM_UTILS_MACRO_REST_HELPER2(qty, __VA_ARGS__)
Packit Service d328f3
#define __NM_UTILS_MACRO_REST_HELPER2(qty, ...)               __NM_UTILS_MACRO_REST_HELPER_##qty(__VA_ARGS__)
Packit Service d328f3
#define __NM_UTILS_MACRO_REST_HELPER_ONE(first)
Packit Service d328f3
#define __NM_UTILS_MACRO_REST_HELPER_TWOORMORE(first, ...)    , __VA_ARGS__
Packit Service d328f3
#define __NM_UTILS_MACRO_REST_NUM(...) \
Packit Service d328f3
    __NM_UTILS_MACRO_REST_SELECT_30TH(__VA_ARGS__, \
Packit Service d328f3
                TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
Packit Service d328f3
                TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
Packit Service d328f3
                TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
Packit Service d328f3
                TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
Packit Service d328f3
                TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
Packit Service d328f3
                TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway)
Packit Service d328f3
#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
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/* http://stackoverflow.com/a/2124385/354393 */
Packit Service d328f3
Packit Service d328f3
#define NM_NARG(...) \
Packit Service d328f3
         _NM_NARG(__VA_ARGS__,_NM_NARG_RSEQ_N())
Packit Service d328f3
#define _NM_NARG(...) \
Packit Service d328f3
         _NM_NARG_ARG_N(__VA_ARGS__)
Packit Service d328f3
#define _NM_NARG_ARG_N( \
Packit Service d328f3
          _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
Packit Service d328f3
         _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
Packit Service d328f3
         _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
Packit Service d328f3
         _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
Packit Service d328f3
         _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
Packit Service d328f3
         _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
Packit Service d328f3
         _61,_62,_63,N,...) N
Packit Service d328f3
#define _NM_NARG_RSEQ_N() \
Packit Service d328f3
         63,62,61,60,                   \
Packit Service d328f3
         59,58,57,56,55,54,53,52,51,50, \
Packit Service d328f3
         49,48,47,46,45,44,43,42,41,40, \
Packit Service d328f3
         39,38,37,36,35,34,33,32,31,30, \
Packit Service d328f3
         29,28,27,26,25,24,23,22,21,20, \
Packit Service d328f3
         19,18,17,16,15,14,13,12,11,10, \
Packit Service d328f3
         9,8,7,6,5,4,3,2,1,0
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#if defined (__GNUC__)
Packit Service d328f3
#define _NM_PRAGMA_WARNING_DO(warning)       G_STRINGIFY(GCC diagnostic ignored warning)
Packit Service d328f3
#elif defined (__clang__)
Packit Service d328f3
#define _NM_PRAGMA_WARNING_DO(warning)       G_STRINGIFY(clang diagnostic ignored warning)
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
/* you can only suppress a specific warning that the compiler
Packit Service d328f3
 * understands. Otherwise you will get another compiler warning
Packit Service d328f3
 * about invalid pragma option.
Packit Service d328f3
 * It's not that bad however, because gcc and clang often have the
Packit Service d328f3
 * same name for the same warning. */
Packit Service d328f3
Packit Service d328f3
#if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
Packit Service d328f3
#define NM_PRAGMA_WARNING_DISABLE(warning) \
Packit Service d328f3
        _Pragma("GCC diagnostic push") \
Packit Service d328f3
        _Pragma(_NM_PRAGMA_WARNING_DO(warning))
Packit Service d328f3
#elif defined (__clang__)
Packit Service d328f3
#define NM_PRAGMA_WARNING_DISABLE(warning) \
Packit Service d328f3
        _Pragma("clang diagnostic push") \
Packit Service d328f3
        _Pragma(_NM_PRAGMA_WARNING_DO(warning))
Packit Service d328f3
#else
Packit Service d328f3
#define NM_PRAGMA_WARNING_DISABLE(warning)
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
#if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
Packit Service d328f3
#define NM_PRAGMA_WARNING_REENABLE \
Packit Service d328f3
    _Pragma("GCC diagnostic pop")
Packit Service d328f3
#elif defined (__clang__)
Packit Service d328f3
#define NM_PRAGMA_WARNING_REENABLE \
Packit Service d328f3
    _Pragma("clang diagnostic pop")
Packit Service d328f3
#else
Packit Service d328f3
#define NM_PRAGMA_WARNING_REENABLE
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/**
Packit Service d328f3
 * NM_G_ERROR_MSG:
Packit Service d328f3
 * @error: (allow-none): the #GError instance
Packit Service d328f3
 *
Packit Service d328f3
 * All functions must follow the convention that when they
Packit Service d328f3
 * return a failure, they must also set the GError to a valid
Packit Service d328f3
 * message. For external API however, we want to be extra
Packit Service d328f3
 * careful before accessing the error instance. Use NM_G_ERROR_MSG()
Packit Service d328f3
 * which is safe to use on NULL.
Packit Service d328f3
 *
Packit Service d328f3
 * Returns: the error message.
Packit Service d328f3
 **/
Packit Service d328f3
static inline const char *
Packit Service d328f3
NM_G_ERROR_MSG (GError *error)
Packit Service d328f3
{
Packit Service d328f3
	return error ? (error->message ? : "(null)") : "(no-error)"; \
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/* macro to return strlen() of a compile time string. */
Packit Service d328f3
#define NM_STRLEN(str)     ( sizeof ("" str) - 1 )
Packit Service d328f3
Packit Service d328f3
/* returns the length of a NULL terminated array of pointers,
Packit Service d328f3
 * like g_strv_length() does. The difference is:
Packit Service d328f3
 *  - it operats on arrays of pointers (of any kind, requiring no cast).
Packit Service d328f3
 *  - it accepts NULL to return zero. */
Packit Service d328f3
#define NM_PTRARRAY_LEN(array) \
Packit Service d328f3
	({ \
Packit Service d328f3
		typeof (*(array)) *const _array = (array); \
Packit Service d328f3
		gsize _n = 0; \
Packit Service d328f3
		\
Packit Service d328f3
		if (_array) { \
Packit Service d328f3
			_nm_unused typeof (*(_array[0])) *_array_check = _array[0]; \
Packit Service d328f3
			while (_array[_n]) \
Packit Service d328f3
				_n++; \
Packit Service d328f3
		} \
Packit Service d328f3
		_n; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
/* Note: @value is only evaluated when *out_val is present.
Packit Service d328f3
 * Thus,
Packit Service d328f3
 *    NM_SET_OUT (out_str, g_strdup ("hallo"));
Packit Service d328f3
 * does the right thing.
Packit Service d328f3
 */
Packit Service d328f3
#define NM_SET_OUT(out_val, value) \
Packit Service d328f3
	G_STMT_START { \
Packit Service d328f3
		typeof(*(out_val)) *_out_val = (out_val); \
Packit Service d328f3
		\
Packit Service d328f3
		if (_out_val) { \
Packit Service d328f3
			*_out_val = (value); \
Packit Service d328f3
		} \
Packit Service d328f3
	} G_STMT_END
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#ifndef _NM_CC_SUPPORT_AUTO_TYPE
Packit Service d328f3
#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 )))
Packit Service d328f3
#define _NM_CC_SUPPORT_AUTO_TYPE 1
Packit Service d328f3
#else
Packit Service d328f3
#define _NM_CC_SUPPORT_AUTO_TYPE 0
Packit Service d328f3
#endif
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
#ifndef _NM_CC_SUPPORT_GENERIC
Packit Service d328f3
#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 ))) || (defined (__clang__))
Packit Service d328f3
#define _NM_CC_SUPPORT_GENERIC 1
Packit Service d328f3
#else
Packit Service d328f3
#define _NM_CC_SUPPORT_GENERIC 0
Packit Service d328f3
#endif
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
#if _NM_CC_SUPPORT_AUTO_TYPE
Packit Service d328f3
#define _nm_auto_type __auto_type
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
#if _NM_CC_SUPPORT_GENERIC
Packit Service d328f3
#define _NM_CONSTCAST_FULL_1(type, obj_expr, obj) \
Packit Service d328f3
	(_Generic ((obj_expr), \
Packit Service d328f3
	           const void        *const: ((const type *) (obj)), \
Packit Service d328f3
	           const void        *     : ((const type *) (obj)), \
Packit Service d328f3
	                 void        *const: ((      type *) (obj)), \
Packit Service d328f3
	                 void        *     : ((      type *) (obj)), \
Packit Service d328f3
	           const type        *const: ((const type *) (obj)), \
Packit Service d328f3
	           const type        *     : ((const type *) (obj)), \
Packit Service d328f3
	                 type        *const: ((      type *) (obj)), \
Packit Service d328f3
	                 type        *     : ((      type *) (obj))))
Packit Service d328f3
#define _NM_CONSTCAST_FULL_2(type, obj_expr, obj, alias_type2) \
Packit Service d328f3
	(_Generic ((obj_expr), \
Packit Service d328f3
	           const void        *const: ((const type *) (obj)), \
Packit Service d328f3
	           const void        *     : ((const type *) (obj)), \
Packit Service d328f3
	                 void        *const: ((      type *) (obj)), \
Packit Service d328f3
	                 void        *     : ((      type *) (obj)), \
Packit Service d328f3
	           const alias_type2 *const: ((const type *) (obj)), \
Packit Service d328f3
	           const alias_type2 *     : ((const type *) (obj)), \
Packit Service d328f3
	                 alias_type2 *const: ((      type *) (obj)), \
Packit Service d328f3
	                 alias_type2 *     : ((      type *) (obj)), \
Packit Service d328f3
	           const type        *const: ((const type *) (obj)), \
Packit Service d328f3
	           const type        *     : ((const type *) (obj)), \
Packit Service d328f3
	                 type        *const: ((      type *) (obj)), \
Packit Service d328f3
	                 type        *     : ((      type *) (obj))))
Packit Service d328f3
#define _NM_CONSTCAST_FULL_3(type, obj_expr, obj, alias_type2, alias_type3) \
Packit Service d328f3
	(_Generic ((obj_expr), \
Packit Service d328f3
	           const void        *const: ((const type *) (obj)), \
Packit Service d328f3
	           const void        *     : ((const type *) (obj)), \
Packit Service d328f3
	                 void        *const: ((      type *) (obj)), \
Packit Service d328f3
	                 void        *     : ((      type *) (obj)), \
Packit Service d328f3
	           const alias_type2 *const: ((const type *) (obj)), \
Packit Service d328f3
	           const alias_type2 *     : ((const type *) (obj)), \
Packit Service d328f3
	                 alias_type2 *const: ((      type *) (obj)), \
Packit Service d328f3
	                 alias_type2 *     : ((      type *) (obj)), \
Packit Service d328f3
	           const alias_type3 *const: ((const type *) (obj)), \
Packit Service d328f3
	           const alias_type3 *     : ((const type *) (obj)), \
Packit Service d328f3
	                 alias_type3 *const: ((      type *) (obj)), \
Packit Service d328f3
	                 alias_type3 *     : ((      type *) (obj)), \
Packit Service d328f3
	           const type        *const: ((const type *) (obj)), \
Packit Service d328f3
	           const type        *     : ((const type *) (obj)), \
Packit Service d328f3
	                 type        *const: ((      type *) (obj)), \
Packit Service d328f3
	                 type        *     : ((      type *) (obj))))
Packit Service d328f3
#define _NM_CONSTCAST_FULL_4(type, obj_expr, obj, alias_type2, alias_type3, alias_type4) \
Packit Service d328f3
	(_Generic ((obj_expr), \
Packit Service d328f3
	           const void        *const: ((const type *) (obj)), \
Packit Service d328f3
	           const void        *     : ((const type *) (obj)), \
Packit Service d328f3
	                 void        *const: ((      type *) (obj)), \
Packit Service d328f3
	                 void        *     : ((      type *) (obj)), \
Packit Service d328f3
	           const alias_type2 *const: ((const type *) (obj)), \
Packit Service d328f3
	           const alias_type2 *     : ((const type *) (obj)), \
Packit Service d328f3
	                 alias_type2 *const: ((      type *) (obj)), \
Packit Service d328f3
	                 alias_type2 *     : ((      type *) (obj)), \
Packit Service d328f3
	           const alias_type3 *const: ((const type *) (obj)), \
Packit Service d328f3
	           const alias_type3 *     : ((const type *) (obj)), \
Packit Service d328f3
	                 alias_type3 *const: ((      type *) (obj)), \
Packit Service d328f3
	                 alias_type3 *     : ((      type *) (obj)), \
Packit Service d328f3
	           const alias_type4 *const: ((const type *) (obj)), \
Packit Service d328f3
	           const alias_type4 *     : ((const type *) (obj)), \
Packit Service d328f3
	                 alias_type4 *const: ((      type *) (obj)), \
Packit Service d328f3
	                 alias_type4 *     : ((      type *) (obj)), \
Packit Service d328f3
	           const type        *const: ((const type *) (obj)), \
Packit Service d328f3
	           const type        *     : ((const type *) (obj)), \
Packit Service d328f3
	                 type        *const: ((      type *) (obj)), \
Packit Service d328f3
	                 type        *     : ((      type *) (obj))))
Packit Service d328f3
#define _NM_CONSTCAST_FULL_x(type, obj_expr, obj, n, ...)   (_NM_CONSTCAST_FULL_##n (type, obj_expr, obj,                        ##__VA_ARGS__))
Packit Service d328f3
#define _NM_CONSTCAST_FULL_y(type, obj_expr, obj, n, ...)   (_NM_CONSTCAST_FULL_x   (type, obj_expr, obj, n,                     ##__VA_ARGS__))
Packit Service d328f3
#define NM_CONSTCAST_FULL(   type, obj_expr, obj,    ...)   (_NM_CONSTCAST_FULL_y   (type, obj_expr, obj, NM_NARG (dummy, ##__VA_ARGS__), ##__VA_ARGS__))
Packit Service d328f3
#else
Packit Service d328f3
#define NM_CONSTCAST_FULL(   type, obj_expr, obj,    ...)   ((type *) (obj))
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
#define NM_CONSTCAST(type, obj, ...) \
Packit Service d328f3
	NM_CONSTCAST_FULL(type, (obj), (obj), ##__VA_ARGS__)
Packit Service d328f3
Packit Service d328f3
#define NM_GOBJECT_CAST(type, obj, is_check, ...) \
Packit Service d328f3
	({ \
Packit Service d328f3
		const void *_obj = (obj); \
Packit Service d328f3
		\
Packit Service d328f3
		nm_assert (_obj || (is_check (_obj))); \
Packit Service d328f3
		NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
#define NM_GOBJECT_CAST_NON_NULL(type, obj, is_check, ...) \
Packit Service d328f3
	({ \
Packit Service d328f3
		const void *_obj = (obj); \
Packit Service d328f3
		\
Packit Service d328f3
		nm_assert (is_check (_obj)); \
Packit Service d328f3
		NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
#if _NM_CC_SUPPORT_GENERIC
Packit Service d328f3
/* returns @value, if the type of @value matches @type.
Packit Service d328f3
 * This requires support for C11 _Generic(). If no support is
Packit Service d328f3
 * present, this returns @value directly.
Packit Service d328f3
 *
Packit Service d328f3
 * It's useful to check the let the compiler ensure that @value is
Packit Service d328f3
 * of a certain type. */
Packit Service d328f3
#define _NM_ENSURE_TYPE(type, value) (_Generic ((value), type: (value)))
Packit Service d328f3
#else
Packit Service d328f3
#define _NM_ENSURE_TYPE(type, value) (value)
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
#if _NM_CC_SUPPORT_GENERIC
Packit Service d328f3
#define NM_PROPAGATE_CONST(test_expr, ptr) \
Packit Service d328f3
	(_Generic ((test_expr), \
Packit Service d328f3
	           const typeof (*(test_expr)) *: ((const typeof (*(ptr)) *) (ptr)), \
Packit Service d328f3
	                                 default: (_Generic ((test_expr), \
Packit Service d328f3
	                                                     typeof (*(test_expr)) *: (ptr)))))
Packit Service d328f3
#else
Packit Service d328f3
#define NM_PROPAGATE_CONST(test_expr, ptr) (ptr)
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#define _NM_IN_SET_EVAL_1( op, _x, y)           (_x == (y))
Packit Service d328f3
#define _NM_IN_SET_EVAL_2( op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_1  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_3( op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_2  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_4( op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_3  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_5( op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_4  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_6( op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_5  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_7( op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_6  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_8( op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_7  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_9( op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_8  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_10(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_9  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_11(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_10 (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_12(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_11 (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_13(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_12 (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_14(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_13 (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_15(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_14 (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_SET_EVAL_16(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_15 (op, _x, __VA_ARGS__)
Packit Service d328f3
Packit Service d328f3
#define _NM_IN_SET_EVAL_N2(op, _x, n, ...)      (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__))
Packit Service d328f3
#define _NM_IN_SET_EVAL_N(op, type, x, n, ...)                      \
Packit Service d328f3
    ({                                                              \
Packit Service d328f3
        type _x = (x);                                              \
Packit Service d328f3
                                                                    \
Packit Service d328f3
        /* trigger a -Wenum-compare warning */                      \
Packit Service d328f3
        nm_assert (TRUE || _x == (x));                              \
Packit Service d328f3
                                                                    \
Packit Service d328f3
        !!_NM_IN_SET_EVAL_N2(op, _x, n, __VA_ARGS__);               \
Packit Service d328f3
    })
Packit Service d328f3
Packit Service d328f3
#define _NM_IN_SET(op, type, x, ...)        _NM_IN_SET_EVAL_N(op, type, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
Packit Service d328f3
Packit Service d328f3
/* Beware that this does short-circuit evaluation (use "||" instead of "|")
Packit Service d328f3
 * which has a possibly unexpected non-function-like behavior.
Packit Service d328f3
 * Use NM_IN_SET_SE if you need all arguments to be evaluted. */
Packit Service d328f3
#define NM_IN_SET(x, ...)                   _NM_IN_SET(||, typeof (x), x, __VA_ARGS__)
Packit Service d328f3
Packit Service d328f3
/* "SE" stands for "side-effect". Contrary to NM_IN_SET(), this does not do
Packit Service d328f3
 * short-circuit evaluation, which can make a difference if the arguments have
Packit Service d328f3
 * side-effects. */
Packit Service d328f3
#define NM_IN_SET_SE(x, ...)                _NM_IN_SET(|,  typeof (x), x, __VA_ARGS__)
Packit Service d328f3
Packit Service d328f3
/* the *_TYPED forms allow to explicitly select the type of "x". This is useful
Packit Service d328f3
 * if "x" doesn't support typeof (bitfields) or you want to gracefully convert
Packit Service d328f3
 * a type using automatic type conversion rules (but not forcing the conversion
Packit Service d328f3
 * with a cast). */
Packit Service d328f3
#define NM_IN_SET_TYPED(type, x, ...)       _NM_IN_SET(||, type,       x, __VA_ARGS__)
Packit Service d328f3
#define NM_IN_SET_SE_TYPED(type, x, ...)    _NM_IN_SET(|,  type,       x, __VA_ARGS__)
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
static inline gboolean
Packit Service d328f3
_NM_IN_STRSET_streq (const char *x, const char *s)
Packit Service d328f3
{
Packit Service d328f3
	return s && strcmp (x, s) == 0;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_1( op, _x, y)        _NM_IN_STRSET_streq (_x, y)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_2( op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_1  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_3( op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_2  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_4( op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_3  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_5( op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_4  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_6( op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_5  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_7( op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_6  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_8( op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_7  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_9( op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_8  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_10(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_9  (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_11(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_10 (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_12(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_11 (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_13(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_12 (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_14(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_13 (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_15(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_14 (op, _x, __VA_ARGS__)
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_16(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_15 (op, _x, __VA_ARGS__)
Packit Service d328f3
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_N2(op, _x, n, ...)   (_NM_IN_STRSET_EVAL_##n(op, _x, __VA_ARGS__))
Packit Service d328f3
#define _NM_IN_STRSET_EVAL_N(op, x, n, ...)                       \
Packit Service d328f3
    ({                                                            \
Packit Service d328f3
        const char *_x = (x);                                     \
Packit Service d328f3
        (   ((_x == NULL) && _NM_IN_SET_EVAL_N2    (op, ((const char *) NULL), n, __VA_ARGS__)) \
Packit Service d328f3
         || ((_x != NULL) && _NM_IN_STRSET_EVAL_N2 (op, _x,                    n, __VA_ARGS__)) \
Packit Service d328f3
        ); \
Packit Service d328f3
    })
Packit Service d328f3
Packit Service d328f3
/* Beware that this does short-circuit evaluation (use "||" instead of "|")
Packit Service d328f3
 * which has a possibly unexpected non-function-like behavior.
Packit Service d328f3
 * Use NM_IN_STRSET_SE if you need all arguments to be evaluted. */
Packit Service d328f3
#define NM_IN_STRSET(x, ...)               _NM_IN_STRSET_EVAL_N(||, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
Packit Service d328f3
Packit Service d328f3
/* "SE" stands for "side-effect". Contrary to NM_IN_STRSET(), this does not do
Packit Service d328f3
 * short-circuit evaluation, which can make a difference if the arguments have
Packit Service d328f3
 * side-effects. */
Packit Service d328f3
#define NM_IN_STRSET_SE(x, ...)            _NM_IN_STRSET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
Packit Service d328f3
Packit Service d328f3
#define NM_STRCHAR_ALL(str, ch_iter, predicate) \
Packit Service d328f3
	({ \
Packit Service d328f3
		gboolean _val = TRUE; \
Packit Service d328f3
		const char *_str = (str); \
Packit Service d328f3
		\
Packit Service d328f3
		if (_str) { \
Packit Service d328f3
			for (;;) { \
Packit Service d328f3
				const char ch_iter = _str[0]; \
Packit Service d328f3
				\
Packit Service d328f3
				if (ch_iter != '\0') { \
Packit Service d328f3
					if (predicate) {\
Packit Service d328f3
						_str++; \
Packit Service d328f3
						continue; \
Packit Service d328f3
					} \
Packit Service d328f3
					_val = FALSE; \
Packit Service d328f3
				} \
Packit Service d328f3
				break; \
Packit Service d328f3
			} \
Packit Service d328f3
		} \
Packit Service d328f3
		_val; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
#define NM_STRCHAR_ANY(str, ch_iter, predicate) \
Packit Service d328f3
	({ \
Packit Service d328f3
		gboolean _val = FALSE; \
Packit Service d328f3
		const char *_str = (str); \
Packit Service d328f3
		\
Packit Service d328f3
		if (_str) { \
Packit Service d328f3
			for (;;) { \
Packit Service d328f3
				const char ch_iter = _str[0]; \
Packit Service d328f3
				\
Packit Service d328f3
				if (ch_iter != '\0') { \
Packit Service d328f3
					if (predicate) { \
Packit Service d328f3
						; \
Packit Service d328f3
					} else { \
Packit Service d328f3
						_str++; \
Packit Service d328f3
						continue; \
Packit Service d328f3
					} \
Packit Service d328f3
					_val = TRUE; \
Packit Service d328f3
				} \
Packit Service d328f3
				break; \
Packit Service d328f3
			} \
Packit Service d328f3
		} \
Packit Service d328f3
		_val; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/* NM_CACHED_QUARK() returns the GQuark for @string, but caches
Packit Service d328f3
 * it in a static variable to speed up future lookups.
Packit Service d328f3
 *
Packit Service d328f3
 * @string must be a string literal.
Packit Service d328f3
 */
Packit Service d328f3
#define NM_CACHED_QUARK(string) \
Packit Service d328f3
	({ \
Packit Service d328f3
		static GQuark _nm_cached_quark = 0; \
Packit Service d328f3
		\
Packit Service d328f3
		(G_LIKELY (_nm_cached_quark != 0) \
Packit Service d328f3
			? _nm_cached_quark \
Packit Service d328f3
			: (_nm_cached_quark = g_quark_from_static_string (""string""))); \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
/* NM_CACHED_QUARK_FCN() is essentially the same as G_DEFINE_QUARK
Packit Service d328f3
 * with two differences:
Packit Service d328f3
 * - @string must be a quoted string-literal
Packit Service d328f3
 * - @fcn must be the full function name, while G_DEFINE_QUARK() appends
Packit Service d328f3
 *   "_quark" to the function name.
Packit Service d328f3
 * Both properties of G_DEFINE_QUARK() are non favorable, because you can no
Packit Service d328f3
 * longer grep for string/fcn -- unless you are aware that you are searching
Packit Service d328f3
 * for G_DEFINE_QUARK() and omit quotes / append _quark(). With NM_CACHED_QUARK_FCN(),
Packit Service d328f3
 * ctags/cscope can locate the use of @fcn (though it doesn't recognize that
Packit Service d328f3
 * NM_CACHED_QUARK_FCN() defines it).
Packit Service d328f3
 */
Packit Service d328f3
#define NM_CACHED_QUARK_FCN(string, fcn) \
Packit Service d328f3
GQuark \
Packit Service d328f3
fcn (void) \
Packit Service d328f3
{ \
Packit Service d328f3
	return NM_CACHED_QUARK (string); \
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#define nm_streq(s1, s2)  (strcmp (s1, s2) == 0)
Packit Service d328f3
#define nm_streq0(s1, s2) (g_strcmp0 (s1, s2) == 0)
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
static inline GString *
Packit Service d328f3
nm_gstring_prepare (GString **l)
Packit Service d328f3
{
Packit Service d328f3
	if (*l)
Packit Service d328f3
		g_string_set_size (*l, 0);
Packit Service d328f3
	else
Packit Service d328f3
		*l = g_string_sized_new (30);
Packit Service d328f3
	return *l;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static inline const char *
Packit Service d328f3
nm_str_not_empty (const char *str)
Packit Service d328f3
{
Packit Service d328f3
	return str && str[0] ? str : NULL;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static inline char *
Packit Service d328f3
nm_strdup_not_empty (const char *str)
Packit Service d328f3
{
Packit Service d328f3
	return str && str[0] ? g_strdup (str) : NULL;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static inline char *
Packit Service d328f3
nm_str_realloc (char *str)
Packit Service d328f3
{
Packit Service d328f3
	gs_free char *s = str;
Packit Service d328f3
Packit Service d328f3
	/* Returns a new clone of @str and frees @str. The point is that @str
Packit Service d328f3
	 * possibly points to a larger chunck of memory. We want to freshly allocate
Packit Service d328f3
	 * a buffer.
Packit Service d328f3
	 *
Packit Service d328f3
	 * We could use realloc(), but that might not do anything or leave
Packit Service d328f3
	 * @str in its memory pool for chunks of a different size (bad for
Packit Service d328f3
	 * fragmentation).
Packit Service d328f3
	 *
Packit Service d328f3
	 * This is only useful when we want to keep the buffer around for a long
Packit Service d328f3
	 * time and want to re-allocate a more optimal buffer. */
Packit Service d328f3
Packit Service d328f3
	return g_strdup (s);
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \
Packit Service d328f3
	(cond) ? (prefix) : "", \
Packit Service d328f3
	(cond) ? (str) : (str_else), \
Packit Service d328f3
	(cond) ? (suffix) : ""
Packit Service d328f3
#define NM_PRINT_FMT_QUOTE_STRING(arg) NM_PRINT_FMT_QUOTED((arg), "\"", (arg), "\"", "(null)")
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/* glib/C provides the following kind of assertions:
Packit Service d328f3
 *   - assert() -- disable with NDEBUG
Packit Service d328f3
 *   - g_return_if_fail() -- disable with G_DISABLE_CHECKS
Packit Service d328f3
 *   - g_assert() -- disable with G_DISABLE_ASSERT
Packit Service d328f3
 * but they are all enabled by default and usually even production builds have
Packit Service d328f3
 * these kind of assertions enabled. It also means, that disabling assertions
Packit Service d328f3
 * is an untested configuration, and might have bugs.
Packit Service d328f3
 *
Packit Service d328f3
 * Add our own assertion macro nm_assert(), which is disabled by default and must
Packit Service d328f3
 * be explicitly enabled. They are useful for more expensive checks or checks that
Packit Service d328f3
 * depend less on runtime conditions (that is, are generally expected to be true). */
Packit Service d328f3
Packit Service d328f3
#ifndef NM_MORE_ASSERTS
Packit Service d328f3
#define NM_MORE_ASSERTS 0
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
#if NM_MORE_ASSERTS
Packit Service d328f3
#define nm_assert(cond) G_STMT_START { g_assert (cond); } G_STMT_END
Packit Service d328f3
#define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } else { g_assert (FALSE && (cond)); } } G_STMT_END
Packit Service d328f3
#define nm_assert_not_reached() G_STMT_START { g_assert_not_reached (); } G_STMT_END
Packit Service d328f3
#else
Packit Service d328f3
#define nm_assert(cond) G_STMT_START { if (FALSE) { if (cond) { } } } G_STMT_END
Packit Service d328f3
#define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } } G_STMT_END
Packit Service d328f3
#define nm_assert_not_reached() G_STMT_START { ; } G_STMT_END
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#define NM_GOBJECT_PROPERTIES_DEFINE_BASE(...) \
Packit Service d328f3
typedef enum { \
Packit Service d328f3
	_PROPERTY_ENUMS_0, \
Packit Service d328f3
	__VA_ARGS__ \
Packit Service d328f3
	_PROPERTY_ENUMS_LAST, \
Packit Service d328f3
} _PropertyEnums; \
Packit Service d328f3
static GParamSpec *obj_properties[_PROPERTY_ENUMS_LAST] = { NULL, }
Packit Service d328f3
Packit Service d328f3
#define NM_GOBJECT_PROPERTIES_DEFINE(obj_type, ...) \
Packit Service d328f3
NM_GOBJECT_PROPERTIES_DEFINE_BASE (__VA_ARGS__); \
Packit Service d328f3
static inline void \
Packit Service d328f3
_notify (obj_type *obj, _PropertyEnums prop) \
Packit Service d328f3
{ \
Packit Service d328f3
	nm_assert (G_IS_OBJECT (obj)); \
Packit Service d328f3
	nm_assert ((gsize) prop < G_N_ELEMENTS (obj_properties)); \
Packit Service d328f3
	g_object_notify_by_pspec ((GObject *) obj, obj_properties[prop]); \
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#define _NM_GET_PRIVATE(self, type, is_check, ...) (&(NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv))
Packit Service d328f3
#if _NM_CC_SUPPORT_AUTO_TYPE
Packit Service d328f3
#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) \
Packit Service d328f3
	({ \
Packit Service d328f3
		_nm_auto_type _self = NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__); \
Packit Service d328f3
		\
Packit Service d328f3
		NM_PROPAGATE_CONST (_self, _self->_priv); \
Packit Service d328f3
	})
Packit Service d328f3
#else
Packit Service d328f3
#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) (NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv)
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
static inline gpointer
Packit Service d328f3
nm_g_object_ref (gpointer obj)
Packit Service d328f3
{
Packit Service d328f3
	/* g_object_ref() doesn't accept NULL. */
Packit Service d328f3
	if (obj)
Packit Service d328f3
		g_object_ref (obj);
Packit Service d328f3
	return obj;
Packit Service d328f3
}
Packit Service d328f3
#define nm_g_object_ref(obj) ((typeof (obj)) nm_g_object_ref (obj))
Packit Service d328f3
Packit Service d328f3
static inline void
Packit Service d328f3
nm_g_object_unref (gpointer obj)
Packit Service d328f3
{
Packit Service d328f3
	/* g_object_unref() doesn't accept NULL. Usully, we workaround that
Packit Service d328f3
	 * by using g_clear_object(), but sometimes that is not convinient
Packit Service d328f3
	 * (for example as as destroy function for a hash table that can contain
Packit Service d328f3
	 * NULL values). */
Packit Service d328f3
	if (obj)
Packit Service d328f3
		g_object_unref (obj);
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/* Assigns GObject @obj to destination @pdst, and takes an additional ref.
Packit Service d328f3
 * The previous value of @pdst is unrefed.
Packit Service d328f3
 *
Packit Service d328f3
 * It makes sure to first increase the ref-count of @obj, and handles %NULL
Packit Service d328f3
 * @obj correctly.
Packit Service d328f3
 * */
Packit Service d328f3
#define nm_g_object_ref_set(pp, obj) \
Packit Service d328f3
	({ \
Packit Service d328f3
		typeof (*(pp)) *const _pp = (pp); \
Packit Service d328f3
		typeof (**_pp) *const _obj = (obj); \
Packit Service d328f3
		typeof (**_pp) *_p; \
Packit Service d328f3
		gboolean _changed = FALSE; \
Packit Service d328f3
		\
Packit Service d328f3
		if (   _pp \
Packit Service d328f3
		    && ((_p = *_pp) != _obj)) { \
Packit Service d328f3
			if (_obj) { \
Packit Service d328f3
				nm_assert (G_IS_OBJECT (_obj)); \
Packit Service d328f3
				 g_object_ref (_obj); \
Packit Service d328f3
			} \
Packit Service d328f3
			if (_p) { \
Packit Service d328f3
				nm_assert (G_IS_OBJECT (_p)); \
Packit Service d328f3
				*_pp = NULL; \
Packit Service d328f3
				g_object_unref (_p); \
Packit Service d328f3
			} \
Packit Service d328f3
			*_pp = _obj; \
Packit Service d328f3
			_changed = TRUE; \
Packit Service d328f3
		} \
Packit Service d328f3
		_changed; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
/* basically, replaces
Packit Service d328f3
 *   g_clear_pointer (&location, g_free)
Packit Service d328f3
 * with
Packit Service d328f3
 *   nm_clear_g_free (&location)
Packit Service d328f3
 *
Packit Service d328f3
 * Another advantage is that by using a macro and typeof(), it is more
Packit Service d328f3
 * typesafe and gives you for example a compiler warning when pp is a const
Packit Service d328f3
 * pointer or points to a const-pointer.
Packit Service d328f3
 */
Packit Service d328f3
#define nm_clear_g_free(pp) \
Packit Service d328f3
	({  \
Packit Service d328f3
		typeof (*(pp)) *_pp = (pp); \
Packit Service d328f3
		typeof (**_pp) *_p; \
Packit Service d328f3
		gboolean _changed = FALSE; \
Packit Service d328f3
		\
Packit Service d328f3
		if (  _pp \
Packit Service d328f3
		    && (_p = *_pp)) { \
Packit Service d328f3
			*_pp = NULL; \
Packit Service d328f3
			g_free (_p); \
Packit Service d328f3
			_changed = TRUE; \
Packit Service d328f3
		} \
Packit Service d328f3
		_changed; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
#define nm_clear_g_object(pp) \
Packit Service d328f3
	({ \
Packit Service d328f3
		typeof (*(pp)) *_pp = (pp); \
Packit Service d328f3
		typeof (**_pp) *_p; \
Packit Service d328f3
		gboolean _changed = FALSE; \
Packit Service d328f3
		\
Packit Service d328f3
		if (   _pp \
Packit Service d328f3
		    && (_p = *_pp)) { \
Packit Service d328f3
			nm_assert (G_IS_OBJECT (_p)); \
Packit Service d328f3
			*_pp = NULL; \
Packit Service d328f3
			g_object_unref (_p); \
Packit Service d328f3
			_changed = TRUE; \
Packit Service d328f3
		} \
Packit Service d328f3
		_changed; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
static inline gboolean
Packit Service d328f3
nm_clear_g_source (guint *id)
Packit Service d328f3
{
Packit Service d328f3
	if (id && *id) {
Packit Service d328f3
		g_source_remove (*id);
Packit Service d328f3
		*id = 0;
Packit Service d328f3
		return TRUE;
Packit Service d328f3
	}
Packit Service d328f3
	return FALSE;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static inline gboolean
Packit Service d328f3
nm_clear_g_signal_handler (gpointer self, gulong *id)
Packit Service d328f3
{
Packit Service d328f3
	if (id && *id) {
Packit Service d328f3
		g_signal_handler_disconnect (self, *id);
Packit Service d328f3
		*id = 0;
Packit Service d328f3
		return TRUE;
Packit Service d328f3
	}
Packit Service d328f3
	return FALSE;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static inline gboolean
Packit Service d328f3
nm_clear_g_variant (GVariant **variant)
Packit Service d328f3
{
Packit Service d328f3
	if (variant && *variant) {
Packit Service d328f3
		g_variant_unref (*variant);
Packit Service d328f3
		*variant = NULL;
Packit Service d328f3
		return TRUE;
Packit Service d328f3
	}
Packit Service d328f3
	return FALSE;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static inline gboolean
Packit Service d328f3
nm_clear_g_cancellable (GCancellable **cancellable)
Packit Service d328f3
{
Packit Service d328f3
	if (cancellable && *cancellable) {
Packit Service d328f3
		g_cancellable_cancel (*cancellable);
Packit Service d328f3
		g_object_unref (*cancellable);
Packit Service d328f3
		*cancellable = NULL;
Packit Service d328f3
		return TRUE;
Packit Service d328f3
	}
Packit Service d328f3
	return FALSE;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/* Determine whether @x is a power of two (@x being an integer type).
Packit Service d328f3
 * Basically, this returns TRUE, if @x has exactly one bit set.
Packit Service d328f3
 * For negative values and zero, this always returns FALSE. */
Packit Service d328f3
#define nm_utils_is_power_of_two(x) ({ \
Packit Service d328f3
		typeof(x) __x = (x); \
Packit Service d328f3
		\
Packit Service d328f3
		(    (__x > ((typeof(__x)) 0)) \
Packit Service d328f3
		 && ((__x & (__x - (((typeof(__x)) 1)))) == ((typeof(__x)) 0))); \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#define NM_UTILS_LOOKUP_DEFAULT(v)            return (v)
Packit Service d328f3
#define NM_UTILS_LOOKUP_DEFAULT_WARN(v)       g_return_val_if_reached (v)
Packit Service d328f3
#define NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT(v)  { nm_assert_not_reached (); return (v); }
Packit Service d328f3
#define NM_UTILS_LOOKUP_ITEM(v, n)            (void) 0; case v: return (n); (void) 0
Packit Service d328f3
#define NM_UTILS_LOOKUP_STR_ITEM(v, n)        NM_UTILS_LOOKUP_ITEM(v, ""n"")
Packit Service d328f3
#define NM_UTILS_LOOKUP_ITEM_IGNORE(v)        (void) 0; case v: break; (void) 0
Packit Service d328f3
#define NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER()   (void) 0; default: break; (void) 0
Packit Service d328f3
Packit Service d328f3
#define _NM_UTILS_LOOKUP_DEFINE(scope, fcn_name, lookup_type, result_type, unknown_val, ...) \
Packit Service d328f3
scope result_type \
Packit Service d328f3
fcn_name (lookup_type val) \
Packit Service d328f3
{ \
Packit Service d328f3
	switch (val) { \
Packit Service d328f3
		(void) 0, \
Packit Service d328f3
		__VA_ARGS__ \
Packit Service d328f3
		(void) 0; \
Packit Service d328f3
	}; \
Packit Service d328f3
	{ unknown_val; } \
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
#define NM_UTILS_LOOKUP_STR_DEFINE(fcn_name, lookup_type, unknown_val, ...) \
Packit Service d328f3
	_NM_UTILS_LOOKUP_DEFINE (, fcn_name, lookup_type, const char *, unknown_val, __VA_ARGS__)
Packit Service d328f3
#define NM_UTILS_LOOKUP_STR_DEFINE_STATIC(fcn_name, lookup_type, unknown_val, ...) \
Packit Service d328f3
	_NM_UTILS_LOOKUP_DEFINE (static, fcn_name, lookup_type, const char *, unknown_val, __VA_ARGS__)
Packit Service d328f3
Packit Service d328f3
/* Call the string-lookup-table function @fcn_name. If the function returns
Packit Service d328f3
 * %NULL, the numeric index is converted to string using a alloca() buffer.
Packit Service d328f3
 * Beware: this macro uses alloca(). */
Packit Service d328f3
#define NM_UTILS_LOOKUP_STR(fcn_name, idx) \
Packit Service d328f3
	({ \
Packit Service d328f3
		typeof (idx) _idx = (idx); \
Packit Service d328f3
		const char *_s; \
Packit Service d328f3
		\
Packit Service d328f3
		_s = fcn_name (_idx); \
Packit Service d328f3
		if (!_s) { \
Packit Service d328f3
			_s = g_alloca (30); \
Packit Service d328f3
			\
Packit Service d328f3
			g_snprintf ((char *) _s, 30, "(%lld)", (long long) _idx); \
Packit Service d328f3
		} \
Packit Service d328f3
		_s; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/* check if @flags has exactly one flag (@check) set. You should call this
Packit Service d328f3
 * only with @check being a compile time constant and a power of two. */
Packit Service d328f3
#define NM_FLAGS_HAS(flags, check)  \
Packit Service d328f3
    ( G_STATIC_ASSERT_EXPR ((check) > 0 && ((check) & ((check) - 1)) == 0), NM_FLAGS_ANY ((flags), (check)) )
Packit Service d328f3
Packit Service d328f3
#define NM_FLAGS_ANY(flags, check)  ( ( ((flags) & (check)) != 0       ) ? TRUE : FALSE )
Packit Service d328f3
#define NM_FLAGS_ALL(flags, check)  ( ( ((flags) & (check)) == (check) ) ? TRUE : FALSE )
Packit Service d328f3
Packit Service d328f3
#define NM_FLAGS_SET(flags, val)  ({ \
Packit Service d328f3
		const typeof(flags) _flags = (flags); \
Packit Service d328f3
		const typeof(flags) _val = (val); \
Packit Service d328f3
		\
Packit Service d328f3
		_flags | _val; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
#define NM_FLAGS_UNSET(flags, val)  ({ \
Packit Service d328f3
		const typeof(flags) _flags = (flags); \
Packit Service d328f3
		const typeof(flags) _val = (val); \
Packit Service d328f3
		\
Packit Service d328f3
		_flags & (~_val); \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
#define NM_FLAGS_ASSIGN(flags, val, assign)  ({ \
Packit Service d328f3
		const typeof(flags) _flags = (flags); \
Packit Service d328f3
		const typeof(flags) _val = (val); \
Packit Service d328f3
		\
Packit Service d328f3
		(assign) \
Packit Service d328f3
			? _flags | (_val) \
Packit Service d328f3
			: _flags & (~_val); \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#define _NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, ORIG_FUNC, VERSIONED_FUNC, ARGS_TYPED, ARGS) \
Packit Service d328f3
RETURN_TYPE VERSIONED_FUNC ARGS_TYPED; \
Packit Service d328f3
RETURN_TYPE VERSIONED_FUNC ARGS_TYPED \
Packit Service d328f3
{ \
Packit Service d328f3
    return ORIG_FUNC ARGS; \
Packit Service d328f3
} \
Packit Service d328f3
RETURN_TYPE ORIG_FUNC ARGS_TYPED; \
Packit Service d328f3
__asm__(".symver "G_STRINGIFY(VERSIONED_FUNC)", "G_STRINGIFY(ORIG_FUNC)"@"G_STRINGIFY(VERSION))
Packit Service d328f3
Packit Service d328f3
#define NM_BACKPORT_SYMBOL(VERSION, RETURN_TYPE, FUNC, ARGS_TYPED, ARGS) \
Packit Service d328f3
_NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, FUNC, _##FUNC##_##VERSION, ARGS_TYPED, ARGS)
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
#define nm_str_skip_leading_spaces(str) \
Packit Service d328f3
	({ \
Packit Service d328f3
		typeof (*(str)) *_str = (str); \
Packit Service d328f3
		_nm_unused const char *_str_type_check = _str; \
Packit Service d328f3
		\
Packit Service d328f3
		if (_str) { \
Packit Service d328f3
			while (g_ascii_isspace (_str[0])) \
Packit Service d328f3
				_str++; \
Packit Service d328f3
		} \
Packit Service d328f3
		_str; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
static inline char *
Packit Service d328f3
nm_strstrip (char *str)
Packit Service d328f3
{
Packit Service d328f3
	/* g_strstrip doesn't like NULL. */
Packit Service d328f3
	return str ? g_strstrip (str) : NULL;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static inline const char *
Packit Service d328f3
nm_strstrip_avoid_copy (const char *str, char **str_free)
Packit Service d328f3
{
Packit Service d328f3
	gsize l;
Packit Service d328f3
	char *s;
Packit Service d328f3
Packit Service d328f3
	nm_assert (str_free && !*str_free);
Packit Service d328f3
Packit Service d328f3
	if (!str)
Packit Service d328f3
		return NULL;
Packit Service d328f3
Packit Service d328f3
	str = nm_str_skip_leading_spaces (str);
Packit Service d328f3
	l = strlen (str);
Packit Service d328f3
	if (   l == 0
Packit Service d328f3
	    || !g_ascii_isspace (str[l - 1]))
Packit Service d328f3
		return str;
Packit Service d328f3
	while (   l > 0
Packit Service d328f3
	       && g_ascii_isspace (str[l - 1]))
Packit Service d328f3
		l--;
Packit Service d328f3
Packit Service d328f3
	s = g_new (char, l + 1);
Packit Service d328f3
	memcpy (s, str, l);
Packit Service d328f3
	s[l] = '\0';
Packit Service d328f3
	*str_free = s;
Packit Service d328f3
	return s;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/* g_ptr_array_sort()'s compare function takes pointers to the
Packit Service d328f3
 * value. Thus, you cannot use strcmp directly. You can use
Packit Service d328f3
 * nm_strcmp_p().
Packit Service d328f3
 *
Packit Service d328f3
 * Like strcmp(), this function is not forgiving to accept %NULL. */
Packit Service d328f3
static inline int
Packit Service d328f3
nm_strcmp_p (gconstpointer a, gconstpointer b)
Packit Service d328f3
{
Packit Service d328f3
	const char *s1 = *((const char **) a);
Packit Service d328f3
	const char *s2 = *((const char **) b);
Packit Service d328f3
Packit Service d328f3
	return strcmp (s1, s2);
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/* like nm_strcmp_p(), suitable for g_ptr_array_sort_with_data().
Packit Service d328f3
 * g_ptr_array_sort() just casts nm_strcmp_p() to a function of different
Packit Service d328f3
 * signature. I guess, in glib there are knowledgeable people that ensure
Packit Service d328f3
 * that this additional argument doesn't cause problems due to different ABI
Packit Service d328f3
 * for every architecture that glib supports.
Packit Service d328f3
 * For NetworkManager, we'd rather avoid such stunts.
Packit Service d328f3
 **/
Packit Service d328f3
static inline int
Packit Service d328f3
nm_strcmp_p_with_data (gconstpointer a, gconstpointer b, gpointer user_data)
Packit Service d328f3
{
Packit Service d328f3
	const char *s1 = *((const char **) a);
Packit Service d328f3
	const char *s2 = *((const char **) b);
Packit Service d328f3
Packit Service d328f3
	return strcmp (s1, s2);
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static inline int
Packit Service d328f3
nm_cmp_uint32_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data)
Packit Service d328f3
{
Packit Service d328f3
	const guint32 a = *((const guint32 *) p_a);
Packit Service d328f3
	const guint32 b = *((const guint32 *) p_b);
Packit Service d328f3
Packit Service d328f3
	if (a < b)
Packit Service d328f3
		return -1;
Packit Service d328f3
	if (a > b)
Packit Service d328f3
		return 1;
Packit Service d328f3
	return 0;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/* Taken from systemd's UNIQ_T and UNIQ macros. */
Packit Service d328f3
Packit Service d328f3
#define NM_UNIQ_T(x, uniq) G_PASTE(__unique_prefix_, G_PASTE(x, uniq))
Packit Service d328f3
#define NM_UNIQ __COUNTER__
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/* glib's MIN()/MAX() macros don't have function-like behavior, in that they evaluate
Packit Service d328f3
 * the argument possibly twice.
Packit Service d328f3
 *
Packit Service d328f3
 * Taken from systemd's MIN()/MAX() macros. */
Packit Service d328f3
Packit Service d328f3
#define NM_MIN(a, b) __NM_MIN(NM_UNIQ, a, NM_UNIQ, b)
Packit Service d328f3
#define __NM_MIN(aq, a, bq, b) \
Packit Service d328f3
	({ \
Packit Service d328f3
		typeof (a) NM_UNIQ_T(A, aq) = (a); \
Packit Service d328f3
		typeof (b) NM_UNIQ_T(B, bq) = (b); \
Packit Service d328f3
		((NM_UNIQ_T(A, aq) < NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
#define NM_MAX(a, b) __NM_MAX(NM_UNIQ, a, NM_UNIQ, b)
Packit Service d328f3
#define __NM_MAX(aq, a, bq, b) \
Packit Service d328f3
	({ \
Packit Service d328f3
		typeof (a) NM_UNIQ_T(A, aq) = (a); \
Packit Service d328f3
		typeof (b) NM_UNIQ_T(B, bq) = (b); \
Packit Service d328f3
		((NM_UNIQ_T(A, aq) > NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
#define NM_CLAMP(x, low, high) __NM_CLAMP(NM_UNIQ, x, NM_UNIQ, low, NM_UNIQ, high)
Packit Service d328f3
#define __NM_CLAMP(xq, x, lowq, low, highq, high) \
Packit Service d328f3
	({ \
Packit Service d328f3
		typeof(x)NM_UNIQ_T(X,xq) = (x); \
Packit Service d328f3
		typeof(low) NM_UNIQ_T(LOW,lowq) = (low); \
Packit Service d328f3
		typeof(high) NM_UNIQ_T(HIGH,highq) = (high); \
Packit Service d328f3
		\
Packit Service d328f3
		( (NM_UNIQ_T(X,xq) > NM_UNIQ_T(HIGH,highq)) \
Packit Service d328f3
		  ? NM_UNIQ_T(HIGH,highq) \
Packit Service d328f3
		  : (NM_UNIQ_T(X,xq) < NM_UNIQ_T(LOW,lowq)) \
Packit Service d328f3
		     ? NM_UNIQ_T(LOW,lowq) \
Packit Service d328f3
		     : NM_UNIQ_T(X,xq)); \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
static inline guint
Packit Service d328f3
nm_encode_version (guint major, guint minor, guint micro)
Packit Service d328f3
{
Packit Service d328f3
	/* analog to the preprocessor macro NM_ENCODE_VERSION(). */
Packit Service d328f3
	return (major << 16) | (minor << 8) | micro;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static inline void
Packit Service d328f3
nm_decode_version (guint version, guint *major, guint *minor, guint *micro)
Packit Service d328f3
{
Packit Service d328f3
	*major = (version & 0xFFFF0000u) >> 16;
Packit Service d328f3
	*minor = (version & 0x0000FF00u) >>  8;
Packit Service d328f3
	*micro = (version & 0x000000FFu);
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/* taken from systemd's DECIMAL_STR_MAX()
Packit Service d328f3
 *
Packit Service d328f3
 * Returns the number of chars needed to format variables of the
Packit Service d328f3
 * specified type as a decimal string. Adds in extra space for a
Packit Service d328f3
 * negative '-' prefix (hence works correctly on signed
Packit Service d328f3
 * types). Includes space for the trailing NUL. */
Packit Service d328f3
#define NM_DECIMAL_STR_MAX(type) \
Packit Service d328f3
    (2+(sizeof(type) <= 1 ? 3 : \
Packit Service d328f3
        sizeof(type) <= 2 ? 5 : \
Packit Service d328f3
        sizeof(type) <= 4 ? 10 : \
Packit Service d328f3
        sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/* if @str is NULL, return "(null)". Otherwise, allocate a buffer using
Packit Service d328f3
 * alloca() of and fill it with @str. @str will be quoted with double quote.
Packit Service d328f3
 * If @str is longer then @trunc_at, the string is truncated and the closing
Packit Service d328f3
 * quote is instead '^' to indicate truncation.
Packit Service d328f3
 *
Packit Service d328f3
 * Thus, the maximum stack allocated buffer will be @trunc_at+3. */
Packit Service d328f3
#define nm_strquote_a(trunc_at, str) \
Packit Service d328f3
	({ \
Packit Service d328f3
		const char *const _str = (str); \
Packit Service d328f3
		\
Packit Service d328f3
		(_str \
Packit Service d328f3
			? ({ \
Packit Service d328f3
				const gsize _trunc_at = (trunc_at); \
Packit Service d328f3
				const gsize _strlen_trunc = NM_MIN (strlen (_str), _trunc_at); \
Packit Service d328f3
				char *_buf; \
Packit Service d328f3
				\
Packit Service d328f3
				_buf = g_alloca (_strlen_trunc + 3); \
Packit Service d328f3
				_buf[0] = '"'; \
Packit Service d328f3
				memcpy (&_buf[1], _str, _strlen_trunc); \
Packit Service d328f3
				_buf[_strlen_trunc + 1] = _str[_strlen_trunc] ? '^' : '"'; \
Packit Service d328f3
				_buf[_strlen_trunc + 2] = '\0'; \
Packit Service d328f3
				_buf; \
Packit Service d328f3
			}) \
Packit Service d328f3
			: "(null)"); \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
#define nm_sprintf_buf(buf, format, ...) \
Packit Service d328f3
	({ \
Packit Service d328f3
		char * _buf = (buf); \
Packit Service d328f3
		int _buf_len; \
Packit Service d328f3
		\
Packit Service d328f3
		/* some static assert trying to ensure that the buffer is statically allocated.
Packit Service d328f3
		 * It disallows a buffer size of sizeof(gpointer) to catch that. */ \
Packit Service d328f3
		G_STATIC_ASSERT (G_N_ELEMENTS (buf) == sizeof (buf) && sizeof (buf) != sizeof (char *)); \
Packit Service d328f3
		_buf_len = g_snprintf (_buf, sizeof (buf), \
Packit Service d328f3
		                       ""format"", ##__VA_ARGS__); \
Packit Service d328f3
		nm_assert (_buf_len < sizeof (buf)); \
Packit Service d328f3
		_buf; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
#define nm_sprintf_bufa(n_elements, format, ...) \
Packit Service d328f3
	({ \
Packit Service d328f3
		char *_buf; \
Packit Service d328f3
		int _buf_len; \
Packit Service d328f3
		typeof (n_elements) _n_elements = (n_elements); \
Packit Service d328f3
		\
Packit Service d328f3
		_buf = g_alloca (_n_elements); \
Packit Service d328f3
		_buf_len = g_snprintf (_buf, _n_elements, \
Packit Service d328f3
		                       ""format"", ##__VA_ARGS__); \
Packit Service d328f3
		nm_assert (_buf_len < _n_elements); \
Packit Service d328f3
		_buf; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
/* aims to alloca() a buffer and fill it with printf(format, name).
Packit Service d328f3
 * Note that format must not contain any format specifier except
Packit Service d328f3
 * "%s".
Packit Service d328f3
 * If the resulting string would be too large for stack allocation,
Packit Service d328f3
 * it allocates a buffer with g_malloc() and assigns it to *p_val_to_free. */
Packit Service d328f3
#define nm_construct_name_a(format, name, p_val_to_free) \
Packit Service d328f3
	({ \
Packit Service d328f3
		const char *const _name = (name); \
Packit Service d328f3
		char **const _p_val_to_free = (p_val_to_free); \
Packit Service d328f3
		const gsize _name_len = strlen (_name); \
Packit Service d328f3
		char *_buf2; \
Packit Service d328f3
		\
Packit Service d328f3
		nm_assert (_p_val_to_free && !*_p_val_to_free); \
Packit Service d328f3
		if (NM_STRLEN (format) + _name_len < 200) \
Packit Service d328f3
			_buf2 = nm_sprintf_bufa (NM_STRLEN (format) + _name_len, format, _name); \
Packit Service d328f3
		else { \
Packit Service d328f3
			_buf2 = g_strdup_printf (format, _name); \
Packit Service d328f3
			*_p_val_to_free = _buf2; \
Packit Service d328f3
		} \
Packit Service d328f3
		(const char *) _buf2; \
Packit Service d328f3
	})
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
/**
Packit Service d328f3
 * The boolean type _Bool is C99 while we mostly stick to C89. However, _Bool is too
Packit Service d328f3
 * convinient to miss and is effectively available in gcc and clang. So, just use it.
Packit Service d328f3
 *
Packit Service d328f3
 * Usually, one would include "stdbool.h" to get the "bool" define which aliases
Packit Service d328f3
 * _Bool. We provide this define here, because we want to make use of it anywhere.
Packit Service d328f3
 * (also, stdbool.h is again C99).
Packit Service d328f3
 *
Packit Service d328f3
 * Using _Bool has advantages over gboolean:
Packit Service d328f3
 *
Packit Service d328f3
 * - commonly _Bool is one byte large, instead of gboolean's 4 bytes (because gboolean
Packit Service d328f3
 *   is a typedef for gint). Especially when having boolean fields in a struct, we can
Packit Service d328f3
 *   thereby easily save some space.
Packit Service d328f3
 *
Packit Service d328f3
 * - _Bool type guarantees that two "true" expressions compare equal. E.g. the follwing
Packit Service d328f3
 *   will not work:
Packit Service d328f3
 *        gboolean v1 = 1;
Packit Service d328f3
 *        gboolean v2 = 2;
Packit Service d328f3
 *        g_assert_cmpint (v1, ==, v2); // will fail
Packit Service d328f3
 *   For that, we often to use !! to coerce gboolean values to 0 or 1:
Packit Service d328f3
 *        g_assert_cmpint (!!v2, ==, TRUE);
Packit Service d328f3
 *   With _Bool type, this will be handled properly by the compiler.
Packit Service d328f3
 *
Packit Service d328f3
 * - For structs, we might want to safe even more space and use bitfields:
Packit Service d328f3
 *       struct s1 {
Packit Service d328f3
 *           gboolean v1:1;
Packit Service d328f3
 *       };
Packit Service d328f3
 *   But the problem here is that gboolean is signed, so that
Packit Service d328f3
 *   v1 will be either 0 or -1 (not 1, TRUE). Thus, the following
Packit Service d328f3
 *   fails:
Packit Service d328f3
 *      struct s1 s = { .v1 = TRUE, };
Packit Service d328f3
 *      g_assert_cmpint (s1.v1, ==, TRUE);
Packit Service d328f3
 *   It will however work just fine with bool/_Bool while retaining the
Packit Service d328f3
 *   notion of having a boolean value.
Packit Service d328f3
 *
Packit Service d328f3
 * Also, add the defines for "true" and "false". Those are nicely highlighted by the editor
Packit Service d328f3
 * as special types, contrary to glib's "TRUE"/"FALSE".
Packit Service d328f3
 */
Packit Service d328f3
Packit Service d328f3
#ifndef bool
Packit Service d328f3
#define bool _Bool
Packit Service d328f3
#define true    1
Packit Service d328f3
#define false   0
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
Packit Service d328f3
#ifdef _G_BOOLEAN_EXPR
Packit Service d328f3
/* g_assert() uses G_LIKELY(), which in turn uses _G_BOOLEAN_EXPR().
Packit Service d328f3
 * As glib's implementation uses a local variable _g_boolean_var_,
Packit Service d328f3
 * we cannot do
Packit Service d328f3
 *   g_assert (some_macro ());
Packit Service d328f3
 * where some_macro() itself expands to ({g_assert(); ...}).
Packit Service d328f3
 * In other words, you cannot have a g_assert() inside a g_assert()
Packit Service d328f3
 * without getting a -Werror=shadow failure.
Packit Service d328f3
 *
Packit Service d328f3
 * Workaround that by re-defining _G_BOOLEAN_EXPR()
Packit Service d328f3
 **/
Packit Service d328f3
#undef  _G_BOOLEAN_EXPR
Packit Service d328f3
#define __NM_G_BOOLEAN_EXPR_IMPL(v, expr) \
Packit Service d328f3
	({ \
Packit Service d328f3
		int NM_UNIQ_T(V, v); \
Packit Service d328f3
		\
Packit Service d328f3
		if (expr) \
Packit Service d328f3
			NM_UNIQ_T(V, v) = 1; \
Packit Service d328f3
		else \
Packit Service d328f3
			NM_UNIQ_T(V, v) = 0; \
Packit Service d328f3
		NM_UNIQ_T(V, v); \
Packit Service d328f3
	})
Packit Service d328f3
#define _G_BOOLEAN_EXPR(expr) __NM_G_BOOLEAN_EXPR_IMPL (NM_UNIQ, expr)
Packit Service d328f3
#endif
Packit Service d328f3
Packit Service d328f3
/*****************************************************************************/
Packit Service d328f3
Packit Service d328f3
static inline int
Packit Service d328f3
nm_steal_fd (int *p_fd)
Packit Service d328f3
{
Packit Service d328f3
	int fd;
Packit Service d328f3
Packit Service d328f3
	if (   p_fd
Packit Service d328f3
	    && ((fd = *p_fd) >= 0)) {
Packit Service d328f3
		*p_fd = -1;
Packit Service d328f3
		return fd;
Packit Service d328f3
	}
Packit Service d328f3
	return -1;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/**
Packit Service d328f3
 * nm_close:
Packit Service d328f3
 *
Packit Service d328f3
 * Like close() but throws an assertion if the input fd is
Packit Service d328f3
 * invalid.  Closing an invalid fd is a programming error, so
Packit Service d328f3
 * it's better to catch it early.
Packit Service d328f3
 */
Packit Service d328f3
static inline int
Packit Service d328f3
nm_close (int fd)
Packit Service d328f3
{
Packit Service d328f3
	int r;
Packit Service d328f3
Packit Service d328f3
	r = close (fd);
Packit Service d328f3
	nm_assert (r != -1 || fd < 0 || errno != EBADF);
Packit Service d328f3
	return r;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
#endif /* __NM_MACROS_INTERNAL_H__ */