1 // Need limited C API version 3.13 for Py_mod_gil
2 #include "pyconfig.h" // Py_GIL_DISABLED
3 #ifndef Py_GIL_DISABLED
4 # define Py_LIMITED_API 0x030d0000
5 #endif
6
7 // gh-85283: On Windows, Py_LIMITED_API requires Py_BUILD_CORE to not attempt
8 // linking the extension to python3.lib (which fails). Py_BUILD_CORE_MODULE is
9 // needed to import Python symbols. Then Python.h undefines Py_BUILD_CORE and
10 // Py_BUILD_CORE_MODULE if Py_LIMITED_API is defined.
11 #define Py_BUILD_CORE
12 #define Py_BUILD_CORE_MODULE
13
14 #include <Python.h>
15
16 #include <stdio.h> // printf()
17 #include <stdlib.h> // qsort()
18 #include <string.h> // memset()
19 #ifdef MS_WIN32
20 # include <windows.h>
21 #endif
22
23 #define EXPORT(x) Py_EXPORTED_SYMBOL x
24
25 /* some functions handy for testing */
26
27 EXPORT(int)
_testfunc_cbk_reg_int(int a,int b,int c,int d,int e,int (* func)(int,int,int,int,int))28 _testfunc_cbk_reg_int(int a, int b, int c, int d, int e,
29 int (*func)(int, int, int, int, int))
30 {
31 return func(a*a, b*b, c*c, d*d, e*e);
32 }
33
34 EXPORT(double)
_testfunc_cbk_reg_double(double a,double b,double c,double d,double e,double (* func)(double,double,double,double,double))35 _testfunc_cbk_reg_double(double a, double b, double c, double d, double e,
36 double (*func)(double, double, double, double, double))
37 {
38 return func(a*a, b*b, c*c, d*d, e*e);
39 }
40
41 /*
42 * This structure should be the same as in test_callbacks.py and the
43 * method test_callback_large_struct. See issues 17310 and 20160: the
44 * structure must be larger than 8 bytes long.
45 */
46
47 typedef struct {
48 unsigned long first;
49 unsigned long second;
50 unsigned long third;
51 } Test;
52
53 EXPORT(void)
_testfunc_cbk_large_struct(Test in,void (* func)(Test))54 _testfunc_cbk_large_struct(Test in, void (*func)(Test))
55 {
56 func(in);
57 }
58
59 /*
60 * See issue 29565. Update a structure passed by value;
61 * the caller should not see any change.
62 */
63
64 EXPORT(void)
_testfunc_large_struct_update_value(Test in)65 _testfunc_large_struct_update_value(Test in)
66 {
67 ((volatile Test *)&in)->first = 0x0badf00d;
68 ((volatile Test *)&in)->second = 0x0badf00d;
69 ((volatile Test *)&in)->third = 0x0badf00d;
70 }
71
72 typedef struct {
73 unsigned int first;
74 unsigned int second;
75 } TestReg;
76
77
78 EXPORT(TestReg) last_tfrsuv_arg = {0};
79
80
81 EXPORT(void)
_testfunc_reg_struct_update_value(TestReg in)82 _testfunc_reg_struct_update_value(TestReg in)
83 {
84 last_tfrsuv_arg = in;
85 ((volatile TestReg *)&in)->first = 0x0badf00d;
86 ((volatile TestReg *)&in)->second = 0x0badf00d;
87 }
88
89 /*
90 * See bpo-22273. Structs containing arrays should work on Linux 64-bit.
91 */
92
93 typedef struct {
94 unsigned char data[16];
95 } Test2;
96
97 EXPORT(int)
_testfunc_array_in_struct2(Test2 in)98 _testfunc_array_in_struct2(Test2 in)
99 {
100 int result = 0;
101 for (unsigned i = 0; i < sizeof(in.data)/sizeof(in.data[0]); i++)
102 result += in.data[i];
103 /* As the structure is passed by value, changes to it shouldn't be
104 * reflected in the caller.
105 */
106 memset(in.data, 0, sizeof(in.data));
107 return result;
108 }
109
110 /*
111 * Test3A struct test the MAX_STRUCT_SIZE 16 with single precision floats.
112 * These structs should be passed via registers on all platforms and they are
113 * used for within bounds tests.
114 */
115 typedef struct {
116 float data[2];
117 float more_data[2];
118 } Test3A;
119
120 EXPORT(double)
_testfunc_array_in_struct3A(Test3A in)121 _testfunc_array_in_struct3A(Test3A in)
122 {
123 double result = 0;
124
125 for (unsigned i = 0; i < sizeof(in.data)/sizeof(in.data[0]); i++)
126 result += in.data[i];
127 for (unsigned i = 0; i < sizeof(in.more_data)/sizeof(in.more_data[0]); i++)
128 result += in.more_data[i];
129 /* As the structure is passed by value, changes to it shouldn't be
130 * reflected in the caller.
131 */
132 memset(in.data, 0, sizeof(in.data));
133 return result;
134 }
135
136 /* The structs Test3B..Test3E use the same functions hence using the MACRO
137 * to define their implementation.
138 */
139
140 #define _TESTFUNC_ARRAY_IN_STRUCT_IMPL \
141 double result = 0; \
142 \
143 for (unsigned i = 0; i < sizeof(in.data)/sizeof(in.data[0]); i++) \
144 result += in.data[i]; \
145 /* As the structure is passed by value, changes to it shouldn't be \
146 * reflected in the caller. \
147 */ \
148 memset(in.data, 0, sizeof(in.data)); \
149 return result; \
150
151 #define _TESTFUNC_ARRAY_IN_STRUCT_SET_DEFAULTS_IMPL \
152 for (unsigned i = 0; i < sizeof(s.data)/sizeof(s.data[0]); i++) \
153 s.data[i] = (double)i+1; \
154 return s; \
155
156
157 /*
158 * Test3B struct test the MAX_STRUCT_SIZE 16 with double precision floats.
159 * These structs should be passed via registers on all platforms and they are
160 * used for within bounds tests.
161 */
162 typedef struct {
163 double data[2];
164 } Test3B;
165
166 EXPORT(double)
_testfunc_array_in_struct3B(Test3B in)167 _testfunc_array_in_struct3B(Test3B in)
168 {
169 _TESTFUNC_ARRAY_IN_STRUCT_IMPL
170 }
171
172 EXPORT(Test3B)
_testfunc_array_in_struct3B_set_defaults(void)173 _testfunc_array_in_struct3B_set_defaults(void)
174 {
175 Test3B s;
176 _TESTFUNC_ARRAY_IN_STRUCT_SET_DEFAULTS_IMPL
177 }
178
179 /*
180 * Test3C struct tests the MAX_STRUCT_SIZE 32. Structs containing arrays of up
181 * to four floating-point types are passed in registers on Arm platforms.
182 * This struct is used for within bounds test on Arm platfroms and for an
183 * out-of-bounds tests for platfroms where MAX_STRUCT_SIZE is less than 32.
184 * See gh-110190.
185 */
186 typedef struct {
187 double data[4];
188 } Test3C;
189
190 EXPORT(double)
_testfunc_array_in_struct3C(Test3C in)191 _testfunc_array_in_struct3C(Test3C in)
192 {
193 _TESTFUNC_ARRAY_IN_STRUCT_IMPL
194 }
195
196 EXPORT(Test3C)
_testfunc_array_in_struct3C_set_defaults(void)197 _testfunc_array_in_struct3C_set_defaults(void)
198 {
199 Test3C s;
200 _TESTFUNC_ARRAY_IN_STRUCT_SET_DEFAULTS_IMPL
201 }
202
203 /*
204 * Test3D struct tests the MAX_STRUCT_SIZE 64. Structs containing arrays of up
205 * to eight floating-point types are passed in registers on PPC64LE platforms.
206 * This struct is used for within bounds test on PPC64LE platfroms and for an
207 * out-of-bounds tests for platfroms where MAX_STRUCT_SIZE is less than 64.
208 * See gh-110190.
209 */
210 typedef struct {
211 double data[8];
212 } Test3D;
213
214 EXPORT(double)
_testfunc_array_in_struct3D(Test3D in)215 _testfunc_array_in_struct3D(Test3D in)
216 {
217 _TESTFUNC_ARRAY_IN_STRUCT_IMPL
218 }
219
220 EXPORT(Test3D)
_testfunc_array_in_struct3D_set_defaults(void)221 _testfunc_array_in_struct3D_set_defaults(void)
222 {
223 Test3D s;
224 _TESTFUNC_ARRAY_IN_STRUCT_SET_DEFAULTS_IMPL
225 }
226
227 /*
228 * Test3E struct tests the out-of-bounds for all architectures.
229 * See gh-110190.
230 */
231 typedef struct {
232 double data[9];
233 } Test3E;
234
235 EXPORT(double)
_testfunc_array_in_struct3E(Test3E in)236 _testfunc_array_in_struct3E(Test3E in)
237 {
238 _TESTFUNC_ARRAY_IN_STRUCT_IMPL
239 }
240
241 EXPORT(Test3E)
_testfunc_array_in_struct3E_set_defaults(void)242 _testfunc_array_in_struct3E_set_defaults(void)
243 {
244 Test3E s;
245 _TESTFUNC_ARRAY_IN_STRUCT_SET_DEFAULTS_IMPL
246 }
247
248 typedef union {
249 long a_long;
250 struct {
251 int an_int;
252 int another_int;
253 } a_struct;
254 } Test4;
255
256 typedef struct {
257 int an_int;
258 struct {
259 int an_int;
260 Test4 a_union;
261 } nested;
262 int another_int;
263 } Test5;
264
265 EXPORT(long)
_testfunc_union_by_value1(Test4 in)266 _testfunc_union_by_value1(Test4 in) {
267 long result = in.a_long + in.a_struct.an_int + in.a_struct.another_int;
268
269 /* As the union/struct are passed by value, changes to them shouldn't be
270 * reflected in the caller.
271 */
272 memset(&in, 0, sizeof(in));
273 return result;
274 }
275
276 EXPORT(long)
_testfunc_union_by_value2(Test5 in)277 _testfunc_union_by_value2(Test5 in) {
278 long result = in.an_int + in.nested.an_int;
279
280 /* As the union/struct are passed by value, changes to them shouldn't be
281 * reflected in the caller.
282 */
283 memset(&in, 0, sizeof(in));
284 return result;
285 }
286
287 EXPORT(long)
_testfunc_union_by_reference1(Test4 * in)288 _testfunc_union_by_reference1(Test4 *in) {
289 long result = in->a_long;
290
291 memset(in, 0, sizeof(Test4));
292 return result;
293 }
294
295 EXPORT(long)
_testfunc_union_by_reference2(Test4 * in)296 _testfunc_union_by_reference2(Test4 *in) {
297 long result = in->a_struct.an_int + in->a_struct.another_int;
298
299 memset(in, 0, sizeof(Test4));
300 return result;
301 }
302
303 EXPORT(long)
_testfunc_union_by_reference3(Test5 * in)304 _testfunc_union_by_reference3(Test5 *in) {
305 long result = in->an_int + in->nested.an_int + in->another_int;
306
307 memset(in, 0, sizeof(Test5));
308 return result;
309 }
310
311 typedef struct {
312 signed int A: 1, B:2, C:3, D:2;
313 } Test6;
314
315 EXPORT(long)
_testfunc_bitfield_by_value1(Test6 in)316 _testfunc_bitfield_by_value1(Test6 in) {
317 long result = in.A + in.B + in.C + in.D;
318
319 /* As the struct is passed by value, changes to it shouldn't be
320 * reflected in the caller.
321 */
322 memset(&in, 0, sizeof(in));
323 return result;
324 }
325
326 EXPORT(long)
_testfunc_bitfield_by_reference1(Test6 * in)327 _testfunc_bitfield_by_reference1(Test6 *in) {
328 long result = in->A + in->B + in->C + in->D;
329
330 memset(in, 0, sizeof(Test6));
331 return result;
332 }
333
334 typedef struct {
335 unsigned int A: 1, B:2, C:3, D:2;
336 } Test7;
337
338 EXPORT(long)
_testfunc_bitfield_by_reference2(Test7 * in)339 _testfunc_bitfield_by_reference2(Test7 *in) {
340 long result = in->A + in->B + in->C + in->D;
341
342 memset(in, 0, sizeof(Test7));
343 return result;
344 }
345
346 typedef union {
347 signed int A: 1, B:2, C:3, D:2;
348 } Test8;
349
350 EXPORT(long)
_testfunc_bitfield_by_value2(Test8 in)351 _testfunc_bitfield_by_value2(Test8 in) {
352 long result = in.A + in.B + in.C + in.D;
353
354 /* As the struct is passed by value, changes to it shouldn't be
355 * reflected in the caller.
356 */
357 memset(&in, 0, sizeof(in));
358 return result;
359 }
360
testfunc_array(int values[4])361 EXPORT(void)testfunc_array(int values[4])
362 {
363 printf("testfunc_array %d %d %d %d\n",
364 values[0],
365 values[1],
366 values[2],
367 values[3]);
368 }
369
testfunc_Ddd(double a,double b)370 EXPORT(long double)testfunc_Ddd(double a, double b)
371 {
372 long double result = (long double)(a * b);
373 printf("testfunc_Ddd(%p, %p)\n", (void *)&a, (void *)&b);
374 printf("testfunc_Ddd(%g, %g)\n", a, b);
375 return result;
376 }
377
testfunc_DDD(long double a,long double b)378 EXPORT(long double)testfunc_DDD(long double a, long double b)
379 {
380 long double result = a * b;
381 printf("testfunc_DDD(%p, %p)\n", (void *)&a, (void *)&b);
382 printf("testfunc_DDD(%Lg, %Lg)\n", a, b);
383 return result;
384 }
385
testfunc_iii(int a,int b)386 EXPORT(int)testfunc_iii(int a, int b)
387 {
388 int result = a * b;
389 printf("testfunc_iii(%p, %p)\n", (void *)&a, (void *)&b);
390 return result;
391 }
392
myprintf(char * fmt,...)393 EXPORT(int)myprintf(char *fmt, ...)
394 {
395 int result;
396 va_list argptr;
397 va_start(argptr, fmt);
398 result = vprintf(fmt, argptr);
399 va_end(argptr);
400 return result;
401 }
402
my_strtok(char * token,const char * delim)403 EXPORT(char *)my_strtok(char *token, const char *delim)
404 {
405 return strtok(token, delim);
406 }
407
my_strchr(const char * s,int c)408 EXPORT(char *)my_strchr(const char *s, int c)
409 {
410 return strchr(s, c);
411 }
412
413
my_sqrt(double a)414 EXPORT(double) my_sqrt(double a)
415 {
416 return sqrt(a);
417 }
418
my_qsort(void * base,size_t num,size_t width,int (* compare)(const void *,const void *))419 EXPORT(void) my_qsort(void *base, size_t num, size_t width, int(*compare)(const void*, const void*))
420 {
421 qsort(base, num, width, compare);
422 }
423
_testfunc_ai8(int a[8])424 EXPORT(int *) _testfunc_ai8(int a[8])
425 {
426 return a;
427 }
428
_testfunc_v(int a,int b,int * presult)429 EXPORT(void) _testfunc_v(int a, int b, int *presult)
430 {
431 *presult = a + b;
432 }
433
_testfunc_i_bhilfd(signed char b,short h,int i,long l,float f,double d)434 EXPORT(int) _testfunc_i_bhilfd(signed char b, short h, int i, long l, float f, double d)
435 {
436 /* printf("_testfunc_i_bhilfd got %d %d %d %ld %f %f\n",
437 b, h, i, l, f, d);
438 */
439 return (int)(b + h + i + l + f + d);
440 }
441
_testfunc_f_bhilfd(signed char b,short h,int i,long l,float f,double d)442 EXPORT(float) _testfunc_f_bhilfd(signed char b, short h, int i, long l, float f, double d)
443 {
444 /* printf("_testfunc_f_bhilfd got %d %d %d %ld %f %f\n",
445 b, h, i, l, f, d);
446 */
447 return (float)(b + h + i + l + f + d);
448 }
449
_testfunc_d_bhilfd(signed char b,short h,int i,long l,float f,double d)450 EXPORT(double) _testfunc_d_bhilfd(signed char b, short h, int i, long l, float f, double d)
451 {
452 /* printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n",
453 b, h, i, l, f, d);
454 */
455 return (double)(b + h + i + l + f + d);
456 }
457
_testfunc_D_bhilfD(signed char b,short h,int i,long l,float f,long double d)458 EXPORT(long double) _testfunc_D_bhilfD(signed char b, short h, int i, long l, float f, long double d)
459 {
460 /* printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n",
461 b, h, i, l, f, d);
462 */
463 return (long double)(b + h + i + l + f + d);
464 }
465
_testfunc_p_p(void * s)466 EXPORT(char *) _testfunc_p_p(void *s)
467 {
468 return (char *)s;
469 }
470
_testfunc_c_p_p(int * argcp,char ** argv)471 EXPORT(void *) _testfunc_c_p_p(int *argcp, char **argv)
472 {
473 return argv[(*argcp)-1];
474 }
475
get_strchr(void)476 EXPORT(void *) get_strchr(void)
477 {
478 return (void *)strchr;
479 }
480
my_strdup(char * src)481 EXPORT(char *) my_strdup(char *src)
482 {
483 char *dst = (char *)malloc(strlen(src)+1);
484 if (!dst)
485 return NULL;
486 strcpy(dst, src);
487 return dst;
488 }
489
my_free(void * ptr)490 EXPORT(void)my_free(void *ptr)
491 {
492 free(ptr);
493 }
494
495 #ifdef HAVE_WCHAR_H
my_wcsdup(wchar_t * src)496 EXPORT(wchar_t *) my_wcsdup(wchar_t *src)
497 {
498 size_t len = wcslen(src);
499 wchar_t *ptr = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
500 if (ptr == NULL)
501 return NULL;
502 memcpy(ptr, src, (len+1) * sizeof(wchar_t));
503 return ptr;
504 }
505
my_wcslen(wchar_t * src)506 EXPORT(size_t) my_wcslen(wchar_t *src)
507 {
508 return wcslen(src);
509 }
510 #endif
511
512 #ifndef MS_WIN32
513 # ifndef __stdcall
514 # define __stdcall /* */
515 # endif
516 #endif
517
518 typedef struct {
519 int (*c)(int, int);
520 int (__stdcall *s)(int, int);
521 } FUNCS;
522
_testfunc_callfuncp(FUNCS * fp)523 EXPORT(int) _testfunc_callfuncp(FUNCS *fp)
524 {
525 fp->c(1, 2);
526 fp->s(3, 4);
527 return 0;
528 }
529
_testfunc_deref_pointer(int * pi)530 EXPORT(int) _testfunc_deref_pointer(int *pi)
531 {
532 return *pi;
533 }
534
535 #ifdef MS_WIN32
_testfunc_piunk(IUnknown FAR * piunk)536 EXPORT(int) _testfunc_piunk(IUnknown FAR *piunk)
537 {
538 piunk->lpVtbl->AddRef(piunk);
539 return piunk->lpVtbl->Release(piunk);
540 }
541 #endif
542
_testfunc_callback_with_pointer(int (* func)(int *))543 EXPORT(int) _testfunc_callback_with_pointer(int (*func)(int *))
544 {
545 int table[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
546
547 return (*func)(table);
548 }
549
_testfunc_q_bhilfdq(signed char b,short h,int i,long l,float f,double d,long long q)550 EXPORT(long long) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f,
551 double d, long long q)
552 {
553 return (long long)(b + h + i + l + f + d + q);
554 }
555
_testfunc_q_bhilfd(signed char b,short h,int i,long l,float f,double d)556 EXPORT(long long) _testfunc_q_bhilfd(signed char b, short h, int i, long l, float f, double d)
557 {
558 return (long long)(b + h + i + l + f + d);
559 }
560
_testfunc_callback_i_if(int value,int (* func)(int))561 EXPORT(int) _testfunc_callback_i_if(int value, int (*func)(int))
562 {
563 int sum = 0;
564 while (value != 0) {
565 sum += func(value);
566 value /= 2;
567 }
568 return sum;
569 }
570
_testfunc_callback_q_qf(long long value,long long (* func)(long long))571 EXPORT(long long) _testfunc_callback_q_qf(long long value,
572 long long (*func)(long long))
573 {
574 long long sum = 0;
575
576 while (value != 0) {
577 sum += func(value);
578 value /= 2;
579 }
580 return sum;
581 }
582
583 typedef struct {
584 char *name;
585 char *value;
586 } SPAM;
587
588 typedef struct {
589 char *name;
590 int num_spams;
591 SPAM *spams;
592 } EGG;
593
594 SPAM my_spams[2] = {
595 { "name1", "value1" },
596 { "name2", "value2" },
597 };
598
599 EGG my_eggs[1] = {
600 { "first egg", 1, my_spams }
601 };
602
getSPAMANDEGGS(EGG ** eggs)603 EXPORT(int) getSPAMANDEGGS(EGG **eggs)
604 {
605 *eggs = my_eggs;
606 return 1;
607 }
608
609 typedef struct tagpoint {
610 int x;
611 int y;
612 } point;
613
_testfunc_byval(point in,point * pout)614 EXPORT(int) _testfunc_byval(point in, point *pout)
615 {
616 if (pout) {
617 pout->x = in.x;
618 pout->y = in.y;
619 }
620 return in.x + in.y;
621 }
622
623 EXPORT (int) an_integer = 42;
624
get_an_integer(void)625 EXPORT(int) get_an_integer(void)
626 {
627 return an_integer;
628 }
629
630 EXPORT(double)
integrate(double a,double b,double (* f)(double),long nstep)631 integrate(double a, double b, double (*f)(double), long nstep)
632 {
633 double x, sum=0.0, dx=(b-a)/(double)nstep;
634 for(x=a+0.5*dx; (b-x)*(x-a)>0.0; x+=dx)
635 sum += f(x);
636 return sum/(double)nstep;
637 }
638
639 typedef struct {
640 void (*initialize)(void *(*)(int), void(*)(void *));
641 } xxx_library;
642
_xxx_init(void * (* Xalloc)(int),void (* Xfree)(void *))643 static void _xxx_init(void *(*Xalloc)(int), void (*Xfree)(void *))
644 {
645 void *ptr;
646
647 printf("_xxx_init got %p %p\n", (void *)Xalloc, (void *)Xfree);
648 printf("calling\n");
649 ptr = Xalloc(32);
650 Xfree(ptr);
651 printf("calls done, ptr was %p\n", ptr);
652 }
653
654 xxx_library _xxx_lib = {
655 _xxx_init
656 };
657
EXPORT(xxx_library)658 EXPORT(xxx_library) *library_get(void)
659 {
660 return &_xxx_lib;
661 }
662
663 #ifdef MS_WIN32
664 /* See Don Box (german), pp 79ff. */
GetString(BSTR * pbstr)665 EXPORT(void) GetString(BSTR *pbstr)
666 {
667 *pbstr = SysAllocString(L"Goodbye!");
668 }
669 #endif
670
671 /*
672 * Some do-nothing functions, for speed tests
673 */
py_func_si(PyObject * self,PyObject * args)674 PyObject *py_func_si(PyObject *self, PyObject *args)
675 {
676 char *name;
677 int i;
678 if (!PyArg_ParseTuple(args, "si", &name, &i))
679 return NULL;
680 Py_RETURN_NONE;
681 }
682
_py_func_si(char * s,int i)683 EXPORT(void) _py_func_si(char *s, int i)
684 {
685 }
686
py_func(PyObject * self,PyObject * args)687 PyObject *py_func(PyObject *self, PyObject *args)
688 {
689 Py_RETURN_NONE;
690 }
691
_py_func(void)692 EXPORT(void) _py_func(void)
693 {
694 }
695
696 EXPORT(long long) last_tf_arg_s = 0;
697 EXPORT(unsigned long long) last_tf_arg_u = 0;
698
699 struct BITS {
700 signed int A: 1, B:2, C:3, D:4, E: 5, F: 6, G: 7, H: 8, I: 9;
701 /*
702 * The test case needs/uses "signed short" bitfields, but the
703 * IBM XLC compiler does not support this
704 */
705 #ifndef __xlc__
706 #define SIGNED_SHORT_BITFIELDS
707 short M: 1, N: 2, O: 3, P: 4, Q: 5, R: 6, S: 7;
708 #endif
709 };
710
unpack_bitfields(struct BITS * bits,char name)711 EXPORT(int) unpack_bitfields(struct BITS *bits, char name)
712 {
713 switch (name) {
714 case 'A': return bits->A;
715 case 'B': return bits->B;
716 case 'C': return bits->C;
717 case 'D': return bits->D;
718 case 'E': return bits->E;
719 case 'F': return bits->F;
720 case 'G': return bits->G;
721 case 'H': return bits->H;
722 case 'I': return bits->I;
723
724 #ifdef SIGNED_SHORT_BITFIELDS
725 case 'M': return bits->M;
726 case 'N': return bits->N;
727 case 'O': return bits->O;
728 case 'P': return bits->P;
729 case 'Q': return bits->Q;
730 case 'R': return bits->R;
731 case 'S': return bits->S;
732 #endif
733 }
734 return 999;
735 }
736
737 static PyMethodDef module_methods[] = {
738 /* {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS},
739 {"get_last_tf_arg_u", get_last_tf_arg_u, METH_NOARGS},
740 */
741 {"func_si", py_func_si, METH_VARARGS},
742 {"func", py_func, METH_NOARGS},
743 { NULL, NULL, 0, NULL},
744 };
745
746 #define S last_tf_arg_s = (long long)c
747 #define U last_tf_arg_u = (unsigned long long)c
748
tf_b(signed char c)749 EXPORT(signed char) tf_b(signed char c) { S; return c/3; }
tf_B(unsigned char c)750 EXPORT(unsigned char) tf_B(unsigned char c) { U; return c/3; }
tf_h(short c)751 EXPORT(short) tf_h(short c) { S; return c/3; }
tf_H(unsigned short c)752 EXPORT(unsigned short) tf_H(unsigned short c) { U; return c/3; }
tf_i(int c)753 EXPORT(int) tf_i(int c) { S; return c/3; }
tf_I(unsigned int c)754 EXPORT(unsigned int) tf_I(unsigned int c) { U; return c/3; }
tf_l(long c)755 EXPORT(long) tf_l(long c) { S; return c/3; }
tf_L(unsigned long c)756 EXPORT(unsigned long) tf_L(unsigned long c) { U; return c/3; }
tf_q(long long c)757 EXPORT(long long) tf_q(long long c) { S; return c/3; }
tf_Q(unsigned long long c)758 EXPORT(unsigned long long) tf_Q(unsigned long long c) { U; return c/3; }
tf_f(float c)759 EXPORT(float) tf_f(float c) { S; return c/3; }
tf_d(double c)760 EXPORT(double) tf_d(double c) { S; return c/3; }
tf_D(long double c)761 EXPORT(long double) tf_D(long double c) { S; return c/3; }
762
763 #ifdef MS_WIN32
EXPORT(signed char)764 EXPORT(signed char) __stdcall s_tf_b(signed char c) { S; return c/3; }
EXPORT(unsigned char)765 EXPORT(unsigned char) __stdcall s_tf_B(unsigned char c) { U; return c/3; }
EXPORT(short)766 EXPORT(short) __stdcall s_tf_h(short c) { S; return c/3; }
EXPORT(unsigned short)767 EXPORT(unsigned short) __stdcall s_tf_H(unsigned short c) { U; return c/3; }
EXPORT(int)768 EXPORT(int) __stdcall s_tf_i(int c) { S; return c/3; }
EXPORT(unsigned int)769 EXPORT(unsigned int) __stdcall s_tf_I(unsigned int c) { U; return c/3; }
EXPORT(long)770 EXPORT(long) __stdcall s_tf_l(long c) { S; return c/3; }
EXPORT(unsigned long)771 EXPORT(unsigned long) __stdcall s_tf_L(unsigned long c) { U; return c/3; }
EXPORT(long long)772 EXPORT(long long) __stdcall s_tf_q(long long c) { S; return c/3; }
EXPORT(unsigned long long)773 EXPORT(unsigned long long) __stdcall s_tf_Q(unsigned long long c) { U; return c/3; }
EXPORT(float)774 EXPORT(float) __stdcall s_tf_f(float c) { S; return c/3; }
EXPORT(double)775 EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; }
EXPORT(long double)776 EXPORT(long double) __stdcall s_tf_D(long double c) { S; return c/3; }
777 #endif
778 /*******/
779
tf_bb(signed char x,signed char c)780 EXPORT(signed char) tf_bb(signed char x, signed char c) { S; return c/3; }
tf_bB(signed char x,unsigned char c)781 EXPORT(unsigned char) tf_bB(signed char x, unsigned char c) { U; return c/3; }
tf_bh(signed char x,short c)782 EXPORT(short) tf_bh(signed char x, short c) { S; return c/3; }
tf_bH(signed char x,unsigned short c)783 EXPORT(unsigned short) tf_bH(signed char x, unsigned short c) { U; return c/3; }
tf_bi(signed char x,int c)784 EXPORT(int) tf_bi(signed char x, int c) { S; return c/3; }
tf_bI(signed char x,unsigned int c)785 EXPORT(unsigned int) tf_bI(signed char x, unsigned int c) { U; return c/3; }
tf_bl(signed char x,long c)786 EXPORT(long) tf_bl(signed char x, long c) { S; return c/3; }
tf_bL(signed char x,unsigned long c)787 EXPORT(unsigned long) tf_bL(signed char x, unsigned long c) { U; return c/3; }
tf_bq(signed char x,long long c)788 EXPORT(long long) tf_bq(signed char x, long long c) { S; return c/3; }
tf_bQ(signed char x,unsigned long long c)789 EXPORT(unsigned long long) tf_bQ(signed char x, unsigned long long c) { U; return c/3; }
tf_bf(signed char x,float c)790 EXPORT(float) tf_bf(signed char x, float c) { S; return c/3; }
tf_bd(signed char x,double c)791 EXPORT(double) tf_bd(signed char x, double c) { S; return c/3; }
tf_bD(signed char x,long double c)792 EXPORT(long double) tf_bD(signed char x, long double c) { S; return c/3; }
tv_i(int c)793 EXPORT(void) tv_i(int c) { S; return; }
794
795 #ifdef MS_WIN32
EXPORT(signed char)796 EXPORT(signed char) __stdcall s_tf_bb(signed char x, signed char c) { S; return c/3; }
EXPORT(unsigned char)797 EXPORT(unsigned char) __stdcall s_tf_bB(signed char x, unsigned char c) { U; return c/3; }
EXPORT(short)798 EXPORT(short) __stdcall s_tf_bh(signed char x, short c) { S; return c/3; }
EXPORT(unsigned short)799 EXPORT(unsigned short) __stdcall s_tf_bH(signed char x, unsigned short c) { U; return c/3; }
EXPORT(int)800 EXPORT(int) __stdcall s_tf_bi(signed char x, int c) { S; return c/3; }
EXPORT(unsigned int)801 EXPORT(unsigned int) __stdcall s_tf_bI(signed char x, unsigned int c) { U; return c/3; }
EXPORT(long)802 EXPORT(long) __stdcall s_tf_bl(signed char x, long c) { S; return c/3; }
EXPORT(unsigned long)803 EXPORT(unsigned long) __stdcall s_tf_bL(signed char x, unsigned long c) { U; return c/3; }
EXPORT(long long)804 EXPORT(long long) __stdcall s_tf_bq(signed char x, long long c) { S; return c/3; }
EXPORT(unsigned long long)805 EXPORT(unsigned long long) __stdcall s_tf_bQ(signed char x, unsigned long long c) { U; return c/3; }
EXPORT(float)806 EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; }
EXPORT(double)807 EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; }
EXPORT(long double)808 EXPORT(long double) __stdcall s_tf_bD(signed char x, long double c) { S; return c/3; }
EXPORT(void)809 EXPORT(void) __stdcall s_tv_i(int c) { S; return; }
810 #endif
811
812 /********/
813
814 #ifndef MS_WIN32
815
816 typedef struct {
817 long x;
818 long y;
819 } POINT;
820
821 typedef struct {
822 long left;
823 long top;
824 long right;
825 long bottom;
826 } RECT;
827
828 #endif
829
PointInRect(RECT * prc,POINT pt)830 EXPORT(int) PointInRect(RECT *prc, POINT pt)
831 {
832 if (pt.x < prc->left)
833 return 0;
834 if (pt.x > prc->right)
835 return 0;
836 if (pt.y < prc->top)
837 return 0;
838 if (pt.y > prc->bottom)
839 return 0;
840 return 1;
841 }
842
843 EXPORT(long left = 10);
844 EXPORT(long top = 20);
845 EXPORT(long right = 30);
846 EXPORT(long bottom = 40);
847
ReturnRect(int i,RECT ar,RECT * br,POINT cp,RECT dr,RECT * er,POINT fp,RECT gr)848 EXPORT(RECT) ReturnRect(int i, RECT ar, RECT* br, POINT cp, RECT dr,
849 RECT *er, POINT fp, RECT gr)
850 {
851 /*Check input */
852 if (ar.left + br->left + dr.left + er->left + gr.left != left * 5)
853 {
854 ar.left = 100;
855 return ar;
856 }
857 if (ar.right + br->right + dr.right + er->right + gr.right != right * 5)
858 {
859 ar.right = 100;
860 return ar;
861 }
862 if (cp.x != fp.x)
863 {
864 ar.left = -100;
865 }
866 if (cp.y != fp.y)
867 {
868 ar.left = -200;
869 }
870 switch(i)
871 {
872 case 0:
873 return ar;
874 break;
875 case 1:
876 return dr;
877 break;
878 case 2:
879 return gr;
880 break;
881
882 }
883 return ar;
884 }
885
886 typedef struct {
887 short x;
888 short y;
889 } S2H;
890
ret_2h_func(S2H inp)891 EXPORT(S2H) ret_2h_func(S2H inp)
892 {
893 inp.x *= 2;
894 inp.y *= 3;
895 return inp;
896 }
897
898 typedef struct {
899 int a, b, c, d, e, f, g, h;
900 } S8I;
901
ret_8i_func(S8I inp)902 EXPORT(S8I) ret_8i_func(S8I inp)
903 {
904 inp.a *= 2;
905 inp.b *= 3;
906 inp.c *= 4;
907 inp.d *= 5;
908 inp.e *= 6;
909 inp.f *= 7;
910 inp.g *= 8;
911 inp.h *= 9;
912 return inp;
913 }
914
GetRectangle(int flag,RECT * prect)915 EXPORT(int) GetRectangle(int flag, RECT *prect)
916 {
917 if (flag == 0)
918 return 0;
919 prect->left = (int)flag;
920 prect->top = (int)flag + 1;
921 prect->right = (int)flag + 2;
922 prect->bottom = (int)flag + 3;
923 return 1;
924 }
925
TwoOutArgs(int a,int * pi,int b,int * pj)926 EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj)
927 {
928 *pi += a;
929 *pj += b;
930 }
931
932 #ifdef MS_WIN32
933
934 typedef struct {
935 char f1;
936 } Size1;
937
938 typedef struct {
939 char f1;
940 char f2;
941 } Size2;
942
943 typedef struct {
944 char f1;
945 char f2;
946 char f3;
947 } Size3;
948
949 typedef struct {
950 char f1;
951 char f2;
952 char f3;
953 char f4;
954 } Size4;
955
956 typedef struct {
957 char f1;
958 char f2;
959 char f3;
960 char f4;
961 char f5;
962 } Size5;
963
964 typedef struct {
965 char f1;
966 char f2;
967 char f3;
968 char f4;
969 char f5;
970 char f6;
971 } Size6;
972
973 typedef struct {
974 char f1;
975 char f2;
976 char f3;
977 char f4;
978 char f5;
979 char f6;
980 char f7;
981 } Size7;
982
983 typedef struct {
984 char f1;
985 char f2;
986 char f3;
987 char f4;
988 char f5;
989 char f6;
990 char f7;
991 char f8;
992 } Size8;
993
994 typedef struct {
995 char f1;
996 char f2;
997 char f3;
998 char f4;
999 char f5;
1000 char f6;
1001 char f7;
1002 char f8;
1003 char f9;
1004 } Size9;
1005
1006 typedef struct {
1007 char f1;
1008 char f2;
1009 char f3;
1010 char f4;
1011 char f5;
1012 char f6;
1013 char f7;
1014 char f8;
1015 char f9;
1016 char f10;
1017 } Size10;
1018
TestSize1()1019 EXPORT(Size1) TestSize1() {
1020 Size1 f;
1021 f.f1 = 'a';
1022 return f;
1023 }
1024
TestSize2()1025 EXPORT(Size2) TestSize2() {
1026 Size2 f;
1027 f.f1 = 'a';
1028 f.f2 = 'b';
1029 return f;
1030 }
1031
TestSize3()1032 EXPORT(Size3) TestSize3() {
1033 Size3 f;
1034 f.f1 = 'a';
1035 f.f2 = 'b';
1036 f.f3 = 'c';
1037 return f;
1038 }
1039
TestSize4()1040 EXPORT(Size4) TestSize4() {
1041 Size4 f;
1042 f.f1 = 'a';
1043 f.f2 = 'b';
1044 f.f3 = 'c';
1045 f.f4 = 'd';
1046 return f;
1047 }
1048
TestSize5()1049 EXPORT(Size5) TestSize5() {
1050 Size5 f;
1051 f.f1 = 'a';
1052 f.f2 = 'b';
1053 f.f3 = 'c';
1054 f.f4 = 'd';
1055 f.f5 = 'e';
1056 return f;
1057 }
1058
TestSize6()1059 EXPORT(Size6) TestSize6() {
1060 Size6 f;
1061 f.f1 = 'a';
1062 f.f2 = 'b';
1063 f.f3 = 'c';
1064 f.f4 = 'd';
1065 f.f5 = 'e';
1066 f.f6 = 'f';
1067 return f;
1068 }
1069
TestSize7()1070 EXPORT(Size7) TestSize7() {
1071 Size7 f;
1072 f.f1 = 'a';
1073 f.f2 = 'b';
1074 f.f3 = 'c';
1075 f.f4 = 'd';
1076 f.f5 = 'e';
1077 f.f6 = 'f';
1078 f.f7 = 'g';
1079 return f;
1080 }
1081
TestSize8()1082 EXPORT(Size8) TestSize8() {
1083 Size8 f;
1084 f.f1 = 'a';
1085 f.f2 = 'b';
1086 f.f3 = 'c';
1087 f.f4 = 'd';
1088 f.f5 = 'e';
1089 f.f6 = 'f';
1090 f.f7 = 'g';
1091 f.f8 = 'h';
1092 return f;
1093 }
1094
TestSize9()1095 EXPORT(Size9) TestSize9() {
1096 Size9 f;
1097 f.f1 = 'a';
1098 f.f2 = 'b';
1099 f.f3 = 'c';
1100 f.f4 = 'd';
1101 f.f5 = 'e';
1102 f.f6 = 'f';
1103 f.f7 = 'g';
1104 f.f8 = 'h';
1105 f.f9 = 'i';
1106 return f;
1107 }
1108
TestSize10()1109 EXPORT(Size10) TestSize10() {
1110 Size10 f;
1111 f.f1 = 'a';
1112 f.f2 = 'b';
1113 f.f3 = 'c';
1114 f.f4 = 'd';
1115 f.f5 = 'e';
1116 f.f6 = 'f';
1117 f.f7 = 'g';
1118 f.f8 = 'h';
1119 f.f9 = 'i';
1120 f.f10 = 'j';
1121 return f;
1122 }
1123
1124 #endif
1125
1126 #ifdef MS_WIN32
EXPORT(S2H)1127 EXPORT(S2H) __stdcall s_ret_2h_func(S2H inp) { return ret_2h_func(inp); }
EXPORT(S8I)1128 EXPORT(S8I) __stdcall s_ret_8i_func(S8I inp) { return ret_8i_func(inp); }
1129 #endif
1130
1131 #ifdef MS_WIN32
1132 /* Should port this */
1133 #include <stdlib.h>
1134 #include <search.h>
1135
KeepObject(IUnknown * punk)1136 EXPORT (HRESULT) KeepObject(IUnknown *punk)
1137 {
1138 static IUnknown *pobj;
1139 if (punk)
1140 punk->lpVtbl->AddRef(punk);
1141 if (pobj)
1142 pobj->lpVtbl->Release(pobj);
1143 pobj = punk;
1144 return S_OK;
1145 }
1146
1147 #endif
1148
1149 #ifdef MS_WIN32
1150
1151 // i38748: c stub for testing stack corruption
1152 // When executing a Python callback with a long and a long long
1153
1154 typedef long(__stdcall *_test_i38748_funcType)(long, long long);
1155
_test_i38748_runCallback(_test_i38748_funcType callback,int a,int b)1156 EXPORT(long) _test_i38748_runCallback(_test_i38748_funcType callback, int a, int b) {
1157 return callback(a, b);
1158 }
1159
1160 #endif
1161
1162 EXPORT(int)
_testfunc_pylist_append(PyObject * list,PyObject * item)1163 _testfunc_pylist_append(PyObject *list, PyObject *item)
1164 {
1165 return PyList_Append(list, item);
1166 }
1167
1168 static struct PyModuleDef_Slot _ctypes_test_slots[] = {
1169 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
1170 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
1171 {0, NULL}
1172 };
1173
1174 static struct PyModuleDef _ctypes_testmodule = {
1175 PyModuleDef_HEAD_INIT,
1176 "_ctypes_test",
1177 NULL,
1178 0,
1179 module_methods,
1180 _ctypes_test_slots,
1181 NULL,
1182 NULL,
1183 NULL
1184 };
1185
1186 PyMODINIT_FUNC
PyInit__ctypes_test(void)1187 PyInit__ctypes_test(void)
1188 {
1189 return PyModuleDef_Init(&_ctypes_testmodule);
1190 }
1191