GFXprim
2D bitmap graphics library with emphasis on speed and correctness
Loading...
Searching...
No Matches
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__ = (a); \
33 typeof(b) gp_b__ = (b); \
34 gp_a__ < gp_b__ ? gp_a__ : gp_b__; \
35})
36
45#define GP_MIN3(a, b, c) ({ \
46 typeof(a) gp_a__ = (a); \
47 typeof(b) gp_b__ = (b); \
48 typeof(c) gp_c__ = (c); \
49 gp_a__ < gp_b__ ? (gp_a__ < gp_c__ ? gp_a__ : gp_c__) : (gp_b__ < gp_c__ ? gp_b__ : gp_c__); \
50})
51
59#define GP_MAX(a, b) ({ \
60 typeof(a) gp_a__ = (a); \
61 typeof(b) gp_b__ = (b); \
62 gp_a__ > gp_b__ ? gp_a__ : gp_b__; \
63})
64
73#define GP_MAX3(a, b, c) ({ \
74 typeof(a) gp_a__ = (a); \
75 typeof(b) gp_b__ = (b); \
76 typeof(c) gp_c__ = (c); \
77 gp_a__ > gp_b__ ? (gp_a__ > gp_c__ ? gp_a__ : gp_c__) : (gp_b__ > gp_c__ ? gp_b__ : gp_c__); \
78})
79
88#define GP_CONCAT2(a, b) a##b
89
90#define GP_UNIQUE_ID__(prefix, suffix) GP_CONCAT2(prefix, suffix)
91
102#define GP_UNIQUE_ID(prefix) GP_UNIQUE_ID__(prefix, __COUNTER__)
103
110#define GP_ABS(a) ({ \
111 typeof(a) gp_a__ = a; \
112 gp_a__ > 0 ? gp_a__ : - gp_a__; \
113})
114
123#define GP_ABS_DIFF(a, b) ({ \
124 typeof(a) gp_a__ = a; \
125 typeof(b) gp_b__ = b; \
126 gp_a__ > gp_b__ ? gp_a__ - gp_b__ : gp_b__ - gp_a__; \
127})
128
135#define GP_ALIGN2(a) ({ \
136 typeof(a) gp_a__ = a; \
137 gp_a__ + (gp_a__%2); \
138})
139
148#define GP_SWAP(a, b) do { \
149 typeof(b) gp_b__ = b; \
150 b = a; \
151 a = gp_b__; \
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__ = a; \
159 (gp_a__ > 0) ? 1 : ((gp_a__ < 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 */
198void 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 */
205void 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(check_cond_, check_message_, ...) do { \
210 if (GP_UNLIKELY(!(check_cond_))) { \
211 if (#__VA_ARGS__ [0]) \
212 GP_INTERNAL_ABORT(check_message_ #check_cond_, \
213 "\n" __VA_ARGS__); \
214 else \
215 GP_INTERNAL_ABORT(check_message_ #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(check_cond_, ...) \
239 GP_GENERAL_CHECK(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(check_cond_, ...) \
250 GP_GENERAL_CHECK(check_cond_, "check failed: ", ##__VA_ARGS__)
251
252#endif /* CORE_GP_COMMON_H */
A compiler dependent macros.