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