1 /* Jitter: header supplying functions and macros which some systems lack.
2    Copyright (C) 2017, 2019, 2020 Luca Saiu
3    Updated in 2021 by Luca Saiu
4    Written by Luca Saiu
5 
6    This file is part of Jitter.
7 
8    Jitter is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 3 of the License, or
11    (at your option) any later version.
12 
13    Jitter is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with Jitter.  If not, see <http://www.gnu.org/licenses/>. */
20 
21 
22 #ifndef JITTER_MISSING_H_
23 #define JITTER_MISSING_H_
24 
25 #include <jitter/jitter-config.h>
26 #include <stdio.h>
27 #include <stddef.h> /* for offsetof, in case it is supported. */
28 
29 
30 /* Struct offset computation.
31  * ************************************************************************** */
32 
33 /* If offsetof is missign I can emulate with a macro which should be portable
34    in practice even if not according to the letter of the Standard. */
35 #if ! defined (JITTER_HAVE_OFFSETOF)
36 # define offsetof(type_name, field_name)             \
37     ((size_t)                                        \
38      ((char *) & (((type_name *) NULL)->field_name)  \
39       - (char *) NULL))
40 #endif // ! defined (JITTER_HAVE_OFFSETOF)
41 
42 
43 
44 
45 /* Alignment qualifiers.
46  * ************************************************************************** */
47 
48 /* If alignas is missing I can emulate it with a GNU C attribute.  In practice
49    alignas is only used (in jitter-heap.h and friends) with GCC, so the issue is
50    just supporting old versions. */
51 #if ! defined (JITTER_HAVE_ALIGNAS)
52 # define alignas(thing) __attribute__((aligned (thing)))
53 # define alignof __alignof__
54 #endif // ! defined (JITTER_HAVE_ALIGNAS)
55 
56 
57 
58 
59 /* GNU C attributes.
60  * ************************************************************************** */
61 
62 /* C compilers not supporting the GNU exensions will not recognize attributes.
63    A simple fix is redefining the attribute keyword as a macro. */
64 #if ! defined (JITTER_HAVE_GNU_C_ATTRIBUTE)
65 # define attribute(ignored_attributes)      /* Nothing. */
66 # define __attribute__(ignored_attributes)  /* Nothing. */
67 #endif /* ! defined (JITTER_HAVE_GNU_C_ATTRIBUTE) */
68 
69 /* After the previous definition, non-GNU C compilers will not have any problem,
70    since every attribute use will be macroexpanded away; therefore it would be
71    useless, in the following, to conditionalize over the attribute syntax
72    availability.  What remains to be solved is older GNU C compilers not knowing
73    about more recently introduced attributes. */
74 #if ! defined (JITTER_HAVE_ATTRIBUTE_NO_REORDER)
75 # define no_reorder      /* Nothing. */
76 # define __no_reorder__  /* Nothing. */
77   /* On configurations where no_reorder is not defined, which will be the case
78      for very old GCCs, configure tries to add -fno-toplevel-reorder to CFLAGS .
79      That is a more brutal, global way of enforcing ordering. */
80 #endif /* #if ! defined (JITTER_HAVE_ATTRIBUTE_NO_REORDER) */
81 #if ! defined (JITTER_HAVE_ATTRIBUTE_RETURNS_NONNULL)
82 # define returns_nonnull      /* Nothing. */
83 # define __returns_nonnull__  /* Nothing. */
84 #endif /* #if ! defined (JITTER_HAVE_ATTRIBUTE_RETURNS_NONNULL) */
85 
86 
87 
88 
89 /* GCC builtins.
90  * ************************************************************************** */
91 
92 /* The logic relying on __builtin_constant_p is probably all conditionalised on
93    GCC, but it is also easy to simulate it where missing with a dummy
94    compatibility macro which treats every expression as non-constant. */
95 #if ! defined (JITTER_HAVE_GCC_BUILTIN_CONSTANT_P)
96 # define __builtin_constant_p(expression) \
97     0
98 #endif /* # if ! defined (JITTER_HAVE_GCC_BUILTIN_CONSTANT_P) */
99 
100 /* We can work with any compiler missing __builtin_expect by defining it as a
101    macro. */
102 #if ! defined (JITTER_HAVE_GCC_BUILTIN_EXPECT)
103 # define __builtin_expect(expression, expected_value) \
104     (expression)
105 #endif /* # if ! defined (JITTER_HAVE_GCC_BUILTIN_EXPECT) */
106 
107 /* Non-GCC compilers or very old GCCs miss the __bultin_unreachable builtin. */
108 #if ! defined (JITTER_HAVE_GCC_BUILTIN_UNREACHABLE)
109 # define __builtin_unreachable()                          \
110     /* It is acceptable to compile this into nothing. */  \
111     do { /* Nothing*/ } while (false)
112 #endif /* # if ! defined (JITTER_HAVE_GCC_BUILTIN_UNREACHABLE) */
113 
114 
115 
116 
117 /* I/O functions.
118  * ************************************************************************** */
119 
120 /* The functions declared here are no-ops if we can live with them doing
121    nothing; otherwise they fail fatally when called.  Each function
122    implementation in jitter-missing.c is disabled by a CPP conditional if
123    the system is found to have a real implementation at configure time. */
124 
125 /* Do nothing. */
126 void
127 flockfile ()
128   __attribute__ ((nonnull (1)));
129 
130 /* Do nothing. */
131 void
132 funlockfile ()
133   __attribute__ ((nonnull (1)));
134 
135 #endif // #ifndef JITTER_MISSING_H_
136