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
86#define GP_ABS(a) ({ \
87 typeof(a) gp_a__ = a; \
88 gp_a__ > 0 ? gp_a__ : - gp_a__; \
89})
90
99#define GP_ABS_DIFF(a, b) ({ \
100 typeof(a) gp_a__ = a; \
101 typeof(b) gp_b__ = b; \
102 gp_a__ > gp_b__ ? gp_a__ - gp_b__ : gp_b__ - gp_a__; \
103})
104
111#define GP_ALIGN2(a) ({ \
112 typeof(a) gp_a__ = a; \
113 gp_a__ + (gp_a__%2); \
114})
115
124#define GP_SWAP(a, b) do { \
125 typeof(b) gp_b__ = b; \
126 b = a; \
127 a = gp_b__; \
128} while (0)
129
130/* Determines the sign of the integer value; it is +1 if value is positive,
131 * -1 if negative, and 0 if it is zero.
132 */
133#define GP_SIGN(a) ({ \
134 typeof(a) gp_a__ = a; \
135 (gp_a__ > 0) ? 1 : ((gp_a__ < 0) ? -1 : 0); \
136})
137
144#define GP_ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
145
156#define GP_CONTAINER_OF(ptr, structure, member) \
157 ((structure *)((char *)(ptr) - offsetof(structure, member)))
158
159/*
160 * Internal macros with common code for GP_ABORT, GP_ASSERT and GP_CHECK.
161 * GP_INTERNAL_ABORT takes a message that may contain % (e.g. assert condition)
162 * and prints message and calls abort().
163 * GP_GENERAL_CHECK is a check with specified message prefix
164 * (for assert and check)
165 */
166#define GP_INTERNAL_ABORT(...) do { \
167 gp_print_abort_info(__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__); \
168 abort(); \
169} while (0)
170
171/*
172 * Prints C stacktrace.
173 */
174void gp_debug_print_cstack(void);
175
176/*
177 * Print as much trace info as possible. Currently, the (C) call stack and
178 * the Python stack if a Python interpreter is set up. In case more wrappers
179 * are written, it should print a trace for the currently active.
180 */
181void gp_print_abort_info(const char *file, const char *function, unsigned int line,
182 const char *msg, const char *fmt, ...)
183 __attribute__ ((format (printf, 5, 6)));
184
185#define GP_GENERAL_CHECK(check_cond_, check_message_, ...) do { \
186 if (GP_UNLIKELY(!(check_cond_))) { \
187 if (#__VA_ARGS__ [0]) \
188 GP_INTERNAL_ABORT(check_message_ #check_cond_, \
189 "\n" __VA_ARGS__); \
190 else \
191 GP_INTERNAL_ABORT(check_message_ #check_cond_, " "); \
192 } \
193} while (0)
194
195/*
196 * Aborts and prints the message along with the location in code
197 * to stderr. Used for fatal errors.
198 *
199 * Use as either GP_ABORT(msg) or GP_ABORT(format, params...) where
200 * msg and format must be string constants.
201 */
202#define GP_ABORT(...) \
203 GP_INTERNAL_ABORT("\n", __VA_ARGS__)
204
205/*
206 * Checks the condition and aborts immediately if it is not satisfied,
207 * printing the condition and location in the source.
208 * (Intended for checking for bugs within the library itself.)
209 *
210 * Use as either GP_ASSERT(cond), GP_ASSERT(cond, msg) or
211 * GP_ASSERT(cond, format, params...) where msg and format must be string
212 * constants.
213 */
214#define GP_ASSERT(check_cond_, ...) \
215 GP_GENERAL_CHECK(check_cond_, "assertion failed: ", ##__VA_ARGS__)
216
217/*
218 * Perform a runtime check, on failure abort and print a message.
219 * (Intended for user-caused errors like invalid arguments.)
220 *
221 * Use as either GP_CHECK(cond), GP_CHECK(cond, msg) or
222 * GP_CHECK(cond, format, params...) where msg and format must be string
223 * constants.
224 */
225#define GP_CHECK(check_cond_, ...) \
226 GP_GENERAL_CHECK(check_cond_, "check failed: ", ##__VA_ARGS__)
227
228#endif /* CORE_GP_COMMON_H */
A compiler dependent macros.