// SPDX-License-Identifier: 0BSD12///////////////////////////////////////////////////////////////////////////////3//4/// \file sysdefs.h5/// \brief Common includes, definitions, system-specific things etc.6///7/// This file is used also by the lzma command line tool, that's why this8/// file is separate from common.h.9//10// Author: Lasse Collin11//12///////////////////////////////////////////////////////////////////////////////1314#ifndef LZMA_SYSDEFS_H15#define LZMA_SYSDEFS_H1617#if defined(_MSC_VER)18# pragma warning(push,1)19# pragma warning(disable: 4028) /* formal parameter different from decl */20# pragma warning(disable: 4142) /* benign redefinition of type */21# pragma warning(disable: 4761) /* integral size mismatch in argument */22#endif2324//////////////25// Includes //26//////////////2728#include "config.h"2930// This #define ensures that C99 and POSIX compliant stdio functions are31// available with MinGW-w64 (both 32-bit and 64-bit). Modern MinGW-w64 adds32// this automatically, for example, when the compiler is in C99 (or later)33// mode when building against msvcrt.dll. It still doesn't hurt to be explicit34// that we always want this and #define this unconditionally.35//36// With Universal CRT (UCRT) this is less important because UCRT contains37// C99-compatible stdio functions. It's still nice to #define this as UCRT38// doesn't support the POSIX thousand separator flag in printf (like "%'u").39#ifdef __MINGW32__40# define __USE_MINGW_ANSI_STDIO 141#endif4243// size_t and NULL44#include <stddef.h>4546#ifdef HAVE_INTTYPES_H47# include <inttypes.h>48#endif4950// C99 says that inttypes.h always includes stdint.h, but some systems51// don't do that, and require including stdint.h separately.52#ifdef HAVE_STDINT_H53# include <stdint.h>54#endif5556// Some pre-C99 systems have SIZE_MAX in limits.h instead of stdint.h. The57// limits are also used to figure out some macros missing from pre-C99 systems.58#include <limits.h>596061#if defined(_MSC_VER) && (_MSC_VER < 1310)62# define UINT64_C(n) n ## ui6463#endif646566// Be more compatible with systems that have non-conforming inttypes.h.67// We assume that int is 32-bit and that long is either 32-bit or 64-bit.68// Full Autoconf test could be more correct, but this should work well enough.69// Note that this duplicates some code from lzma.h, but this is better since70// we can work without inttypes.h thanks to Autoconf tests.71#ifndef UINT32_C72# if UINT_MAX != 4294967295U73# error UINT32_C is not defined and unsigned int is not 32-bit.74# endif75# define UINT32_C(n) n ## U76#endif77#ifndef UINT32_MAX78# define UINT32_MAX UINT32_C(4294967295)79#endif80#ifndef PRIu3281# define PRIu32 "u"82#endif83#ifndef PRIx3284# define PRIx32 "x"85#endif86#ifndef PRIX3287# define PRIX32 "X"88#endif8990#if ULONG_MAX == 4294967295UL91# ifndef UINT64_C92# define UINT64_C(n) n ## ULL93# endif94# ifndef PRIu6495# define PRIu64 "llu"96# endif97# ifndef PRIx6498# define PRIx64 "llx"99# endif100# ifndef PRIX64101# define PRIX64 "llX"102# endif103#else104# ifndef UINT64_C105# define UINT64_C(n) n ## UL106# endif107# ifndef PRIu64108# define PRIu64 "lu"109# endif110# ifndef PRIx64111# define PRIx64 "lx"112# endif113# ifndef PRIX64114# define PRIX64 "lX"115# endif116#endif117#ifndef UINT64_MAX118# define UINT64_MAX UINT64_C(18446744073709551615)119#endif120121// Incorrect(?) SIZE_MAX:122// - Interix headers typedef size_t to unsigned long,123// but a few lines later define SIZE_MAX to INT32_MAX.124// - SCO OpenServer (x86) headers typedef size_t to unsigned int125// but define SIZE_MAX to INT32_MAX.126#if defined(__INTERIX) || defined(_SCO_DS)127# undef SIZE_MAX128#endif129130// The code currently assumes that size_t is either 32-bit or 64-bit.131#ifndef SIZE_MAX132# if SIZEOF_SIZE_T == 4133# define SIZE_MAX UINT32_MAX134# elif SIZEOF_SIZE_T == 8135# define SIZE_MAX UINT64_MAX136# else137# error size_t is not 32-bit or 64-bit138# endif139#endif140#if SIZE_MAX != UINT32_MAX && SIZE_MAX != UINT64_MAX141# error size_t is not 32-bit or 64-bit142#endif143144#include <stdlib.h>145#include <assert.h>146147// Pre-C99 systems lack stdbool.h. All the code in XZ Utils must be written148// so that it works with fake bool type, for example:149//150// bool foo = (flags & 0x100) != 0;151// bool bar = !!(flags & 0x100);152//153// This works with the real C99 bool but breaks with fake bool:154//155// bool baz = (flags & 0x100);156//157#ifdef HAVE_STDBOOL_H158# include <stdbool.h>159#else160# if ! HAVE__BOOL161typedef unsigned char _Bool;162# endif163# define bool _Bool164# define false 0165# define true 1166# define __bool_true_false_are_defined 1167#endif168169#include <string.h>170171// Visual Studio 2013 update 2 supports only __inline, not inline.172// MSVC v19.0 / VS 2015 and newer support both.173//174// MSVC v19.27 (VS 2019 version 16.7) added support for restrict.175// Older ones support only __restrict.176#ifdef _MSC_VER177# if _MSC_VER < 1900 && !defined(inline)178# define inline __inline179# endif180# if _MSC_VER < 1927 && !defined(restrict)181# define restrict __restrict182# endif183#elif defined(__EDG__) && defined(__LCC__)184# ifndef inline185# define inline __inline186# endif187# ifndef restrict188# define restrict __restrict189# endif190#endif191192////////////193// Macros //194////////////195196#undef memzero197#define memzero(s, n) memset(s, 0, n)198199// NOTE: Avoid using MIN() and MAX(), because even conditionally defining200// those macros can cause some portability trouble, since on some systems201// the system headers insist defining their own versions.202#define my_min(x, y) ((x) < (y) ? (x) : (y))203#define my_max(x, y) ((x) > (y) ? (x) : (y))204205#ifndef ARRAY_SIZE206# define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))207#endif208209#if defined(__GNUC__) \210&& ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4)211# define lzma_attr_alloc_size(x) __attribute__((__alloc_size__(x)))212#else213# define lzma_attr_alloc_size(x)214#endif215216#endif217218219