1 /* @(#)stdint.h	1.37 15/12/10 Copyright 1997-2015 J. Schilling */
2 /*
3  *	Abstraction from stdint.h
4  *
5  *	Copyright (c) 1997-2015 J. Schilling
6  */
7 /*
8  * The contents of this file are subject to the terms of the
9  * Common Development and Distribution License, Version 1.0 only
10  * (the "License").  You may not use this file except in compliance
11  * with the License.
12  *
13  * See the file CDDL.Schily.txt in this distribution for details.
14  * A copy of the CDDL is also available via the Internet at
15  * http://www.opensource.org/licenses/cddl1.txt
16  *
17  * When distributing Covered Code, include this CDDL HEADER in each
18  * file and include the License file CDDL.Schily.txt from this distribution.
19  */
20 
21 #ifndef	_SCHILY_STDINT_H
22 #define	_SCHILY_STDINT_H
23 
24 #ifndef	_SCHILY_MCONFIG_H
25 #include <schily/mconfig.h>
26 #endif
27 
28 /*
29  * Let us include system defined types too.
30  */
31 #ifndef	_SCHILY_TYPES_H
32 #include <schily/types.h>
33 #endif
34 
35 /*
36  * Include sys/param.h for NBBY - needed in case that CHAR_BIT is missing
37  */
38 #ifndef	_SCHILY_PARAM_H
39 #include <schily/param.h>	/* Must be before limits.h */
40 #endif
41 
42 /*
43  * Include limits.h for CHAR_BIT - needed by TYPE_MINVAL(t) and  TYPE_MAXVAL(t)
44  */
45 #ifndef	_SCHILY_LIMITS_H
46 #include <schily/limits.h>
47 #endif
48 
49 #ifndef	CHAR_BIT
50 #ifdef	NBBY
51 #define	CHAR_BIT	NBBY
52 #endif
53 #endif
54 
55 /*
56  * Last resort: define CHAR_BIT by hand
57  */
58 #ifndef	CHAR_BIT
59 #define	CHAR_BIT	8
60 #endif
61 
62 /*
63  * These macros may not work on all platforms but as we depend
64  * on two's complement in many places, they do not reduce portability.
65  * The macros below work with 2s complement and ones complement machines.
66  * Verify with this table...
67  *
68  *	Bits	1's c.	2's complement.
69  * 	100	-3	-4
70  * 	101	-2	-3
71  * 	110	-1	-2
72  * 	111	-0	-1
73  * 	000	+0	 0
74  * 	001	+1	+1
75  * 	010	+2	+2
76  * 	011	+3	+3
77  *
78  * Computing -TYPE_MINVAL(type) will not work on 2's complement machines
79  * if 'type' is int or more. Use:
80  *		((unsigned type)(-1 * (TYPE_MINVAL(type)+1))) + 1;
81  * it works for both 1's complement and 2's complement machines.
82  */
83 #define	TYPE_ISSIGNED(t)	(((t)-1) < ((t)0))
84 #define	TYPE_ISUNSIGNED(t)	(!TYPE_ISSIGNED(t))
85 #define	TYPE_MSBVAL(t)		((t)(~((t)0) << (sizeof (t)*CHAR_BIT - 1)))
86 #define	TYPE_MINVAL(t)		(TYPE_ISSIGNED(t)			\
87 				    ? TYPE_MSBVAL(t)			\
88 				    : ((t)0))
89 #define	TYPE_MAXVAL(t)		((t)(~((t)0) - TYPE_MINVAL(t)))
90 
91 /*
92  * MSVC has size_t in stddef.h
93  */
94 #ifdef HAVE_STDDEF_H
95 #ifndef	_INCL_STDDEF_H
96 #include <stddef.h>
97 #define	_INCL_STDDEF_H
98 #endif
99 #endif
100 
101 /*
102  * CHAR_IS_UNSIGNED is needed to define int8_t
103  */
104 #ifdef	__CHAR_UNSIGNED__	/* GNU GCC define (dynamic)	*/
105 #ifndef CHAR_IS_UNSIGNED
106 #define	CHAR_IS_UNSIGNED	/* Sing Schily define (static)	*/
107 #endif
108 #endif
109 
110 /*
111  * This is a definition for a compiler dependant 64 bit type.
112  * There is currently a silently fallback to a long if the compiler does not
113  * support it. Check if this is the right way.
114  *
115  * Be very careful here as MSVC does not implement long long but rather __int64
116  * and once someone makes 'long long' 128 bits on a 64 bit machine, we need to
117  * check for a MSVC __int128 type.
118  */
119 #ifndef	NO_LONGLONG
120 #	if	!defined(USE_LONGLONG) && defined(HAVE_LONGLONG)
121 #		define	USE_LONGLONG
122 #	endif
123 #	if	!defined(USE_LONGLONG) && defined(HAVE___INT64)
124 #		define	USE_LONGLONG
125 #	endif
126 #endif
127 
128 #ifdef	USE_LONGLONG
129 
130 #	if	defined(HAVE___INT64)
131 
132 typedef	__int64			Llong;
133 typedef	unsigned __int64	Ullong;	/* We should avoid this */
134 typedef	unsigned __int64	ULlong;
135 
136 #define	SIZEOF_LLONG		SIZEOF___INT64
137 #define	SIZEOF_ULLONG		SIZEOF_UNSIGNED___INT64
138 
139 #	else	/* We must have HAVE_LONG_LONG */
140 
141 typedef	long long		Llong;
142 typedef	unsigned long long	Ullong;	/* We should avoid this */
143 typedef	unsigned long long	ULlong;
144 
145 #define	SIZEOF_LLONG		SIZEOF_LONG_LONG
146 #define	SIZEOF_ULLONG		SIZEOF_UNSIGNED_LONG_LONG
147 
148 #	endif	/* HAVE___INT64 / HAVE_LONG_LONG */
149 
150 #else	/* !USE_LONGLONG */
151 
152 typedef	long			Llong;
153 typedef	unsigned long		Ullong;	/* We should avoid this */
154 typedef	unsigned long		ULlong;
155 
156 #define	SIZEOF_LLONG		SIZEOF_LONG
157 #define	SIZEOF_ULLONG		SIZEOF_UNSIGNED_LONG
158 
159 #endif	/* USE_LONGLONG */
160 
161 #ifndef	LLONG_MIN
162 #define	LLONG_MIN	TYPE_MINVAL(Llong)
163 #endif
164 #ifndef	LLONG_MAX
165 #define	LLONG_MAX	TYPE_MAXVAL(Llong)
166 #endif
167 #ifndef	ULLONG_MAX
168 #define	ULLONG_MAX	TYPE_MAXVAL(Ullong)
169 #endif
170 
171 /*
172  * Start inttypes.h emulation.
173  *
174  * Thanks to Solaris 2.4 and even recent 1999 Linux versions, we
175  * cannot use the official UNIX-98 names here. Old Solaris versions
176  * define parts of the types in some exotic include files.
177  * Linux even defines incompatible types in <sys/types.h>.
178  */
179 
180 #if defined(HAVE_INTTYPES_H) || defined(HAVE_STDINT_H)
181 #if defined(HAVE_INTTYPES_H)
182 #	ifndef	_INCL_INTTYPES_H
183 #	include <inttypes.h>
184 #	define	_INCL_INTTYPES_H
185 #	endif
186 #else
187 #if defined(HAVE_STDINT_H)
188 #	ifndef	_INCL_STDINT_H
189 #	include <stdint.h>
190 #	define	_INCL_STDINT_H
191 #	endif
192 #endif
193 #endif
194 
195 #ifdef	__cplusplus
196 extern "C" {
197 #endif
198 
199 /*
200  * On VMS on VAX, these types are present but non-scalar.
201  * Thus we may not be able to use them
202  */
203 #ifdef	HAVE_LONGLONG
204 #	define	HAVE_INT64_T
205 #	define	HAVE_UINT64_T
206 #endif
207 
208 #define	Int8_t			int8_t
209 #define	Int16_t			int16_t
210 #define	Int32_t			int32_t
211 #ifdef	HAVE_LONGLONG
212 #define	Int64_t			int64_t
213 #endif
214 #define	Intmax_t		intmax_t
215 #define	UInt8_t			uint8_t
216 #define	UInt16_t		uint16_t
217 #define	UInt32_t		uint32_t
218 #ifdef	HAVE_LONGLONG
219 #define	UInt64_t		uint64_t
220 #endif
221 #define	UIntmax_t		uintmax_t
222 
223 #define	Intptr_t		intptr_t
224 #define	UIntptr_t		uintptr_t
225 
226 /*
227  * If we only have a UNIX-98 inttypes.h but no SUSv3
228  *
229  * Beware not to use int64_t / uint64_t as VMS on a VAX defines
230  * them as non-scalar (structure) based types.
231  */
232 #ifndef	HAVE_TYPE_INTMAX_T
233 #define	intmax_t	Llong
234 #endif
235 #ifndef	HAVE_TYPE_UINTMAX_T
236 #define	uintmax_t	ULlong
237 #endif
238 
239 #ifdef	__cplusplus
240 }
241 #endif
242 
243 #else	/* !HAVE_INTTYPES_H */
244 
245 #ifdef	__cplusplus
246 extern "C" {
247 #endif
248 
249 #if SIZEOF_CHAR != 1 || SIZEOF_UNSIGNED_CHAR != 1
250 /*
251  * #error will not work for all compilers (e.g. sunos4)
252  * The following line will abort compilation on all compilers
253  * if the above is true. And that's what we want.
254  */
255 error  Sizeof char is not equal 1
256 
257 #include <schily/err_char.h>	/* Avoid "unknown directive" with K&R */
258 #endif
259 
260 #if	defined(__STDC__) || defined(CHAR_IS_UNSIGNED)
261 	typedef	signed char		Int8_t;
262 #else
263 	typedef	char			Int8_t;
264 #endif
265 
266 #if SIZEOF_SHORT_INT == 2
267 	typedef	short			Int16_t;
268 #else
269 	error		No int16_t found
270 
271 #include <schily/err_type.h>	/* Avoid "unknown directive" with K&R */
272 #endif
273 
274 #if SIZEOF_INT == 4
275 #if defined(_MSC_VER) && SIZEOF_LONG_INT == 4
276 	typedef	long			Int32_t;
277 #else
278 	typedef	int			Int32_t;
279 #endif
280 #else
281 	error		No int32_t found
282 
283 #include <schily/err_type.h>	/* Avoid "unknown directive" with K&R */
284 #endif
285 
286 #if SIZEOF_LONG_INT == 8
287 	typedef		long		Int64_t;
288 #	define	HAVE_INT64_T
289 #else
290 #if SIZEOF_LONG_LONG == 8
291 	typedef		long long	Int64_t;
292 #	define	HAVE_INT64_T
293 #else
294 #if SIZEOF___INT64 == 8
295 	typedef		__int64		Int64_t;
296 #	define	HAVE_INT64_T
297 #else
298 /*
299  * Tolerate platforms without 64-Bit support.
300  */
301 /*	error		No int64_t found */
302 #endif
303 #endif
304 #endif
305 
306 #if SIZEOF_CHAR_P == SIZEOF_INT
307 	typedef		int		Intptr_t;
308 #else
309 #if SIZEOF_CHAR_P == SIZEOF_LONG_INT
310 	typedef		long		Intptr_t;
311 #else
312 #if SIZEOF_CHAR_P == SIZEOF_LLONG
313 	typedef		Llong		Intptr_t;
314 #else
315 	error		No intptr_t found
316 
317 #include <schily/err_type.h>	/* Avoid "unknown directive" with K&R */
318 #endif
319 #endif
320 #endif
321 
322 typedef	unsigned char		UInt8_t;
323 
324 #if SIZEOF_UNSIGNED_SHORT_INT == 2
325 	typedef	unsigned short		UInt16_t;
326 #else
327 	error		No uint16_t found
328 
329 #include <schily/err_type.h>	/* Avoid "unknown directive" with K&R */
330 #endif
331 
332 #if SIZEOF_UNSIGNED_INT == 4
333 #if defined(_MSC_VER) && SIZEOF_UNSIGNED_LONG_INT == 4
334 	typedef	unsigned long		UInt32_t;
335 #else
336 	typedef	unsigned int		UInt32_t;
337 #endif
338 #else
339 	error		No int32_t found
340 
341 #include <schily/err_type.h>	/* Avoid "unknown directive" with K&R */
342 #endif
343 
344 #if SIZEOF_UNSIGNED_LONG_INT == 8
345 	typedef	unsigned long		UInt64_t;
346 #	define	HAVE_UINT64_T
347 #else
348 #if SIZEOF_UNSIGNED_LONG_LONG == 8
349 	typedef	unsigned long long	UInt64_t;
350 #	define	HAVE_UINT64_T
351 #else
352 #if SIZEOF_UNSIGNED___INT64 == 8
353 	typedef	unsigned __int64	UInt64_t;
354 #	define	HAVE_UINT64_T
355 #else
356 /*
357  * Tolerate platforms without 64-Bit support.
358  */
359 /*	error		No uint64_t found */
360 #endif
361 #endif
362 #endif
363 
364 #define	Intmax_t	Llong
365 #define	UIntmax_t	Ullong
366 
367 #if SIZEOF_CHAR_P == SIZEOF_UNSIGNED_INT
368 	typedef		unsigned int	UIntptr_t;
369 #else
370 #if SIZEOF_CHAR_P == SIZEOF_UNSIGNED_LONG_INT
371 	typedef		unsigned long	UIntptr_t;
372 #else
373 #if SIZEOF_CHAR_P == SIZEOF_ULLONG
374 	typedef		ULlong		UIntptr_t;
375 #else
376 	error		No uintptr_t found
377 
378 #include <schily/err_type.h>	/* Avoid "unknown directive" with K&R */
379 #endif
380 #endif
381 #endif
382 
383 #ifdef	_MSC_VER
384 /*
385  * All recent platforms define the POSIX/C-99 compliant types from inttypes.h
386  * except Microsoft. With these #defines, we may also use official types on a
387  * Microsoft environment.
388  *
389  * Warning: Linux-2.2 and before do not have inttypes.h and define some of the
390  * types in an incmpatible way.
391  */
392 #undef	int8_t
393 #define	int8_t			Int8_t
394 #undef	int16_t
395 #define	int16_t			Int16_t
396 #undef	int32_t
397 #define	int32_t			Int32_t
398 #undef	int64_t
399 #define	int64_t			Int64_t
400 #undef	intmax_t
401 #define	intmax_t		Intmax_t
402 #undef	uint8_t
403 #define	uint8_t			UInt8_t
404 #undef	uint16_t
405 #define	uint16_t		UInt16_t
406 #undef	uint32_t
407 #define	uint32_t		UInt32_t
408 #undef	uint64_t
409 #define	uint64_t		UInt64_t
410 #undef	uintmax_t
411 #define	uintmax_t		UIntmax_t
412 
413 #undef	intptr_t
414 #define	intptr_t		Intptr_t
415 #undef	uintptr_t
416 #define	uintptr_t		UIntptr_t
417 #endif	/* _MSC_VER */
418 
419 #ifdef	__cplusplus
420 }
421 #endif
422 
423 #endif	/* HAVE_INTTYPES_H */
424 
425 #ifndef	INT8_MIN
426 #define	INT8_MIN	TYPE_MINVAL(Int8_t)
427 #endif
428 #ifndef	INT8_MAX
429 #define	INT8_MAX	TYPE_MAXVAL(Int8_t)
430 #endif
431 #ifndef	UINT8_MAX
432 #define	UINT8_MAX	TYPE_MAXVAL(UInt8_t)
433 #endif
434 
435 #ifndef	INT16_MIN
436 #define	INT16_MIN	TYPE_MINVAL(Int16_t)
437 #endif
438 #ifndef	INT16_MAX
439 #define	INT16_MAX	TYPE_MAXVAL(Int16_t)
440 #endif
441 #ifndef	UINT16_MAX
442 #define	UINT16_MAX	TYPE_MAXVAL(UInt16_t)
443 #endif
444 
445 #ifndef	INT32_MIN
446 #define	INT32_MIN	TYPE_MINVAL(Int32_t)
447 #endif
448 #ifndef	INT32_MAX
449 #define	INT32_MAX	TYPE_MAXVAL(Int32_t)
450 #endif
451 #ifndef	UINT32_MAX
452 #define	UINT32_MAX	TYPE_MAXVAL(UInt32_t)
453 #endif
454 
455 #ifdef	HAVE_INT64_T
456 #ifndef	INT64_MIN
457 #define	INT64_MIN	TYPE_MINVAL(Int64_t)
458 #endif
459 #ifndef	INT64_MAX
460 #define	INT64_MAX	TYPE_MAXVAL(Int64_t)
461 #endif
462 #endif
463 #ifdef	HAVE_UINT64_T
464 #ifndef	UINT64_MAX
465 #define	UINT64_MAX	TYPE_MAXVAL(UInt64_t)
466 #endif
467 #endif
468 
469 #ifndef	INTMAX_MIN
470 #define	INTMAX_MIN	TYPE_MINVAL(Intmax_t)
471 #endif
472 #ifndef	INTMAX_MAX
473 #define	INTMAX_MAX	TYPE_MAXVAL(Intmax_t)
474 #endif
475 #ifndef	UINTMAX_MAX
476 #define	UINTMAX_MAX	TYPE_MAXVAL(UIntmax_t)
477 #endif
478 
479 #define	SIZE_T_MIN	TYPE_MINVAL(size_t)
480 #ifdef	SIZE_T_MAX
481 #undef	SIZE_T_MAX			/* FreeBSD has a similar #define */
482 #endif
483 #define	SIZE_T_MAX	TYPE_MAXVAL(size_t)
484 
485 #define	SSIZE_T_MIN	TYPE_MINVAL(ssize_t)
486 #define	SSIZE_T_MAX	TYPE_MAXVAL(ssize_t)
487 
488 #endif	/* _SCHILY_STDINT_H */
489