C Standard Library Extensions 1.3.1
cxmacros.h
1/*
2 * This file is part of the ESO C Extension Library
3 * Copyright (C) 2001-2026 European Southern Observatory
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <https://www.gnu.org/licenses/>.
17 */
18
19
20/*
21 * This file MUST not include any other cext header file.
22 */
23
24#ifndef CX_MACROS_H
25#define CX_MACROS_H
26
27
28/*
29 * Get the system's definition of NULL from stddef.h
30 */
31
32#include <stddef.h>
33
34
35/*
36 * An alias for __extension__
37 */
38
39#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
40# define CX_GNUC_EXTENSION __extension__
41#else
42# define CX_GNUC_EXTENSION
43#endif
44
45
46/*
47 * Macros for the GNU compiler function attributes
48 */
49
50#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
51# define CX_GNUC_PURE __attribute__((__pure__))
52# define CX_GNUC_MALLOC __attribute__((__malloc__))
53#else
54# define G_GNUC_PURE
55# define G_GNUC_MALLOC
56#endif
57
58#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
59# define CX_GNUC_PRINTF(fmt_idx, arg_idx) \
60 __attribute__((__format__(__printf__, fmt_idx, arg_idx)))
61# define CX_GNUC_SCANF(fmt_idx, arg_idx) \
62 __attribute__((__format__(__scanf__, fmt_idx, arg_idx)))
63# define CX_GNUC_FORMAT(arg_idx) __attribute__((__format_arg__(arg_idx)))
64# define CX_GNUC_NORETURN __attribute__((__noreturn__))
65# define CX_GNUC_CONST __attribute__((__const__))
66# define CX_GNUC_UNUSED __attribute__((__unused__))
67#else
68# define CX_GNUC_PRINTF(fmt_idx, arg_idx)
69# define CX_GNUC_SCANF(fmt_idx, arg_idx)
70# define CX_GNUC_FORMAT(arg_idx)
71# define CX_GNUC_NORETURN
72# define CX_GNUC_CONST
73# define CX_GNUC_UNUSED
74#endif
75
76
77/*
78 * Wrap the gcc __PRETTY_FUNCTION__ and __FUNCTION__ variables with macros.
79 */
80
81#if defined(__GNUC__) && (__GNUC__ < 3)
82# define CX_GNUC_FUNCTION __FUNCTION__
83# define CX_GNUC_PRETTY_FUNCTION __PRETTY_FUNCTION__
84#else /* !__GNUC__ */
85# define CX_GNUC_FUNCTION ""
86# define CX_GNUC_PRETTY_FUNCTION ""
87#endif /* !__GNUC__ */
88
89#define CX_STRINGIFY(macro) CX_STRINGIFY_ARG(macro)
90#define CX_STRINGIFY_ARG(contents) #contents
91
92
93/*
94 * String identifier for the current code position
95 */
96
97#if defined(__GNUC__) && (__GNUC__ < 3)
98# define CX_CODE_POS \
99 __FILE__ ":" CX_STRINGIFY(__LINE__) ":" __PRETTY_FUNCTION__ "()"
100#else
101# define CX_CODE_POS __FILE__ ":" CX_STRINGIFY(__LINE__)
102#endif
103
104
105/*
106 * Current function identifier
107 */
108#if defined(__GNUC__)
109# define CX_FUNC_NAME ((const char *)(__PRETTY_FUNCTION__))
110#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 19901L
111# define CX_FUNC_NAME ((const char *)(__func__))
112#else
113# define CX_FUNC_NAME ((const char *)("???"))
114#endif
115
116
117/*
118 * C code guard
119 */
120
121#undef CX_BEGIN_DECLS
122#undef CX_END_DECLS
123
124#ifdef __cplusplus
125# define CX_BEGIN_DECLS extern "C" {
126# define CX_END_DECLS }
127#else
128# define CX_BEGIN_DECLS /* empty */
129# define CX_END_DECLS /* empty */
130#endif
131
132
133/*
134 * Some popular macros. If the system provides already a definition for some
135 * of them this definition is used, assuming the definition is correct.
136 */
137
138#ifndef NULL
139# ifdef __cplusplus
140# define NULL (0L)
141# else /* !__cplusplus */
142# define NULL ((void *)0)
143# endif /* !__cplusplus */
144#endif
145
146#ifndef FALSE
147# define FALSE (0)
148#endif
149
150#ifndef TRUE
151# define TRUE (!FALSE)
152#endif
153
154#ifndef CX_MIN
155# define CX_MIN(a, b) ((a) < (b) ? (a) : (b))
156#endif
157
158#ifndef CX_MAX
159# define CX_MAX(a, b) ((a) > (b) ? (a) : (b))
160#endif
161
162#ifndef CX_ABS
163# define CX_ABS(a) ((a) < (0) ? -(a) : (a))
164#endif
165
166#ifndef CX_CLAMP
167# define CX_CLAMP(a, low, high) \
168 (((a) > (high)) ? (high) : (((a) < (low)) ? (low) : (a)))
169#endif
170
171
172/*
173 * Number of elements in an array
174 */
175
176#define CX_N_ELEMENTS(array) (sizeof(array) / sizeof((array)[0]))
177
178#endif /* CX_MACROS_H */