]> Sergey Matveev's repositories - bfs.git/blob - src/config.h
Release 3.0.3
[bfs.git] / src / config.h
1 // Copyright © Tavian Barnes <tavianator@tavianator.com>
2 // SPDX-License-Identifier: 0BSD
3
4 /**
5  * Configuration and feature/platform detection.
6  */
7
8 #ifndef BFS_CONFIG_H
9 #define BFS_CONFIG_H
10
11 #include <stddef.h>
12
13 #if __STDC_VERSION__ < 202311L
14 #  include <stdalign.h>
15 #  include <stdbool.h>
16 #  include <stdnoreturn.h>
17 #endif
18
19 // bfs packaging configuration
20
21 #ifndef BFS_COMMAND
22 #  define BFS_COMMAND "bfs"
23 #endif
24 #ifndef BFS_VERSION
25 #  define BFS_VERSION "3.0.3"
26 #endif
27 #ifndef BFS_HOMEPAGE
28 #  define BFS_HOMEPAGE "https://tavianator.com/projects/bfs.html"
29 #endif
30
31 // Check for system headers
32
33 #ifdef __has_include
34
35 #if __has_include(<mntent.h>)
36 #  define BFS_HAS_MNTENT_H true
37 #endif
38 #if __has_include(<paths.h>)
39 #  define BFS_HAS_PATHS_H true
40 #endif
41 #if __has_include(<sys/acl.h>)
42 #  define BFS_HAS_SYS_ACL_H true
43 #endif
44 #if __has_include(<sys/capability.h>)
45 #  define BFS_HAS_SYS_CAPABILITY_H true
46 #endif
47 #if __has_include(<sys/extattr.h>)
48 #  define BFS_HAS_SYS_EXTATTR_H true
49 #endif
50 #if __has_include(<sys/mkdev.h>)
51 #  define BFS_HAS_SYS_MKDEV_H true
52 #endif
53 #if __has_include(<sys/param.h>)
54 #  define BFS_HAS_SYS_PARAM_H true
55 #endif
56 #if __has_include(<sys/sysmacros.h>)
57 #  define BFS_HAS_SYS_SYSMACROS_H true
58 #endif
59 #if __has_include(<sys/xattr.h>)
60 #  define BFS_HAS_SYS_XATTR_H true
61 #endif
62 #if __has_include(<threads.h>)
63 #  define BFS_HAS_THREADS_H true
64 #endif
65 #if __has_include(<util.h>)
66 #  define BFS_HAS_UTIL_H true
67 #endif
68
69 #else // !__has_include
70
71 #define BFS_HAS_MNTENT_H __GLIBC__
72 #define BFS_HAS_PATHS_H true
73 #define BFS_HAS_SYS_ACL_H true
74 #define BFS_HAS_SYS_CAPABILITY_H __linux__
75 #define BFS_HAS_SYS_EXTATTR_H __FreeBSD__
76 #define BFS_HAS_SYS_MKDEV_H false
77 #define BFS_HAS_SYS_PARAM_H true
78 #define BFS_HAS_SYS_SYSMACROS_H __GLIBC__
79 #define BFS_HAS_SYS_XATTR_H __linux__
80 #define BFS_HAS_THREADS_H (!__STDC_NO_THREADS__)
81 #define BFS_HAS_UTIL_H __NetBSD__
82
83 #endif // !__has_include
84
85 #ifndef BFS_USE_MNTENT_H
86 #  define BFS_USE_MNTENT_H BFS_HAS_MNTENT_H
87 #endif
88 #ifndef BFS_USE_PATHS_H
89 #  define BFS_USE_PATHS_H BFS_HAS_PATHS_H
90 #endif
91 #ifndef BFS_USE_SYS_ACL_H
92 #  define BFS_USE_SYS_ACL_H BFS_HAS_SYS_ACL_H
93 #endif
94 #ifndef BFS_USE_SYS_CAPABILITY_H
95 #  define BFS_USE_SYS_CAPABILITY_H (BFS_HAS_SYS_CAPABILITY_H && !__FreeBSD__)
96 #endif
97 #ifndef BFS_USE_SYS_EXTATTR_H
98 #  define BFS_USE_SYS_EXTATTR_H BFS_HAS_SYS_EXTATTR_H
99 #endif
100 #ifndef BFS_USE_SYS_MKDEV_H
101 #  define BFS_USE_SYS_MKDEV_H BFS_HAS_SYS_MKDEV_H
102 #endif
103 #ifndef BFS_USE_SYS_PARAM_H
104 #  define BFS_USE_SYS_PARAM_H BFS_HAS_SYS_PARAM_H
105 #endif
106 #ifndef BFS_USE_SYS_SYSMACROS_H
107 #  define BFS_USE_SYS_SYSMACROS_H BFS_HAS_SYS_SYSMACROS_H
108 #endif
109 #ifndef BFS_USE_SYS_XATTR_H
110 #  define BFS_USE_SYS_XATTR_H BFS_HAS_SYS_XATTR_H
111 #endif
112 #ifndef BFS_USE_THREADS_H
113 #  define BFS_USE_THREADS_H BFS_HAS_THREADS_H
114 #endif
115 #ifndef BFS_USE_UTIL_H
116 #  define BFS_USE_UTIL_H BFS_HAS_UTIL_H
117 #endif
118
119 // Stub out feature detection on old/incompatible compilers
120
121 #ifndef __has_feature
122 #  define __has_feature(feat) false
123 #endif
124
125 #ifndef __has_c_attribute
126 #  define __has_c_attribute(attr) false
127 #endif
128
129 #ifndef __has_attribute
130 #  define __has_attribute(attr) false
131 #endif
132
133 // Platform detection
134
135 // Get the definition of BSD if available
136 #if BFS_USE_SYS_PARAM_H
137 #  include <sys/param.h>
138 #endif
139
140 #ifndef __GLIBC_PREREQ
141 #  define __GLIBC_PREREQ(maj, min) false
142 #endif
143
144 // Fundamental utilities
145
146 /**
147  * Get the length of an array.
148  */
149 #define countof(array) (sizeof(array) / sizeof(0[array]))
150
151 /**
152  * False sharing/destructive interference/largest cache line size.
153  */
154 #ifdef __GCC_DESTRUCTIVE_SIZE
155 #  define FALSE_SHARING_SIZE __GCC_DESTRUCTIVE_SIZE
156 #else
157 #  define FALSE_SHARING_SIZE 64
158 #endif
159
160 /**
161  * True sharing/constructive interference/smallest cache line size.
162  */
163 #ifdef __GCC_CONSTRUCTIVE_SIZE
164 #  define TRUE_SHARING_SIZE __GCC_CONSTRUCTIVE_SIZE
165 #else
166 #  define TRUE_SHARING_SIZE 64
167 #endif
168
169 /**
170  * Alignment specifier that avoids false sharing.
171  */
172 #define cache_align alignas(FALSE_SHARING_SIZE)
173
174 // Wrappers for attributes
175
176 /**
177  * Silence compiler warnings about switch/case fall-throughs.
178  */
179 #if __has_c_attribute(fallthrough)
180 #  define fallthru [[fallthrough]]
181 #elif __has_attribute(fallthrough)
182 #  define fallthru __attribute__((fallthrough))
183 #else
184 #  define fallthru ((void)0)
185 #endif
186
187 /**
188  * Adds compiler warnings for bad printf()-style function calls, if supported.
189  */
190 #if __has_attribute(format)
191 #  define BFS_FORMATTER(fmt, args) __attribute__((format(printf, fmt, args)))
192 #else
193 #  define BFS_FORMATTER(fmt, args)
194 #endif
195
196 /**
197  * Check if function multiversioning via GNU indirect functions (ifunc) is supported.
198  */
199 #ifndef BFS_USE_TARGET_CLONES
200 #  if __has_attribute(target_clones) && (__GLIBC__ || __FreeBSD__ || __NetBSD__)
201 #    define BFS_USE_TARGET_CLONES true
202 #  endif
203 #endif
204
205 /**
206  * Ignore a particular GCC warning for a region of code.
207  */
208 #if __GNUC__
209 #  define BFS_PRAGMA_STRINGIFY(...) _Pragma(#__VA_ARGS__)
210 #  define BFS_SUPPRESS(warning) \
211         _Pragma("GCC diagnostic push"); \
212         BFS_PRAGMA_STRINGIFY(GCC diagnostic ignored warning)
213 #  define BFS_UNSUPPRESS() \
214         _Pragma("GCC diagnostic pop")
215 #else
216 #  define BFS_SUPPRESS(warning)
217 #  define BFS_UNSUPPRESS()
218 #endif
219
220 #endif // BFS_CONFIG_H