vkd3d: Disable printf format checks.
[wine.git] / libs / vkd3d / include / private / vkd3d_common.h
blob6b5cdf8cf2c08c5443869993fe2a60914e865257
1 /*
2 * Copyright 2016 Józef Kucia for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #ifndef __VKD3D_COMMON_H
20 #define __VKD3D_COMMON_H
22 #include "config.h"
23 #define WIN32_LEAN_AND_MEAN
24 #include "windows.h"
25 #include "vkd3d_types.h"
27 #include <ctype.h>
28 #include <limits.h>
29 #include <stdbool.h>
30 #include <stdint.h>
31 #include <stdio.h>
32 #include <stdlib.h>
34 #ifdef _MSC_VER
35 #include <intrin.h>
36 #endif
38 #ifndef ARRAY_SIZE
39 # define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
40 #endif
42 #define DIV_ROUND_UP(a, b) ((a) % (b) == 0 ? (a) / (b) : (a) / (b) + 1)
44 #define STATIC_ASSERT(e) extern void __VKD3D_STATIC_ASSERT__(int [(e) ? 1 : -1])
46 #define MEMBER_SIZE(t, m) sizeof(((t *)0)->m)
48 #define VKD3D_MAKE_TAG(ch0, ch1, ch2, ch3) \
49 ((uint32_t)(ch0) | ((uint32_t)(ch1) << 8) \
50 | ((uint32_t)(ch2) << 16) | ((uint32_t)(ch3) << 24))
52 static inline size_t align(size_t addr, size_t alignment)
54 return (addr + (alignment - 1)) & ~(alignment - 1);
57 #ifdef __GNUC__
58 # define VKD3D_NORETURN __attribute__((noreturn))
59 # ifdef __MINGW_PRINTF_FORMAT
60 # define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, args)))
61 # else
62 # define VKD3D_PRINTF_FUNC(fmt, args) /* __attribute__((format(printf, fmt, args))) */
63 # endif
64 # define VKD3D_UNUSED __attribute__((unused))
65 # define VKD3D_UNREACHABLE __builtin_unreachable()
66 #else
67 # define VKD3D_NORETURN
68 # define VKD3D_PRINTF_FUNC(fmt, args)
69 # define VKD3D_UNUSED
70 # define VKD3D_UNREACHABLE (void)0
71 #endif /* __GNUC__ */
73 VKD3D_NORETURN static inline void vkd3d_unreachable_(const char *filename, unsigned int line)
75 fprintf(stderr, "%s:%u: Aborting, reached unreachable code.\n", filename, line);
76 abort();
79 #ifdef NDEBUG
80 #define vkd3d_unreachable() VKD3D_UNREACHABLE
81 #else
82 #define vkd3d_unreachable() vkd3d_unreachable_(__FILE__, __LINE__)
83 #endif
85 static inline unsigned int vkd3d_popcount(unsigned int v)
87 #ifdef _MSC_VER
88 return __popcnt(v);
89 #elif defined(__MINGW32__)
90 return __builtin_popcount(v);
91 #else
92 v -= (v >> 1) & 0x55555555;
93 v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
94 return (((v + (v >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24;
95 #endif
98 static inline bool vkd3d_bitmask_is_contiguous(unsigned int mask)
100 unsigned int i, j;
102 for (i = 0, j = 0; i < sizeof(mask) * CHAR_BIT; ++i)
104 if (mask & (1u << i))
105 ++j;
106 else if (j)
107 break;
110 return vkd3d_popcount(mask) == j;
113 /* Undefined for x == 0. */
114 static inline unsigned int vkd3d_log2i(unsigned int x)
116 #ifdef _WIN32
117 /* _BitScanReverse returns the index of the highest set bit,
118 * unlike clz which is 31 - index. */
119 ULONG result;
120 _BitScanReverse(&result, x);
121 return (unsigned int)result;
122 #elif defined(HAVE_BUILTIN_CLZ)
123 return __builtin_clz(x) ^ 0x1f;
124 #else
125 static const unsigned int l[] =
127 ~0u, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
128 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
129 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
130 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
131 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
132 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
133 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
134 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
135 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
136 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
137 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
138 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
139 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
140 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
141 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
142 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
144 unsigned int i;
146 return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24
147 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
148 #endif
151 static inline void *vkd3d_memmem( const void *haystack, size_t haystack_len, const void *needle, size_t needle_len)
153 const char *str = haystack;
155 while (haystack_len >= needle_len)
157 if (!memcmp(str, needle, needle_len))
158 return (char *)str;
159 ++str;
160 --haystack_len;
162 return NULL;
165 static inline bool vkd3d_bound_range(size_t start, size_t count, size_t limit)
167 #ifdef HAVE_BUILTIN_ADD_OVERFLOW
168 size_t sum;
170 return !__builtin_add_overflow(start, count, &sum) && sum <= limit;
171 #else
172 return start <= limit && count <= limit - start;
173 #endif
176 static inline bool vkd3d_object_range_overflow(size_t start, size_t count, size_t size)
178 return (~(size_t)0 - start) / size < count;
181 static inline uint16_t vkd3d_make_u16(uint8_t low, uint8_t high)
183 return low | ((uint16_t)high << 8);
186 static inline uint32_t vkd3d_make_u32(uint16_t low, uint16_t high)
188 return low | ((uint32_t)high << 16);
191 static inline int vkd3d_u32_compare(uint32_t x, uint32_t y)
193 return (x > y) - (x < y);
196 static inline bool bitmap_clear(uint32_t *map, unsigned int idx)
198 return map[idx >> 5] &= ~(1u << (idx & 0x1f));
201 static inline bool bitmap_set(uint32_t *map, unsigned int idx)
203 return map[idx >> 5] |= (1u << (idx & 0x1f));
206 static inline bool bitmap_is_set(const uint32_t *map, unsigned int idx)
208 return map[idx >> 5] & (1u << (idx & 0x1f));
211 static inline int ascii_isupper(int c)
213 return 'A' <= c && c <= 'Z';
216 static inline int ascii_tolower(int c)
218 return ascii_isupper(c) ? c - 'A' + 'a' : c;
221 static inline int ascii_strncasecmp(const char *a, const char *b, size_t n)
223 int c_a, c_b;
225 while (n--)
227 c_a = ascii_tolower(*a++);
228 c_b = ascii_tolower(*b++);
229 if (c_a != c_b || !c_a)
230 return c_a - c_b;
232 return 0;
235 static inline int ascii_strcasecmp(const char *a, const char *b)
237 int c_a, c_b;
241 c_a = ascii_tolower(*a++);
242 c_b = ascii_tolower(*b++);
243 } while (c_a == c_b && c_a != '\0');
245 return c_a - c_b;
248 #ifndef _WIN32
249 # if HAVE_SYNC_ADD_AND_FETCH
250 static inline LONG InterlockedIncrement(LONG volatile *x)
252 return __sync_add_and_fetch(x, 1);
254 static inline LONG64 InterlockedIncrement64(LONG64 volatile *x)
256 return __sync_add_and_fetch(x, 1);
258 static inline LONG InterlockedAdd(LONG volatile *x, LONG val)
260 return __sync_add_and_fetch(x, val);
262 # else
263 # error "InterlockedIncrement() not implemented for this platform"
264 # endif /* HAVE_SYNC_ADD_AND_FETCH */
266 # if HAVE_SYNC_SUB_AND_FETCH
267 static inline LONG InterlockedDecrement(LONG volatile *x)
269 return __sync_sub_and_fetch(x, 1);
271 # else
272 # error "InterlockedDecrement() not implemented for this platform"
273 # endif
275 #endif /* _WIN32 */
277 static inline void vkd3d_parse_version(const char *version, int *major, int *minor)
279 *major = atoi(version);
281 while (isdigit(*version))
282 ++version;
283 if (*version == '.')
284 ++version;
286 *minor = atoi(version);
289 HRESULT hresult_from_vkd3d_result(int vkd3d_result);
291 #ifdef _WIN32
292 static inline void *vkd3d_dlopen(const char *name)
294 return LoadLibraryA(name);
297 static inline void *vkd3d_dlsym(void *handle, const char *symbol)
299 return GetProcAddress(handle, symbol);
302 static inline int vkd3d_dlclose(void *handle)
304 return FreeLibrary(handle);
307 static inline const char *vkd3d_dlerror(void)
309 unsigned int error = GetLastError();
310 static char message[256];
312 if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, message, sizeof(message), NULL))
313 return message;
314 sprintf(message, "Unknown error %u.\n", error);
315 return message;
317 #elif defined(HAVE_DLFCN_H)
318 #include <dlfcn.h>
320 static inline void *vkd3d_dlopen(const char *name)
322 return dlopen(name, RTLD_NOW);
325 static inline void *vkd3d_dlsym(void *handle, const char *symbol)
327 return dlsym(handle, symbol);
330 static inline int vkd3d_dlclose(void *handle)
332 return dlclose(handle);
335 static inline const char *vkd3d_dlerror(void)
337 return dlerror();
339 #else
340 static inline void *vkd3d_dlopen(const char *name)
342 return NULL;
345 static inline void *vkd3d_dlsym(void *handle, const char *symbol)
347 return NULL;
350 static inline int vkd3d_dlclose(void *handle)
352 return 0;
355 static inline const char *vkd3d_dlerror(void)
357 return "Not implemented for this platform.\n";
359 #endif
361 #endif /* __VKD3D_COMMON_H */