controller link as operation
[oweals/gnunet.git] / src / include / gnunet_common.h
index f57c18cb7bfe7cf49709e1fdf3aee80ef4b9a647..dae3d4945aed75b348e5391d6a7bd58e940a0d69 100644 (file)
 #include <stdarg.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 0x00090000
+#define GNUNET_UTIL_VERSION 0x00090200
 
 /**
  * Named constants for return values.  The following
 
 #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
+
 /**
  * Endian operations
  */
 #  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_htole64(x) __bswap_64 (x)
 #  define GNUNET_be64toh(x) (x)
 #  define GNUNET_le64toh(x) __bswap_64 (x)
-# endif
 #endif
 
 
 
+
 /**
  * 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
  */
 #define GNUNET_UNUSED __attribute__((unused))
 
+/**
+ * gcc-ism to document functions that don't return
+ */
+#define GNUNET_NORETURN __attribute__((noreturn))
+
+#if MINGW
+#if __GNUC__ > 3
+/**
+ * gcc 4.x-ism to pack structures even on W32 (to be used before structs);
+ * Using this would cause structs to be unaligned on the stack on Sparc,
+ * so we *only* use this on W32 (see #670578 from Debian); fortunately,
+ * W32 doesn't run on sparc anyway.
+ */
+#define GNUNET_NETWORK_STRUCT_BEGIN \
+  _Pragma("pack(push)") \
+  _Pragma("pack(1)")
+
+/**
+ * gcc 4.x-ism to pack structures even on W32 (to be used after structs)
+ * Using this would cause structs to be unaligned on the stack on Sparc,
+ * so we *only* use this on W32 (see #670578 from Debian); fortunately,
+ * W32 doesn't run on sparc anyway.
+ */
+#define GNUNET_NETWORK_STRUCT_END _Pragma("pack(pop)")
+
+#else
+#error gcc 4.x or higher required on W32 systems
+#endif
+#else
+/**
+ * Define as empty, GNUNET_PACKED should suffice, but this won't work on W32
+ */
+#define GNUNET_NETWORK_STRUCT_BEGIN 
+
+/**
+ * Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;
+ */
+#define GNUNET_NETWORK_STRUCT_END
+#endif
 
 /* ************************ super-general types *********************** */
 
+GNUNET_NETWORK_STRUCT_BEGIN
+
 /**
  * Header for all communications.
  */
@@ -141,11 +240,10 @@ struct GNUNET_MessageHeader
 /**
  * @brief 512-bit hashcode
  */
-typedef struct
+struct GNUNET_HashCode
 {
   uint32_t bits[512 / 8 / sizeof (uint32_t)];   /* = 16 */
-}
-GNUNET_HashCode;
+};
 
 
 /**
@@ -154,9 +252,9 @@ GNUNET_HashCode;
  */
 struct GNUNET_PeerIdentity
 {
-  GNUNET_HashCode hashPubKey GNUNET_PACKED;
+  struct GNUNET_HashCode hashPubKey;
 };
-
+GNUNET_NETWORK_STRUCT_END
 
 /**
  * Function called with a filename.
@@ -202,9 +300,12 @@ typedef void (*GNUNET_Logger) (void *cls, enum GNUNET_ErrorType kind,
 
 
 /**
- * Number of log calls to ignore.
+ * Get the number of log calls that are going to be skipped
+ *
+ * @return number of log calls to be ignored
  */
-extern unsigned int skip_log;
+int
+GNUNET_get_log_skip ();
 
 #if !defined(GNUNET_CULL_LOGGING)
 int
@@ -259,23 +360,27 @@ GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind, const char *comp,
 #if !defined(GNUNET_CULL_LOGGING)
 #define GNUNET_log_from(kind,comp,...) do { int log_line = __LINE__;\
   static int log_call_enabled = GNUNET_LOG_CALL_STATUS;\
-  if (GN_UNLIKELY(log_call_enabled == -1))\
-    log_call_enabled = GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), comp, __FILE__, __FUNCTION__, log_line);\
-  if (GN_UNLIKELY(skip_log > 0)) {skip_log--;}\
-  else {\
-    if (GN_UNLIKELY(log_call_enabled))\
-      GNUNET_log_from_nocheck (kind, comp, __VA_ARGS__);\
+  if ((GNUNET_EXTRA_LOGGING > 0) || ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) { \
+    if (GN_UNLIKELY(log_call_enabled == -1))\
+      log_call_enabled = GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), (comp), __FILE__, __FUNCTION__, log_line); \
+    if (GN_UNLIKELY(GNUNET_get_log_skip () > 0)) { GNUNET_log_skip (-1, GNUNET_NO); }\
+    else {\
+      if (GN_UNLIKELY(log_call_enabled))\
+        GNUNET_log_from_nocheck ((kind), comp, __VA_ARGS__);   \
+    }\
   }\
 } while (0)
 
 #define GNUNET_log(kind,...) do { int log_line = __LINE__;\
   static int log_call_enabled = GNUNET_LOG_CALL_STATUS;\
-  if (GN_UNLIKELY(log_call_enabled == -1))\
-    log_call_enabled = GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), NULL, __FILE__, __FUNCTION__, log_line);\
-  if (GN_UNLIKELY(skip_log > 0)) {skip_log--;}\
-  else {\
-    if (GN_UNLIKELY(log_call_enabled))\
-      GNUNET_log_nocheck (kind, __VA_ARGS__);\
+  if ((GNUNET_EXTRA_LOGGING > 0) || ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) { \
+    if (GN_UNLIKELY(log_call_enabled == -1))\
+      log_call_enabled = GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), NULL, __FILE__, __FUNCTION__, log_line);\
+    if (GN_UNLIKELY(GNUNET_get_log_skip () > 0)) { GNUNET_log_skip (-1, GNUNET_NO); }\
+    else {\
+      if (GN_UNLIKELY(log_call_enabled))\
+        GNUNET_log_nocheck ((kind), __VA_ARGS__);      \
+    }\
   }\
 } while (0)
 #else
@@ -288,16 +393,16 @@ GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind, const char *comp,
  * Abort the process, generate a core dump if possible.
  */
 void
-GNUNET_abort (void);
+GNUNET_abort (void) GNUNET_NORETURN;
 
 /**
  * Ignore the next n calls to the log function.
  *
- * @param n number of log calls to ignore
+ * @param n number of log calls to ignore (could be negative)
  * @param check_reset GNUNET_YES to assert that the log skip counter is currently zero
  */
 void
-GNUNET_log_skip (unsigned int n, int check_reset);
+GNUNET_log_skip (int n, int check_reset);
 
 
 /**
@@ -341,7 +446,7 @@ GNUNET_logger_remove (GNUNET_Logger logger, void *logger_cls);
  * @return string
  */
 const char *
-GNUNET_h2s (const GNUNET_HashCode * hc);
+GNUNET_h2s (const struct GNUNET_HashCode * hc);
 
 
 /**
@@ -354,7 +459,7 @@ GNUNET_h2s (const GNUNET_HashCode * hc);
  * @return string
  */
 const char *
-GNUNET_h2s_full (const GNUNET_HashCode * hc);
+GNUNET_h2s_full (const struct GNUNET_HashCode * hc);
 
 
 /**
@@ -369,6 +474,17 @@ GNUNET_h2s_full (const GNUNET_HashCode * hc);
 const char *
 GNUNET_i2s (const struct GNUNET_PeerIdentity *pid);
 
+/**
+ * Convert a peer identity to a string (for printing debug messages).
+ * This is one of the very few calls in the entire API that is
+ * NOT reentrant!
+ *
+ * @param pid the peer identity
+ * @return string form of the pid; will be overwritten by next
+ *         call to GNUNET_i2s.
+ */
+const char *
+GNUNET_i2s_full (const struct GNUNET_PeerIdentity *pid);
 
 /**
  * Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string
@@ -465,6 +581,21 @@ GNUNET_ntohll (uint64_t n);
 uint64_t
 GNUNET_htonll (uint64_t n);
 
+/**
+ * Convert double to network-byte-order.
+ * @param d the value in network byte order
+ * @return the same value in host byte order
+ */
+double 
+GNUNET_hton_double (double d);
+
+/**
+ * Convert double to host-byte-order
+ * @param d the value in network byte order
+ * @return the same value in host byte order
+ */
+double 
+GNUNET_ntoh_double (double d);
 
 /* ************************* allocation functions ****************** */
 
@@ -742,4 +873,17 @@ GNUNET_copy_message (const struct GNUNET_MessageHeader *msg);
 #endif
 #endif
 
+
+
+
+#if 0                           /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
 #endif /*GNUNET_COMMON_H_ */