/ src / minisketch / src / util.h
util.h
 1  /**********************************************************************
 2   * Copyright (c) 2018 Pieter Wuille, Greg Maxwell, Gleb Naumenko      *
 3   * Distributed under the MIT software license, see the accompanying   *
 4   * file LICENSE or http://www.opensource.org/licenses/mit-license.php.*
 5   **********************************************************************/
 6  
 7  #ifndef _MINISKETCH_UTIL_H_
 8  #define _MINISKETCH_UTIL_H_
 9  
10  #ifdef MINISKETCH_VERIFY
11  #include <stdio.h>
12  #endif
13  
14  #if !defined(__GNUC_PREREQ)
15  # if defined(__GNUC__)&&defined(__GNUC_MINOR__)
16  #  define __GNUC_PREREQ(_maj,_min) \
17   ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
18  # else
19  #  define __GNUC_PREREQ(_maj,_min) 0
20  # endif
21  #endif
22  
23  #if __GNUC_PREREQ(3, 0)
24  #define EXPECT(x,c) __builtin_expect((x),(c))
25  #else
26  #define EXPECT(x,c) (x)
27  #endif
28  
29  /* Assertion macros */
30  
31  /**
32   * Unconditional failure on condition failure.
33   * Primarily used in testing harnesses.
34   */
35  #define CHECK(cond) do { \
36      if (EXPECT(!(cond), 0)) { \
37          fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, "Check condition failed: " #cond); \
38          abort(); \
39      } \
40  } while(0)
41  
42  /**
43   * Check macro that does nothing in normal non-verify builds but crashes in verify builds.
44   * This is used to test conditions at runtime that should always be true, but are either
45   * expensive to test or in locations where returning on failure would be messy.
46   */
47  #ifdef MINISKETCH_VERIFY
48  #define CHECK_SAFE(cond) CHECK(cond)
49  #else
50  #define CHECK_SAFE(cond)
51  #endif
52  
53  /**
54   * Check a condition and return on failure in non-verify builds, crash in verify builds.
55   * Used for inexpensive conditions which believed to be always true in locations where
56   * a graceful exit is possible.
57   */
58  #ifdef MINISKETCH_VERIFY
59  #define CHECK_RETURN(cond, rvar) do { \
60      if (EXPECT(!(cond), 0)) { \
61          fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, "Check condition failed: " #cond); \
62          abort(); \
63          return rvar; /* Does nothing, but causes compile to warn on incorrect return types. */ \
64      } \
65  } while(0)
66  #else
67  #define CHECK_RETURN(cond, rvar) do { \
68      if (EXPECT(!(cond), 0)) { \
69          return rvar; \
70      } \
71  } while(0)
72  #endif
73  
74  #endif