Stop %'s in GP_ASSERT() from breaking printf format
[gfxprim.git] / core / GP_Common.h
blob8560a7fec68c0718a7b7f6dcaac6296329f28c54
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
20 * <jiri.bluebear.dluhos@gmail.com> *
21 * *
22 * Copyright (C) 2009-2010 Cyril Hrubis <metan@ucw.cz> *
23 * *
24 *****************************************************************************/
26 #ifndef GP_COMMON_H
27 #define GP_COMMON_H
29 #include <stdio.h>
30 #include <stdint.h>
31 #include <stdlib.h>
32 #include <unistd.h>
35 * Returns a minimum of the two numbers.
37 #define GP_MIN(a, b) ({ \
38 typeof(a) _a = (a); \
39 typeof(b) _b = (b); \
40 _a < _b ? _a : _b; \
44 * Returns a maximum of the two numbers.
46 #define GP_MAX(a, b) ({ \
47 typeof(a) _a = (a); \
48 typeof(b) _b = (b); \
49 _a > _b ? _a : _b; \
53 * The standard likely() and unlikely() used in Kernel
55 #ifndef likely
56 #ifdef __GNUC__
57 #define likely(x) __builtin_expect(!!(x),1)
58 #define unlikely(x) __builtin_expect(!!(x),0)
59 #else
60 #define likely(x) x
61 #define unlikely(x) x
62 #endif
63 #endif
66 * Internal macros with common code for GP_ABORT, GP_ASSERT and GP_CHECK.
67 * GP_INTERNAL_ABORT takes a message that may contain % (e.g. assert condition)
68 * and prints:
69 * "*** gfxprim: __FILE__:__LINE__: in __FUNCTION__: str_abort_msg_" format(__VA_ARGS__) "\n"
71 * GP_GENERAL_CHECK is a check with specified message prefix (for assert and check)
74 #define GP_INTERNAL_ABORT(str_abort_msg_, ...) do { \
75 fprintf(stderr, "*** gfxprim: %s:%d: in %s: %s", \
76 __FILE__, __LINE__, __FUNCTION__, str_abort_msg_); \
77 if (! (#__VA_ARGS__ [0])) \
78 fprintf(stderr, "abort()"); \
79 else \
80 fprintf(stderr, " " __VA_ARGS__); \
81 fprintf(stderr, "\n"); \
82 abort(); \
83 } while (0)
85 #define GP_GENERAL_CHECK(check_cond_, check_message_, ...) do { \
86 if (unlikely(!(check_cond_))) { \
87 if (#__VA_ARGS__ [0]) \
88 GP_INTERNAL_ABORT(check_message_ #check_cond_, "\n" __VA_ARGS__); \
89 else \
90 GP_INTERNAL_ABORT(check_message_ #check_cond_, " "); \
91 } \
92 } while (0)
95 * Aborts and prints the message along with the location in code
96 * to stderr. Used for fatal errors.
98 * Use as either GP_ABORT(), GP_ABORT(msg) or GP_ABORT(format, params...) where
99 * msg and format must be string constants.
101 #define GP_ABORT(...) GP_INTERNAL_ABORT("", ##__VA_ARGS__)
104 * Checks the condition and aborts immediately if it is not satisfied,
105 * printing the condition and location in the source.
106 * (Intended for checking for bugs within the library itself.)
108 * Use as either GP_ASSERT(cond), GP_ASSERT(cond, msg) or
109 * GP_ASSERT(cond, format, params...) where msg and format must be string
110 * constants.
112 #define GP_ASSERT(check_cond_, ...) \
113 GP_GENERAL_CHECK(check_cond_, "asserion failed: ", ##__VA_ARGS__);
116 * Perform a runtime check, on failure abort and print a message.
117 * (Intended for user-caused errors like invalid arguments.)
119 * Use as either GP_CHECK(cond), GP_CHECK(cond, msg) or
120 * GP_CHECK(cond, format, params...) where msg and format must be string
121 * constants.
123 #define GP_CHECK(check_cond_, ...) \
124 GP_GENERAL_CHECK(check_cond_, "check failed: ", ##__VA_ARGS__);
127 * Swap a and b using an intermediate variable
129 #define GP_SWAP(a, b) do { \
130 typeof(a) tmp = b; \
131 b = a; \
132 a = tmp; \
133 } while (0)
136 * Helper macros to read/write parts of words
138 * Return (shifted) count bits at offset of value
139 * Note: operates with value types same as val
141 #define GP_GET_BITS(offset, count, val) ( ( (val)>>(offset) ) & ( ((((typeof(val))1)<<(count)) - 1) ) )
144 * Set count bits of dest at ofset to val (shifted by offset)
146 * Does not check val for overflow
147 * Operates on 8, 16, and 32 bit values, depending on the type of dest,
148 * this should be unsigned
150 * GP_SET_BITS_OR anly sets (|=) the bits, assuming these are clear beforehand
151 * GP_CLEAR_BITS sets the target bits to zero
152 * GP_SET_BITS does both
154 #define GP_CLEAR_BITS(offset, count, dest) ( (dest) &= ~(((((typeof(dest))1) << (count)) - 1) << (offset)) )
156 #define GP_SET_BITS_OR(offset, dest, val) ( (dest) |= ((val)<<(offset)) )
158 #define GP_SET_BITS(offset, count, dest, val) (GP_CLEAR_BITS(offset, count, dest), \
159 GP_SET_BITS_OR(offset, dest, val) )
162 /* Determines the sign of the integer value; it is +1 if value is positive,
163 * -1 if negative, and 0 if it is zero.
165 #define GP_SIGN(a) ({ \
166 typeof(a) _a = a; \
167 (_a > 0) ? 1 : ((_a < 0) ? -1 : 0); \
170 #endif /* GP_COMMON_H */