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