cpython/Modules/_ctypes/_ctypes_test.c

// Need limited C API version 3.13 for Py_mod_gil
#include "pyconfig.h"   // Py_GIL_DISABLED
#ifndef Py_GIL_DISABLED
#define Py_LIMITED_API
#endif

// gh-85283: On Windows, Py_LIMITED_API requires Py_BUILD_CORE to not attempt
// linking the extension to python3.lib (which fails). Py_BUILD_CORE_MODULE is
// needed to import Python symbols. Then Python.h undefines Py_BUILD_CORE and
// Py_BUILD_CORE_MODULE if Py_LIMITED_API is defined.
#define Py_BUILD_CORE
#define Py_BUILD_CORE_MODULE

#include <Python.h>

#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
#  include "../_complex.h"        // csqrt()
#  undef I                        // for _ctypes_test_generated.c.h
#endif
#include <stdio.h>                // printf()
#include <stdlib.h>               // qsort()
#include <string.h>               // memset()
#ifdef MS_WIN32
#  include <windows.h>
#endif

#define EXPORT(x)

#include "_ctypes_test_generated.c.h"

/* some functions handy for testing */

EXPORT(int)
_testfunc_cbk_reg_int(int a, int b, int c, int d, int e,
                      int (*func)(int, int, int, int, int))
{}

EXPORT(double)
_testfunc_cbk_reg_double(double a, double b, double c, double d, double e,
                         double (*func)(double, double, double, double, double))
{}

/*
 * This structure should be the same as in test_callbacks.py and the
 * method test_callback_large_struct. See issues 17310 and 20160: the
 * structure must be larger than 8 bytes long.
 */

Test;

EXPORT(void)
_testfunc_cbk_large_struct(Test in, void (*func)(Test))
{}

/*
 * See issue 29565. Update a structure passed by value;
 * the caller should not see any change.
 */

EXPORT(void)
_testfunc_large_struct_update_value(Test in)
{}

TestReg;


EXPORT(TestReg) last_tfrsuv_arg =;


EXPORT(void)
_testfunc_reg_struct_update_value(TestReg in)
{}

/*
 * See bpo-22273. Structs containing arrays should work on Linux 64-bit.
 */

Test2;

EXPORT(int)
_testfunc_array_in_struct2(Test2 in)
{}

/*
 * Test3A struct test the MAX_STRUCT_SIZE 16 with single precision floats.
 * These structs should be passed via registers on all platforms and they are
 * used for within bounds tests.
 */
Test3A;

EXPORT(double)
_testfunc_array_in_struct3A(Test3A in)
{}

/* The structs Test3B..Test3E use the same functions hence using the MACRO
 * to define their implementation.
 */

#define _TESTFUNC_ARRAY_IN_STRUCT_IMPL                                                      \

#define _TESTFUNC_ARRAY_IN_STRUCT_SET_DEFAULTS_IMPL                                                           \


/*
 * Test3B struct test the MAX_STRUCT_SIZE 16 with double precision floats.
 * These structs should be passed via registers on all platforms and they are
 * used for within bounds tests.
 */
Test3B;

EXPORT(double)
_testfunc_array_in_struct3B(Test3B in)
{}

EXPORT(Test3B)
_testfunc_array_in_struct3B_set_defaults(void)
{}

/*
 * Test3C struct tests the MAX_STRUCT_SIZE 32. Structs containing arrays of up
 * to four floating-point types are passed in registers on Arm platforms.
 * This struct is used for within-bounds tests on Arm platforms and for an
 * out-of-bounds test for platforms where MAX_STRUCT_SIZE is less than 32.
 * See gh-110190.
 */
Test3C;

EXPORT(double)
_testfunc_array_in_struct3C(Test3C in)
{}

EXPORT(Test3C)
_testfunc_array_in_struct3C_set_defaults(void)
{}

/*
 * Test3D struct tests the MAX_STRUCT_SIZE 64. Structs containing arrays of up
 * to eight floating-point types are passed in registers on PPC64LE platforms.
 * This struct is used for within bounds test on PPC64LE platforms and for an
 * out-of-bounds tests for platforms where MAX_STRUCT_SIZE is less than 64.
 * See gh-110190.
 */
Test3D;

EXPORT(double)
_testfunc_array_in_struct3D(Test3D in)
{}

EXPORT(Test3D)
_testfunc_array_in_struct3D_set_defaults(void)
{}

/*
 * Test3E struct tests the out-of-bounds for all architectures.
 * See gh-110190.
 */
Test3E;

EXPORT(double)
_testfunc_array_in_struct3E(Test3E in)
{}

EXPORT(Test3E)
_testfunc_array_in_struct3E_set_defaults(void)
{}

Test4;

Test5;

EXPORT(long)
_testfunc_union_by_value1(Test4 in) {}

EXPORT(long)
_testfunc_union_by_value2(Test5 in) {}

EXPORT(long)
_testfunc_union_by_reference1(Test4 *in) {}

EXPORT(long)
_testfunc_union_by_reference2(Test4 *in) {}

EXPORT(long)
_testfunc_union_by_reference3(Test5 *in) {}

Test6;

EXPORT(long)
_testfunc_bitfield_by_value1(Test6 in) {}

EXPORT(long)
_testfunc_bitfield_by_reference1(Test6 *in) {}

Test7;

EXPORT(long)
_testfunc_bitfield_by_reference2(Test7 *in) {}

Test9;

EXPORT(long)
_testfunc_bitfield_by_reference3(Test9 *in, long pos) {}

Test8;

EXPORT(long)
_testfunc_bitfield_by_value2(Test8 in) {}

EXPORT(void)testfunc_array(int values[4])
{}

EXPORT(long double)testfunc_Ddd(double a, double b)
{}

EXPORT(long double)testfunc_DDD(long double a, long double b)
{}

EXPORT(int)testfunc_iii(int a, int b)
{}

EXPORT(int)myprintf(char *fmt, ...)
{}

EXPORT(char *)my_strtok(char *token, const char *delim)
{}

EXPORT(char *)my_strchr(const char *s, int c)
{}


EXPORT(double) my_sqrt(double a)
{}

#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
EXPORT(double complex) my_csqrt(double complex a)
{
    return csqrt(a);
}

EXPORT(float complex) my_csqrtf(float complex a)
{
    return csqrtf(a);
}

EXPORT(long double complex) my_csqrtl(long double complex a)
{
    return csqrtl(a);
}
#endif

EXPORT(void) my_qsort(void *base, size_t num, size_t width, int(*compare)(const void*, const void*))
{}

EXPORT(int *) _testfunc_ai8(int a[8])
{}

EXPORT(void) _testfunc_v(int a, int b, int *presult)
{}

EXPORT(int) _testfunc_i_bhilfd(signed char b, short h, int i, long l, float f, double d)
{}

EXPORT(float) _testfunc_f_bhilfd(signed char b, short h, int i, long l, float f, double d)
{}

EXPORT(double) _testfunc_d_bhilfd(signed char b, short h, int i, long l, float f, double d)
{}

EXPORT(long double) _testfunc_D_bhilfD(signed char b, short h, int i, long l, float f, long double d)
{}

EXPORT(char *) _testfunc_p_p(void *s)
{}

EXPORT(void *) _testfunc_c_p_p(int *argcp, char **argv)
{}

EXPORT(void *) get_strchr(void)
{}

EXPORT(char *) my_strdup(char *src)
{}

EXPORT(void)my_free(void *ptr)
{}

#ifdef HAVE_WCHAR_H
EXPORT(wchar_t *) my_wcsdup(wchar_t *src)
{}

EXPORT(size_t) my_wcslen(wchar_t *src)
{}
#endif

#ifndef MS_WIN32
# ifndef __stdcall
#  define __stdcall /* */
# endif
#endif

FUNCS;

EXPORT(int) _testfunc_callfuncp(FUNCS *fp)
{}

EXPORT(int) _testfunc_deref_pointer(int *pi)
{}

#ifdef MS_WIN32
EXPORT(int) _testfunc_piunk(IUnknown FAR *piunk)
{
    piunk->lpVtbl->AddRef(piunk);
    return piunk->lpVtbl->Release(piunk);
}
#endif

EXPORT(int) _testfunc_callback_with_pointer(int (*func)(int *))
{}

EXPORT(long long) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f,
                                      double d, long long q)
{}

EXPORT(long long) _testfunc_q_bhilfd(signed char b, short h, int i, long l, float f, double d)
{}

EXPORT(int) _testfunc_callback_i_if(int value, int (*func)(int))
{}

EXPORT(long long) _testfunc_callback_q_qf(long long value,
                                          long long (*func)(long long))
{}

SPAM;

EGG;

SPAM my_spams[2] =;

EGG my_eggs[1] =;

EXPORT(int) getSPAMANDEGGS(EGG **eggs)
{}

point;

EXPORT(int) _testfunc_byval(point in, point *pout)
{}

EXPORT (int) an_integer =;

EXPORT(int) get_an_integer(void)
{}

EXPORT(double)
integrate(double a, double b, double (*f)(double), long nstep)
{}

xxx_library;

static void _xxx_init(void *(*Xalloc)(int), void (*Xfree)(void *))
{}

xxx_library _xxx_lib =;

EXPORT(xxx_library) *library_get(void)
{}

#ifdef MS_WIN32
/* See Don Box (german), pp 79ff. */
EXPORT(void) GetString(BSTR *pbstr)
{
    *pbstr = SysAllocString(L"Goodbye!");
}
#endif

/*
 * Some do-nothing functions, for speed tests
 */
PyObject *py_func_si(PyObject *self, PyObject *args)
{}

EXPORT(void) _py_func_si(char *s, int i)
{}

PyObject *py_func(PyObject *self, PyObject *args)
{}

EXPORT(void) _py_func(void)
{}

EXPORT(long long) last_tf_arg_s =;
EXPORT(unsigned long long) last_tf_arg_u =;

struct BITS {};

EXPORT(int) unpack_bitfields(struct BITS *bits, char name)
{}

#if (defined(MS_WIN32) || ((defined(__x86_64__) || defined(__i386__) || defined(__ppc64__)) && (defined(__GNUC__) || defined(__clang__))))
struct
#ifndef MS_WIN32
__attribute__ ((ms_struct))
#endif
BITS_msvc
{};

EXPORT(int) unpack_bitfields_msvc(struct BITS_msvc *bits, char name)
{}
#endif

static PyMethodDef module_methods[] =;

#define S
#define U

EXPORT(signed char) tf_b(signed char c) {}
EXPORT(unsigned char) tf_B(unsigned char c) {}
EXPORT(short) tf_h(short c) {}
EXPORT(unsigned short) tf_H(unsigned short c) {}
EXPORT(int) tf_i(int c) {}
EXPORT(unsigned int) tf_I(unsigned int c) {}
EXPORT(long) tf_l(long c) {}
EXPORT(unsigned long) tf_L(unsigned long c) {}
EXPORT(long long) tf_q(long long c) {}
EXPORT(unsigned long long) tf_Q(unsigned long long c) {}
EXPORT(float) tf_f(float c) {}
EXPORT(double) tf_d(double c) {}
EXPORT(long double) tf_D(long double c) {}

#ifdef MS_WIN32
EXPORT(signed char) __stdcall s_tf_b(signed char c) { S; return c/3; }
EXPORT(unsigned char) __stdcall s_tf_B(unsigned char c) { U; return c/3; }
EXPORT(short) __stdcall s_tf_h(short c) { S; return c/3; }
EXPORT(unsigned short) __stdcall s_tf_H(unsigned short c) { U; return c/3; }
EXPORT(int) __stdcall s_tf_i(int c) { S; return c/3; }
EXPORT(unsigned int) __stdcall s_tf_I(unsigned int c) { U; return c/3; }
EXPORT(long) __stdcall s_tf_l(long c) { S; return c/3; }
EXPORT(unsigned long) __stdcall s_tf_L(unsigned long c) { U; return c/3; }
EXPORT(long long) __stdcall s_tf_q(long long c) { S; return c/3; }
EXPORT(unsigned long long) __stdcall s_tf_Q(unsigned long long c) { U; return c/3; }
EXPORT(float) __stdcall s_tf_f(float c) { S; return c/3; }
EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; }
EXPORT(long double) __stdcall s_tf_D(long double c) { S; return c/3; }
#endif
/*******/

EXPORT(signed char) tf_bb(signed char x, signed char c) {}
EXPORT(unsigned char) tf_bB(signed char x, unsigned char c) {}
EXPORT(short) tf_bh(signed char x, short c) {}
EXPORT(unsigned short) tf_bH(signed char x, unsigned short c) {}
EXPORT(int) tf_bi(signed char x, int c) {}
EXPORT(unsigned int) tf_bI(signed char x, unsigned int c) {}
EXPORT(long) tf_bl(signed char x, long c) {}
EXPORT(unsigned long) tf_bL(signed char x, unsigned long c) {}
EXPORT(long long) tf_bq(signed char x, long long c) {}
EXPORT(unsigned long long) tf_bQ(signed char x, unsigned long long c) {}
EXPORT(float) tf_bf(signed char x, float c) {}
EXPORT(double) tf_bd(signed char x, double c) {}
EXPORT(long double) tf_bD(signed char x, long double c) {}
EXPORT(void) tv_i(int c) {}

#ifdef MS_WIN32
EXPORT(signed char) __stdcall s_tf_bb(signed char x, signed char c) { S; return c/3; }
EXPORT(unsigned char) __stdcall s_tf_bB(signed char x, unsigned char c) { U; return c/3; }
EXPORT(short) __stdcall s_tf_bh(signed char x, short c) { S; return c/3; }
EXPORT(unsigned short) __stdcall s_tf_bH(signed char x, unsigned short c) { U; return c/3; }
EXPORT(int) __stdcall s_tf_bi(signed char x, int c) { S; return c/3; }
EXPORT(unsigned int) __stdcall s_tf_bI(signed char x, unsigned int c) { U; return c/3; }
EXPORT(long) __stdcall s_tf_bl(signed char x, long c) { S; return c/3; }
EXPORT(unsigned long) __stdcall s_tf_bL(signed char x, unsigned long c) { U; return c/3; }
EXPORT(long long) __stdcall s_tf_bq(signed char x, long long c) { S; return c/3; }
EXPORT(unsigned long long) __stdcall s_tf_bQ(signed char x, unsigned long long c) { U; return c/3; }
EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; }
EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; }
EXPORT(long double) __stdcall s_tf_bD(signed char x, long double c) { S; return c/3; }
EXPORT(void) __stdcall s_tv_i(int c) { S; return; }
#endif

/********/

#ifndef MS_WIN32

POINT;

RECT;

#endif

EXPORT(int) PointInRect(RECT *prc, POINT pt)
{}

EXPORT(long left =;
EXPORT(long top =;
EXPORT(long right =;
EXPORT(long bottom =;

EXPORT(RECT) ReturnRect(int i, RECT ar, RECT* br, POINT cp, RECT dr,
                        RECT *er, POINT fp, RECT gr)
{}

S2H;

EXPORT(S2H) ret_2h_func(S2H inp)
{}

S8I;

EXPORT(S8I) ret_8i_func(S8I inp)
{}

EXPORT(int) GetRectangle(int flag, RECT *prect)
{}

EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj)
{}

#ifdef MS_WIN32

typedef struct {
    char f1;
} Size1;

typedef struct {
    char f1;
    char f2;
} Size2;

typedef struct {
    char f1;
    char f2;
    char f3;
} Size3;

typedef struct {
    char f1;
    char f2;
    char f3;
    char f4;
} Size4;

typedef struct {
    char f1;
    char f2;
    char f3;
    char f4;
    char f5;
} Size5;

typedef struct {
    char f1;
    char f2;
    char f3;
    char f4;
    char f5;
    char f6;
} Size6;

typedef struct {
    char f1;
    char f2;
    char f3;
    char f4;
    char f5;
    char f6;
    char f7;
} Size7;

typedef struct {
    char f1;
    char f2;
    char f3;
    char f4;
    char f5;
    char f6;
    char f7;
    char f8;
} Size8;

typedef struct {
    char f1;
    char f2;
    char f3;
    char f4;
    char f5;
    char f6;
    char f7;
    char f8;
    char f9;
} Size9;

typedef struct {
    char f1;
    char f2;
    char f3;
    char f4;
    char f5;
    char f6;
    char f7;
    char f8;
    char f9;
    char f10;
} Size10;

EXPORT(Size1) TestSize1() {
    Size1 f;
    f.f1 = 'a';
    return f;
}

EXPORT(Size2) TestSize2() {
    Size2 f;
    f.f1 = 'a';
    f.f2 = 'b';
    return f;
}

EXPORT(Size3) TestSize3() {
    Size3 f;
    f.f1 = 'a';
    f.f2 = 'b';
    f.f3 = 'c';
    return f;
}

EXPORT(Size4) TestSize4() {
    Size4 f;
    f.f1 = 'a';
    f.f2 = 'b';
    f.f3 = 'c';
    f.f4 = 'd';
    return f;
}

EXPORT(Size5) TestSize5() {
    Size5 f;
    f.f1 = 'a';
    f.f2 = 'b';
    f.f3 = 'c';
    f.f4 = 'd';
    f.f5 = 'e';
    return f;
}

EXPORT(Size6) TestSize6() {
    Size6 f;
    f.f1 = 'a';
    f.f2 = 'b';
    f.f3 = 'c';
    f.f4 = 'd';
    f.f5 = 'e';
    f.f6 = 'f';
    return f;
}

EXPORT(Size7) TestSize7() {
    Size7 f;
    f.f1 = 'a';
    f.f2 = 'b';
    f.f3 = 'c';
    f.f4 = 'd';
    f.f5 = 'e';
    f.f6 = 'f';
    f.f7 = 'g';
    return f;
}

EXPORT(Size8) TestSize8() {
    Size8 f;
    f.f1 = 'a';
    f.f2 = 'b';
    f.f3 = 'c';
    f.f4 = 'd';
    f.f5 = 'e';
    f.f6 = 'f';
    f.f7 = 'g';
    f.f8 = 'h';
    return f;
}

EXPORT(Size9) TestSize9() {
    Size9 f;
    f.f1 = 'a';
    f.f2 = 'b';
    f.f3 = 'c';
    f.f4 = 'd';
    f.f5 = 'e';
    f.f6 = 'f';
    f.f7 = 'g';
    f.f8 = 'h';
    f.f9 = 'i';
    return f;
}

EXPORT(Size10) TestSize10() {
    Size10 f;
    f.f1 = 'a';
    f.f2 = 'b';
    f.f3 = 'c';
    f.f4 = 'd';
    f.f5 = 'e';
    f.f6 = 'f';
    f.f7 = 'g';
    f.f8 = 'h';
    f.f9 = 'i';
    f.f10 = 'j';
    return f;
}

#endif

#ifdef MS_WIN32
EXPORT(S2H) __stdcall s_ret_2h_func(S2H inp) { return ret_2h_func(inp); }
EXPORT(S8I) __stdcall s_ret_8i_func(S8I inp) { return ret_8i_func(inp); }
#endif

#ifdef MS_WIN32
/* Should port this */
#include <stdlib.h>
#include <search.h>

EXPORT (HRESULT) KeepObject(IUnknown *punk)
{
    static IUnknown *pobj;
    if (punk)
        punk->lpVtbl->AddRef(punk);
    if (pobj)
        pobj->lpVtbl->Release(pobj);
    pobj = punk;
    return S_OK;
}

#endif

#ifdef MS_WIN32

// i38748: c stub for testing stack corruption
// When executing a Python callback with a long and a long long

typedef long(__stdcall *_test_i38748_funcType)(long, long long);

EXPORT(long) _test_i38748_runCallback(_test_i38748_funcType callback, int a, int b) {
    return callback(a, b);
}

#endif

EXPORT(int)
_testfunc_pylist_append(PyObject *list, PyObject *item)
{}

static struct PyModuleDef_Slot _ctypes_test_slots[] =;

static struct PyModuleDef _ctypes_testmodule =;

PyMODINIT_FUNC
PyInit__ctypes_test(void)
{}