/*
This file is part of GNUnet.
Copyright (C) 2006-2013 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file include/gnunet_common.h
* @brief commonly used definitions; globals in this file
* are exempt from the rule that the module name ("common")
* must be part of the symbol name.
*
* @author Christian Grothoff
* @author Nils Durner
*
* @defgroup logging Logging
* @see [Documentation](https://gnunet.org/logging)
*
* @defgroup memory Memory management
*/
#ifndef GNUNET_COMMON_H
#define GNUNET_COMMON_H
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef MINGW
#include "winproc.h"
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
#ifdef HAVE_BYTESWAP_H
#include <byteswap.h>
#endif
#ifdef __cplusplus
extern "C"
{
#if 0 /* keep Emacsens' auto-indent happy */
}
#endif
#endif
/**
* Version of the API (for entire gnunetutil.so library).
*/
#define GNUNET_UTIL_VERSION 0x000A0102
/**
* Named constants for return values. The following invariants hold:
* `GNUNET_NO == 0` (to allow `if (GNUNET_NO)`) `GNUNET_OK !=
* GNUNET_SYSERR`, `GNUNET_OK != GNUNET_NO`, `GNUNET_NO !=
* GNUNET_SYSERR` and finally `GNUNET_YES != GNUNET_NO`.
*/
#define GNUNET_OK 1
#define GNUNET_SYSERR -1
#define GNUNET_YES 1
#define GNUNET_NO 0
#define GNUNET_MIN(a,b) (((a) < (b)) ? (a) : (b))
#define GNUNET_MAX(a,b) (((a) > (b)) ? (a) : (b))
/* some systems use one underscore only, and mingw uses no underscore... */
#ifndef __BYTE_ORDER
#ifdef _BYTE_ORDER
#define __BYTE_ORDER _BYTE_ORDER
#else
#ifdef BYTE_ORDER
#define __BYTE_ORDER BYTE_ORDER
#endif
#endif
#endif
#ifndef __BIG_ENDIAN
#ifdef _BIG_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#else
#ifdef BIG_ENDIAN
#define __BIG_ENDIAN BIG_ENDIAN
#endif
#endif
#endif
#ifndef __LITTLE_ENDIAN
#ifdef _LITTLE_ENDIAN
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#else
#ifdef LITTLE_ENDIAN
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#endif
#endif
#endif
/**
* @ingroup logging
* define #GNUNET_EXTRA_LOGGING if using this header outside the GNUnet source
* tree where gnunet_config.h is unavailable
*/
#ifndef GNUNET_EXTRA_LOGGING
#define GNUNET_EXTRA_LOGGING 0
#endif
/**
* Endian operations
*/
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define GNUNET_htobe16(x) __bswap_16 (x)
# define GNUNET_htole16(x) (x)
# define GNUNET_be16toh(x) __bswap_16 (x)
# define GNUNET_le16toh(x) (x)
# define GNUNET_htobe32(x) __bswap_32 (x)
# define GNUNET_htole32(x) (x)
# define GNUNET_be32toh(x) __bswap_32 (x)
# define GNUNET_le32toh(x) (x)
# define GNUNET_htobe64(x) __bswap_64 (x)
# define GNUNET_htole64(x) (x)
# define GNUNET_be64toh(x) __bswap_64 (x)
# define GNUNET_le64toh(x) (x)
#endif
# if __BYTE_ORDER == __BIG_ENDIAN
# define GNUNET_htobe16(x) (x)
# define GNUNET_htole16(x) __bswap_16 (x)
# define GNUNET_be16toh(x) (x)
# define GNUNET_le16toh(x) __bswap_16 (x)
# define GNUNET_htobe32(x) (x)
# define GNUNET_htole32(x) __bswap_32 (x)
# define GNUNET_be32toh(x) (x)
# define GNUNET_le32toh(x) __bswap_32 (x)
# define GNUNET_htobe64(x) (x)
# define GNUNET_htole64(x) __bswap_64 (x)
# define GNUNET_be64toh(x) (x)
# define GNUNET_le64toh(x) __bswap_64 (x)
#endif
/**
* Macro used to avoid using 0 for the length of a variable-size
* array (Non-Zero-Length).
*
* Basically, C standard says that "int[n] x;" is undefined if n=0.
* This was supposed to prevent issues with pointer aliasing.
* However, C compilers may conclude that n!=0 as n=0 would be
* undefined, and then optimize under the assumption n!=0, which
* could cause actual issues. Hence, when initializing an array
* on the stack with a variable-length that might be zero, write
* "int[GNUNET_NZL(n)] x;" instead of "int[n] x".
*/
#define GNUNET_NZL(l) GNUNET_MAX(1,l)
/**
* gcc-ism to get packed structs.
*/
#define GNUNET_PACKED __attribute__((packed))
/**
* gcc-ism to get gcc bitfield layout when compiling with -mms-bitfields
*/
#if MINGW
#define GNUNET_GCC_STRUCT_LAYOUT __attribute__((gcc_struct))
#else
#define GNUNET_GCC_STRUCT_LAYOUT
#endif
/**
* gcc-ism to force alignment; we use this to align char-arrays
* that may then be cast to 'struct's. See also gcc
* bug #33594.
*/
#ifdef __BIGGEST_ALIGNMENT__
#define GNUNET_ALIGN __attribute__((aligned (__BIGGEST_ALIGNMENT__)))
#else
#define GNUNET_ALIGN __attribute__((aligned (8)))
#endif
/**
* gcc-ism to document unused arguments