1///////////////////////////////////////////////////////////////////////////////
2//
3/// \file       sysdefs.h
4/// \brief      Common includes, definitions, system-specific things etc.
5///
6/// This file is used also by the lzma command line tool, that's why this
7/// file is separate from common.h.
8//
9//  Author:     Lasse Collin
10//
11//  This file has been put into the public domain.
12//  You can do whatever you want with this file.
13//
14///////////////////////////////////////////////////////////////////////////////
15
16#ifndef LZMA_SYSDEFS_H
17#define LZMA_SYSDEFS_H
18
19//////////////
20// Includes //
21//////////////
22
23#ifdef HAVE_CONFIG_H
24#	include <config.h>
25#endif
26
27// Get standard-compliant stdio functions under MinGW and MinGW-w64.
28#ifdef __MINGW32__
29#	define __USE_MINGW_ANSI_STDIO 1
30#endif
31
32// size_t and NULL
33#include <stddef.h>
34
35#ifdef HAVE_INTTYPES_H
36#	include <inttypes.h>
37#endif
38
39// C99 says that inttypes.h always includes stdint.h, but some systems
40// don't do that, and require including stdint.h separately.
41#ifdef HAVE_STDINT_H
42#	include <stdint.h>
43#endif
44
45// Some pre-C99 systems have SIZE_MAX in limits.h instead of stdint.h. The
46// limits are also used to figure out some macros missing from pre-C99 systems.
47#include <limits.h>
48
49// Be more compatible with systems that have non-conforming inttypes.h.
50// We assume that int is 32-bit and that long is either 32-bit or 64-bit.
51// Full Autoconf test could be more correct, but this should work well enough.
52// Note that this duplicates some code from lzma.h, but this is better since
53// we can work without inttypes.h thanks to Autoconf tests.
54#ifndef UINT32_C
55#	if UINT_MAX != 4294967295U
56#		error UINT32_C is not defined and unsigned int is not 32-bit.
57#	endif
58#	define UINT32_C(n) n ## U
59#endif
60#ifndef UINT32_MAX
61#	define UINT32_MAX UINT32_C(4294967295)
62#endif
63#ifndef PRIu32
64#	define PRIu32 "u"
65#endif
66#ifndef PRIx32
67#	define PRIx32 "x"
68#endif
69#ifndef PRIX32
70#	define PRIX32 "X"
71#endif
72
73#if ULONG_MAX == 4294967295UL
74#	ifndef UINT64_C
75#		define UINT64_C(n) n ## ULL
76#	endif
77#	ifndef PRIu64
78#		define PRIu64 "llu"
79#	endif
80#	ifndef PRIx64
81#		define PRIx64 "llx"
82#	endif
83#	ifndef PRIX64
84#		define PRIX64 "llX"
85#	endif
86#else
87#	ifndef UINT64_C
88#		define UINT64_C(n) n ## UL
89#	endif
90#	ifndef PRIu64
91#		define PRIu64 "lu"
92#	endif
93#	ifndef PRIx64
94#		define PRIx64 "lx"
95#	endif
96#	ifndef PRIX64
97#		define PRIX64 "lX"
98#	endif
99#endif
100#ifndef UINT64_MAX
101#	define UINT64_MAX UINT64_C(18446744073709551615)
102#endif
103
104// Incorrect(?) SIZE_MAX:
105//   - Interix headers typedef size_t to unsigned long,
106//     but a few lines later define SIZE_MAX to INT32_MAX.
107//   - SCO OpenServer (x86) headers typedef size_t to unsigned int
108//     but define SIZE_MAX to INT32_MAX.
109#if defined(__INTERIX) || defined(_SCO_DS)
110#	undef SIZE_MAX
111#endif
112
113// The code currently assumes that size_t is either 32-bit or 64-bit.
114#ifndef SIZE_MAX
115#	if SIZEOF_SIZE_T == 4
116#		define SIZE_MAX UINT32_MAX
117#	elif SIZEOF_SIZE_T == 8
118#		define SIZE_MAX UINT64_MAX
119#	else
120#		error size_t is not 32-bit or 64-bit
121#	endif
122#endif
123#if SIZE_MAX != UINT32_MAX && SIZE_MAX != UINT64_MAX
124#	error size_t is not 32-bit or 64-bit
125#endif
126
127#include <stdlib.h>
128#include <assert.h>
129
130// Pre-C99 systems lack stdbool.h. All the code in LZMA Utils must be written
131// so that it works with fake bool type, for example:
132//
133//    bool foo = (flags & 0x100) != 0;
134//    bool bar = !!(flags & 0x100);
135//
136// This works with the real C99 bool but breaks with fake bool:
137//
138//    bool baz = (flags & 0x100);
139//
140#ifdef HAVE_STDBOOL_H
141#	include <stdbool.h>
142#else
143#	if ! HAVE__BOOL
144typedef unsigned char _Bool;
145#	endif
146#	define bool _Bool
147#	define false 0
148#	define true 1
149#	define __bool_true_false_are_defined 1
150#endif
151
152// string.h should be enough but let's include strings.h and memory.h too if
153// they exists, since that shouldn't do any harm, but may improve portability.
154#include <string.h>
155
156#ifdef HAVE_STRINGS_H
157#	include <strings.h>
158#endif
159
160#ifdef HAVE_MEMORY_H
161#	include <memory.h>
162#endif
163
164// As of MSVC 2013, inline and restrict are supported with
165// non-standard keywords.
166#if defined(_WIN32) && defined(_MSC_VER)
167#	ifndef inline
168#		define inline __inline
169#	endif
170#	ifndef restrict
171#		define restrict __restrict
172#	endif
173#endif
174
175////////////
176// Macros //
177////////////
178
179#undef memzero
180#define memzero(s, n) memset(s, 0, n)
181
182// NOTE: Avoid using MIN() and MAX(), because even conditionally defining
183// those macros can cause some portability trouble, since on some systems
184// the system headers insist defining their own versions.
185#define my_min(x, y) ((x) < (y) ? (x) : (y))
186#define my_max(x, y) ((x) > (y) ? (x) : (y))
187
188#ifndef ARRAY_SIZE
189#	define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
190#endif
191
192#if defined(__GNUC__) \
193		&& ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4)
194#	define lzma_attr_alloc_size(x) __attribute__((__alloc_size__(x)))
195#else
196#	define lzma_attr_alloc_size(x)
197#endif
198
199#endif
200