3275bb1f5274d2263b2d4d7dfa26a7cfb44fff38
[bpt/coccinelle.git] / bundles / pycaml / chemoelectric-pycaml-8614105 / pycaml_stubs.c
1 /*
2 * (C) arty 2002
3
4 This library is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2.1 of the
7 License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 USA
18
19
20 Heavy modifications (Bugfixes!) done by T.F.
21
22 See
23
24 http://mail.python.org/pipermail/doc-sig/2001-July/001956.html
25
26 for a discussion of result value stealing and a list of functions where
27 this becomes relevant.
28
29 Further modifications by Barry Schwartz.
30
31 */
32
33 #include <Python.h>
34 #include <caml/mlvalues.h>
35 #include <caml/memory.h>
36 #include <caml/fail.h>
37 #include <caml/callback.h>
38 #include <caml/custom.h>
39 #include <caml/alloc.h>
40 #include <unistd.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include "pycaml_stubs.h"
44
45 #if 3 <= PY_MAJOR_VERSION
46 #include <wchar.h>
47 #if 4 <= PY_MAJOR_VERSION || (PY_MAJOR_VERSION == 3 && 1 <= PY_MINOR_VERSION)
48 #define USE_PYCAPSULE 1
49 #else
50 #define USE_PYCAPSULE 0
51 #endif
52 #endif
53
54
55 static void *xmalloc(size_t size)
56 {
57 void *p = malloc(size);
58 if (p == NULL) {
59 fprintf(stderr, "Virtual memory exhausted\n");
60 exit(1);
61 }
62 return p;
63 }
64
65 #if 3 <= PY_MAJOR_VERSION
66
67 static wchar_t *copy_to_wide_string(const char *s)
68 {
69 size_t n;
70 wchar_t *ws;
71
72 ws = NULL;
73 n = mbstowcs(NULL, s, 0) + 1;
74 if (n != (size_t) -1) {
75 ws = xmalloc(n * sizeof (wchar_t));
76 mbstowcs(ws, s, n);
77 }
78 return ws;
79 }
80
81 static size_t multibyte_strlen(const wchar_t *ws)
82 {
83 char buffer[MB_CUR_MAX];
84 int i;
85 size_t size;
86 size_t n;
87 mbstate_t ps;
88
89 n = wcrtomb(NULL, L'\0', &ps); /* Initialize the parse state. */
90 size = 0;
91 i = 0;
92 while (size != (size_t) -1 && ws[i] != L'\0') {
93 n = wcrtomb(buffer, ws[i], &ps);
94 if (n != (size_t) -1)
95 size += n;
96 else
97 size = (size_t) -1;
98 i++;
99 }
100 return size;
101 }
102
103 static char *copy_from_wide_string(const wchar_t *ws)
104 {
105 char *s;
106 int i;
107 int j;
108 size_t size;
109 size_t n;
110 mbstate_t ps;
111
112 s = NULL;
113 size = multibyte_strlen(ws);
114 if (size != (size_t) -1) {
115 s = xmalloc((size + 1) * sizeof (char));
116 n = wcrtomb(NULL, L'\0', &ps); /* Initialize the parse state. */
117 j = 0;
118 i = 0;
119 while (ws[i] != L'\0') {
120 n = wcrtomb(s + j, ws[i], &ps);
121 j += n;
122 i++;
123 }
124 s[j] = '\0';
125 }
126 return s;
127 }
128
129 #endif /* 3 <= PY_MAJOR_VERSION */
130
131 static void *getcustom( value v )
132 {
133 return *((void **)Data_custom_val(v));
134 }
135
136 static void pydecref( value v )
137 {
138 if( getcustom(v) ) {
139 /* printf("GC - pydecref obj 0x%08x to refcount=%d\nOBJ=",getcustom(v),((PyObject *)getcustom(v))->ob_refcnt-1);
140 PyObject_Print((PyObject *)getcustom(v),stdout,0);
141 printf("END OBJ\n");
142 fflush(stdout);
143 */
144 Py_DECREF((PyObject *)getcustom(v));
145 }
146 }
147
148 #if PY_MAJOR_VERSION <= 2
149
150 static int pycompare( value v1, value v2 )
151 {
152 int result;
153
154 if (getcustom(v1) && !getcustom(v2))
155 result = -1;
156 else if (getcustom(v2) && !getcustom(v1))
157 result = 1;
158 else if (!getcustom(v1) && !getcustom(v2))
159 result = 0;
160 else
161 PyObject_Cmp((PyObject *)getcustom(v1),
162 (PyObject *)getcustom(v2), &result);
163 return result;
164 }
165
166 #else /* PY_MAJOR_VERSION <= 2 */
167
168 static int pycompare(value v1, value v2)
169 {
170 int result;
171
172 if (getcustom(v1) && !getcustom(v2))
173 result = -1;
174 else if (getcustom(v2) && !getcustom(v1))
175 result = 1;
176 else if (!getcustom(v1) && !getcustom(v2))
177 result = 0;
178 else if (1 == PyObject_RichCompareBool((PyObject *) getcustom(v1),
179 (PyObject *) getcustom(v2), Py_EQ))
180 result = 0;
181 else if (1 == PyObject_RichCompareBool((PyObject *) getcustom(v1),
182 (PyObject *) getcustom(v2), Py_LT))
183 result = -1;
184 else if (1 == PyObject_RichCompareBool((PyObject *) getcustom(v1),
185 (PyObject *) getcustom(v2), Py_GT))
186 result = 1;
187 else
188 result = -1; /* Is there a better value to put here? */
189
190 return result;
191 }
192
193 #endif /* PY_MAJOR_VERSION <= 2 */
194
195 static long pyhash( value v )
196 {
197 if (getcustom(v))
198 return PyObject_Hash((PyObject *)getcustom(v));
199 else
200 return 0L;
201 }
202
203 static unsigned long pydeserialize( void *dst )
204 {
205 return 0L;
206 }
207
208 struct custom_operations pyops =
209 {
210 "PythonObject",
211 pydecref,
212 pycompare,
213 pyhash,
214 custom_serialize_default,
215 pydeserialize
216 };
217
218 struct custom_operations fnops =
219 {
220 "FuncPointer",
221 NULL,
222 NULL,
223 NULL,
224 NULL,
225 NULL
226 };
227
228 static value pywrap(PyObject *obj)
229 {
230 CAMLparam0();
231 CAMLlocal1(v);
232
233 if (obj != NULL)
234 Py_INCREF(obj);
235
236 v = caml_alloc_custom( &pyops, sizeof( PyObject * ), 100, 30000000 );
237 *((PyObject **)Data_custom_val(v)) = obj;
238 CAMLreturn(v);
239 }
240
241 /* T.F.: we may want to pywrap in such a way that we steal the reference: */
242 static value pywrap_steal( PyObject *obj )
243 {
244 CAMLparam0();
245 CAMLlocal1(v);
246
247 v = caml_alloc_custom( &pyops, sizeof( PyObject * ), 100, 30000000 );
248 *((PyObject **)Data_custom_val(v)) = obj;
249 CAMLreturn(v);
250 }
251
252 static PyObject *
253 pyunwrap( value v )
254 {
255 return *((PyObject **)Data_custom_val(v));
256 }
257
258 #if USE_PYCAPSULE
259
260 static void
261 caml_destructor(PyObject *v, const char *capsule_name)
262 {
263 value *valptr = (value *) PyCapsule_GetPointer(v, capsule_name);
264 caml_remove_global_root(valptr);
265 free(valptr);
266 }
267
268 static void
269 camldestr(PyObject *v)
270 {
271 caml_destructor(v, "caml-other");
272 }
273
274 static void
275 camldestr_pill(PyObject *v)
276 {
277 caml_destructor(v, "caml-pill");
278 }
279
280 #else /* USE_PYCAPSULE */
281
282 static void
283 camldestr(void *v)
284 {
285 value *valptr = (value *) v;
286 /* printf("DDD camlwrap remove_global_root(0x%08x)\n",valptr);fflush(stdout); */
287 caml_remove_global_root(valptr);
288 free(v);
289 }
290
291 static void
292 camldestr_pill(void *v, void *unused_dummy_receiving_ocamlpill_token)
293 {
294 value *valptr = (value *) v;
295 /* printf("DDD camlwrap remove_global_root(0x%08x)\n",valptr);fflush(stdout); */
296 caml_remove_global_root(valptr);
297 free(v);
298 }
299
300 #endif /* USE_PYCAPSULE */
301
302 /* T.F. Extension: the pill token is a subtle hack:
303
304 One problem is that, as it seems, there are
305 some python objects around which would be regarded as
306 being of OtherType in original PyCaml.
307
308 As these are opaque, we do not really have a good way
309 to discern them from OCaml pills, and passing such an
310 opaque value (which cannot be investigated systematically)
311 where an ocaml pill is expected is bound to result
312 in crashes (which we want to avoid).
313
314 How to get rid of this? We somehow have to be able to properly
315 identify OCaml Pills and extend the python types with CamlType.
316
317 We do this by using the PyCObject_Check to determine c-object type,
318 and abuse the closure parameter that is passed on to the destructor
319 (which can be queried independently, and actually is not used by our
320 destructor) as a token designating OCaml pills.
321
322 Barry Schwartz: PyCapsule has a name field that can be used for
323 identification, in place of the PyCObject hack described above.
324
325 */
326 #if !USE_PYCAPSULE
327 static const char *ocamlpill_token = "CAML";
328 #endif
329
330 static PyObject *
331 camlwrap(value val, void *aux_str, int size)
332 {
333 value *v = (value *) xmalloc(sizeof(value) + size);
334 *v = val;
335 memcpy((void *)v + sizeof(value), aux_str, size);
336 caml_register_global_root(v);
337 /* printf("DDD camlwrap caml_register_global_root(0x%08x)\n",v);fflush(stdout); */
338 #if USE_PYCAPSULE
339 return PyCapsule_New(v, "caml-other", camldestr);
340 #else
341 return PyCObject_FromVoidPtr(v, camldestr);
342 #endif
343 }
344
345 static PyObject *
346 camlwrap_pill(value val, void *aux_str, int size)
347 {
348 value *v = (value *) xmalloc(sizeof(value) + size);
349 *v = val;
350 memcpy((void *)v + sizeof(value), aux_str, size);
351 caml_register_global_root(v);
352 #if USE_PYCAPSULE
353 return PyCapsule_New(v, "caml-pill", camldestr_pill);
354 #else
355 return PyCObject_FromVoidPtrAndDesc(v, (void*)ocamlpill_token, camldestr_pill);
356 #endif
357 }
358
359
360 static void *
361 caml_aux(PyObject *obj)
362 {
363 #if USE_PYCAPSULE
364 value *v = (value *) PyCapsule_GetPointer(obj, "caml-other");
365 #else
366 value *v = (value *) PyCObject_AsVoidPtr(obj);
367 #endif
368 return (void *) v + sizeof(value);
369 }
370
371 /*
372 PyObject *pycall_callback_buggy( PyObject *obj, PyObject *args ) {
373 value out;
374 value *v;
375
376 if( !PyCObject_Check(obj) ) {
377 Py_INCREF(Py_None);
378 return Py_None;
379 }
380 v = (value *)PyCObject_AsVoidPtr( obj );
381 out = caml_callback(*v,pywrap(args));
382 return pyunwrap(out);
383 }
384 */
385
386 /* T.F.: - I think the definition above is flawed...
387 Looking at the definitions of OCAML macros in memory.h,
388 this is how I suppose it should work:
389 */
390
391 PyObject *pycall_callback( PyObject *obj, PyObject *args )
392 {
393 CAMLparam0();
394 CAMLlocal3(ml_out, ml_func, ml_args);
395 PyObject *out;
396
397 #if USE_PYCAPSULE
398 void *p = PyCapsule_GetPointer(obj, "caml-other");
399 if (p == NULL)
400 {
401 Py_INCREF(Py_None);
402 return Py_None;
403 }
404 ml_func = * (value *) p;
405 #else
406 if (!PyCObject_Check(obj))
407 {
408 Py_INCREF(Py_None);
409 return Py_None;
410 }
411
412 ml_func = * (value *) PyCObject_AsVoidPtr(obj);
413 #endif
414 ml_args = pywrap(args);
415 ml_out = caml_callback(ml_func, ml_args);
416 out = pyunwrap(ml_out);
417 /* T.F.:
418 The result which we have now is borrowed - most probably,
419 there is only one reference to it which says
420 "I am reachable through the ML heap".
421 We have to properly transfer ownership, and hence
422 see that we own that reference:
423 */
424 Py_XINCREF(out);
425 CAMLreturnT(PyObject *, out);
426 }
427
428 /*-----------------------------------------------------------------------*/
429
430 static FILE *make_FILE(int fd_int)
431 {
432 int fd_duplicate;
433
434 fd_duplicate = dup(fd_int);
435 return fdopen(fd_duplicate, "r+");
436 }
437
438 /*-----------------------------------------------------------------------*/
439
440 value pynull(value unit)
441 {
442 CAMLparam1(unit);
443 CAMLreturn(pywrap(0));
444 }
445
446 value pynone(value unit)
447 {
448 CAMLparam1(unit);
449 CAMLreturn(pywrap(Py_None));
450 }
451
452 value py_true(value unit)
453 {
454 CAMLparam1(unit);
455 CAMLreturn(pywrap(Py_True));
456 }
457
458 value py_false(value unit)
459 {
460 CAMLparam1(unit);
461 CAMLreturn(pywrap(Py_False));
462 }
463
464 /*-----------------------------------------------------------------------*/
465
466 #define Type1(func) \
467 CAMLprim value func##_wrapper(value unit) \
468 { \
469 CAMLparam1(unit); \
470 func(); \
471 CAMLreturn(Val_unit); \
472 }
473
474 Type1(Py_Initialize)
475 Type1(Py_Finalize)
476 Type1(PyErr_Print)
477 Type1(PyErr_Clear)
478 Type1(PyImport_Cleanup)
479
480 /*-----------------------------------------------------------------------*/
481
482 #define Type2(func) \
483 CAMLprim value func##_wrapper(value obj) \
484 { \
485 CAMLparam1(obj); \
486 \
487 func(Int_val(obj)); \
488 CAMLreturn(Val_unit); \
489 }
490
491 Type2(Py_Exit)
492 Type2(PyErr_PrintEx)
493
494 /*-----------------------------------------------------------------------*/
495
496 #if PY_MAJOR_VERSION <= 2
497
498 #define Type3(func) \
499 CAMLprim value func##_wrapper(value obj) \
500 { \
501 CAMLparam1(obj); \
502 \
503 func(String_val(obj)); \
504 CAMLreturn(Val_unit); \
505 }
506
507 #else
508
509 #define Type3(func) \
510 CAMLprim value func##_wrapper(value obj) \
511 { \
512 CAMLparam1(obj); \
513 \
514 char *s = String_val(obj); \
515 wchar_t *ws = copy_to_wide_string(s); \
516 func(ws); \
517 free(ws); \
518 CAMLreturn(Val_unit); \
519 }
520
521 #endif
522
523 Type3(Py_SetProgramName)
524 Type3(Py_SetPythonHome)
525
526 /*-----------------------------------------------------------------------*/
527
528 #define Type4(func) \
529 CAMLprim value func##_wrapper(value unit) \
530 { \
531 CAMLparam1(unit); \
532 \
533 int result = func(); \
534 CAMLreturn(Val_int(result)); \
535 }
536
537 Type4(Py_IsInitialized)
538
539 #if PY_MAJOR_VERSION <= 2
540 Type4(PyEval_GetRestricted)
541 #endif
542
543 /*-----------------------------------------------------------------------*/
544
545 #define Type5(func) \
546 CAMLprim value func##_wrapper(value obj) \
547 { \
548 CAMLparam1(obj); \
549 \
550 int result = func(String_val(obj)); \
551 CAMLreturn(Val_int(result)); \
552 }
553
554 Type5(PyRun_SimpleString)
555 Type5(PyImport_ImportFrozenModule)
556
557 /*-----------------------------------------------------------------------*/
558
559 /* Perhaps these should take a wrapped (FILE*) as argument instead of
560 * an integer file descriptor. */
561
562 #define Type6(func) \
563 CAMLprim value func##_wrapper(value py_args) \
564 { \
565 CAMLparam1(py_args); \
566 \
567 FILE *f = make_FILE(Int_val(Field(py_args, 0))); \
568 int result = func(f, String_val(Field(py_args, 1))); \
569 fclose(f); \
570 CAMLreturn(Val_int(result)); \
571 }
572
573 Type6(PyRun_AnyFile)
574 Type6(PyRun_SimpleFile)
575 Type6(PyRun_InteractiveOne)
576 Type6(PyRun_InteractiveLoop)
577 Type6(Py_FdIsInteractive)
578
579 /*-----------------------------------------------------------------------*/
580
581 /* Perhaps these should take a wrapped (FILE*) as argument instead of
582 * an integer file descriptor. */
583
584 #define Type7(func) \
585 CAMLprim value func##_wrapper(value py_args) \
586 { \
587 CAMLparam1(py_args); \
588 \
589 FILE *f = make_FILE(Int_val(Field(py_args, 0))); \
590 int result = func(f, \
591 String_val(Field(py_args, 1)), \
592 Int_val(Field(py_args, 2))); \
593 fclose(f); \
594 CAMLreturn(Val_int(result)); \
595 }
596
597 Type7(PyRun_AnyFileEx)
598 Type7(PyRun_SimpleFileEx)
599
600 /*-----------------------------------------------------------------------*/
601
602 #define Type8(func) \
603 CAMLprim value func##_wrapper(value unit) \
604 { \
605 CAMLparam1(unit); \
606 CAMLreturn(caml_copy_string(func())); \
607 }
608
609 #if PY_MAJOR_VERSION <= 2
610 #define Type8a Type8
611 #else
612 #define Type8a(func) \
613 CAMLprim value func##_wrapper(value unit) \
614 { \
615 CAMLparam1(unit); \
616 CAMLlocal1(string); \
617 wchar_t *ws; \
618 char *s; \
619 \
620 ws = func(); \
621 if (ws == NULL) \
622 string = pynull(Val_unit); \
623 else \
624 { \
625 s = copy_from_wide_string(ws); \
626 if (s == NULL) \
627 string = pynull(Val_unit); \
628 else \
629 string = caml_copy_string(s); \
630 } \
631 CAMLreturn(string); \
632 }
633 #endif
634
635 Type8(Py_GetVersion)
636 Type8(Py_GetPlatform)
637 Type8(Py_GetCopyright)
638 Type8(Py_GetCompiler)
639 Type8(Py_GetBuildInfo)
640
641 Type8a(Py_GetProgramName)
642 Type8a(Py_GetPythonHome)
643 Type8a(Py_GetProgramFullPath)
644 Type8a(Py_GetPrefix)
645 Type8a(Py_GetExecPrefix)
646 Type8a(Py_GetPath)
647
648 /*-----------------------------------------------------------------------*/
649
650 #define Type9(func, wrap_obj) \
651 CAMLprim value func##_wrapper(value py_args) \
652 { \
653 CAMLparam1(py_args); \
654 \
655 PyObject *new_obj = func(String_val(Field(py_args, 0)), \
656 Int_val(Field(py_args, 1)), \
657 pyunwrap(Field(py_args, 2)), \
658 pyunwrap(Field(py_args, 3))); \
659 CAMLreturn(wrap_obj(new_obj)); \
660 }
661
662 Type9(PyRun_String, pywrap_steal)
663
664 /*-----------------------------------------------------------------------*/
665
666 /* Perhaps these should take a wrapped (FILE*) as argument instead of
667 * an integer file descriptor. */
668
669 #define Type10(func, wrap_obj) \
670 CAMLprim value func##_wrapper(value py_args) \
671 { \
672 CAMLparam1(py_args); \
673 \
674 FILE *f = make_FILE(Int_val(Field(py_args, 0))); \
675 PyObject *new_obj = func(f, \
676 String_val(Field(py_args, 1)), \
677 Int_val(Field(py_args, 2)), \
678 pyunwrap(Field(py_args, 3)), \
679 pyunwrap(Field(py_args, 4))); \
680 fclose(f); \
681 CAMLreturn(wrap_obj(new_obj)); \
682 }
683
684 Type10(PyRun_File, pywrap_steal)
685
686 /*-----------------------------------------------------------------------*/
687
688 /* Perhaps these should take a wrapped (FILE*) as argument instead of
689 * an integer file descriptor. */
690
691 #define Type11(func, wrap_obj) \
692 CAMLprim value func##_wrapper(value py_args) \
693 { \
694 CAMLparam1(py_args); \
695 \
696 FILE *f = make_FILE(Int_val(Field(py_args, 0))); \
697 PyObject *new_obj = func(f, \
698 String_val(Field(py_args, 1)), \
699 Int_val(Field(py_args, 2)), \
700 pyunwrap(Field(py_args, 3)), \
701 pyunwrap(Field(py_args, 4)), \
702 Int_val(Field(py_args, 5))); \
703 fclose(f); \
704 CAMLreturn(wrap_obj(new_obj)); \
705 }
706
707 Type11(PyRun_FileEx, pywrap_steal)
708
709 /*-----------------------------------------------------------------------*/
710
711 #define Type12(func, wrap_obj) \
712 CAMLprim value func##_wrapper(value py_args) \
713 { \
714 CAMLparam1(py_args); \
715 \
716 PyObject *new_obj = func(String_val(Field(py_args, 0)), \
717 String_val(Field(py_args, 1)), \
718 Int_val(Field(py_args, 2))); \
719 CAMLreturn(wrap_obj(new_obj)); \
720 }
721
722 Type12(Py_CompileString, pywrap_steal)
723
724 /*-----------------------------------------------------------------------*/
725
726 /* Perhaps these should take a wrapped (FILE*) as argument instead of
727 * an integer file descriptor. */
728
729 #define Type13(func) \
730 CAMLprim value func##_wrapper(value py_args) \
731 { \
732 CAMLparam1(py_args); \
733 \
734 FILE *f = make_FILE(Int_val(Field(py_args, 1))); \
735 int result = func(pyunwrap(Field(py_args, 0)), \
736 f, \
737 Int_val(Field(py_args, 2))); \
738 fclose(f); \
739 CAMLreturn(Val_int(result)); \
740 }
741
742 Type13(PyObject_Print)
743
744 /*-----------------------------------------------------------------------*/
745
746 #define Type_GetSlice(func, wrap_obj) \
747 CAMLprim value func##_wrapper(value py_args) \
748 { \
749 CAMLparam1(py_args); \
750 \
751 PyObject *new_obj = func(pyunwrap(Field(py_args, 0)), \
752 Int_val(Field(py_args, 1)), \
753 Int_val(Field(py_args, 2))); \
754 CAMLreturn(wrap_obj(new_obj)); \
755 }
756
757 Type_GetSlice(PySequence_GetSlice, pywrap_steal)
758 Type_GetSlice(PyTuple_GetSlice, pywrap_steal)
759
760 /*-----------------------------------------------------------------------*/
761
762 #define Type14(func, wrap_obj) \
763 CAMLprim value func##_wrapper(value obj) \
764 { \
765 CAMLparam1(obj); \
766 \
767 PyObject *new_obj = func(pyunwrap(obj)); \
768 CAMLreturn(wrap_obj(new_obj)); \
769 }
770
771 #if PY_MAJOR_VERSION <= 2
772 #define Type14a(func, substitute, wrap_obj) Type14(func, wrap_obj)
773 #else
774 #define Type14a(func, substitute, wrap_obj) \
775 CAMLprim value func##_wrapper(value obj) \
776 { \
777 CAMLparam1(obj); \
778 \
779 PyObject *new_obj = substitute(pyunwrap(obj)); \
780 CAMLreturn(wrap_obj(new_obj)); \
781 }
782 #endif
783
784 Type14(PyMethod_Function, pywrap)
785 Type14(PyMethod_Self, pywrap)
786 Type14(PyModule_GetDict, pywrap)
787
788 #if PY_MAJOR_VERSION <= 2
789 Type14(PyMethod_Class, pywrap)
790 #endif
791
792 Type14(PyUnicode_AsUTF8String, pywrap_steal)
793 Type14(PyUnicode_AsUTF16String, pywrap_steal)
794 Type14(PyUnicode_AsUTF32String, pywrap_steal)
795 Type14(PyObject_Repr, pywrap_steal)
796 Type14(PyImport_ReloadModule, pywrap_steal)
797 Type14(PyImport_Import, pywrap_steal)
798 Type14(PyObject_Str, pywrap_steal)
799 Type14(PyObject_Type, pywrap_steal)
800 Type14(PyDict_Keys, pywrap_steal)
801 Type14(PyDict_Values, pywrap_steal)
802 Type14(PyDict_Items, pywrap_steal)
803 Type14(PyDict_Copy, pywrap_steal)
804 Type14(PySequence_Tuple, pywrap_steal)
805 Type14(PySequence_List, pywrap_steal)
806 Type14(PyNumber_Long, pywrap_steal)
807 Type14(PyNumber_Float, pywrap_steal)
808 Type14(PyNumber_Negative, pywrap_steal)
809 Type14(PyNumber_Positive, pywrap_steal)
810 Type14(PyNumber_Absolute, pywrap_steal)
811 Type14(PyNumber_Invert, pywrap_steal)
812 Type14(PyIter_Next, pywrap_steal)
813
814 Type14a(PyObject_Unicode, PyObject_Str, pywrap_steal)
815 Type14a(PyNumber_Int, PyNumber_Long, pywrap_steal)
816
817 /*-----------------------------------------------------------------------*/
818
819 #define Type15(func, wrap_obj) \
820 CAMLprim value func##_wrapper(value py_args) \
821 { \
822 CAMLparam1(py_args); \
823 \
824 PyObject *new_obj = func(pyunwrap(Field(py_args, 0)), \
825 pyunwrap(Field(py_args, 1)), \
826 Int_val(Field(py_args, 2))); \
827 CAMLreturn(wrap_obj(new_obj)); \
828 }
829
830 Type15(PyObject_RichCompare, pywrap_steal);
831
832 /*-----------------------------------------------------------------------*/
833
834 #define Type16(func, wrap_obj) \
835 CAMLprim value func##_wrapper(value py_args) \
836 { \
837 CAMLparam1(py_args); \
838 \
839 PyObject *new_obj = func(pyunwrap(Field(py_args, 0)), \
840 String_val(Field(py_args, 1))); \
841 CAMLreturn(wrap_obj(new_obj)); \
842 }
843
844 Type16(PyDict_GetItemString, pywrap)
845
846 Type16(PyObject_GetAttrString, pywrap_steal)
847 Type16(PySequence_Fast, pywrap_steal)
848 Type16(PyMapping_GetItemString, pywrap_steal)
849
850 /*-----------------------------------------------------------------------*/
851
852 #define Type17(func, wrap_obj) \
853 CAMLprim value func##_wrapper(value py_args) \
854 { \
855 CAMLparam1(py_args); \
856 \
857 PyObject *new_obj = func(pyunwrap(Field(py_args, 0)), \
858 pyunwrap(Field(py_args, 1))); \
859 CAMLreturn(wrap_obj(new_obj)); \
860 }
861
862 Type17(PyDict_GetItem, pywrap)
863
864 Type17(PyEval_CallObject, pywrap_steal)
865
866 #if PY_MAJOR_VERSION <= 2
867 Type17(PyBytes_Format, pywrap_steal)
868 #endif
869
870 #if PY_MAJOR_VERSION <= 2
871 Type17(PyInstance_NewRaw, pywrap_steal)
872 #endif
873
874 Type17(PySequence_Concat, pywrap_steal)
875 Type17(PySequence_InPlaceConcat, pywrap_steal)
876
877 Type17(PyObject_GetAttr, pywrap_steal)
878 Type17(PyObject_GetItem, pywrap_steal)
879
880 Type17(PyNumber_Add, pywrap_steal)
881 Type17(PyNumber_Subtract, pywrap_steal)
882 Type17(PyNumber_Multiply, pywrap_steal)
883 Type17(PyNumber_Remainder, pywrap_steal)
884 Type17(PyNumber_Divmod, pywrap_steal)
885 Type17(PyNumber_TrueDivide, pywrap_steal)
886 Type17(PyNumber_FloorDivide, pywrap_steal)
887
888 #if PY_MAJOR_VERSION <= 2
889 Type17(PyNumber_Divide, pywrap_steal)
890 #endif
891
892 Type17(PyNumber_Lshift, pywrap_steal)
893 Type17(PyNumber_Rshift, pywrap_steal)
894 Type17(PyNumber_And, pywrap_steal)
895 Type17(PyNumber_Xor, pywrap_steal)
896 Type17(PyNumber_Or, pywrap_steal)
897
898 Type17(PyNumber_InPlaceAdd, pywrap_steal)
899 Type17(PyNumber_InPlaceSubtract, pywrap_steal)
900 Type17(PyNumber_InPlaceMultiply, pywrap_steal)
901 Type17(PyNumber_InPlaceTrueDivide, pywrap_steal)
902 Type17(PyNumber_InPlaceFloorDivide, pywrap_steal)
903 Type17(PyNumber_InPlaceRemainder, pywrap_steal)
904 Type17(PyNumber_InPlaceLshift, pywrap_steal)
905 Type17(PyNumber_InPlaceRshift, pywrap_steal)
906 Type17(PyNumber_InPlaceAnd, pywrap_steal)
907 Type17(PyNumber_InPlaceXor, pywrap_steal)
908 Type17(PyNumber_InPlaceOr, pywrap_steal)
909
910 #if PY_MAJOR_VERSION <= 2
911 Type17(PyNumber_InPlaceDivide, pywrap_steal)
912 #endif
913
914 /*-----------------------------------------------------------------------*/
915
916 #define Type18(func) \
917 CAMLprim value func##_wrapper(value obj) \
918 { \
919 CAMLparam1(obj); \
920 \
921 int result = func(pyunwrap(obj)); \
922 CAMLreturn(Val_int(result)); \
923 }
924
925 Type18(PyObject_IsTrue)
926 Type18(PyObject_Not)
927 Type18(PyCallable_Check)
928 Type18(PyBytes_Size)
929 Type18(PyDict_Size)
930 Type18(PyTuple_Size)
931 Type18(PyErr_ExceptionMatches)
932 Type18(PyObject_Size)
933 Type18(PyNumber_Check)
934 Type18(PySequence_Check)
935 Type18(PySequence_Size)
936 Type18(PySequence_Length)
937 Type18(PyMapping_Check)
938 Type18(PyMapping_Size)
939 Type18(PyMapping_Length)
940 Type18(PyIter_Check)
941 Type18(PyUnicode_GetSize)
942
943 /*-----------------------------------------------------------------------*/
944
945 #define Type19(func) \
946 CAMLprim value func##_wrapper(value py_args) \
947 { \
948 CAMLparam1(py_args); \
949 \
950 int result = func(pyunwrap(Field(py_args, 0)), \
951 pyunwrap(Field(py_args, 1))); \
952 CAMLreturn(Val_int(result)); \
953 }
954
955 Type19(PyObject_HasAttr)
956 Type19(PyObject_DelItem)
957 Type19(PyDict_DelItem)
958 Type19(PyErr_GivenExceptionMatches)
959 Type19(PySequence_Count)
960 Type19(PySequence_Contains)
961 Type19(PySequence_In)
962 Type19(PySequence_Index)
963 Type19(PyMapping_HasKey)
964
965 #if PY_MAJOR_VERSION <= 2
966 Type19(PyObject_Compare)
967 #endif
968
969 /*-----------------------------------------------------------------------*/
970
971 #define Type20(func) \
972 CAMLprim value func##_wrapper(value py_args) \
973 { \
974 CAMLparam1(py_args); \
975 \
976 int result = func(pyunwrap(Field(py_args, 0)), \
977 pyunwrap(Field(py_args, 1)), \
978 Int_val(Field(py_args, 2))); \
979 CAMLreturn(Val_int(result)); \
980 }
981
982 Type20(PyObject_RichCompareBool)
983
984 /*-----------------------------------------------------------------------*/
985
986 #define Type21(func) \
987 CAMLprim value func##_wrapper(value py_args) \
988 { \
989 CAMLparam1(py_args); \
990 \
991 int result = func(pyunwrap(Field(py_args, 0)), \
992 String_val(Field(py_args, 1)), \
993 pyunwrap(Field(py_args, 2))); \
994 CAMLreturn(Val_int(result)); \
995 }
996
997 Type21(PyObject_SetAttrString)
998 Type21(PyDict_SetItemString)
999 Type21(PyMapping_SetItemString)
1000
1001 /*-----------------------------------------------------------------------*/
1002
1003 #define Type22(func) \
1004 CAMLprim value func##_wrapper(value py_args) \
1005 { \
1006 CAMLparam1(py_args); \
1007 \
1008 int result = func(pyunwrap(Field(py_args, 0)), \
1009 String_val(Field(py_args, 1))); \
1010 CAMLreturn(Val_int(result)); \
1011 }
1012
1013 Type22(PyMapping_HasKeyString)
1014 Type22(PyObject_HasAttrString)
1015 Type22(PyDict_DelItemString)
1016
1017 /*-----------------------------------------------------------------------*/
1018
1019 /*
1020 Type23 not implemented:
1021 PyNumber_Coerce
1022 PyNumber_CoerceEx
1023 */
1024
1025 /*-----------------------------------------------------------------------*/
1026
1027 #define Type24(func) \
1028 CAMLprim value func##_wrapper(value py_args) \
1029 { \
1030 CAMLparam1(py_args); \
1031 \
1032 int result = func(pyunwrap(Field(py_args, 0)), \
1033 pyunwrap(Field(py_args, 1)), \
1034 pyunwrap(Field(py_args, 2))); \
1035 CAMLreturn(Val_int(result)); \
1036 }
1037
1038 Type24(PyObject_SetAttr)
1039 Type24(PyObject_SetItem)
1040 Type24(PyDict_SetItem)
1041
1042 /*-----------------------------------------------------------------------*/
1043
1044 #define Type25(func) \
1045 CAMLprim value func##_wrapper(value obj) \
1046 { \
1047 CAMLparam1(obj); \
1048 CAMLreturn(copy_int64(func(pyunwrap(obj)))); \
1049 }
1050
1051 #if PY_MAJOR_VERSION <= 2
1052 #define Type25a(func, substitute) Type25(func)
1053 #else
1054 #define Type25a(func, substitute) \
1055 CAMLprim value func##_wrapper(value obj) \
1056 { \
1057 CAMLparam1(obj); \
1058 CAMLreturn(copy_int64(substitute(pyunwrap(obj)))); \
1059 }
1060 #endif
1061
1062 Type25(PyObject_Hash)
1063 Type25a(PyInt_AsLong, PyLong_AsLong)
1064
1065 /*-----------------------------------------------------------------------*/
1066
1067 #define Type26(func, byte_type) \
1068 CAMLprim value func##_wrapper(value obj) \
1069 { \
1070 CAMLparam1(obj); \
1071 CAMLlocal1(string); \
1072 \
1073 byte_type *s = func(pyunwrap(obj)); \
1074 if (s == NULL) \
1075 string = pynull(Val_unit); \
1076 else \
1077 string = caml_copy_string(s); \
1078 CAMLreturn(string); \
1079 }
1080
1081 Type26(PyBytes_AsString, char)
1082 Type26(PyModule_GetName, const char)
1083 Type26(PyModule_GetFilename, const char)
1084
1085 /*-----------------------------------------------------------------------*/
1086
1087 #define Type28(func, wrap_obj) \
1088 CAMLprim value func##_wrapper(value obj) \
1089 { \
1090 CAMLparam1(obj); \
1091 \
1092 PyObject *result = func(String_val(obj)); \
1093 CAMLreturn(wrap_obj(result)); \
1094 }
1095
1096 Type28(PyImport_AddModule, pywrap)
1097
1098 Type28(PyBytes_FromString, pywrap_steal)
1099 Type28(PyUnicode_FromString, pywrap_steal)
1100 Type28(PyModule_New, pywrap_steal)
1101 Type28(PyImport_ImportModule, pywrap_steal)
1102
1103 /*-----------------------------------------------------------------------*/
1104
1105 #define Type29(func, wrap_obj) \
1106 CAMLprim value func##_wrapper(value unit) \
1107 { \
1108 CAMLparam1(unit); \
1109 \
1110 PyObject *result = func(); \
1111 CAMLreturn(wrap_obj(result)); \
1112 }
1113
1114 Type29(PyErr_Occurred, pywrap)
1115 Type29(PyImport_GetModuleDict, pywrap)
1116 Type29(PyEval_GetBuiltins, pywrap)
1117 Type29(PyEval_GetGlobals, pywrap)
1118 Type29(PyEval_GetLocals, pywrap)
1119 /* Type29(PyEval_GetFrame, pywrap) -- FIX: Should return wrapped (PyFrameObject*), not wrapped (Object*). */
1120
1121 Type29(PyDict_New, pywrap_steal)
1122
1123 /*-----------------------------------------------------------------------*/
1124
1125 #define Type30(func) \
1126 CAMLprim value func##_wrapper(value obj) \
1127 { \
1128 CAMLparam1(obj); \
1129 \
1130 func(pyunwrap(obj)); \
1131 CAMLreturn(Val_unit); \
1132 }
1133
1134 Type30(PyDict_Clear)
1135 Type30(PyErr_SetNone)
1136
1137 /*-----------------------------------------------------------------------*/
1138
1139 /*
1140 Type31 -- currently not implemented:
1141 PyDict_Next
1142 */
1143
1144 /*-----------------------------------------------------------------------*/
1145
1146 #define Type34(func, wrap_obj) \
1147 CAMLprim value func##_wrapper(value obj) \
1148 { \
1149 CAMLparam1(obj); \
1150 \
1151 PyObject *new_obj = func(Int64_val(obj)); \
1152 CAMLreturn(wrap_obj(new_obj)); \
1153 }
1154
1155 #if PY_MAJOR_VERSION <= 2
1156
1157 #define Type34a(func, substitute, wrap_obj) Type34(func, wrap_obj)
1158
1159 #else
1160
1161 #define Type34a(func, substitute, wrap_obj) \
1162 CAMLprim value func##_wrapper(value obj) \
1163 { \
1164 CAMLparam1(obj); \
1165 \
1166 PyObject *new_obj = substitute(Int64_val(obj)); \
1167 CAMLreturn(wrap_obj(new_obj)); \
1168 }
1169
1170 #endif
1171
1172 Type34a(PyInt_FromLong, PyLong_FromLong, pywrap_steal)
1173
1174 /*-----------------------------------------------------------------------*/
1175
1176 #define Type35(func) \
1177 CAMLprim value func##_wrapper(value unit) \
1178 { \
1179 CAMLparam1(unit); \
1180 CAMLreturn(copy_int64(func())); \
1181 }
1182
1183 #if PY_MAJOR_VERSION <= 2
1184 Type35(PyInt_GetMax)
1185 #endif
1186
1187 Type35(PyImport_GetMagicNumber)
1188
1189 /*-----------------------------------------------------------------------*/
1190
1191 #define Type36(func, wrap_obj) \
1192 CAMLprim value func##_wrapper(value obj) \
1193 { \
1194 CAMLparam1(obj); \
1195 \
1196 PyObject *new_obj = func(Double_val(obj)); \
1197 CAMLreturn(wrap_obj(new_obj)); \
1198 }
1199
1200 Type36(PyFloat_FromDouble, pywrap_steal)
1201
1202 /*-----------------------------------------------------------------------*/
1203
1204 #define Type37(func) \
1205 CAMLprim value func##_wrapper(value obj) \
1206 { \
1207 CAMLparam1(obj); \
1208 CAMLreturn(copy_double(func(pyunwrap(obj)))); \
1209 }
1210
1211 Type37(PyFloat_AsDouble)
1212
1213 /*-----------------------------------------------------------------------*/
1214
1215 #define Type39(func, wrap_obj) \
1216 CAMLprim value func##_wrapper(value obj) \
1217 { \
1218 CAMLparam1(obj); \
1219 \
1220 PyObject *new_obj = func(Int_val(obj)); \
1221 CAMLreturn(wrap_obj(new_obj)); \
1222 }
1223
1224 Type39(PyTuple_New, pywrap_steal);
1225
1226 /*-----------------------------------------------------------------------*/
1227
1228 #define Type40(func, wrap_obj) \
1229 CAMLprim value func##_wrapper(value py_args) \
1230 { \
1231 CAMLparam1(py_args); \
1232 \
1233 PyObject *new_obj = func(pyunwrap(Field(py_args, 0)), \
1234 Int_val(Field(py_args, 1))); \
1235 CAMLreturn(wrap_obj(new_obj)); \
1236 }
1237
1238 Type40(PyTuple_GetItem, pywrap)
1239
1240 Type40(PySequence_InPlaceRepeat, pywrap_steal)
1241 Type40(PySequence_Repeat, pywrap_steal)
1242 Type40(PySequence_GetItem, pywrap_steal)
1243
1244 /*-----------------------------------------------------------------------*/
1245
1246 #define Type40b(func) \
1247 CAMLprim value func##_wrapper(value py_args) \
1248 { \
1249 CAMLparam1(py_args); \
1250 \
1251 int result = func(pyunwrap(Field(py_args, 0)), \
1252 Int_val(Field(py_args, 1))); \
1253 CAMLreturn(Val_int(result)); \
1254 }
1255
1256 Type40b(PySequence_DelItem)
1257
1258 /*-----------------------------------------------------------------------*/
1259
1260 /* |do_steal| here means: "do we steal the arg[2] reference (which is
1261 an OCaml reference)?" If our function is stealing, we first have
1262 to get a reference. */
1263
1264 #define Type41(func, do_steal) \
1265 CAMLprim value func##_wrapper(value py_args) \
1266 { \
1267 CAMLparam1(py_args); \
1268 \
1269 PyObject *x = pyunwrap(Field(py_args, 2)); \
1270 if (do_steal) \
1271 Py_INCREF(x); \
1272 CAMLreturn(Val_int(func(pyunwrap(Field(py_args, 0)), \
1273 Int_val(Field(py_args, 1)), \
1274 x))); \
1275 }
1276
1277
1278 Type41(PySequence_SetItem, 0)
1279
1280 Type41(PyTuple_SetItem, 1)
1281
1282 /*-----------------------------------------------------------------------*/
1283
1284 #define Type42(func, wrap_obj) \
1285 CAMLprim value func##_wrapper(value py_args) \
1286 { \
1287 CAMLparam1(py_args); \
1288 \
1289 PyObject *new_obj = func(pyunwrap(Field(py_args, 0)), \
1290 pyunwrap(Field(py_args, 1)), \
1291 pyunwrap(Field(py_args, 2))); \
1292 CAMLreturn(wrap_obj(new_obj)); \
1293 }
1294
1295 #if PY_MAJOR_VERSION <= 2
1296 #define Type42a Type42
1297 #else
1298 #define Type42a(func, wrap_obj) \
1299 CAMLprim value func##_wrapper(value py_args) \
1300 { \
1301 CAMLparam1(py_args); \
1302 \
1303 PyObject *new_obj = func(pyunwrap(Field(py_args, 0)), \
1304 pyunwrap(Field(py_args, 2))); \
1305 CAMLreturn(wrap_obj(new_obj)); \
1306 }
1307 #endif
1308
1309 Type42(PySlice_New, pywrap_steal)
1310 Type42(PyEval_CallObjectWithKeywords, pywrap_steal)
1311 Type42(PyNumber_Power, pywrap_steal)
1312 Type42(PyNumber_InPlacePower, pywrap_steal)
1313
1314 #if PY_MAJOR_VERSION <= 2
1315 Type42(PyClass_New, pywrap_steal)
1316 Type42(PyInstance_New, pywrap_steal)
1317 #else
1318 /* Calls the builtin-function: type(name,bases,dict), with the
1319 * name of the class, tuples of parent names, and dictionary
1320 * with initializations of fields.
1321 */
1322 CAMLprim value PyClass_New_wrapper(value py_args)
1323 {
1324 CAMLparam1(py_args);
1325 PyObject *bases = pyunwrap(Field(py_args, 0));
1326 PyObject *dict = pyunwrap(Field(py_args, 1));
1327 PyObject *name = pyunwrap(Field(py_args, 2));
1328 PyObject *new_obj =
1329 PyObject_CallFunctionObjArgs
1330 ( (PyObject *) &PyType_Type, name, bases, dict, NULL);
1331 CAMLreturn(pywrap_steal(new_obj));
1332 }
1333 #endif
1334
1335 Type42a(PyMethod_New, pywrap_steal)
1336
1337 /*-----------------------------------------------------------------------*/
1338
1339 /*
1340 Type43(PySlice_GetIndices) <-- Not supported in this version.
1341 */
1342
1343 /*-----------------------------------------------------------------------*/
1344
1345 #define Type45(func) \
1346 CAMLprim value func##_wrapper(value py_args) \
1347 { \
1348 CAMLparam1(py_args); \
1349 \
1350 func(pyunwrap(Field(py_args, 0)), \
1351 pyunwrap(Field(py_args, 1))); \
1352 CAMLreturn(Val_unit); \
1353 }
1354
1355 Type45(PyErr_SetObject)
1356
1357 /*-----------------------------------------------------------------------*/
1358
1359 #define Type46(func) \
1360 CAMLprim value func##_wrapper(value py_args) \
1361 { \
1362 CAMLparam1(py_args); \
1363 \
1364 func(pyunwrap(Field(py_args, 0)), \
1365 String_val(Field(py_args, 1))); \
1366 CAMLreturn(Val_unit); \
1367 }
1368
1369 Type46(PyErr_SetString)
1370
1371 /*-----------------------------------------------------------------------*/
1372
1373 #define Type47(func, wrap_obj) \
1374 CAMLprim value func##_wrapper(value py_args) \
1375 { \
1376 CAMLparam1(py_args); \
1377 CAMLlocal1(result); \
1378 \
1379 PyObject *obj1 = pyunwrap(Field(py_args, 0)); \
1380 PyObject *obj2 = pyunwrap(Field(py_args, 1)); \
1381 PyObject *obj3 = pyunwrap(Field(py_args, 2)); \
1382 func(&obj1, &obj2, &obj3); \
1383 result = caml_alloc_tuple(3); \
1384 Store_field(result, 0, wrap_obj(obj1)); \
1385 Store_field(result, 1, wrap_obj(obj2)); \
1386 Store_field(result, 2, wrap_obj(obj3)); \
1387 CAMLreturn(result); \
1388 }
1389
1390 Type47(PyErr_Fetch, pywrap_steal)
1391 Type47(PyErr_NormalizeException, pywrap_steal)
1392
1393 /*-----------------------------------------------------------------------*/
1394
1395 #define Type48(func) \
1396 CAMLprim value func##_wrapper(value py_args) \
1397 { \
1398 CAMLparam1(py_args); \
1399 \
1400 func(pyunwrap(Field(py_args, 0)), \
1401 pyunwrap(Field(py_args, 1)), \
1402 pyunwrap(Field(py_args, 2))); \
1403 CAMLreturn(Val_unit); \
1404 }
1405
1406 Type48(PyErr_Restore)
1407
1408 /*-----------------------------------------------------------------------*/
1409
1410
1411 #define Type49(func, wrap_obj) \
1412 CAMLprim value func##_wrapper(value py_args) \
1413 { \
1414 CAMLparam1(py_args); \
1415 \
1416 PyObject *result = func(String_val(Field(py_args, 0)), \
1417 pyunwrap(Field(py_args, 1))); \
1418 CAMLreturn(wrap_obj(result)); \
1419 }
1420
1421 Type49(PyImport_ExecCodeModule, pywrap_steal)
1422
1423 /*-----------------------------------------------------------------------*/
1424
1425 #define Type50(func, wrap_obj) \
1426 CAMLprim value func##_wrapper(value py_args) \
1427 { \
1428 CAMLparam1(py_args); \
1429 \
1430 PyObject *result = func(String_val(Field(py_args, 0)), \
1431 pyunwrap(Field(py_args, 1)), \
1432 String_val(Field(py_args, 2))); \
1433 CAMLreturn(wrap_obj(result)); \
1434 }
1435
1436 Type50(PyImport_ExecCodeModuleEx, pywrap_steal)
1437
1438 /*-----------------------------------------------------------------------*/
1439
1440 #define Type51(func, wrap_obj) \
1441 CAMLprim value func##_wrapper(value py_args) \
1442 { \
1443 CAMLparam1(py_args); \
1444 \
1445 PyObject *result = func(String_val(Field(py_args, 0)), \
1446 pyunwrap(Field(py_args, 1)), \
1447 pyunwrap(Field(py_args, 2)), \
1448 pyunwrap(Field(py_args, 3))); \
1449 CAMLreturn(wrap_obj(result)); \
1450 }
1451
1452 Type51(PyImport_ImportModuleEx, pywrap_steal)
1453
1454 /*-----------------------------------------------------------------------*/
1455
1456 #define Type52(func, byte_type) \
1457 CAMLprim value func##_wrapper(value obj) \
1458 { \
1459 CAMLparam1(obj); \
1460 CAMLlocal1(string); \
1461 \
1462 int return_val; \
1463 byte_type *buffer; \
1464 Py_ssize_t length; \
1465 \
1466 return_val = func(pyunwrap(obj), &buffer, &length); \
1467 if (return_val == -1) { \
1468 string = pynull(Val_unit); \
1469 } else { \
1470 string = caml_alloc_string(length); \
1471 memcpy(String_val(string), buffer, length); \
1472 } \
1473 CAMLreturn(string); \
1474 }
1475
1476 Type52(PyBytes_AsStringAndSize, char)
1477 Type52(PyObject_AsCharBuffer, const char)
1478 Type52(PyObject_AsReadBuffer, const void)
1479 Type52(PyObject_AsWriteBuffer, void)
1480
1481 /*-----------------------------------------------------------------------*/
1482
1483 #define Type53(func) \
1484 CAMLprim value func##_wrapper(value py_args) \
1485 { \
1486 CAMLparam1(py_args); \
1487 \
1488 int result = func(pyunwrap(Field(py_args, 0)), \
1489 Int_val(Field(py_args, 1)), \
1490 Int_val(Field(py_args, 2)), \
1491 pyunwrap(Field(py_args, 3))); \
1492 CAMLreturn(Val_int(result)); \
1493 }
1494
1495 Type53(PySequence_SetSlice)
1496
1497 /*-----------------------------------------------------------------------*/
1498
1499 #define Type54(func) \
1500 CAMLprim value func##_wrapper(value py_args) \
1501 { \
1502 CAMLparam1(py_args); \
1503 \
1504 int result = func(pyunwrap(Field(py_args, 0)), \
1505 Int_val(Field(py_args, 1)), \
1506 Int_val(Field(py_args, 2))); \
1507 CAMLreturn(Val_int(result)); \
1508 }
1509
1510 Type54(PySequence_DelSlice)
1511
1512 /*-----------------------------------------------------------------------*/
1513
1514 #define TypeUTF8Decoder(func, wrap_obj) \
1515 CAMLprim value func##_wrapper(value py_args) \
1516 { \
1517 CAMLparam1(py_args); \
1518 \
1519 PyObject *result; \
1520 \
1521 char *utf8 = String_val(Field(py_args, 0)); \
1522 Py_ssize_t utf8_length = caml_string_length(Field(py_args, 0)); \
1523 \
1524 if (Field(py_args, 1) == Val_int(0)) \
1525 result = func(utf8, utf8_length, NULL); \
1526 else \
1527 result = func(utf8, utf8_length, \
1528 String_val(Field(Field(py_args, 1), 0))); \
1529 CAMLreturn(wrap_obj(result)); \
1530 }
1531
1532 TypeUTF8Decoder(PyUnicode_DecodeUTF8, pywrap_steal)
1533
1534 /*-----------------------------------------------------------------------*/
1535
1536 #define TypeUTF16Decoder(func, wrap_obj) \
1537 CAMLprim value func##_wrapper(value py_args) \
1538 { \
1539 CAMLparam1(py_args); \
1540 \
1541 PyObject *result; \
1542 char *errors; \
1543 \
1544 char *s = String_val(Field(py_args, 0)); \
1545 Py_ssize_t s_length = caml_string_length(Field(py_args, 0)); \
1546 \
1547 if (Field(py_args, 1) == Val_int(0)) \
1548 errors = NULL; \
1549 else \
1550 errors = String_val(Field(Field(py_args, 1), 0)); \
1551 \
1552 if (Field(py_args, 2) == Val_int(0)) \
1553 result = func(s, s_length, errors, NULL); \
1554 else { \
1555 int byteorder = Int_val(Field(Field(py_args, 2), 0)); \
1556 result = func(s, s_length, errors, &byteorder); \
1557 } \
1558 \
1559 CAMLreturn(wrap_obj(result)); \
1560 }
1561
1562 TypeUTF16Decoder(PyUnicode_DecodeUTF16, pywrap_steal)
1563 TypeUTF16Decoder(PyUnicode_DecodeUTF32, pywrap_steal)
1564
1565 /*-----------------------------------------------------------------------*/
1566
1567 CAMLprim value PyUnicode_FromUnicode_wrapper(value closure, value length)
1568 {
1569 CAMLparam2(closure, length);
1570 CAMLlocal2(index, val); /* We need named intermediate values for
1571 * garbage collection. */
1572
1573 Py_ssize_t len = Int_val(length);
1574 Py_ssize_t i;
1575 PyObject *result;
1576
1577 result = PyUnicode_FromUnicode(NULL, len);
1578 if (result != NULL) {
1579 Py_UNICODE *p = PyUnicode_AS_UNICODE(result);
1580 for (i = 0; i < len; i++) {
1581 index = Val_int(i);
1582 val = caml_callback(closure, index);
1583 p[i] = Int_val(val) & 0x7FFFFFFF;
1584 }
1585 }
1586
1587 CAMLreturn(pywrap_steal(result));
1588 }
1589
1590 CAMLprim value PyUnicode_AsUnicode_wrapper(value uni)
1591 {
1592 CAMLparam1(uni);
1593 CAMLlocal1(result);
1594
1595 PyObject *py_uni = pyunwrap(uni);
1596 Py_UNICODE *p = PyUnicode_AsUnicode(py_uni);
1597
1598 if (p != NULL) {
1599 Py_ssize_t len = PyUnicode_GET_SIZE(py_uni);
1600 Py_ssize_t i;
1601
1602 result = caml_alloc(len, 0);
1603 for (i = 0; i < len; i++)
1604 Store_field(result, i, Val_int(p[i]));
1605 }
1606
1607 CAMLreturn(result);
1608 }
1609
1610 /*-----------------------------------------------------------------------*/
1611
1612 /* Value -> Pyobject */
1613
1614 value pywrapvalue( value cb ) {
1615 CAMLparam1(cb);
1616 CAMLreturn(pywrap_steal(camlwrap(cb,NULL,0)));
1617 /* T.F.: camlwrap already gives us a reference. We steal that. */
1618 }
1619
1620 /* For pills, we use an extension: */
1621 value pywrapvalue_pill( value cb ) {
1622 CAMLparam1(cb);
1623 CAMLreturn(pywrap_steal(camlwrap_pill(cb,NULL,0)));
1624 }
1625
1626
1627 value pycaml_seterror(value ml_err,value ml_str)
1628 {
1629 CAMLparam2(ml_err,ml_str);
1630 PyObject *err;
1631 int nr_err;
1632
1633 nr_err=Int_val(ml_err);
1634
1635 switch(nr_err) {
1636 case 0:
1637 err=PyExc_Exception;
1638 break;
1639 case 1:
1640 #if PY_MAJOR_VERSION <= 2
1641 err=PyExc_StandardError;
1642 break;
1643 #else
1644 /* PyExc_StandardError is obsolete. Maybe it would be better
1645 * to raise an OCaml exception. */
1646 err=PyExc_Exception;
1647 break;
1648 #endif
1649 case 2:
1650 err=PyExc_ArithmeticError;
1651 break;
1652 case 3:
1653 err=PyExc_LookupError;
1654 break;
1655 case 4:
1656 err=PyExc_AssertionError;
1657 break;
1658 case 5:
1659 err=PyExc_AttributeError;
1660 break;
1661 case 6:
1662 err=PyExc_EOFError;
1663 break;
1664 case 7:
1665 err=PyExc_EnvironmentError;
1666 break;
1667 case 8:
1668 err=PyExc_FloatingPointError;
1669 break;
1670 case 9:
1671 err=PyExc_IOError;
1672 break;
1673 case 10:
1674 err=PyExc_ImportError;
1675 break;
1676 case 11:
1677 err=PyExc_IndexError;
1678 break;
1679 case 12:
1680 err=PyExc_KeyError;
1681 break;
1682 case 13:
1683 err=PyExc_KeyboardInterrupt;
1684 break;
1685 case 14:
1686 err=PyExc_MemoryError;
1687 break;
1688 case 15:
1689 err=PyExc_NameError;
1690 break;
1691 case 16:
1692 err=PyExc_NotImplementedError;
1693 break;
1694 case 17:
1695 err=PyExc_OSError;
1696 break;
1697 case 18:
1698 err=PyExc_OverflowError;
1699 break;
1700 case 19:
1701 err=PyExc_ReferenceError;
1702 break;
1703 case 20:
1704 err=PyExc_RuntimeError;
1705 break;
1706 case 21:
1707 err=PyExc_SyntaxError;
1708 break;
1709 case 22:
1710 err=PyExc_SystemExit;
1711 break;
1712 case 23:
1713 err=PyExc_TypeError;
1714 break;
1715 case 24:
1716 err=PyExc_ValueError;
1717 break;
1718 case 25:
1719 err=PyExc_ZeroDivisionError;
1720 break;
1721 default:
1722 /* Maybe it would be better here to raise an OCaml
1723 * exception. */
1724 #if PY_MAJOR_VERSION <= 2
1725 err=PyExc_StandardError;
1726 #else
1727 err=PyExc_Exception;
1728 #endif
1729 }
1730
1731 PyErr_SetString(err,String_val(ml_str));
1732 CAMLreturn(Val_unit);
1733 }
1734
1735 value pyunwrapvalue(value cb)
1736 {
1737 CAMLparam1(cb);
1738 value *v;
1739 #if USE_PYCAPSULE
1740 v = (value *) PyCapsule_GetPointer(pyunwrap(cb), "caml-pill");
1741 if (v == NULL)
1742 v = (value *) PyCapsule_GetPointer(pyunwrap(cb), "caml-other");
1743 #else
1744 v = (value *) PyCObject_AsVoidPtr(pyunwrap(cb));
1745 #endif
1746 CAMLreturn(*v);
1747 }
1748
1749 /* Create the function table */
1750
1751 typedef struct _python_func_table {
1752 void *func;
1753 int format;
1754 int steal_result;
1755 char *desc;
1756 } python_func_table;
1757
1758 int PyRun_SimpleString_(const char *command)
1759 {
1760 return PyRun_SimpleStringFlags(command, NULL);
1761 }
1762
1763 int PyRun_SimpleFile_(FILE *fp, const char *filename)
1764 {
1765 return PyRun_SimpleFileExFlags(fp, filename, 0, NULL);
1766 }
1767
1768 int PyRun_AnyFile_(FILE *fp, const char *filename)
1769 {
1770 return PyRun_AnyFileExFlags(fp, filename, 0, NULL);
1771 }
1772
1773 int PyRun_InteractiveOne_(FILE *fp, const char *filename)
1774 {
1775 return PyRun_InteractiveOneFlags(fp, filename, NULL);
1776 }
1777
1778 int PyRun_InteractiveLoop_(FILE *fp, const char *filename)
1779 {
1780 return PyRun_InteractiveLoopFlags(fp, filename, NULL);
1781 }
1782
1783 int PyRun_AnyFileEx_(FILE *fp, const char *filename, int closeit)
1784 {
1785 return PyRun_AnyFileExFlags(fp, filename, closeit, NULL);
1786 }
1787
1788 int PyRun_SimpleFileEx_(FILE *fp, const char *filename, int closeit)
1789 {
1790 return PyRun_SimpleFileExFlags(fp, filename, closeit, NULL);
1791 }
1792
1793 PyObject* PyRun_String_(const char *str, int start, PyObject *globals, PyObject *locals)
1794 {
1795 return PyRun_StringFlags(str, start, globals, locals, NULL);
1796 }
1797
1798 PyObject* PyRun_File_(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals)
1799 {
1800 return PyRun_FileExFlags(fp, filename, start, globals, locals, 0, NULL);
1801 }
1802
1803 PyObject* PyRun_FileEx_(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, int closeit)
1804 {
1805 return PyRun_FileExFlags(fp, filename, start, globals, locals, closeit, NULL);
1806 }
1807
1808 PyObject* Py_CompileString_(const char *str, const char *filename, int start)
1809 {
1810 return Py_CompileStringFlags(str, filename, start, NULL);
1811 }
1812
1813 PyObject* PyImport_ImportModuleEx_(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)
1814 {
1815 return PyImport_ImportModuleLevel(name, globals, locals, fromlist, -1);
1816 }
1817
1818 enum PycamlTypeLabels {
1819 TupleType = 0,
1820 BytesType,
1821 UnicodeType,
1822 BoolType,
1823 IntType,
1824 FloatType,
1825 ListType,
1826 NoneType,
1827 CallableType,
1828 ModuleType,
1829 ClassType,
1830 TypeType,
1831 DictType,
1832 NullType,
1833 CamlpillType,
1834 OtherType,
1835 EitherStringType, /* Signifies that either of BytesType or UnicodeType is allowed. */
1836 CamlpillSubtype, /* Signifies that only the particular Camlpill variety is allowed. */
1837 AnyType /* Allow any python object. */
1838 };
1839
1840 value pytype( value obj ) {
1841 CAMLparam1(obj);
1842 PyObject *pobj = pyunwrap( obj );
1843 if( !pobj ) CAMLreturn(NullType);
1844 else if( PyTuple_Check( pobj ) ) CAMLreturn(Val_int(TupleType));
1845 else if( PyBytes_Check( pobj ) ) CAMLreturn(Val_int(BytesType));
1846 else if( PyUnicode_Check( pobj ) ) CAMLreturn(Val_int(UnicodeType));
1847 else if( PyBool_Check( pobj ) ) CAMLreturn(Val_int(BoolType));
1848 #if PY_MAJOR_VERSION <= 2
1849 else if( PyInt_Check( pobj ) ) CAMLreturn(Val_int(IntType));
1850 #else
1851 else if( PyLong_Check( pobj ) ) CAMLreturn(Val_int(IntType));
1852 #endif
1853 else if( PyFloat_Check( pobj ) ) CAMLreturn(Val_int(FloatType));
1854 else if( PyList_Check( pobj ) ) CAMLreturn(Val_int(ListType));
1855 else if( pobj == Py_None ) CAMLreturn(Val_int(NoneType));
1856 else if( PyCallable_Check( pobj ) ) CAMLreturn(Val_int(CallableType));
1857 else if( PyModule_Check( pobj ) ) CAMLreturn(Val_int(ModuleType));
1858 #if PY_MAJOR_VERSION <= 2
1859 else if( PyClass_Check( pobj ) ) CAMLreturn(Val_int(ClassType));
1860 #endif
1861 else if( PyType_Check( pobj ) ) CAMLreturn(Val_int(TypeType));
1862 else if( PyDict_Check( pobj ) ) CAMLreturn(Val_int(DictType));
1863 #if USE_PYCAPSULE
1864 else if (PyCapsule_IsValid(pobj, "caml-pill"))
1865 CAMLreturn(Val_int(CamlpillType));
1866 #else /* USE_PYCAPSULE */
1867 else if (PyCObject_Check(pobj))
1868 {
1869 void *desc = PyCObject_GetDesc(pobj);
1870 if (desc == (void *) ocamlpill_token)
1871 CAMLreturn(Val_int(CamlpillType));
1872 else
1873 CAMLreturn(Val_int(OtherType));
1874 }
1875 #endif /* USE_PYCAPSULE */
1876 else
1877 CAMLreturn(Val_int(OtherType));
1878 }
1879
1880 value pytuple_fromarray( value array ) {
1881 CAMLparam1(array);
1882 PyObject *tuple = PyTuple_New(Wosize_val(array));
1883 int i;
1884 int x;
1885
1886 for( i = 0; i < Wosize_val(array); i++ )
1887 {
1888 PyObject *entry;
1889 entry=pyunwrap(Field(array,i));
1890 /* T.F.:
1891 entry's reference count was increased by one because it is visible
1892 from within OCaml (and OCaml's GC will take care of decreasing
1893 this again upon finalization. But now, we do add another use to
1894 entry. So, we have to increase its reference count manually:
1895
1896 Note that even if tuple contained some python value before
1897 (which it does not), we do not have to Py_DECREF the
1898 reference count on the old entry, as the PyTuple_SetItem/PyList_SetItem
1899 does this of its own! Nice, isn't it?
1900 */
1901 Py_INCREF(entry);
1902 x = PyTuple_SetItem(tuple,i,entry);
1903 }
1904
1905 CAMLreturn(pywrap_steal(tuple));
1906 }
1907
1908 value pytuple_toarray( value array ) {
1909 CAMLparam1(array);
1910 PyObject *obj = pyunwrap(array);
1911 int i;
1912 CAMLlocal1(rv);
1913
1914 rv = caml_alloc_tuple(PySequence_Size(obj));
1915 /* XXX T.F.: actually, using caml_alloc_tuple to get an array is not overly aesthetic... */
1916
1917 for (i = 0; i < PySequence_Size(obj); i++)
1918 Store_field(rv, i, pywrap_steal(PySequence_GetItem(obj, i)));
1919
1920 CAMLreturn(rv);
1921 }
1922
1923 value pywrap_closure( value closure ) {
1924 CAMLparam1(closure);
1925 PyMethodDef ml;
1926 PyObject *obj;
1927 PyMethodDef *ml_def;
1928 ml.ml_name = "anonymous_closure";
1929 ml.ml_meth = pycall_callback;
1930 ml.ml_flags = 1;
1931 ml.ml_doc = "Anonymous closure";
1932 obj = camlwrap(closure, &ml, sizeof(ml));
1933 ml_def = (PyMethodDef *) caml_aux(obj);
1934 CAMLreturn(pywrap_steal(PyCFunction_New(ml_def, obj)));
1935 }
1936
1937 /*
1938 value pymodule_initmodule( value name, value funclist ) { ... }
1939 Removed by T.F., as this piece of code seemed quite buggy....
1940 */
1941
1942 /* -- T.F. Extensions -- */
1943
1944 /*
1945 In case of "You used it the wrong way" or "this should not happen",
1946 we want to be able to just bailout from python into ocaml with an
1947 exception.
1948
1949
1950 Note: this is not being used, as we decided to do error handling the
1951 other way round: python is in charge, ocaml lies "beneath the surface",
1952 so we effectively always bailout into python.
1953 */
1954
1955 #if 0
1956 static int pycaml_raise_error(int type, char *message)
1957 {
1958 CAMLlocal1(ex);
1959 ex=caml_alloc_tuple(3);
1960 Store_field(ex,0,Val_int(type));
1961 Store_field(ex,1,caml_copy_string(message));
1962 raise_with_arg(*caml_named_value("ocaml_exn_pycaml"),ex);
1963 }
1964 #endif
1965
1966 /* This is just an adjusted copy of pytuple_fromarray. */
1967 value pylist_fromarray( value array ) {
1968 CAMLparam1(array);
1969 PyObject *list = PyList_New(Wosize_val(array));
1970 int i;
1971 int x;
1972
1973 for( i = 0; i < Wosize_val(array); i++ )
1974 {
1975 PyObject *entry;
1976 entry=pyunwrap(Field(array,i));
1977 /* T.F.: See pytuple_fromarray code comments! */
1978 Py_INCREF(entry);
1979 x = PyList_SetItem(list,i,entry);
1980 }
1981 CAMLreturn(pywrap_steal(list));
1982 }
1983
1984 /* We also need it the other way round */
1985 value pylist_toarray( value pylist ) {
1986 CAMLparam1(pylist);
1987 PyObject *obj = pyunwrap(pylist);
1988 int i,len;
1989 CAMLlocal1(rv);
1990
1991 rv = caml_alloc_tuple( PySequence_Size(obj) );
1992
1993 len=PySequence_Size(obj);
1994
1995 for( i = 0; i < len; i++ )
1996 Store_field(rv,i,pywrap_steal(PySequence_GetItem(obj,i)));
1997
1998 CAMLreturn(rv);
1999 }
2000
2001 value pylist_set( value pylist, value index, value v ) {
2002 CAMLparam3(pylist,index,v);
2003 PyObject *list, *new_entry;
2004
2005 list = pyunwrap(pylist);
2006 new_entry=pyunwrap(v);
2007 Py_INCREF(new_entry);
2008 PyList_SetItem(list,Int_val(index),new_entry);
2009
2010 CAMLreturn(Val_unit);
2011 }
2012
2013 value pylist_get( value pylist, value index) {
2014 CAMLparam2(pylist,index);
2015 PyObject *list = pyunwrap(pylist);
2016
2017 /* T.F.: According to the Python docs, we own the reference produced by
2018 PySequence_GetItem. Hence, we have to steal that reference...
2019 */
2020 CAMLreturn(pywrap_steal(PySequence_GetItem(list,Int_val(index))));
2021 }
2022
2023
2024
2025 /* It's nice to have this variant of pywrap_closure */
2026 value pywrap_closure_docstring(value docstring, value closure) {
2027 CAMLparam2(docstring, closure);
2028 PyMethodDef ml;
2029 PyObject *obj;
2030 PyMethodDef *ml_def;
2031 ml.ml_name = "anonymous_closure";
2032 ml.ml_meth = pycall_callback;
2033 ml.ml_flags = 1;
2034 ml.ml_doc = String_val(docstring);
2035 obj = camlwrap(closure,&ml,sizeof(ml));
2036 ml_def = (PyMethodDef *) caml_aux(obj);
2037 CAMLreturn(pywrap_steal(PyCFunction_New(ml_def,obj)));
2038 }
2039
2040 /* Using pyrun_interactiveloop the way it was in the original code
2041 may work on some systems, but then just by chance. We have to
2042 do this in a cleaner way:
2043 */
2044 value pycaml_prompt(value ml_unit) {
2045 CAMLparam1(ml_unit);
2046
2047 PyRun_InteractiveLoop(stdin,"<stdin>");
2048
2049 CAMLreturn(Val_unit);
2050 }
2051
2052
2053 /* The function below is highly useful for debugging! */
2054 value pyrefcount(value pyobj) {
2055 CAMLparam1(pyobj);
2056 PyObject *obj = pyunwrap(pyobj);
2057
2058 CAMLreturn(Val_int(obj->ob_refcnt));
2059 }