331 lines
11 KiB
C
331 lines
11 KiB
C
|
#ifndef Py_PYPORT_H
|
||
|
#define Py_PYPORT_H
|
||
|
|
||
|
#include <pyconfig.h> /* include for defines */
|
||
|
|
||
|
#include <inttypes.h>
|
||
|
|
||
|
/**************************************************************************
|
||
|
Symbols and macros to supply platform-independent interfaces to basic
|
||
|
C language & library operations whose spellings vary across platforms.
|
||
|
|
||
|
Please try to make documentation here as clear as possible: by definition,
|
||
|
the stuff here is trying to illuminate C's darkest corners.
|
||
|
|
||
|
Config #defines referenced here:
|
||
|
|
||
|
SIGNED_RIGHT_SHIFT_ZERO_FILLS
|
||
|
Meaning: To be defined iff i>>j does not extend the sign bit when i is a
|
||
|
signed integral type and i < 0.
|
||
|
Used in: Py_ARITHMETIC_RIGHT_SHIFT
|
||
|
|
||
|
Py_DEBUG
|
||
|
Meaning: Extra checks compiled in for debug mode.
|
||
|
Used in: Py_SAFE_DOWNCAST
|
||
|
|
||
|
**************************************************************************/
|
||
|
|
||
|
/* typedefs for some C9X-defined synonyms for integral types.
|
||
|
*
|
||
|
* The names in Python are exactly the same as the C9X names, except with a
|
||
|
* Py_ prefix. Until C9X is universally implemented, this is the only way
|
||
|
* to ensure that Python gets reliable names that don't conflict with names
|
||
|
* in non-Python code that are playing their own tricks to define the C9X
|
||
|
* names.
|
||
|
*
|
||
|
* NOTE: don't go nuts here! Python has no use for *most* of the C9X
|
||
|
* integral synonyms. Only define the ones we actually need.
|
||
|
*/
|
||
|
|
||
|
/* typedefs for some C9X-defined synonyms for integral types. */
|
||
|
#ifndef PY_LONG_LONG
|
||
|
#define PY_LONG_LONG long long
|
||
|
/* If LLONG_MAX is defined in limits.h, use that. */
|
||
|
#define PY_LLONG_MIN LLONG_MIN
|
||
|
#define PY_LLONG_MAX LLONG_MAX
|
||
|
#define PY_ULLONG_MAX ULLONG_MAX
|
||
|
#endif
|
||
|
|
||
|
#define PY_UINT32_T uint32_t
|
||
|
#define PY_UINT64_T uint64_t
|
||
|
|
||
|
/* Signed variants of the above */
|
||
|
#define PY_INT32_T int32_t
|
||
|
#define PY_INT64_T int64_t
|
||
|
|
||
|
|
||
|
/* uintptr_t is the C9X name for an unsigned integral type such that a
|
||
|
* legitimate void* can be cast to uintptr_t and then back to void* again
|
||
|
* without loss of information. Similarly for intptr_t, wrt a signed
|
||
|
* integral type.
|
||
|
*/
|
||
|
typedef uintptr_t Py_uintptr_t;
|
||
|
typedef intptr_t Py_intptr_t;
|
||
|
|
||
|
/* CPython does this differently */
|
||
|
#ifdef _WIN64
|
||
|
typedef long long Py_ssize_t;
|
||
|
typedef long long Py_hash_t;
|
||
|
typedef unsigned long long Py_uhash_t;
|
||
|
#else
|
||
|
typedef long Py_ssize_t;
|
||
|
typedef long Py_hash_t;
|
||
|
typedef unsigned long Py_uhash_t;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/* Py_hash_t is the same size as a pointer. */
|
||
|
#define SIZEOF_PY_HASH_T SIZEOF_SIZE_T
|
||
|
/* Py_uhash_t is the unsigned equivalent needed to calculate numeric hash. */
|
||
|
#define SIZEOF_PY_UHASH_T SIZEOF_SIZE_T
|
||
|
|
||
|
/* Largest possible value of size_t. */
|
||
|
#define PY_SIZE_MAX SIZE_MAX
|
||
|
|
||
|
/* Largest positive value of type Py_ssize_t. */
|
||
|
#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1))
|
||
|
/* Smallest negative value of type Py_ssize_t. */
|
||
|
#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1)
|
||
|
|
||
|
#include <stdarg.h>
|
||
|
|
||
|
/* Py_LOCAL can be used instead of static to get the fastest possible calling
|
||
|
* convention for functions that are local to a given module.
|
||
|
*
|
||
|
* Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining,
|
||
|
* for platforms that support that.
|
||
|
*
|
||
|
* If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more
|
||
|
* "aggressive" inlining/optimization is enabled for the entire module. This
|
||
|
* may lead to code bloat, and may slow things down for those reasons. It may
|
||
|
* also lead to errors, if the code relies on pointer aliasing. Use with
|
||
|
* care.
|
||
|
*
|
||
|
* NOTE: You can only use this for functions that are entirely local to a
|
||
|
* module; functions that are exported via method tables, callbacks, etc,
|
||
|
* should keep using static.
|
||
|
*/
|
||
|
|
||
|
#if defined(_MSC_VER)
|
||
|
# if defined(PY_LOCAL_AGGRESSIVE)
|
||
|
/* enable more aggressive optimization for MSVC */
|
||
|
/* active in both release and debug builds - see bpo-43271 */
|
||
|
# pragma optimize("gt", on)
|
||
|
#endif
|
||
|
/* ignore warnings if the compiler decides not to inline a function */
|
||
|
# pragma warning(disable: 4710)
|
||
|
/* fastest possible local call under MSVC */
|
||
|
# define Py_LOCAL(type) static type __fastcall
|
||
|
# define Py_LOCAL_INLINE(type) static __inline type __fastcall
|
||
|
#else
|
||
|
# define Py_LOCAL(type) static type
|
||
|
# define Py_LOCAL_INLINE(type) static inline type
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
/* CPython needs this for the c-extension datetime, which is pure python on PyPy
|
||
|
downstream packages assume it is here (Pandas for instance) */
|
||
|
#include <time.h>
|
||
|
#ifndef _MSC_VER
|
||
|
#include <sys/time.h>
|
||
|
#endif
|
||
|
|
||
|
/*******************************
|
||
|
* stat() and fstat() fiddling *
|
||
|
*******************************/
|
||
|
|
||
|
/* We expect that stat and fstat exist on most systems.
|
||
|
* It's confirmed on Unix, Mac and Windows.
|
||
|
* If you don't have them, add
|
||
|
* #define DONT_HAVE_STAT
|
||
|
* and/or
|
||
|
* #define DONT_HAVE_FSTAT
|
||
|
* to your pyconfig.h. Python code beyond this should check HAVE_STAT and
|
||
|
* HAVE_FSTAT instead.
|
||
|
* Also
|
||
|
* #define HAVE_SYS_STAT_H
|
||
|
* if <sys/stat.h> exists on your platform, and
|
||
|
* #define HAVE_STAT_H
|
||
|
* if <stat.h> does.
|
||
|
*/
|
||
|
#ifndef DONT_HAVE_STAT
|
||
|
#define HAVE_STAT
|
||
|
#endif
|
||
|
|
||
|
#ifndef DONT_HAVE_FSTAT
|
||
|
#define HAVE_FSTAT
|
||
|
#endif
|
||
|
|
||
|
#ifdef RISCOS
|
||
|
#include <sys/types.h>
|
||
|
#include "unixstuff.h"
|
||
|
#endif
|
||
|
|
||
|
#ifdef HAVE_SYS_STAT_H
|
||
|
#if defined(PYOS_OS2) && defined(PYCC_GCC)
|
||
|
#include <sys/types.h>
|
||
|
#endif
|
||
|
#include <sys/stat.h>
|
||
|
#elif defined(HAVE_STAT_H)
|
||
|
#include <stat.h>
|
||
|
#else
|
||
|
#endif
|
||
|
|
||
|
/* Py_DEPRECATED(version)
|
||
|
* Declare a variable, type, or function deprecated.
|
||
|
* The macro must be placed before the declaration.
|
||
|
* Usage:
|
||
|
* Py_DEPRECATED(3.3) extern int old_var;
|
||
|
* Py_DEPRECATED(3.4) typedef int T1;
|
||
|
* Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);
|
||
|
*/
|
||
|
#if defined(__GNUC__) \
|
||
|
&& ((__GNUC__ >= 4) || (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
|
||
|
#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
|
||
|
#elif defined(_MSC_VER)
|
||
|
#define Py_DEPRECATED(VERSION) __declspec(deprecated( \
|
||
|
"deprecated in " #VERSION))
|
||
|
#else
|
||
|
#define Py_DEPRECATED(VERSION_UNUSED)
|
||
|
#endif
|
||
|
|
||
|
/* Declarations for symbol visibility.
|
||
|
|
||
|
PyAPI_FUNC(type): Declares a public Python API function and return type
|
||
|
PyAPI_DATA(type): Declares public Python data and its type
|
||
|
PyMODINIT_FUNC: A Python module init function. If these functions are
|
||
|
inside the Python core, they are private to the core.
|
||
|
If in an extension module, it may be declared with
|
||
|
external linkage depending on the platform.
|
||
|
|
||
|
As a number of platforms support/require "__declspec(dllimport/dllexport)",
|
||
|
we support a HAVE_DECLSPEC_DLL macro to save duplication.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
All windows ports, except cygwin, are handled in PC/pyconfig.h.
|
||
|
|
||
|
Cygwin is the only other autoconf platform requiring special
|
||
|
linkage handling and it uses __declspec().
|
||
|
*/
|
||
|
#if defined(__CYGWIN__)
|
||
|
# define HAVE_DECLSPEC_DLL
|
||
|
#endif
|
||
|
|
||
|
#include "exports.h"
|
||
|
|
||
|
/* only get special linkage if built as shared or platform is Cygwin */
|
||
|
#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__)
|
||
|
# if defined(HAVE_DECLSPEC_DLL)
|
||
|
# if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||
|
# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE
|
||
|
# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE
|
||
|
/* module init functions inside the core need no external linkage */
|
||
|
/* except for Cygwin to handle embedding */
|
||
|
# if defined(__CYGWIN__)
|
||
|
# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
|
||
|
# else /* __CYGWIN__ */
|
||
|
# define PyMODINIT_FUNC PyObject*
|
||
|
# endif /* __CYGWIN__ */
|
||
|
# else /* Py_BUILD_CORE */
|
||
|
/* Building an extension module, or an embedded situation */
|
||
|
/* public Python functions and data are imported */
|
||
|
/* Under Cygwin, auto-import functions to prevent compilation */
|
||
|
/* failures similar to those described at the bottom of 4.1: */
|
||
|
/* http://docs.python.org/extending/windows.html#a-cookbook-approach */
|
||
|
# if !defined(__CYGWIN__)
|
||
|
# define PyAPI_FUNC(RTYPE) Py_IMPORTED_SYMBOL RTYPE
|
||
|
# endif /* !__CYGWIN__ */
|
||
|
# define PyAPI_DATA(RTYPE) extern Py_IMPORTED_SYMBOL RTYPE
|
||
|
/* module init functions outside the core must be exported */
|
||
|
# if defined(__cplusplus)
|
||
|
# define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject*
|
||
|
# else /* __cplusplus */
|
||
|
# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
|
||
|
# endif /* __cplusplus */
|
||
|
# endif /* Py_BUILD_CORE */
|
||
|
# endif /* HAVE_DECLSPEC_DLL */
|
||
|
#endif /* Py_ENABLE_SHARED */
|
||
|
|
||
|
/* If no external linkage macros defined by now, create defaults */
|
||
|
#ifndef PyAPI_FUNC
|
||
|
# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE
|
||
|
#endif
|
||
|
#ifndef PyAPI_DATA
|
||
|
# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE
|
||
|
#endif
|
||
|
#ifndef PyMODINIT_FUNC
|
||
|
# if defined(__cplusplus)
|
||
|
# define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject*
|
||
|
# else /* __cplusplus */
|
||
|
# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
|
||
|
# endif /* __cplusplus */
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Hide GCC attributes from compilers that don't support them.
|
||
|
*/
|
||
|
#if (!defined(__GNUC__) || __GNUC__ < 2 || \
|
||
|
(__GNUC__ == 2 && __GNUC_MINOR__ < 7) )
|
||
|
#define Py_GCC_ATTRIBUTE(x)
|
||
|
#else
|
||
|
#define Py_GCC_ATTRIBUTE(x) __attribute__(x)
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* Specify alignment on compilers that support it.
|
||
|
*/
|
||
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
||
|
#define Py_ALIGNED(x) __attribute__((aligned(x)))
|
||
|
#else
|
||
|
#define Py_ALIGNED(x)
|
||
|
#endif
|
||
|
|
||
|
/* Eliminate end-of-loop code not reached warnings from SunPro C
|
||
|
* when using do{...}while(0) macros
|
||
|
*/
|
||
|
#ifdef __SUNPRO_C
|
||
|
#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED)
|
||
|
#endif
|
||
|
|
||
|
#ifndef Py_LL
|
||
|
#define Py_LL(x) x##LL
|
||
|
#endif
|
||
|
|
||
|
#ifndef Py_ULL
|
||
|
#define Py_ULL(x) Py_LL(x##U)
|
||
|
#endif
|
||
|
|
||
|
#define Py_VA_COPY va_copy
|
||
|
|
||
|
/* Mark a function which cannot return. Example:
|
||
|
PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void);
|
||
|
|
||
|
XLC support is intentionally omitted due to bpo-40244 */
|
||
|
#if defined(__clang__) || \
|
||
|
(defined(__GNUC__) && \
|
||
|
((__GNUC__ >= 3) || \
|
||
|
(__GNUC__ == 2) && (__GNUC_MINOR__ >= 5)))
|
||
|
# define _Py_NO_RETURN __attribute__((__noreturn__))
|
||
|
#elif defined(_MSC_VER)
|
||
|
# define _Py_NO_RETURN __declspec(noreturn)
|
||
|
#else
|
||
|
# define _Py_NO_RETURN
|
||
|
#endif
|
||
|
|
||
|
|
||
|
// Preprocessor check for a builtin preprocessor function. Always return 0
|
||
|
// if __has_builtin() macro is not defined.
|
||
|
//
|
||
|
// __has_builtin() is available on clang and GCC 10.
|
||
|
#ifdef __has_builtin
|
||
|
# define _Py__has_builtin(x) __has_builtin(x)
|
||
|
#else
|
||
|
# define _Py__has_builtin(x) 0
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#endif /* Py_PYPORT_H */
|