GFXprim
2D bitmap graphics library with emphasis on speed and correctness
Loading...
Searching...
No Matches
include
core
gp_common.h
Go to the documentation of this file.
1
// SPDX-License-Identifier: LGPL-2.1-or-later
2
/*
3
* Copyright (C) 2009-2012 Jiri "BlueBear" Dluhos
4
* <jiri.bluebear.dluhos@gmail.com>
5
*
6
* Copyright (C) 2009-2024 Cyril Hrubis <metan@ucw.cz>
7
*/
8
13
#ifndef CORE_GP_COMMON_H
14
#define CORE_GP_COMMON_H
15
16
#include <stdio.h>
17
#include <stdint.h>
18
#include <stdlib.h>
19
#include <unistd.h>
20
#include <stddef.h>
21
22
#include <
core/gp_compiler.h
>
23
31
#define GP_MIN(a, b) ({ \
32
typeof(a) gp_a_tmp = (a); \
33
typeof(b) gp_b_tmp = (b); \
34
gp_a_tmp < gp_b_tmp ? gp_a_tmp : gp_b_tmp; \
35
})
36
45
#define GP_MIN3(a, b, c) ({ \
46
typeof(a) gp_a_tmp = (a); \
47
typeof(b) gp_b_tmp = (b); \
48
typeof(c) gp_c_tmp = (c); \
49
gp_a_tmp < gp_b_tmp ? (gp_a_tmp < gp_c_tmp ? gp_a_tmp : gp_c_tmp) : (gp_b_tmp < gp_c_tmp ? gp_b_tmp : gp_c_tmp); \
50
})
51
59
#define GP_MAX(a, b) ({ \
60
typeof(a) gp_a_tmp = (a); \
61
typeof(b) gp_b_tmp = (b); \
62
gp_a_tmp > gp_b_tmp ? gp_a_tmp : gp_b_tmp; \
63
})
64
73
#define GP_MAX3(a, b, c) ({ \
74
typeof(a) gp_a_tmp = (a); \
75
typeof(b) gp_b_tmp = (b); \
76
typeof(c) gp_c_tmp = (c); \
77
gp_a_tmp > gp_b_tmp ? (gp_a_tmp > gp_c_tmp ? gp_a_tmp : gp_c_tmp) : (gp_b_tmp > gp_c_tmp ? gp_b_tmp : gp_c_tmp); \
78
})
79
88
#define GP_CONCAT2(a, b) a##b
89
90
#define GP_UNIQUE_ID2(prefix, suffix) GP_CONCAT2(prefix, suffix)
91
102
#define GP_UNIQUE_ID(prefix) GP_UNIQUE_ID2(prefix, __COUNTER__)
103
110
#define GP_ABS(a) ({ \
111
typeof(a) gp_a_tmp = a; \
112
gp_a_tmp > 0 ? gp_a_tmp : - gp_a_tmp; \
113
})
114
123
#define GP_ABS_DIFF(a, b) ({ \
124
typeof(a) gp_a_tmp = a; \
125
typeof(b) gp_b_tmp = b; \
126
gp_a_tmp > gp_b_tmp ? gp_a_tmp - gp_b_tmp : gp_b_tmp - gp_a_tmp; \
127
})
128
135
#define GP_ALIGN2(a) ({ \
136
typeof(a) gp_a_tmp = a; \
137
gp_a_tmp + (gp_a_tmp%2); \
138
})
139
148
#define GP_SWAP(a, b) do { \
149
typeof(b) gp_b_tmp = b; \
150
b = a; \
151
a = gp_b_tmp; \
152
} while (0)
153
154
/* Determines the sign of the integer value; it is +1 if value is positive,
155
* -1 if negative, and 0 if it is zero.
156
*/
157
#define GP_SIGN(a) ({ \
158
typeof(a) gp_a_tmp = a; \
159
(gp_a_tmp > 0) ? 1 : ((gp_a_tmp < 0) ? -1 : 0); \
160
})
161
168
#define GP_ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
169
180
#define GP_CONTAINER_OF(ptr, structure, member) \
181
((structure *)((char *)(ptr) - offsetof(structure, member)))
182
183
/*
184
* Internal macros with common code for GP_ABORT, GP_ASSERT and GP_CHECK.
185
* GP_INTERNAL_ABORT takes a message that may contain % (e.g. assert condition)
186
* and prints message and calls abort().
187
* GP_GENERAL_CHECK is a check with specified message prefix
188
* (for assert and check)
189
*/
190
#define GP_INTERNAL_ABORT(...) do { \
191
gp_print_abort_info(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__); \
192
abort(); \
193
} while (0)
194
195
/*
196
* Prints C stacktrace.
197
*/
198
void
gp_debug_print_cstack(
void
);
199
200
/*
201
* Print as much trace info as possible. Currently, the (C) call stack and
202
* the Python stack if a Python interpreter is set up. In case more wrappers
203
* are written, it should print a trace for the currently active.
204
*/
205
void
gp_print_abort_info(
const
char
*file,
const
char
*function,
unsigned
int
line,
206
const
char
*msg,
const
char
*fmt, ...)
207
__attribute__ ((format (printf, 5, 6)));
208
209
#define GP_GENERAL_CHECK(gp_check_cond, gp_check_message, ...) do { \
210
if (GP_UNLIKELY(!(gp_check_cond))) { \
211
if (#__VA_ARGS__ [0]) \
212
GP_INTERNAL_ABORT(gp_check_message #gp_check_cond, \
213
"\n" __VA_ARGS__); \
214
else \
215
GP_INTERNAL_ABORT(gp_check_message #gp_check_cond, " "); \
216
} \
217
} while (0)
218
219
/*
220
* Aborts and prints the message along with the location in code
221
* to stderr. Used for fatal errors.
222
*
223
* Use as either GP_ABORT(msg) or GP_ABORT(format, params...) where
224
* msg and format must be string constants.
225
*/
226
#define GP_ABORT(...) \
227
GP_INTERNAL_ABORT("\n", __VA_ARGS__)
228
229
/*
230
* Checks the condition and aborts immediately if it is not satisfied,
231
* printing the condition and location in the source.
232
* (Intended for checking for bugs within the library itself.)
233
*
234
* Use as either GP_ASSERT(cond), GP_ASSERT(cond, msg) or
235
* GP_ASSERT(cond, format, params...) where msg and format must be string
236
* constants.
237
*/
238
#define GP_ASSERT(gp_check_cond, ...) \
239
GP_GENERAL_CHECK(gp_check_cond, "assertion failed: ", ##__VA_ARGS__)
240
241
/*
242
* Perform a runtime check, on failure abort and print a message.
243
* (Intended for user-caused errors like invalid arguments.)
244
*
245
* Use as either GP_CHECK(cond), GP_CHECK(cond, msg) or
246
* GP_CHECK(cond, format, params...) where msg and format must be string
247
* constants.
248
*/
249
#define GP_CHECK(gp_check_cond, ...) \
250
GP_GENERAL_CHECK(gp_check_cond, "check failed: ", ##__VA_ARGS__)
251
252
#endif
/* CORE_GP_COMMON_H */
gp_compiler.h
A compiler dependent macros.
Generated by
1.12.0