1 /*
2  * libdpkg - Debian packaging suite library routines
3  * macros.h - C language support macros
4  *
5  * Copyright © 2008-2012 Guillem Jover <guillem@debian.org>
6  *
7  * This is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  */
20 
21 #ifndef LIBDPKG_MACROS_H
22 #define LIBDPKG_MACROS_H
23 
24 /**
25  * @defgroup macros C language support macros
26  * @ingroup dpkg-public
27  * @{
28  */
29 
30 #ifndef LIBDPKG_VOLATILE_API
31 #error "The libdpkg API is to be considered volatile, please read 'README.api'."
32 #endif
33 
34 /* Language definitions. */
35 
36 #ifdef __GNUC__
37 #define DPKG_GCC_VERSION (__GNUC__ << 8 | __GNUC_MINOR__)
38 #else
39 #define DPKG_GCC_VERSION 0
40 #endif
41 
42 #if DPKG_GCC_VERSION >= 0x0300
43 #define DPKG_ATTR_UNUSED	__attribute__((unused))
44 #define DPKG_ATTR_CONST		__attribute__((const))
45 #define DPKG_ATTR_PURE		__attribute__((pure))
46 #define DPKG_ATTR_MALLOC	__attribute__((malloc))
47 #define DPKG_ATTR_NORET		__attribute__((noreturn))
48 #define DPKG_ATTR_PRINTF(n)	__attribute__((format(printf, n, n + 1)))
49 #define DPKG_ATTR_VPRINTF(n)	__attribute__((format(printf, n, 0)))
50 #else
51 #define DPKG_ATTR_UNUSED
52 #define DPKG_ATTR_CONST
53 #define DPKG_ATTR_PURE
54 #define DPKG_ATTR_MALLOC
55 #define DPKG_ATTR_NORET
56 #define DPKG_ATTR_PRINTF(n)
57 #define DPKG_ATTR_VPRINTF(n)
58 #endif
59 
60 #if DPKG_GCC_VERSION > 0x0302
61 #define DPKG_ATTR_NONNULL(...)	__attribute__((nonnull(__VA_ARGS__)))
62 #define DPKG_ATTR_REQRET	__attribute__((warn_unused_result))
63 #else
64 #define DPKG_ATTR_NONNULL(...)
65 #define DPKG_ATTR_REQRET
66 #endif
67 
68 #if DPKG_GCC_VERSION >= 0x0400
69 #define DPKG_ATTR_SENTINEL	__attribute__((sentinel))
70 #else
71 #define DPKG_ATTR_SENTINEL
72 #endif
73 
74 #if defined(__cplusplus) && __cplusplus >= 201103L
75 #define DPKG_ATTR_THROW(exception)
76 #define DPKG_ATTR_NOEXCEPT		noexcept
77 #elif defined(__cplusplus)
78 #define DPKG_ATTR_THROW(exception)	throw(exception)
79 #define DPKG_ATTR_NOEXCEPT		throw()
80 #endif
81 
82 #ifdef __cplusplus
83 #define DPKG_BEGIN_DECLS	extern "C" {
84 #define DPKG_END_DECLS		}
85 #else
86 #define DPKG_BEGIN_DECLS
87 #define DPKG_END_DECLS
88 #endif
89 
90 /**
91  * @def DPKG_BIT
92  *
93  * Return the integer value of bit n.
94  */
95 #define DPKG_BIT(n)	(1UL << (n))
96 
97 /**
98  * @def array_count
99  *
100  * Returns the amount of items in an array.
101  */
102 #ifndef array_count
103 #define array_count(a) (sizeof(a) / sizeof((a)[0]))
104 #endif
105 
106 /* For C++ use native implementations from STL or similar. */
107 #ifndef __cplusplus
108 #ifndef min
109 #define min(a, b) ((a) < (b) ? (a) : (b))
110 #endif
111 
112 #ifndef max
113 #define max(a, b) ((a) > (b) ? (a) : (b))
114 #endif
115 #endif
116 
117 /**
118  * @def clamp
119  *
120  * Returns a normalized value within the low and high limits.
121  *
122  * @param v The value to clamp.
123  * @param l The low limit.
124  * @param h The high limit.
125  */
126 #ifndef clamp
127 #define clamp(v, l, h) ((v) > (h) ? (h) : ((v) < (l) ? (l) : (v)))
128 #endif
129 
130 /** @} */
131 
132 #endif /* LIBDPKG_MACROS_H */
133