view th_types.h @ 747:57ccf6402d2a

No need to check for both __MINGW32__ and __MINGW64__, the former is enough.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 21 Dec 2022 13:20:06 +0200
parents a557d1b2a356
children c6b2546d3ae3
line wrap: on
line source

/*
 * Type definations
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2002-2022 Tecnic Software productions (TNSP)
 *
 * Please read file 'COPYING' for information on license and distribution.
 *
 * If your code uses "config.h", you need to #include
 * it before including this header.
 */
/// @file
/// @brief Various platform-specific type and macro definitions.
#ifndef TH_TYPES_H
#define TH_TYPES_H 1


// Meh, this is a hack due to the crap non-portability of 64bit
// printf() PRI* type specifiers/modifiers
#if !defined(TH_USE_BONK_TYPES) && defined(__MINGW32__)
#  define __USE_MINGW_ANSI_STDIO 1
#endif


// Older MinGW-w64 versions do not play well with certain PRI* and type
// checking of printf() format specifiers, so .. only define the attribute
// macro for GCC/clang and new enough MinGW-w64.
#if (defined(__GNUC__) || defined(__clang__)) && (!defined(__MINGW64__) || __GNUC__ >= 12)
#  define TH_ATTR_PRINTF_FMT(xstart, xend) __attribute__ ((__format__ (__printf__, (xstart), (xend))))
#else
#  define TH_ATTR_PRINTF_FMT(xstart, xend)
#endif


// Check for system type
#if defined(__WIN64) || defined(_WIN64) || defined(__WIN32) || defined(_WIN32)
#  define TH_PLAT_WINDOWS 1
#elif defined(__DJGPP__) && __DJGPP__ >= 2
#  define TH_PLAT_DOS 1
#  undef __STRICT_ANSI__
#else
#  define TH_PLAT_UNIX 1
#endif


// Check for standard headers
#if defined(HAVE_INTTYPES_H)
#  include <inttypes.h>
#  ifndef HAVE_STDINT_H
#    define HAVE_STDINT_H 1
#  endif
#elif defined(HAVE_STDINT_H)
#  include <stdint.h>
#elif defined(HAVE_SYS_TYPES_H)
#  include <sys/types.h>
#endif


// Check for arch bitness
#if !defined(TH_ARCH) && (defined(__WIN64) || defined(_WIN64))
#  define TH_ARCH 64
#endif

#if !defined(TH_ARCH) && (defined(__WIN32) || defined(_WIN32))
#  define TH_ARCH 32
#endif

#if !defined(TH_ARCH)
#  if UINTPTR_MAX == 0xffffffff
#    define TH_ARCH 32
#  elif UINTPTR_MAX == 0xffffffffffffffff
#    define TH_ARCH 64
#  endif
#endif


#if !defined(TH_ARCH)
#  if defined(__LP64__) || defined(_LP64)
#    define TH_ARCH 64
#  else
#    define TH_ARCH 32
#  endif
#endif


// Do we have a valid arch?
// If we don't have ISO C99 inttypes.h, define PRI* macros
#ifndef HAVE_INTTYPES_H
#  if TH_ARCH == 32
#    define PRIu32        "u"
#    define PRId32        "d"
#    define PRIx32        "x"
#    define PRIi32        "i"
#    define PRIo32        "o"
#    define PRIu64        "llu"
#    define PRId64        "lld"
#    define PRIx64        "llx"
#    define PRIi64        "lli"
#    define PRIo64        "llo"
#  elif TH_ARCH == 64
#    define PRIu32        "u"
#    define PRId32        "d"
#    define PRIx32        "x"
#    define PRIi32        "i"
#    define PRIo32        "o"
#    define PRIu64        "lu"
#    define PRId64        "ld"
#    define PRIx64        "lx"
#    define PRIi64        "li"
#    define PRIo64        "lo"
#  else
#    error Could not determine architecture (32/64bit), please define TH_ARCH=32 or 64
#  endif
#endif


// Define some printf specifiers and other useful things
#if TH_ARCH == 32
#  define PRIu_SIZE_T       PRIu32
#  define PRId_SSIZE_T      PRId32
#  define PRIx_SIZE_T       PRIx32
#  define PRIX_SIZE_T       PRIX32
#  ifdef TH_USE_BONK_TYPES
#    define PRId_OFF_T      "ld"
#    define PRIx_OFF_T      "lx"
#    define PRIX_OFF_T      "lX"
#  else
#    define PRId_OFF_T      PRId32
#    define PRIx_OFF_T      PRIx32
#    define PRIX_OFF_T      PRIX32
#  endif
#  ifndef TH_PTRSIZE
#    define TH_PTRSIZE 32
#  endif
#  ifndef INTPTR_MIN
#    define INTPTR_MIN    (-0x7fffffffL - 1)
#    define INTPTR_MAX    ( 0x7fffffffL)
#    define UINTPTR_MAX   ( 0xffffffffUL)
#  endif
#elif TH_ARCH == 64
#  ifdef TH_USE_BONK_TYPES
#    define PRIu_SIZE_T     "I64u"
#    define PRId_SSIZE_T    "I64d"
#    define PRIx_SIZE_T     "I64x"
#    define PRIX_SIZE_T     "I64X"
#    define PRId_OFF_T      "I64d"
#    define PRIx_OFF_T      "I64x"
#    define PRIX_OFF_T      "I64X"
#  else
#    define PRIu_SIZE_T     PRIu64
#    define PRId_SSIZE_T    PRId64
#    define PRIx_SIZE_T     PRIx64
#    define PRIX_SIZE_T     PRIX64
#    define PRId_OFF_T      PRId64
#    define PRIx_OFF_T      PRIx64
#    define PRIX_OFF_T      PRIX64
#  endif
#  ifndef TH_PTRSIZE
#    define TH_PTRSIZE 64
#  endif
#  ifndef INTPTR_MIN
#    define INTPTR_MIN    (-0x7fffffffffffffffL - 1)
#    define INTPTR_MAX    ( 0x7fffffffffffffffL)
#    define UINTPTR_MAX   ( 0xffffffffffffffffUL)
#  endif
#endif


/* Default assumptions for these types should be ok for most 32/64bit platforms...
 */
#if !defined(HAVE_STDINT_H) && !defined(HAVE_SYS_TYPES_H)
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short int uint16_t;
typedef signed short int int16_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;
typedef unsigned long long uint64_t;
typedef signed long long int64_t;

#if TH_ARCH == 32
typedef long long int intmax_t;
typedef unsigned long long int uintmax_t;
#elif TH_ARCH == 64
typedef long int intmax_t;
typedef unsigned long int uintmax_t;
#endif
#endif


/* Define a boolean type, if needed
 */
#if defined(HAVE_STDBOOL_H)
#  include <stdbool.h>
#elif !defined(false) && !defined(true) && !defined(bool)
typedef enum { false = 0, true = 1 } bool;
#else
#  error Missing boolean definition and could not define our own.
#endif


/** @brief th_char_t
 * Character type. Currently it is not recommended to re-define this,
 * but in distant future it may be possible to change to uint32_t for
 * Unicode 32bit handling.
 */
#ifdef TH_CHAR_TYPE
typedef TH_CHAR_TYPE th_char_t;
#else
typedef char th_char_t;
#endif


#endif // TH_TYPES_H