1 #ifndef _RE2C_UTIL_C99_STDINT_
2 #define _RE2C_UTIL_C99_STDINT_
3 
4 #include "config.h"
5 
6 #if HAVE_STDINT_H
7 #    include <stdint.h>
8 #else // HAVE_STDINT_H
9 
10 // A humble attempt to provide C99 compliant <stdint.h>
11 // for environments that don't have it (e.g., MSVC 2003).
12 //
13 // First, we try to define exact-width integer types. We don't
14 // rely on any particular environment: instead, we search for
15 // a type of certain width in the following list:
16 //     char      (C89)
17 //     short     (C89)
18 //     int       (C89)
19 //     long      (C89)
20 //     long long (C99)
21 //     __int64   (MSVC-specific)
22 // (we consider even insane possibilities for simplicity).
23 // The size of each type is defined by autoconf in the form
24 // of a macro SIZEOF_<TYPE> (set to 0 for nonexistent types).
25 // If we don't find a type with the required width, we don't
26 // define the corresponding exact-width C99 type at all.
27 //
28 // We define other types and constants based on exact-width
29 // types and C99 standard.
30 //
31 // We use SIZEOF_VOID_P to determine size of pointers.
32 //
33 // We use SIZEOF_0<SUFFIX> to find suitable 64-bit integer
34 // constant suffix.
35 
36 // C99-7.18.1.1 Exact-width integer types
37 
38 // int8_t, uint8_t
39 #if SIZEOF_CHAR == 1
40     typedef   signed char int8_t;
41     typedef unsigned char uint8_t;
42 #elif SIZEOF_SHORT == 1
43     typedef   signed short int8_t;
44     typedef unsigned short uint8_t;
45 #elif SIZEOF_INT == 1
46     typedef   signed int int8_t;
47     typedef unsigned int uint8_t;
48 #elif SIZEOF_LONG == 1
49     typedef   signed long int8_t;
50     typedef unsigned long uint8_t;
51 #elif SIZEOF_LONG_LONG == 1
52     typedef   signed long long int8_t;
53     typedef unsigned long long uint8_t;
54 #elif SIZEOF___INT64 == 1
55     typedef   signed __int64 int8_t;
56     typedef unsigned __int64 uint8_t;
57 #endif
58 
59 // int16_t, uint16_t
60 #if SIZEOF_CHAR == 2
61     typedef   signed char int16_t;
62     typedef unsigned char uint16_t;
63 #elif SIZEOF_SHORT == 2
64     typedef   signed short int16_t;
65     typedef unsigned short uint16_t;
66 #elif SIZEOF_INT == 2
67     typedef   signed int int16_t;
68     typedef unsigned int uint16_t;
69 #elif SIZEOF_LONG == 2
70     typedef   signed long int16_t;
71     typedef unsigned long uint16_t;
72 #elif SIZEOF_LONG_LONG == 2
73     typedef   signed long long int16_t;
74     typedef unsigned long long uint16_t;
75 #elif SIZEOF___INT64 == 2
76     typedef   signed __int64 int16_t;
77     typedef unsigned __int64 uint16_t;
78 #endif
79 
80 // int32_t, uint32_t
81 #if SIZEOF_CHAR == 4
82     typedef   signed char int32_t;
83     typedef unsigned char uint32_t;
84 #elif SIZEOF_SHORT == 4
85     typedef   signed short int32_t;
86     typedef unsigned short uint32_t;
87 #elif SIZEOF_INT == 4
88     typedef   signed int int32_t;
89     typedef unsigned int uint32_t;
90 #elif SIZEOF_LONG == 4
91     typedef   signed long int32_t;
92     typedef unsigned long uint32_t;
93 #elif SIZEOF_LONG_LONG == 4
94     typedef   signed long long int32_t;
95     typedef unsigned long long uint32_t;
96 #elif SIZEOF___INT64 == 4
97     typedef   signed __int64 int32_t;
98     typedef unsigned __int64 uint32_t;
99 #endif
100 
101 // int64_t, uint64_t
102 #if SIZEOF_CHAR == 8
103     typedef   signed char int64_t;
104     typedef unsigned char uint64_t;
105 #elif SIZEOF_SHORT == 8
106     typedef   signed short int64_t;
107     typedef unsigned short uint64_t;
108 #elif SIZEOF_INT == 8
109     typedef   signed int int64_t;
110     typedef unsigned int uint64_t;
111 #elif SIZEOF_LONG == 8
112     typedef   signed long int64_t;
113     typedef unsigned long uint64_t;
114 #elif SIZEOF_LONG_LONG == 8
115     typedef   signed long long int64_t;
116     typedef unsigned long long uint64_t;
117 #elif SIZEOF___INT64 == 8
118     typedef   signed __int64 int64_t;
119     typedef unsigned __int64 uint64_t;
120 #endif
121 
122 // C99-7.18.1.2 Minimum-width integer types
123 typedef int8_t   int_least8_t;
124 typedef int16_t  int_least16_t;
125 typedef int32_t  int_least32_t;
126 typedef int64_t  int_least64_t;
127 typedef uint8_t  uint_least8_t;
128 typedef uint16_t uint_least16_t;
129 typedef uint32_t uint_least32_t;
130 typedef uint64_t uint_least64_t;
131 
132 // C99-7.18.1.3 Fastest minimum-width integer types
133 typedef int8_t   int_fast8_t;
134 typedef int16_t  int_fast16_t;
135 typedef int32_t  int_fast32_t;
136 typedef int64_t  int_fast64_t;
137 typedef uint8_t  uint_fast8_t;
138 typedef uint16_t uint_fast16_t;
139 typedef uint32_t uint_fast32_t;
140 typedef uint64_t uint_fast64_t;
141 
142 // C99-7.18.1.4 Integer types capable of holding object pointers
143 #if SIZEOF_VOID_P == 8
144    typedef int64_t  intptr_t;
145    typedef uint64_t uintptr_t;
146 #else
147    typedef          int intptr_t;
148    typedef unsigned int uintptr_t;
149 #endif
150 
151 // C99-7.18.1.5 Greatest-width integer types
152 typedef int64_t  intmax_t;
153 typedef uint64_t uintmax_t;
154 
155 #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // See footnote 220 at page 257 and footnote 221 at page 259
156 
157 // C99-7.18.2.1 Limits of exact-width integer types
158 #define INT8_MIN   (-128)                 // -2^(8 - 1)
159 #define INT8_MAX   127                    //  2^(8 - 1) - 1
160 #define INT16_MIN  (-32768)               // -2^(16 - 1)
161 #define INT16_MAX  32767                  //  2^(16 - 1) - 1
162 #define INT32_MIN  (-2147483648)          // -2^(32 - 1)
163 #define INT32_MAX  2147483647             //  2^(32 - 1) - 1
164 #define INT64_MIN  (-9223372036854775808) // -2^(64 - 1)
165 #define INT64_MAX  9223372036854775807    //  2^(64 - 1) - 1
166 #define UINT8_MAX  0xFF               // 2^8 - 1
167 #define UINT16_MAX 0xFFFF             // 2^16 - 1
168 #define UINT32_MAX 0xFFFFffff         // 2^32 - 1
169 #define UINT64_MAX 0xFFFFffffFFFFffff // 2^64 - 1
170 
171 // C99-7.18.2.2 Limits of minimum-width integer types
172 #define INT_LEAST8_MIN   INT8_MIN
173 #define INT_LEAST8_MAX   INT8_MAX
174 #define INT_LEAST16_MIN  INT16_MIN
175 #define INT_LEAST16_MAX  INT16_MAX
176 #define INT_LEAST32_MIN  INT32_MIN
177 #define INT_LEAST32_MAX  INT32_MAX
178 #define INT_LEAST64_MIN  INT64_MIN
179 #define INT_LEAST64_MAX  INT64_MAX
180 #define UINT_LEAST8_MAX  UINT8_MAX
181 #define UINT_LEAST16_MAX UINT16_MAX
182 #define UINT_LEAST32_MAX UINT32_MAX
183 #define UINT_LEAST64_MAX UINT64_MAX
184 
185 // C99-7.18.2.3 Limits of fastest minimum-width integer types
186 #define INT_FAST8_MIN   INT8_MIN
187 #define INT_FAST8_MAX   INT8_MAX
188 #define INT_FAST16_MIN  INT16_MIN
189 #define INT_FAST16_MAX  INT16_MAX
190 #define INT_FAST32_MIN  INT32_MIN
191 #define INT_FAST32_MAX  INT32_MAX
192 #define INT_FAST64_MIN  INT64_MIN
193 #define INT_FAST64_MAX  INT64_MAX
194 #define UINT_FAST8_MAX  UINT8_MAX
195 #define UINT_FAST16_MAX UINT16_MAX
196 #define UINT_FAST32_MAX UINT32_MAX
197 #define UINT_FAST64_MAX UINT64_MAX
198 
199 // C99-7.18.2.4 Limits of integer types capable of holding object pointers
200 #define INTPTR_MIN  (-32767) // -(2^15 - 1)
201 #define INTPTR_MAX  32767    // 2^15 - 1
202 #define UINTPTR_MAX 0xFFFF   // 2^16 - 1
203 
204 // C99-7.18.2.5 Limits of greatest-width integer types
205 #define INTMAX_MIN  (-9223372036854775807) // -(2^63 - 1)
206 #define INTMAX_MAX  9223372036854775807    // 2^63 - 1
207 #define UINTMAX_MAX 0xFFFFffffFFFFffff     // 2^64 - 1
208 
209 // C99-7.18.3 Limits of other integer types:
210 //     "An implementation shall define only the macros
211 //     corresponding to those typedef names it actually
212 //     provides"
213 // and footnote 222 at page 259:
214 //     "A freestanding implementation need not provide
215 //     all of these types."
216 //
217 // Since we don't define corresponding types, we don't
218 // define the following limits either:
219 //     PTRDIFF_MIN
220 //     PTRDIFF_MAX
221 //     SIG_ATOMIC_MIN
222 //     SIG_ATOMIC_MAX
223 //     SIZE_MAX
224 //     WCHAR_MIN
225 //     WCHAR_MAX
226 //     WINT_MIN
227 //     WINT_MAX
228 
229 #endif // __STDC_LIMIT_MACROS
230 
231 #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // See footnote 224 at page 260
232 
233 // C99-7.18.4.1 Macros for minimum-width integer constants
234 #define INT8_C(x)   x
235 #define UINT8_C(x)  x##u
236 #define INT16_C(x)  x
237 #define UINT16_C(x) x##u
238 #define INT32_C(x)  x
239 #define UINT32_C(x) x##u
240 #if SIZEOF_0L == 8
241 #    define  INT64_C(x) x##l
242 #    define UINT64_C(x) x##ul
243 #elif SIZEOF_0LL == 8
244 #    define  INT64_C(x) x##ll
245 #    define UINT64_C(x) x##ull
246 #elif SIZEOF_0I8 == 8
247 #    define  INT64_C(x) x##i8
248 #    define UINT64_C(x) x##ui8
249 #else
250 #    define  INT64_C(x) x
251 #    define UINT64_C(x) x##u
252 #endif
253 
254 // C99-7.18.4.2 Macros for greatest-width integer constants
255 #define INTMAX_C  INT64_C
256 #define UINTMAX_C UINT64_C
257 
258 #endif // __STDC_CONSTANT_MACROS
259 
260 #endif // HAVE_STDINT_H
261 
262 #endif // _RE2C_UTIL_C99_STDINT_
263