• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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