Home | History | Annotate | Download | only in _ctypes
      1 #include <Python.h>
      2 
      3 /*
      4   Backwards compatibility, no longer strictly required:
      5   Python2.2 used LONG_LONG instead of PY_LONG_LONG
      6 */
      7 #if defined(HAVE_LONG_LONG) && !defined(PY_LONG_LONG)
      8 #define PY_LONG_LONG LONG_LONG
      9 #endif
     10 
     11 #ifdef MS_WIN32
     12 #include <windows.h>
     13 #endif
     14 
     15 #if defined(MS_WIN32) || defined(__CYGWIN__)
     16 #define EXPORT(x) __declspec(dllexport) x
     17 #else
     18 #define EXPORT(x) x
     19 #endif
     20 
     21 /* some functions handy for testing */
     22 
     23 EXPORT(int)
     24 _testfunc_cbk_reg_int(int a, int b, int c, int d, int e,
     25                       int (*func)(int, int, int, int, int))
     26 {
     27     return func(a*a, b*b, c*c, d*d, e*e);
     28 }
     29 
     30 EXPORT(double)
     31 _testfunc_cbk_reg_double(double a, double b, double c, double d, double e,
     32                          double (*func)(double, double, double, double, double))
     33 {
     34     return func(a*a, b*b, c*c, d*d, e*e);
     35 }
     36 
     37 /*
     38  * This structure should be the same as in test_callbacks.py and the
     39  * method test_callback_large_struct. See issues 17310 and 20160: the
     40  * structure must be larger than 8 bytes long.
     41  */
     42 
     43 typedef struct {
     44     unsigned long first;
     45     unsigned long second;
     46     unsigned long third;
     47 } Test;
     48 
     49 EXPORT(void)
     50 _testfunc_cbk_large_struct(Test in, void (*func)(Test))
     51 {
     52     func(in);
     53 }
     54 
     55 EXPORT(void)testfunc_array(int values[4])
     56 {
     57     printf("testfunc_array %d %d %d %d\n",
     58            values[0],
     59            values[1],
     60            values[2],
     61            values[3]);
     62 }
     63 
     64 EXPORT(long double)testfunc_Ddd(double a, double b)
     65 {
     66     long double result = (long double)(a * b);
     67     printf("testfunc_Ddd(%p, %p)\n", &a, &b);
     68     printf("testfunc_Ddd(%g, %g)\n", a, b);
     69     return result;
     70 }
     71 
     72 EXPORT(long double)testfunc_DDD(long double a, long double b)
     73 {
     74     long double result = a * b;
     75     printf("testfunc_DDD(%p, %p)\n", &a, &b);
     76     printf("testfunc_DDD(%Lg, %Lg)\n", a, b);
     77     return result;
     78 }
     79 
     80 EXPORT(int)testfunc_iii(int a, int b)
     81 {
     82     int result = a * b;
     83     printf("testfunc_iii(%p, %p)\n", &a, &b);
     84     return result;
     85 }
     86 
     87 EXPORT(int)myprintf(char *fmt, ...)
     88 {
     89     int result;
     90     va_list argptr;
     91     va_start(argptr, fmt);
     92     result = vprintf(fmt, argptr);
     93     va_end(argptr);
     94     return result;
     95 }
     96 
     97 EXPORT(char *)my_strtok(char *token, const char *delim)
     98 {
     99     return strtok(token, delim);
    100 }
    101 
    102 EXPORT(char *)my_strchr(const char *s, int c)
    103 {
    104     return strchr(s, c);
    105 }
    106 
    107 
    108 EXPORT(double) my_sqrt(double a)
    109 {
    110     return sqrt(a);
    111 }
    112 
    113 EXPORT(void) my_qsort(void *base, size_t num, size_t width, int(*compare)(const void*, const void*))
    114 {
    115     qsort(base, num, width, compare);
    116 }
    117 
    118 EXPORT(int *) _testfunc_ai8(int a[8])
    119 {
    120     return a;
    121 }
    122 
    123 EXPORT(void) _testfunc_v(int a, int b, int *presult)
    124 {
    125     *presult = a + b;
    126 }
    127 
    128 EXPORT(int) _testfunc_i_bhilfd(signed char b, short h, int i, long l, float f, double d)
    129 {
    130 /*      printf("_testfunc_i_bhilfd got %d %d %d %ld %f %f\n",
    131                b, h, i, l, f, d);
    132 */
    133     return (int)(b + h + i + l + f + d);
    134 }
    135 
    136 EXPORT(float) _testfunc_f_bhilfd(signed char b, short h, int i, long l, float f, double d)
    137 {
    138 /*      printf("_testfunc_f_bhilfd got %d %d %d %ld %f %f\n",
    139                b, h, i, l, f, d);
    140 */
    141     return (float)(b + h + i + l + f + d);
    142 }
    143 
    144 EXPORT(double) _testfunc_d_bhilfd(signed char b, short h, int i, long l, float f, double d)
    145 {
    146 /*      printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n",
    147                b, h, i, l, f, d);
    148 */
    149     return (double)(b + h + i + l + f + d);
    150 }
    151 
    152 EXPORT(long double) _testfunc_D_bhilfD(signed char b, short h, int i, long l, float f, long double d)
    153 {
    154 /*      printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n",
    155                b, h, i, l, f, d);
    156 */
    157     return (long double)(b + h + i + l + f + d);
    158 }
    159 
    160 EXPORT(char *) _testfunc_p_p(void *s)
    161 {
    162     return (char *)s;
    163 }
    164 
    165 EXPORT(void *) _testfunc_c_p_p(int *argcp, char **argv)
    166 {
    167     return argv[(*argcp)-1];
    168 }
    169 
    170 EXPORT(void *) get_strchr(void)
    171 {
    172     return (void *)strchr;
    173 }
    174 
    175 EXPORT(char *) my_strdup(char *src)
    176 {
    177     char *dst = (char *)malloc(strlen(src)+1);
    178     if (!dst)
    179         return NULL;
    180     strcpy(dst, src);
    181     return dst;
    182 }
    183 
    184 EXPORT(void)my_free(void *ptr)
    185 {
    186     free(ptr);
    187 }
    188 
    189 #ifdef HAVE_WCHAR_H
    190 EXPORT(wchar_t *) my_wcsdup(wchar_t *src)
    191 {
    192     size_t len = wcslen(src);
    193     wchar_t *ptr = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
    194     if (ptr == NULL)
    195         return NULL;
    196     memcpy(ptr, src, (len+1) * sizeof(wchar_t));
    197     return ptr;
    198 }
    199 
    200 EXPORT(size_t) my_wcslen(wchar_t *src)
    201 {
    202     return wcslen(src);
    203 }
    204 #endif
    205 
    206 #ifndef MS_WIN32
    207 # ifndef __stdcall
    208 #  define __stdcall /* */
    209 # endif
    210 #endif
    211 
    212 typedef struct {
    213     int (*c)(int, int);
    214     int (__stdcall *s)(int, int);
    215 } FUNCS;
    216 
    217 EXPORT(int) _testfunc_callfuncp(FUNCS *fp)
    218 {
    219     fp->c(1, 2);
    220     fp->s(3, 4);
    221     return 0;
    222 }
    223 
    224 EXPORT(int) _testfunc_deref_pointer(int *pi)
    225 {
    226     return *pi;
    227 }
    228 
    229 #ifdef MS_WIN32
    230 EXPORT(int) _testfunc_piunk(IUnknown FAR *piunk)
    231 {
    232     piunk->lpVtbl->AddRef(piunk);
    233     return piunk->lpVtbl->Release(piunk);
    234 }
    235 #endif
    236 
    237 EXPORT(int) _testfunc_callback_with_pointer(int (*func)(int *))
    238 {
    239     int table[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    240 
    241     return (*func)(table);
    242 }
    243 
    244 #ifdef HAVE_LONG_LONG
    245 EXPORT(PY_LONG_LONG) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f,
    246                                      double d, PY_LONG_LONG q)
    247 {
    248     return (PY_LONG_LONG)(b + h + i + l + f + d + q);
    249 }
    250 
    251 EXPORT(PY_LONG_LONG) _testfunc_q_bhilfd(signed char b, short h, int i, long l, float f, double d)
    252 {
    253     return (PY_LONG_LONG)(b + h + i + l + f + d);
    254 }
    255 
    256 EXPORT(int) _testfunc_callback_i_if(int value, int (*func)(int))
    257 {
    258     int sum = 0;
    259     while (value != 0) {
    260         sum += func(value);
    261         value /= 2;
    262     }
    263     return sum;
    264 }
    265 
    266 EXPORT(PY_LONG_LONG) _testfunc_callback_q_qf(PY_LONG_LONG value,
    267                                              PY_LONG_LONG (*func)(PY_LONG_LONG))
    268 {
    269     PY_LONG_LONG sum = 0;
    270 
    271     while (value != 0) {
    272         sum += func(value);
    273         value /= 2;
    274     }
    275     return sum;
    276 }
    277 
    278 #endif
    279 
    280 typedef struct {
    281     char *name;
    282     char *value;
    283 } SPAM;
    284 
    285 typedef struct {
    286     char *name;
    287     int num_spams;
    288     SPAM *spams;
    289 } EGG;
    290 
    291 SPAM my_spams[2] = {
    292     { "name1", "value1" },
    293     { "name2", "value2" },
    294 };
    295 
    296 EGG my_eggs[1] = {
    297     { "first egg", 1, my_spams }
    298 };
    299 
    300 EXPORT(int) getSPAMANDEGGS(EGG **eggs)
    301 {
    302     *eggs = my_eggs;
    303     return 1;
    304 }
    305 
    306 typedef struct tagpoint {
    307     int x;
    308     int y;
    309 } point;
    310 
    311 EXPORT(int) _testfunc_byval(point in, point *pout)
    312 {
    313     if (pout) {
    314         pout->x = in.x;
    315         pout->y = in.y;
    316     }
    317     return in.x + in.y;
    318 }
    319 
    320 EXPORT (int) an_integer = 42;
    321 
    322 EXPORT(int) get_an_integer(void)
    323 {
    324     return an_integer;
    325 }
    326 
    327 EXPORT(double)
    328 integrate(double a, double b, double (*f)(double), long nstep)
    329 {
    330     double x, sum=0.0, dx=(b-a)/(double)nstep;
    331     for(x=a+0.5*dx; (b-x)*(x-a)>0.0; x+=dx)
    332         sum += f(x);
    333     return sum/(double)nstep;
    334 }
    335 
    336 typedef struct {
    337     void (*initialize)(void *(*)(int), void(*)(void *));
    338 } xxx_library;
    339 
    340 static void _xxx_init(void *(*Xalloc)(int), void (*Xfree)(void *))
    341 {
    342     void *ptr;
    343 
    344     printf("_xxx_init got %p %p\n", Xalloc, Xfree);
    345     printf("calling\n");
    346     ptr = Xalloc(32);
    347     Xfree(ptr);
    348     printf("calls done, ptr was %p\n", ptr);
    349 }
    350 
    351 xxx_library _xxx_lib = {
    352     _xxx_init
    353 };
    354 
    355 EXPORT(xxx_library) *library_get(void)
    356 {
    357     return &_xxx_lib;
    358 }
    359 
    360 #ifdef MS_WIN32
    361 /* See Don Box (german), pp 79ff. */
    362 EXPORT(void) GetString(BSTR *pbstr)
    363 {
    364     *pbstr = SysAllocString(L"Goodbye!");
    365 }
    366 #endif
    367 
    368 /*
    369  * Some do-nothing functions, for speed tests
    370  */
    371 PyObject *py_func_si(PyObject *self, PyObject *args)
    372 {
    373     char *name;
    374     int i;
    375     if (!PyArg_ParseTuple(args, "si", &name, &i))
    376         return NULL;
    377     Py_INCREF(Py_None);
    378     return Py_None;
    379 }
    380 
    381 EXPORT(void) _py_func_si(char *s, int i)
    382 {
    383 }
    384 
    385 PyObject *py_func(PyObject *self, PyObject *args)
    386 {
    387     Py_INCREF(Py_None);
    388     return Py_None;
    389 }
    390 
    391 EXPORT(void) _py_func(void)
    392 {
    393 }
    394 
    395 EXPORT(PY_LONG_LONG) last_tf_arg_s;
    396 EXPORT(unsigned PY_LONG_LONG) last_tf_arg_u;
    397 
    398 struct BITS {
    399     int A: 1, B:2, C:3, D:4, E: 5, F: 6, G: 7, H: 8, I: 9;
    400     short M: 1, N: 2, O: 3, P: 4, Q: 5, R: 6, S: 7;
    401 };
    402 
    403 DL_EXPORT(void) set_bitfields(struct BITS *bits, char name, int value)
    404 {
    405     switch (name) {
    406     case 'A': bits->A = value; break;
    407     case 'B': bits->B = value; break;
    408     case 'C': bits->C = value; break;
    409     case 'D': bits->D = value; break;
    410     case 'E': bits->E = value; break;
    411     case 'F': bits->F = value; break;
    412     case 'G': bits->G = value; break;
    413     case 'H': bits->H = value; break;
    414     case 'I': bits->I = value; break;
    415 
    416     case 'M': bits->M = value; break;
    417     case 'N': bits->N = value; break;
    418     case 'O': bits->O = value; break;
    419     case 'P': bits->P = value; break;
    420     case 'Q': bits->Q = value; break;
    421     case 'R': bits->R = value; break;
    422     case 'S': bits->S = value; break;
    423     }
    424 }
    425 
    426 DL_EXPORT(int) unpack_bitfields(struct BITS *bits, char name)
    427 {
    428     switch (name) {
    429     case 'A': return bits->A;
    430     case 'B': return bits->B;
    431     case 'C': return bits->C;
    432     case 'D': return bits->D;
    433     case 'E': return bits->E;
    434     case 'F': return bits->F;
    435     case 'G': return bits->G;
    436     case 'H': return bits->H;
    437     case 'I': return bits->I;
    438 
    439     case 'M': return bits->M;
    440     case 'N': return bits->N;
    441     case 'O': return bits->O;
    442     case 'P': return bits->P;
    443     case 'Q': return bits->Q;
    444     case 'R': return bits->R;
    445     case 'S': return bits->S;
    446     }
    447     return 0;
    448 }
    449 
    450 static PyMethodDef module_methods[] = {
    451 /*      {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS},
    452     {"get_last_tf_arg_u", get_last_tf_arg_u, METH_NOARGS},
    453 */
    454     {"func_si", py_func_si, METH_VARARGS},
    455     {"func", py_func, METH_NOARGS},
    456     { NULL, NULL, 0, NULL},
    457 };
    458 
    459 #define S last_tf_arg_s = (PY_LONG_LONG)c
    460 #define U last_tf_arg_u = (unsigned PY_LONG_LONG)c
    461 
    462 EXPORT(signed char) tf_b(signed char c) { S; return c/3; }
    463 EXPORT(unsigned char) tf_B(unsigned char c) { U; return c/3; }
    464 EXPORT(short) tf_h(short c) { S; return c/3; }
    465 EXPORT(unsigned short) tf_H(unsigned short c) { U; return c/3; }
    466 EXPORT(int) tf_i(int c) { S; return c/3; }
    467 EXPORT(unsigned int) tf_I(unsigned int c) { U; return c/3; }
    468 EXPORT(long) tf_l(long c) { S; return c/3; }
    469 EXPORT(unsigned long) tf_L(unsigned long c) { U; return c/3; }
    470 EXPORT(PY_LONG_LONG) tf_q(PY_LONG_LONG c) { S; return c/3; }
    471 EXPORT(unsigned PY_LONG_LONG) tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
    472 EXPORT(float) tf_f(float c) { S; return c/3; }
    473 EXPORT(double) tf_d(double c) { S; return c/3; }
    474 EXPORT(long double) tf_D(long double c) { S; return c/3; }
    475 
    476 #ifdef MS_WIN32
    477 EXPORT(signed char) __stdcall s_tf_b(signed char c) { S; return c/3; }
    478 EXPORT(unsigned char) __stdcall s_tf_B(unsigned char c) { U; return c/3; }
    479 EXPORT(short) __stdcall s_tf_h(short c) { S; return c/3; }
    480 EXPORT(unsigned short) __stdcall s_tf_H(unsigned short c) { U; return c/3; }
    481 EXPORT(int) __stdcall s_tf_i(int c) { S; return c/3; }
    482 EXPORT(unsigned int) __stdcall s_tf_I(unsigned int c) { U; return c/3; }
    483 EXPORT(long) __stdcall s_tf_l(long c) { S; return c/3; }
    484 EXPORT(unsigned long) __stdcall s_tf_L(unsigned long c) { U; return c/3; }
    485 EXPORT(PY_LONG_LONG) __stdcall s_tf_q(PY_LONG_LONG c) { S; return c/3; }
    486 EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
    487 EXPORT(float) __stdcall s_tf_f(float c) { S; return c/3; }
    488 EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; }
    489 EXPORT(long double) __stdcall s_tf_D(long double c) { S; return c/3; }
    490 #endif
    491 /*******/
    492 
    493 EXPORT(signed char) tf_bb(signed char x, signed char c) { S; return c/3; }
    494 EXPORT(unsigned char) tf_bB(signed char x, unsigned char c) { U; return c/3; }
    495 EXPORT(short) tf_bh(signed char x, short c) { S; return c/3; }
    496 EXPORT(unsigned short) tf_bH(signed char x, unsigned short c) { U; return c/3; }
    497 EXPORT(int) tf_bi(signed char x, int c) { S; return c/3; }
    498 EXPORT(unsigned int) tf_bI(signed char x, unsigned int c) { U; return c/3; }
    499 EXPORT(long) tf_bl(signed char x, long c) { S; return c/3; }
    500 EXPORT(unsigned long) tf_bL(signed char x, unsigned long c) { U; return c/3; }
    501 EXPORT(PY_LONG_LONG) tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
    502 EXPORT(unsigned PY_LONG_LONG) tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
    503 EXPORT(float) tf_bf(signed char x, float c) { S; return c/3; }
    504 EXPORT(double) tf_bd(signed char x, double c) { S; return c/3; }
    505 EXPORT(long double) tf_bD(signed char x, long double c) { S; return c/3; }
    506 EXPORT(void) tv_i(int c) { S; return; }
    507 
    508 #ifdef MS_WIN32
    509 EXPORT(signed char) __stdcall s_tf_bb(signed char x, signed char c) { S; return c/3; }
    510 EXPORT(unsigned char) __stdcall s_tf_bB(signed char x, unsigned char c) { U; return c/3; }
    511 EXPORT(short) __stdcall s_tf_bh(signed char x, short c) { S; return c/3; }
    512 EXPORT(unsigned short) __stdcall s_tf_bH(signed char x, unsigned short c) { U; return c/3; }
    513 EXPORT(int) __stdcall s_tf_bi(signed char x, int c) { S; return c/3; }
    514 EXPORT(unsigned int) __stdcall s_tf_bI(signed char x, unsigned int c) { U; return c/3; }
    515 EXPORT(long) __stdcall s_tf_bl(signed char x, long c) { S; return c/3; }
    516 EXPORT(unsigned long) __stdcall s_tf_bL(signed char x, unsigned long c) { U; return c/3; }
    517 EXPORT(PY_LONG_LONG) __stdcall s_tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
    518 EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
    519 EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; }
    520 EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; }
    521 EXPORT(long double) __stdcall s_tf_bD(signed char x, long double c) { S; return c/3; }
    522 EXPORT(void) __stdcall s_tv_i(int c) { S; return; }
    523 #endif
    524 
    525 /********/
    526 
    527 #ifndef MS_WIN32
    528 
    529 typedef struct {
    530     long x;
    531     long y;
    532 } POINT;
    533 
    534 typedef struct {
    535     long left;
    536     long top;
    537     long right;
    538     long bottom;
    539 } RECT;
    540 
    541 #endif
    542 
    543 EXPORT(int) PointInRect(RECT *prc, POINT pt)
    544 {
    545     if (pt.x < prc->left)
    546         return 0;
    547     if (pt.x > prc->right)
    548         return 0;
    549     if (pt.y < prc->top)
    550         return 0;
    551     if (pt.y > prc->bottom)
    552         return 0;
    553     return 1;
    554 }
    555 
    556 EXPORT(long left = 10);
    557 EXPORT(long top = 20);
    558 EXPORT(long right = 30);
    559 EXPORT(long bottom = 40);
    560 
    561 EXPORT(RECT) ReturnRect(int i, RECT ar, RECT* br, POINT cp, RECT dr,
    562                         RECT *er, POINT fp, RECT gr)
    563 {
    564     /*Check input */
    565     if (ar.left + br->left + dr.left + er->left + gr.left != left * 5)
    566     {
    567         ar.left = 100;
    568         return ar;
    569     }
    570     if (ar.right + br->right + dr.right + er->right + gr.right != right * 5)
    571     {
    572         ar.right = 100;
    573         return ar;
    574     }
    575     if (cp.x != fp.x)
    576     {
    577         ar.left = -100;
    578     }
    579     if (cp.y != fp.y)
    580     {
    581         ar.left = -200;
    582     }
    583     switch(i)
    584     {
    585     case 0:
    586         return ar;
    587         break;
    588     case 1:
    589         return dr;
    590         break;
    591     case 2:
    592         return gr;
    593         break;
    594 
    595     }
    596     return ar;
    597 }
    598 
    599 typedef struct {
    600     short x;
    601     short y;
    602 } S2H;
    603 
    604 EXPORT(S2H) ret_2h_func(S2H inp)
    605 {
    606     inp.x *= 2;
    607     inp.y *= 3;
    608     return inp;
    609 }
    610 
    611 typedef struct {
    612     int a, b, c, d, e, f, g, h;
    613 } S8I;
    614 
    615 EXPORT(S8I) ret_8i_func(S8I inp)
    616 {
    617     inp.a *= 2;
    618     inp.b *= 3;
    619     inp.c *= 4;
    620     inp.d *= 5;
    621     inp.e *= 6;
    622     inp.f *= 7;
    623     inp.g *= 8;
    624     inp.h *= 9;
    625     return inp;
    626 }
    627 
    628 EXPORT(int) GetRectangle(int flag, RECT *prect)
    629 {
    630     if (flag == 0)
    631         return 0;
    632     prect->left = (int)flag;
    633     prect->top = (int)flag + 1;
    634     prect->right = (int)flag + 2;
    635     prect->bottom = (int)flag + 3;
    636     return 1;
    637 }
    638 
    639 EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj)
    640 {
    641     *pi += a;
    642     *pj += b;
    643 }
    644 
    645 #ifdef MS_WIN32
    646 EXPORT(S2H) __stdcall s_ret_2h_func(S2H inp) { return ret_2h_func(inp); }
    647 EXPORT(S8I) __stdcall s_ret_8i_func(S8I inp) { return ret_8i_func(inp); }
    648 #endif
    649 
    650 #ifdef MS_WIN32
    651 /* Should port this */
    652 #include <stdlib.h>
    653 #include <search.h>
    654 
    655 EXPORT (HRESULT) KeepObject(IUnknown *punk)
    656 {
    657     static IUnknown *pobj;
    658     if (punk)
    659         punk->lpVtbl->AddRef(punk);
    660     if (pobj)
    661         pobj->lpVtbl->Release(pobj);
    662     pobj = punk;
    663     return S_OK;
    664 }
    665 
    666 #endif
    667 
    668 DL_EXPORT(void)
    669 init_ctypes_test(void)
    670 {
    671     Py_InitModule("_ctypes_test", module_methods);
    672 }
    673