1// SPDX-License-Identifier: 0BSD
2
3///////////////////////////////////////////////////////////////////////////////
4//
5/// \file       tuklib_common.h
6/// \brief      Common definitions for tuklib modules
7//
8//  Author:     Lasse Collin
9//
10///////////////////////////////////////////////////////////////////////////////
11
12#ifndef TUKLIB_COMMON_H
13#define TUKLIB_COMMON_H
14
15// The config file may be replaced by a package-specific file.
16// It should include at least stddef.h, stdbool.h, inttypes.h, and limits.h.
17#include "tuklib_config.h"
18
19// TUKLIB_SYMBOL_PREFIX is prefixed to all symbols exported by
20// the tuklib modules. If you use a tuklib module in a library,
21// you should use TUKLIB_SYMBOL_PREFIX to make sure that there
22// are no symbol conflicts in case someone links your library
23// into application that also uses the same tuklib module.
24#ifndef TUKLIB_SYMBOL_PREFIX
25#	define TUKLIB_SYMBOL_PREFIX
26#endif
27
28#define TUKLIB_CAT_X(a, b) a ## b
29#define TUKLIB_CAT(a, b) TUKLIB_CAT_X(a, b)
30
31#ifndef TUKLIB_SYMBOL
32#	define TUKLIB_SYMBOL(sym) TUKLIB_CAT(TUKLIB_SYMBOL_PREFIX, sym)
33#endif
34
35#ifndef TUKLIB_DECLS_BEGIN
36#	ifdef __cplusplus
37#		define TUKLIB_DECLS_BEGIN extern "C" {
38#	else
39#		define TUKLIB_DECLS_BEGIN
40#	endif
41#endif
42
43#ifndef TUKLIB_DECLS_END
44#	ifdef __cplusplus
45#		define TUKLIB_DECLS_END }
46#	else
47#		define TUKLIB_DECLS_END
48#	endif
49#endif
50
51#if defined(__GNUC__) && defined(__GNUC_MINOR__)
52#	define TUKLIB_GNUC_REQ(major, minor) \
53		((__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)) \
54			|| __GNUC__ > (major))
55#else
56#	define TUKLIB_GNUC_REQ(major, minor) 0
57#endif
58
59// tuklib_attr_noreturn attribute is used to mark functions as non-returning.
60// We cannot use "noreturn" as the macro name because then C23 code that
61// uses [[noreturn]] would break as it would expand to [[ [[noreturn]] ]].
62//
63// tuklib_attr_noreturn must be used at the beginning of function declaration
64// to work in all cases. The [[noreturn]] syntax is the most limiting, it
65// must be even before any GNU C's __attribute__ keywords:
66//
67//     tuklib_attr_noreturn
68//     __attribute__((nonnull(1)))
69//     extern void foo(const char *s);
70//
71// FIXME: Update __STDC_VERSION__ for the final C23 version. 202000 is used
72// by GCC 13 and Clang 15 with -std=c2x.
73#if   defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000
74#	define tuklib_attr_noreturn [[noreturn]]
75#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112
76#	define tuklib_attr_noreturn _Noreturn
77#elif TUKLIB_GNUC_REQ(2, 5)
78#	define tuklib_attr_noreturn __attribute__((__noreturn__))
79#elif defined(_MSC_VER)
80#	define tuklib_attr_noreturn __declspec(noreturn)
81#else
82#	define tuklib_attr_noreturn
83#endif
84
85#if (defined(_WIN32) && !defined(__CYGWIN__)) \
86		|| defined(__OS2__) || defined(__MSDOS__)
87#	define TUKLIB_DOSLIKE 1
88#endif
89
90#endif
91