1 /**
2  * $Id: c25431b414ae49947dd6bb256edd982e60702c11 $
3  *
4  * @brief Source control functions
5  *
6  * @copyright 2013 The FreeRADIUS server project
7  */
8 #ifndef _BUILD_H
9 #define _BUILD_H
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 #include <freeradius-devel/autoconf.h> /* Needed for endian macros */
14 
15 /*
16  *	The ubiquitous stringify macros
17  */
18 #define XSTRINGIFY(x) #x
19 #define STRINGIFY(x) XSTRINGIFY(x)
20 #define JOINSTR(x,y) XSTRINGIFY(x ## y)
21 
22 /*
23  *	HEX concatenation macros
24  */
25 #ifndef HEXIFY
26 #  define XHEXIFY4(b1,b2,b3,b4)	(0x ## b1 ## b2 ## b3 ## b4)
27 #  define HEXIFY4(b1,b2,b3,b4)	XHEXIFY4(b1, b2, b3, b4)
28 
29 #  define XHEXIFY3(b1,b2,b3)	(0x ## b1 ## b2 ## b3)
30 #  define HEXIFY3(b1,b2,b3)	XHEXIFY3(b1, b2, b3)
31 
32 #  define XHEXIFY2(b1,b2)	(0x ## b1 ## b2)
33 #  define HEXIFY2(b1,b2)	XHEXIFY2(b1, b2)
34 
35 #  define XHEXIFY(b1)		(0x ## b1)
36 #  define HEXIFY(b1)		XHEXIFY(b1)
37 #endif
38 
39 /*
40  *	struct field size
41  */
42 #define SIZEOF_MEMBER(_t, _m) sizeof(((_t *)0)->_m)
43 
44 /*
45  *	Only use GCC __attribute__ if were building with a GCClike
46  *	compiler.
47  */
48 #ifdef __GNUC__
49 #  define CC_HINT(_x) __attribute__ ((_x))
50 #  define likely(_x)	__builtin_expect((_x), 1)
51 #  define unlikely(_x)	__builtin_expect((_x), 0)
52 #else
53 #  define CC_HINT(_x)
54 #  define likely(_x)	_x
55 #  define unlikely(_x)	_x
56 #endif
57 
58 #ifdef HAVE_ATTRIBUTE_BOUNDED
59 #  define CC_BOUNDED(_x, ...) CC_HINT(__bounded__(_x, ## __VA_ARGS__))
60 #else
61 #  define CC_BOUNDED(...)
62 #endif
63 
64 /*
65  *      GCC uses __SANITIZE_ADDRESS__, clang uses __has_feature, which
66  *      GCC complains about.
67  */
68 #ifndef __SANITIZE_ADDRESS__
69 #ifdef __has_feature
70 #if __has_feature(address_sanitizer)
71 #define __SANITIZE_ADDRESS__ (1)
72 #endif
73 #endif
74 #endif
75 
76 /*
77  *	Macros to add pragmas
78  */
79 #define PRAGMA(_x) _Pragma(#_x)
80 
81 /*
82  *	Macros for controlling warnings in GCC >= 4.2 and clang >= 2.8
83  */
84 #if defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
85 #  define DIAG_PRAGMA(_x) PRAGMA(GCC diagnostic _x)
86 #  if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
87 #    define DIAG_OFF(_x) DIAG_PRAGMA(push) DIAG_PRAGMA(ignored JOINSTR(-W,_x))
88 #    define DIAG_ON(_x) DIAG_PRAGMA(pop)
89 #  else
90 #    define DIAG_OFF(_x) DIAG_PRAGMA(ignored JOINSTR(-W,_x))
91 #    define DIAG_ON(_x)  DIAG_PRAGMA(warning JOINSTR(-W,_x))
92 #  endif
93 #elif defined(__clang__) && ((__clang_major__ * 100) + __clang_minor__ >= 208)
94 #  define DIAG_PRAGMA(_x) PRAGMA(clang diagnostic _x)
95 #  define DIAG_OFF(_x) DIAG_PRAGMA(push) DIAG_PRAGMA(ignored JOINSTR(-W,_x))
96 #  define DIAG_ON(_x) DIAG_PRAGMA(pop)
97 #else
98 #  define DIAG_OFF(_x)
99 #  define DIAG_ON(_x)
100 #endif
101 
102 /*
103  *	GCC and clang use different macros
104  */
105 #ifdef __clang__
106 # define DIAG_OPTIONAL DIAG_OFF(unknown-pragmas)
107 #else
108 # define DIAG_OPTIONAL DIAG_OFF(pragmas)
109 #endif
110 
111 /*
112  *	For dealing with APIs which are only deprecated in OSX (like the OpenSSL API)
113  */
114 #ifdef __APPLE__
115 #  define USES_APPLE_DEPRECATED_API DIAG_OFF(deprecated-declarations)
116 #  define USES_APPLE_RST DIAG_ON(deprecated-declarations)
117 #else
118 #  define USES_APPLE_DEPRECATED_API
119 #  define USES_APPLE_RST
120 #endif
121 
122 #if defined(__GNUC__)
123 /* force inclusion of ident keywords in the face of optimization */
124 #  define RCSID(id) static char const rcsid[] __attribute__ ((used)) = id;
125 #  define RCSIDH(h, id) static char const rcsid_ ## h [] __attribute__ ((used)) = id;
126 #elif defined(__SUNPRO_C)
127 /* put ident keyword into comment section (nicer than gcc way) */
128 #  define RCSID(id) PRAGMA(sun ident id)
129 #  define RCSIDH(h, id) PRAGMA(sun ident id)
130 #else
131 #  define RCSID(id)
132 #  define RCSIDH(h, id)
133 #endif
134 
135 /*
136  *	Try and determine endianness of the target system.
137  *
138  *	Other projects seem to use endian.h and variants, but these are
139  *	in non standard locations, and may mess up cross compiling.
140  *
141  *	Here at least the endianness can be set explicitly with
142  *	-DLITTLE_ENDIAN or -DBIG_ENDIAN.
143  */
144 #if !defined(FR_LITTLE_ENDIAN) && !defined(FR_BIG_ENDIAN)
145 #  if defined(__LITTLE_ENDIAN__) || \
146       (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
147 #    define FR_LITTLE_ENDIAN 1
148 #  elif defined(__BIG_ENDIAN__) || \
149       (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
150 #    define FR_BIG_ENDIAN 1
151 #  else
152 #    error Failed determining endianness of system
153 #  endif
154 #endif
155 
156 #ifdef __cplusplus
157 }
158 #endif
159 #endif /* _BUILD_H */
160