blob: d13fec4e9ead92e2cc0af9ea836266becc7e7f9c [file] [log] [blame]
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001/*****************************************************************
2 This file should be kept compatible with Python 2.3, see PEP 291.
3 *****************************************************************/
4
5
Thomas Hellerd4c93202006-03-08 19:35:11 +00006#include <Python.h>
7
8/*
9 Backwards compatibility:
10 Python2.2 used LONG_LONG instead of PY_LONG_LONG
11*/
12#if defined(HAVE_LONG_LONG) && !defined(PY_LONG_LONG)
13#define PY_LONG_LONG LONG_LONG
14#endif
15
16#ifdef MS_WIN32
17#include <windows.h>
18#endif
19
20#if defined(MS_WIN32) || defined(__CYGWIN__)
21#define EXPORT(x) __declspec(dllexport) x
22#else
23#define EXPORT(x) x
24#endif
25
26/* some functions handy for testing */
27
Thomas Wouters89f507f2006-12-13 04:49:30 +000028EXPORT(int)myprintf(char *fmt, ...)
29{
30 int result;
31 va_list argptr;
32 va_start(argptr, fmt);
33 result = vprintf(fmt, argptr);
34 va_end(argptr);
35 return result;
36}
37
Thomas Hellerd4c93202006-03-08 19:35:11 +000038EXPORT(char *)my_strtok(char *token, const char *delim)
39{
40 return strtok(token, delim);
41}
42
43EXPORT(char *)my_strchr(const char *s, int c)
44{
45 return strchr(s, c);
46}
47
48
49EXPORT(double) my_sqrt(double a)
50{
51 return sqrt(a);
52}
53
54EXPORT(void) my_qsort(void *base, size_t num, size_t width, int(*compare)(const void*, const void*))
55{
56 qsort(base, num, width, compare);
57}
58
59EXPORT(int *) _testfunc_ai8(int a[8])
60{
61 return a;
62}
63
64EXPORT(void) _testfunc_v(int a, int b, int *presult)
65{
66 *presult = a + b;
67}
68
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000069EXPORT(int) _testfunc_i_bhilfd(signed char b, short h, int i, long l, float f, double d)
Thomas Hellerd4c93202006-03-08 19:35:11 +000070{
71// printf("_testfunc_i_bhilfd got %d %d %d %ld %f %f\n",
72// b, h, i, l, f, d);
73 return (int)(b + h + i + l + f + d);
74}
75
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000076EXPORT(float) _testfunc_f_bhilfd(signed char b, short h, int i, long l, float f, double d)
Thomas Hellerd4c93202006-03-08 19:35:11 +000077{
78// printf("_testfunc_f_bhilfd got %d %d %d %ld %f %f\n",
79// b, h, i, l, f, d);
80 return (float)(b + h + i + l + f + d);
81}
82
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000083EXPORT(double) _testfunc_d_bhilfd(signed char b, short h, int i, long l, float f, double d)
Thomas Hellerd4c93202006-03-08 19:35:11 +000084{
85// printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n",
86// b, h, i, l, f, d);
87 return (double)(b + h + i + l + f + d);
88}
89
90EXPORT(char *) _testfunc_p_p(void *s)
91{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000092 return (char *)s;
Thomas Hellerd4c93202006-03-08 19:35:11 +000093}
94
95EXPORT(void *) _testfunc_c_p_p(int *argcp, char **argv)
96{
97 return argv[(*argcp)-1];
98}
99
100EXPORT(void *) get_strchr(void)
101{
102 return (void *)strchr;
103}
104
105EXPORT(char *) my_strdup(char *src)
106{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000107 char *dst = (char *)malloc(strlen(src)+1);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000108 if (!dst)
109 return NULL;
110 strcpy(dst, src);
111 return dst;
112}
113
Thomas Wouters477c8d52006-05-27 19:21:47 +0000114EXPORT(void)my_free(void *ptr)
115{
116 free(ptr);
117}
118
Thomas Hellerd4c93202006-03-08 19:35:11 +0000119#ifdef HAVE_WCHAR_H
120EXPORT(wchar_t *) my_wcsdup(wchar_t *src)
121{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000122 size_t len = wcslen(src);
123 wchar_t *ptr = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000124 if (ptr == NULL)
125 return NULL;
126 memcpy(ptr, src, (len+1) * sizeof(wchar_t));
127 return ptr;
128}
129
130EXPORT(size_t) my_wcslen(wchar_t *src)
131{
132 return wcslen(src);
133}
134#endif
135
136#ifndef MS_WIN32
137# ifndef __stdcall
138# define __stdcall /* */
139# endif
140#endif
141
142typedef struct {
143 int (*c)(int, int);
144 int (__stdcall *s)(int, int);
145} FUNCS;
146
147EXPORT(int) _testfunc_callfuncp(FUNCS *fp)
148{
149 fp->c(1, 2);
150 fp->s(3, 4);
151 return 0;
152}
153
154EXPORT(int) _testfunc_deref_pointer(int *pi)
155{
156 return *pi;
157}
158
159#ifdef MS_WIN32
160EXPORT(int) _testfunc_piunk(IUnknown FAR *piunk)
161{
162 piunk->lpVtbl->AddRef(piunk);
163 return piunk->lpVtbl->Release(piunk);
164}
165#endif
166
167EXPORT(int) _testfunc_callback_with_pointer(int (*func)(int *))
168{
169 int table[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
170
171 return (*func)(table);
172}
173
174#ifdef HAVE_LONG_LONG
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000175EXPORT(PY_LONG_LONG) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f,
Thomas Hellerd4c93202006-03-08 19:35:11 +0000176 double d, PY_LONG_LONG q)
177{
178 return (PY_LONG_LONG)(b + h + i + l + f + d + q);
179}
180
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000181EXPORT(PY_LONG_LONG) _testfunc_q_bhilfd(signed char b, short h, int i, long l, float f, double d)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000182{
183 return (PY_LONG_LONG)(b + h + i + l + f + d);
184}
185
186EXPORT(int) _testfunc_callback_i_if(int value, int (*func)(int))
187{
188 int sum = 0;
189 while (value != 0) {
190 sum += func(value);
191 value /= 2;
192 }
193 return sum;
194}
195
196EXPORT(PY_LONG_LONG) _testfunc_callback_q_qf(PY_LONG_LONG value,
197 PY_LONG_LONG (*func)(PY_LONG_LONG))
198{
199 PY_LONG_LONG sum = 0;
200
201 while (value != 0) {
202 sum += func(value);
203 value /= 2;
204 }
205 return sum;
206}
207
208#endif
209
Thomas Hellerd4c93202006-03-08 19:35:11 +0000210typedef struct {
211 char *name;
212 char *value;
213} SPAM;
214
215typedef struct {
216 char *name;
217 int num_spams;
218 SPAM *spams;
219} EGG;
220
221SPAM my_spams[2] = {
222 { "name1", "value1" },
223 { "name2", "value2" },
224};
225
226EGG my_eggs[1] = {
227 { "first egg", 1, my_spams }
228};
229
230EXPORT(int) getSPAMANDEGGS(EGG **eggs)
231{
232 *eggs = my_eggs;
233 return 1;
234}
235
236typedef struct tagpoint {
237 int x;
238 int y;
239} point;
240
241EXPORT(int) _testfunc_byval(point in, point *pout)
242{
243 if (pout) {
244 pout->x = in.x;
245 pout->y = in.y;
246 }
247 return in.x + in.y;
248}
249
250EXPORT (int) an_integer = 42;
251
252EXPORT(int) get_an_integer(void)
253{
254 return an_integer;
255}
256
257EXPORT(double)
258integrate(double a, double b, double (*f)(double), long nstep)
259{
260 double x, sum=0.0, dx=(b-a)/(double)nstep;
261 for(x=a+0.5*dx; (b-x)*(x-a)>0.0; x+=dx)
262 sum += f(x);
263 return sum/(double)nstep;
264}
265
266typedef struct {
267 void (*initialize)(void *(*)(int), void(*)(void *));
268} xxx_library;
269
270static void _xxx_init(void *(*Xalloc)(int), void (*Xfree)(void *))
271{
272 void *ptr;
273
274 printf("_xxx_init got %p %p\n", Xalloc, Xfree);
275 printf("calling\n");
276 ptr = Xalloc(32);
277 Xfree(ptr);
278 printf("calls done, ptr was %p\n", ptr);
279}
280
281xxx_library _xxx_lib = {
282 _xxx_init
283};
284
285EXPORT(xxx_library) *library_get(void)
286{
287 return &_xxx_lib;
288}
289
290#ifdef MS_WIN32
291/* See Don Box (german), pp 79ff. */
292EXPORT(void) GetString(BSTR *pbstr)
293{
294 *pbstr = SysAllocString(L"Goodbye!");
295}
296#endif
297
298/*
299 * Some do-nothing functions, for speed tests
300 */
301PyObject *py_func_si(PyObject *self, PyObject *args)
302{
303 char *name;
304 int i;
305 if (!PyArg_ParseTuple(args, "si", &name, &i))
306 return NULL;
307 Py_INCREF(Py_None);
308 return Py_None;
309}
310
311EXPORT(void) _py_func_si(char *s, int i)
312{
313}
314
315PyObject *py_func(PyObject *self, PyObject *args)
316{
317 Py_INCREF(Py_None);
318 return Py_None;
319}
320
321EXPORT(void) _py_func(void)
322{
323}
324
325EXPORT(PY_LONG_LONG) last_tf_arg_s;
326EXPORT(unsigned PY_LONG_LONG) last_tf_arg_u;
327
328struct BITS {
329 int A: 1, B:2, C:3, D:4, E: 5, F: 6, G: 7, H: 8, I: 9;
330 short M: 1, N: 2, O: 3, P: 4, Q: 5, R: 6, S: 7;
331};
332
333DL_EXPORT(void) set_bitfields(struct BITS *bits, char name, int value)
334{
335 switch (name) {
336 case 'A': bits->A = value; break;
337 case 'B': bits->B = value; break;
338 case 'C': bits->C = value; break;
339 case 'D': bits->D = value; break;
340 case 'E': bits->E = value; break;
341 case 'F': bits->F = value; break;
342 case 'G': bits->G = value; break;
343 case 'H': bits->H = value; break;
344 case 'I': bits->I = value; break;
345
346 case 'M': bits->M = value; break;
347 case 'N': bits->N = value; break;
348 case 'O': bits->O = value; break;
349 case 'P': bits->P = value; break;
350 case 'Q': bits->Q = value; break;
351 case 'R': bits->R = value; break;
352 case 'S': bits->S = value; break;
353 }
354}
355
356DL_EXPORT(int) unpack_bitfields(struct BITS *bits, char name)
357{
358 switch (name) {
359 case 'A': return bits->A;
360 case 'B': return bits->B;
361 case 'C': return bits->C;
362 case 'D': return bits->D;
363 case 'E': return bits->E;
364 case 'F': return bits->F;
365 case 'G': return bits->G;
366 case 'H': return bits->H;
367 case 'I': return bits->I;
368
369 case 'M': return bits->M;
370 case 'N': return bits->N;
371 case 'O': return bits->O;
372 case 'P': return bits->P;
373 case 'Q': return bits->Q;
374 case 'R': return bits->R;
375 case 'S': return bits->S;
376 }
377 return 0;
378}
379
380PyMethodDef module_methods[] = {
381// {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS},
382// {"get_last_tf_arg_u", get_last_tf_arg_u, METH_NOARGS},
383 {"func_si", py_func_si, METH_VARARGS},
384 {"func", py_func, METH_NOARGS},
385 { NULL, NULL, 0, NULL},
386};
387
388#define S last_tf_arg_s = (PY_LONG_LONG)c
389#define U last_tf_arg_u = (unsigned PY_LONG_LONG)c
390
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000391EXPORT(signed char) tf_b(signed char c) { S; return c/3; }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000392EXPORT(unsigned char) tf_B(unsigned char c) { U; return c/3; }
393EXPORT(short) tf_h(short c) { S; return c/3; }
394EXPORT(unsigned short) tf_H(unsigned short c) { U; return c/3; }
395EXPORT(int) tf_i(int c) { S; return c/3; }
396EXPORT(unsigned int) tf_I(unsigned int c) { U; return c/3; }
397EXPORT(long) tf_l(long c) { S; return c/3; }
398EXPORT(unsigned long) tf_L(unsigned long c) { U; return c/3; }
399EXPORT(PY_LONG_LONG) tf_q(PY_LONG_LONG c) { S; return c/3; }
400EXPORT(unsigned PY_LONG_LONG) tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
401EXPORT(float) tf_f(float c) { S; return c/3; }
402EXPORT(double) tf_d(double c) { S; return c/3; }
403
404#ifdef MS_WIN32
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000405EXPORT(signed char) __stdcall s_tf_b(signed char c) { S; return c/3; }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000406EXPORT(unsigned char) __stdcall s_tf_B(unsigned char c) { U; return c/3; }
407EXPORT(short) __stdcall s_tf_h(short c) { S; return c/3; }
408EXPORT(unsigned short) __stdcall s_tf_H(unsigned short c) { U; return c/3; }
409EXPORT(int) __stdcall s_tf_i(int c) { S; return c/3; }
410EXPORT(unsigned int) __stdcall s_tf_I(unsigned int c) { U; return c/3; }
411EXPORT(long) __stdcall s_tf_l(long c) { S; return c/3; }
412EXPORT(unsigned long) __stdcall s_tf_L(unsigned long c) { U; return c/3; }
413EXPORT(PY_LONG_LONG) __stdcall s_tf_q(PY_LONG_LONG c) { S; return c/3; }
414EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
415EXPORT(float) __stdcall s_tf_f(float c) { S; return c/3; }
416EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; }
417#endif
418/*******/
419
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000420EXPORT(signed char) tf_bb(signed char x, signed char c) { S; return c/3; }
421EXPORT(unsigned char) tf_bB(signed char x, unsigned char c) { U; return c/3; }
422EXPORT(short) tf_bh(signed char x, short c) { S; return c/3; }
423EXPORT(unsigned short) tf_bH(signed char x, unsigned short c) { U; return c/3; }
424EXPORT(int) tf_bi(signed char x, int c) { S; return c/3; }
425EXPORT(unsigned int) tf_bI(signed char x, unsigned int c) { U; return c/3; }
426EXPORT(long) tf_bl(signed char x, long c) { S; return c/3; }
427EXPORT(unsigned long) tf_bL(signed char x, unsigned long c) { U; return c/3; }
428EXPORT(PY_LONG_LONG) tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
429EXPORT(unsigned PY_LONG_LONG) tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
430EXPORT(float) tf_bf(signed char x, float c) { S; return c/3; }
431EXPORT(double) tf_bd(signed char x, double c) { S; return c/3; }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000432EXPORT(void) tv_i(int c) { S; return; }
433
434#ifdef MS_WIN32
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000435EXPORT(signed char) __stdcall s_tf_bb(signed char x, signed char c) { S; return c/3; }
436EXPORT(unsigned char) __stdcall s_tf_bB(signed char x, unsigned char c) { U; return c/3; }
437EXPORT(short) __stdcall s_tf_bh(signed char x, short c) { S; return c/3; }
438EXPORT(unsigned short) __stdcall s_tf_bH(signed char x, unsigned short c) { U; return c/3; }
439EXPORT(int) __stdcall s_tf_bi(signed char x, int c) { S; return c/3; }
440EXPORT(unsigned int) __stdcall s_tf_bI(signed char x, unsigned int c) { U; return c/3; }
441EXPORT(long) __stdcall s_tf_bl(signed char x, long c) { S; return c/3; }
442EXPORT(unsigned long) __stdcall s_tf_bL(signed char x, unsigned long c) { U; return c/3; }
443EXPORT(PY_LONG_LONG) __stdcall s_tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
444EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
445EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; }
446EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000447EXPORT(void) __stdcall s_tv_i(int c) { S; return; }
448#endif
449
450/********/
451
452#ifndef MS_WIN32
453
454typedef struct {
455 long x;
456 long y;
457} POINT;
458
459typedef struct {
460 long left;
461 long top;
462 long right;
463 long bottom;
464} RECT;
465
466#endif
467
468EXPORT(int) PointInRect(RECT *prc, POINT pt)
469{
470 if (pt.x < prc->left)
471 return 0;
472 if (pt.x > prc->right)
473 return 0;
474 if (pt.y < prc->top)
475 return 0;
476 if (pt.y > prc->bottom)
477 return 0;
478 return 1;
479}
480
481typedef struct {
482 short x;
483 short y;
484} S2H;
485
486EXPORT(S2H) ret_2h_func(S2H inp)
487{
488 inp.x *= 2;
489 inp.y *= 3;
490 return inp;
491}
492
493typedef struct {
494 int a, b, c, d, e, f, g, h;
495} S8I;
496
497EXPORT(S8I) ret_8i_func(S8I inp)
498{
499 inp.a *= 2;
500 inp.b *= 3;
501 inp.c *= 4;
502 inp.d *= 5;
503 inp.e *= 6;
504 inp.f *= 7;
505 inp.g *= 8;
506 inp.h *= 9;
507 return inp;
508}
509
510EXPORT(int) GetRectangle(int flag, RECT *prect)
511{
512 if (flag == 0)
513 return 0;
514 prect->left = (int)flag;
515 prect->top = (int)flag + 1;
516 prect->right = (int)flag + 2;
517 prect->bottom = (int)flag + 3;
518 return 1;
519}
520
521EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj)
522{
523 *pi += a;
524 *pj += b;
525}
526
527#ifdef MS_WIN32
528EXPORT(S2H) __stdcall s_ret_2h_func(S2H inp) { return ret_2h_func(inp); }
529EXPORT(S8I) __stdcall s_ret_8i_func(S8I inp) { return ret_8i_func(inp); }
530#endif
531
532#ifdef MS_WIN32
533/* Should port this */
534#include <stdlib.h>
535#include <search.h>
536
537EXPORT (HRESULT) KeepObject(IUnknown *punk)
538{
539 static IUnknown *pobj;
540 if (punk)
541 punk->lpVtbl->AddRef(punk);
542 if (pobj)
543 pobj->lpVtbl->Release(pobj);
544 pobj = punk;
545 return S_OK;
546}
547
548#endif
549
550DL_EXPORT(void)
551init_ctypes_test(void)
552{
553 Py_InitModule("_ctypes_test", module_methods);
554}