PageRenderTime 69ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 1ms

/bundles/pyml/pyml-current/pyml_stubs.c

https://github.com/coccinelle/coccinelle
C | 1414 lines | 1244 code | 125 blank | 45 comment | 181 complexity | 8783665e6fae541dbfc3fd37dc4ba5bd MD5 | raw file
  1. #define _GNU_SOURCE
  2. #include <caml/mlvalues.h>
  3. #include <caml/memory.h>
  4. #include <caml/fail.h>
  5. #include <caml/callback.h>
  6. #include <caml/custom.h>
  7. #include <caml/alloc.h>
  8. #include <sys/param.h>
  9. #include <string.h>
  10. #include <stdbool.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <errno.h>
  15. #include <stdcompat.h>
  16. #include "pyml_stubs.h"
  17. static FILE *(*Python__Py_fopen)(const char *pathname, const char *mode);
  18. static FILE *(*Python__Py_wfopen)(const wchar_t *pathname, const char *mode);
  19. static void *xmalloc(size_t size)
  20. {
  21. void *p = malloc(size);
  22. if (!p) {
  23. failwith("Virtual memory exhausted\n");
  24. }
  25. return p;
  26. }
  27. #ifdef _WIN32
  28. #include <windows.h>
  29. typedef HINSTANCE library_t;
  30. static library_t
  31. open_library(const char *filename)
  32. {
  33. return LoadLibrary(filename);
  34. }
  35. void
  36. close_library(library_t library)
  37. {
  38. if (!FreeLibrary(library)) {
  39. fprintf(stderr, "close_library.\n");
  40. exit(EXIT_FAILURE);
  41. }
  42. }
  43. static library_t
  44. get_default_library(void)
  45. {
  46. return GetModuleHandle(0);
  47. }
  48. static void *
  49. find_symbol(library_t library, const char *name)
  50. {
  51. return GetProcAddress(library, name);
  52. }
  53. int
  54. unsetenv(const char *name)
  55. {
  56. size_t len = strlen(name);
  57. char string[len + 2];
  58. snprintf(string, len + 2, "%s=", name);
  59. return _putenv(string);
  60. }
  61. extern int win_CRT_fd_of_filedescr(value handle);
  62. static FILE *
  63. file_of_file_descr(value file_descr, const char *mode)
  64. {
  65. CAMLparam1(file_descr);
  66. int fd = win_CRT_fd_of_filedescr(file_descr);
  67. FILE *result = _fdopen(dup(fd), mode);
  68. CAMLreturnT(FILE *, result);
  69. }
  70. #else
  71. #include <dlfcn.h>
  72. typedef void *library_t;
  73. static library_t
  74. open_library(const char *filename)
  75. {
  76. return dlopen(filename, RTLD_LAZY | RTLD_GLOBAL);
  77. }
  78. void
  79. close_library(library_t filename)
  80. {
  81. if (dlclose(filename)) {
  82. fprintf(stderr, "close_library: %s.\n", dlerror());
  83. exit(EXIT_FAILURE);
  84. }
  85. }
  86. static library_t
  87. get_default_library(void)
  88. {
  89. return RTLD_DEFAULT;
  90. }
  91. static void *
  92. find_symbol(library_t library, const char *name)
  93. {
  94. return dlsym(library, name);
  95. }
  96. static FILE *
  97. file_of_file_descr(value file_descr, const char *mode)
  98. {
  99. CAMLparam1(file_descr);
  100. int fd = Int_val(file_descr);
  101. FILE *result = fdopen(dup(fd), mode);
  102. CAMLreturnT(FILE *, result);
  103. }
  104. #endif
  105. /* The following definitions are extracted and simplified from
  106. #include <Python.h>
  107. */
  108. typedef struct {
  109. int cf_flags;
  110. } PyCompilerFlags;
  111. #define Py_TPFLAGS_INT_SUBCLASS (1L<<23)
  112. #define Py_TPFLAGS_LONG_SUBCLASS (1UL << 24)
  113. #define Py_TPFLAGS_LIST_SUBCLASS (1UL << 25)
  114. #define Py_TPFLAGS_TUPLE_SUBCLASS (1UL << 26)
  115. #define Py_TPFLAGS_BYTES_SUBCLASS (1UL << 27)
  116. #define Py_TPFLAGS_UNICODE_SUBCLASS (1UL << 28)
  117. #define Py_TPFLAGS_DICT_SUBCLASS (1UL << 29)
  118. #define Py_TPFLAGS_BASE_EXC_SUBCLASS (1UL << 30)
  119. #define Py_TPFLAGS_TYPE_SUBCLASS (1UL << 31)
  120. #define Py_LT 0
  121. #define Py_LE 1
  122. #define Py_EQ 2
  123. #define Py_NE 3
  124. #define Py_GT 4
  125. #define Py_GE 5
  126. typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
  127. typedef struct PyMethodDef {
  128. const char *ml_name;
  129. PyCFunction ml_meth;
  130. int ml_flags;
  131. const char *ml_doc;
  132. } PyMethodDef;
  133. typedef void (*PyCapsule_Destructor)(PyObject *);
  134. static void *Python27__PyObject_NextNotImplemented;
  135. /* Global variables for the library */
  136. /* version_major != 0 iff the library is initialized */
  137. static int version_major;
  138. static int version_minor;
  139. static library_t library;
  140. /* Functions that are special enough to deserved to be wrapped specifically */
  141. /* Wrapped by pywrap_closure */
  142. static PyObject *(*Python_PyCFunction_NewEx)
  143. (PyMethodDef *, PyObject *, PyObject *);
  144. /* Wrapped by closure and capsule */
  145. static void *(*Python27_PyCapsule_New)
  146. (void *, const char *, PyCapsule_Destructor);
  147. static void *(*Python27_PyCapsule_GetPointer)(PyObject *, const char *);
  148. static int (*Python27_PyCapsule_IsValid)(PyObject *, const char *);
  149. static void *(*Python2_PyCObject_FromVoidPtr)(void *, void (*)(void *));
  150. static void *(*Python2_PyCObject_AsVoidPtr)(PyObject *);
  151. /* Hack for multi-arguments */
  152. static PyObject *(*Python_PyObject_CallFunctionObjArgs)(PyObject *, ...);
  153. static PyObject *(*Python_PyObject_CallMethodObjArgs)(
  154. PyObject *, PyObject *, ...);
  155. /* Wrapped by PyErr_Fetch_wrapper */
  156. static void (*Python_PyErr_Fetch)(PyObject **, PyObject **, PyObject **);
  157. static void (*Python_PyErr_NormalizeException)
  158. (PyObject **, PyObject **, PyObject **);
  159. /* Resolved differently between Python 2 and Python 3 */
  160. static PyObject *Python__Py_FalseStruct;
  161. /* Buffer and size */
  162. static int (*Python_PyString_AsStringAndSize)
  163. (PyObject *, char **, Py_ssize_t *);
  164. static int (*Python_PyObject_AsCharBuffer)
  165. (PyObject *, const char **, Py_ssize_t *);
  166. static int (*Python_PyObject_AsReadBuffer)
  167. (PyObject *, const void **, Py_ssize_t *);
  168. static int (*Python_PyObject_AsWriteBuffer)
  169. (PyObject *, void **, Py_ssize_t *);
  170. /* Length argument */
  171. static PyObject *(*Python_PyLong_FromString)(const char *, const char **, int);
  172. /* Internal use only */
  173. static void (*Python_PyMem_Free)(void *);
  174. static enum UCS { UCS_NONE, UCS2, UCS4 } ucs;
  175. /* Single instance of () */
  176. static PyObject *tuple_empty;
  177. #include "pyml.h"
  178. static void *getcustom( value v )
  179. {
  180. return *((void **)Data_custom_val(v));
  181. }
  182. static void pydecref( value v )
  183. {
  184. if (getcustom(v)) {
  185. Py_DECREF((PyObject *)getcustom(v));
  186. }
  187. }
  188. static int
  189. rich_compare_bool_nofail
  190. (PyObject *o1, PyObject *o2, int opid)
  191. {
  192. int result = Python_PyObject_RichCompareBool(o1, o2, opid);
  193. if (result == -1) {
  194. Python_PyErr_Clear();
  195. result = 0;
  196. }
  197. return result;
  198. }
  199. static int
  200. pycompare(value v1, value v2)
  201. {
  202. int result;
  203. PyObject *o1 = getcustom(v1);
  204. PyObject *o2 = getcustom(v2);
  205. if (o1 && !o2)
  206. result = -1;
  207. else if (o2 && !o1)
  208. result = 1;
  209. else if (!o1 && !o2)
  210. result = 0;
  211. else if (version_major < 3)
  212. Python2_PyObject_Cmp(o1, o2, &result);
  213. else if (rich_compare_bool_nofail(o1, o2, Py_EQ))
  214. result = 0;
  215. else if (rich_compare_bool_nofail(o1, o2, Py_LT))
  216. result = -1;
  217. else if (rich_compare_bool_nofail(o1, o2, Py_GT))
  218. result = 1;
  219. else
  220. result = -1;
  221. return result;
  222. }
  223. static intnat
  224. pyhash( value v )
  225. {
  226. if (getcustom(v)) {
  227. intnat result = Python_PyObject_Hash((PyObject *)getcustom(v));
  228. if (result == -1) {
  229. Python_PyErr_Clear();
  230. }
  231. return result;
  232. }
  233. else {
  234. return 0;
  235. }
  236. }
  237. static uintnat
  238. pydeserialize(void *dst)
  239. {
  240. return 0L;
  241. }
  242. struct custom_operations pyops =
  243. {
  244. "PythonObject",
  245. pydecref,
  246. pycompare,
  247. pyhash,
  248. custom_serialize_default,
  249. pydeserialize
  250. };
  251. enum code {
  252. CODE_NULL,
  253. CODE_NONE,
  254. CODE_TRUE,
  255. CODE_FALSE,
  256. CODE_TUPLE_EMPTY
  257. };
  258. static void *
  259. resolve(const char *symbol)
  260. {
  261. void *result = find_symbol(library, symbol);
  262. if (!result) {
  263. char *fmt = "Cannot resolve %s.\n";
  264. ssize_t size = snprintf(NULL, 0, fmt, symbol);
  265. char *msg = xmalloc(size + 1);
  266. snprintf(msg, size + 1, fmt, symbol);
  267. failwith(msg);
  268. }
  269. return result;
  270. }
  271. static void *
  272. resolve_optional(const char *symbol)
  273. {
  274. return find_symbol(library, symbol);
  275. }
  276. value
  277. pyml_wrap(PyObject *object, bool steal)
  278. {
  279. CAMLparam0();
  280. CAMLlocal1(v);
  281. if (!object) {
  282. CAMLreturn(Val_int(CODE_NULL));
  283. }
  284. if (object == Python__Py_NoneStruct) {
  285. CAMLreturn(Val_int(CODE_NONE));
  286. }
  287. if (object == Python__Py_TrueStruct) {
  288. CAMLreturn(Val_int(CODE_TRUE));
  289. }
  290. if (object == Python__Py_FalseStruct) {
  291. CAMLreturn(Val_int(CODE_FALSE));
  292. }
  293. unsigned long flags =
  294. ((struct _typeobject *) pyobjectdescr(pyobjectdescr(object)->ob_type))
  295. ->tp_flags;
  296. if (flags & Py_TPFLAGS_TUPLE_SUBCLASS
  297. && Python_PySequence_Length(object) == 0) {
  298. CAMLreturn(Val_int(CODE_TUPLE_EMPTY));
  299. }
  300. if (!steal) {
  301. Py_INCREF(object);
  302. }
  303. v = caml_alloc_custom(&pyops, sizeof(PyObject *), 100, 30000000);
  304. *((PyObject **)Data_custom_val(v)) = object;
  305. CAMLreturn(v);
  306. }
  307. PyObject *
  308. pyml_unwrap(value v)
  309. {
  310. if (Is_long(v))
  311. switch (Int_val(v)) {
  312. case CODE_NULL:
  313. return NULL;
  314. case CODE_NONE:
  315. return Python__Py_NoneStruct;
  316. case CODE_TRUE:
  317. return Python__Py_TrueStruct;
  318. case CODE_FALSE:
  319. return Python__Py_FalseStruct;
  320. case CODE_TUPLE_EMPTY:
  321. return tuple_empty;
  322. }
  323. return *((PyObject **)Data_custom_val(v));
  324. }
  325. /*
  326. static value
  327. pyml_wrap_compilerflags(PyCompilerFlags *flags)
  328. {
  329. CAMLparam0();
  330. CAMLlocal2(ref, some);
  331. if (!flags) {
  332. CAMLreturn(Val_int(0));
  333. }
  334. else {
  335. ref = caml_alloc(0, 1);
  336. Store_field(ref, 0, Val_int(flags->cf_flags));
  337. some = caml_alloc(0, 1);
  338. Store_field(some, 0, ref);
  339. CAMLreturn(some);
  340. }
  341. }
  342. */
  343. static PyCompilerFlags *
  344. pyml_unwrap_compilerflags(value v)
  345. {
  346. CAMLparam1(v);
  347. if (Is_block(v)) {
  348. PyCompilerFlags *flags = malloc(sizeof(PyCompilerFlags));
  349. flags->cf_flags = Int_val(Field(Field(v, 0), 0));
  350. CAMLreturnT(PyCompilerFlags *, flags);
  351. }
  352. else {
  353. CAMLreturnT(PyCompilerFlags *, NULL);
  354. }
  355. }
  356. /*
  357. static value
  358. pyml_wrap_intref(int v)
  359. {
  360. CAMLparam0();
  361. CAMLlocal1(ref);
  362. ref = caml_alloc(0, 1);
  363. Store_field(ref, 0, Val_int(v));
  364. CAMLreturn(ref);
  365. }
  366. */
  367. static int
  368. pyml_unwrap_intref(value v)
  369. {
  370. CAMLparam1(v);
  371. CAMLreturnT(int, Int_val(Field(v, 0)));
  372. }
  373. static void *
  374. unwrap_capsule(PyObject *obj, const char *type)
  375. {
  376. if (Python27_PyCapsule_GetPointer) {
  377. return Python27_PyCapsule_GetPointer(obj, type);
  378. }
  379. else {
  380. return Python2_PyCObject_AsVoidPtr(obj);
  381. }
  382. }
  383. static PyObject *
  384. wrap_capsule(void *ptr, char *type, void (*destr)(PyObject *))
  385. {
  386. if (Python27_PyCapsule_New) {
  387. return Python27_PyCapsule_New(ptr, type, destr);
  388. }
  389. else {
  390. return Python2_PyCObject_FromVoidPtr(ptr, (void(*)(void *))destr);
  391. }
  392. }
  393. static PyObject *
  394. pycall_callback(PyObject *obj, PyObject *args)
  395. {
  396. CAMLparam0();
  397. CAMLlocal3(ml_out, ml_func, ml_args);
  398. PyObject *out;
  399. void *p = unwrap_capsule(obj, "ocaml-closure");
  400. if (!p) {
  401. Py_INCREF(Python__Py_NoneStruct);
  402. CAMLreturnT(PyObject *, Python__Py_NoneStruct);
  403. }
  404. ml_func = *(value *) p;
  405. ml_args = pyml_wrap(args, false);
  406. ml_out = caml_callback(ml_func, ml_args);
  407. out = pyml_unwrap(ml_out);
  408. Py_XINCREF(out);
  409. CAMLreturnT(PyObject *, out);
  410. }
  411. static PyObject *
  412. pycall_callback_with_keywords(PyObject *obj, PyObject *args, PyObject *keywords)
  413. {
  414. CAMLparam0();
  415. CAMLlocal4(ml_out, ml_func, ml_args, ml_keywords);
  416. PyObject *out;
  417. void *p = unwrap_capsule(obj, "ocaml-closure");
  418. if (!p) {
  419. Py_INCREF(Python__Py_NoneStruct);
  420. CAMLreturnT(PyObject *, Python__Py_NoneStruct);
  421. }
  422. ml_func = *(value *) p;
  423. ml_args = pyml_wrap(args, false);
  424. ml_keywords = pyml_wrap(keywords, false);
  425. ml_out = caml_callback2(ml_func, ml_args, ml_keywords);
  426. out = pyml_unwrap(ml_out);
  427. Py_XINCREF(out);
  428. CAMLreturnT(PyObject *, out);
  429. }
  430. static void
  431. caml_destructor(PyObject *v, const char *capsule_name)
  432. {
  433. value *valptr = (value *) unwrap_capsule(v, capsule_name);
  434. caml_remove_global_root(valptr);
  435. free(valptr);
  436. }
  437. static void
  438. camldestr_capsule(PyObject *v)
  439. {
  440. caml_destructor(v, "ocaml-capsule");
  441. }
  442. static PyObject *
  443. camlwrap_capsule(value val, void *aux_str, int size)
  444. {
  445. value *v = (value *) malloc(sizeof(value) + size);
  446. *v = val;
  447. memcpy((void *)v + sizeof(value), aux_str, size);
  448. caml_register_global_root(v);
  449. return wrap_capsule(v, "ocaml-capsule", camldestr_capsule);
  450. }
  451. static void *
  452. caml_aux(PyObject *obj)
  453. {
  454. value *v = (value *) unwrap_capsule(obj, "ocaml-closure");
  455. return (void *) v + sizeof(value);
  456. }
  457. void
  458. pyml_assert_initialized()
  459. {
  460. if (!version_major) {
  461. failwith("Run 'Py.initialize ()' first");
  462. }
  463. }
  464. void
  465. pyml_assert_python2()
  466. {
  467. if (version_major != 2) {
  468. pyml_assert_initialized();
  469. failwith("Python 2 needed");
  470. }
  471. }
  472. void
  473. pyml_assert_ucs2()
  474. {
  475. if (ucs != UCS2) {
  476. pyml_assert_initialized();
  477. failwith("Python with UCS2 needed");
  478. }
  479. }
  480. void
  481. pyml_assert_ucs4()
  482. {
  483. if (ucs != UCS4) {
  484. pyml_assert_initialized();
  485. failwith("Python with UCS4 needed");
  486. }
  487. }
  488. void
  489. pyml_assert_python3()
  490. {
  491. if (version_major != 3) {
  492. pyml_assert_initialized();
  493. failwith("Python 3 needed");
  494. }
  495. }
  496. void
  497. pyml_check_symbol_available(void *symbol, char *symbol_name)
  498. {
  499. if (!symbol) {
  500. char *fmt = "Symbol unavailable with this version of Python: %s.\n";
  501. ssize_t size = snprintf(NULL, 0, fmt, symbol_name);
  502. if (size < 0) {
  503. failwith("Symbol unavailable with this version of Python.\n");
  504. return;
  505. }
  506. char *msg = xmalloc(size + 1);
  507. size = snprintf(msg, size + 1, fmt, symbol_name);
  508. if (size < 0) {
  509. failwith("Symbol unavailable with this version of Python.\n");
  510. return;
  511. }
  512. failwith(msg);
  513. }
  514. }
  515. void *
  516. deref_not_null(void *pointer)
  517. {
  518. if (pointer) {
  519. return *(void **) pointer;
  520. }
  521. else {
  522. return NULL;
  523. }
  524. }
  525. struct pyml_closure {
  526. value value;
  527. PyMethodDef method;
  528. };
  529. static char *anon_closure = "anonymous_closure";
  530. static void
  531. camldestr_closure(PyObject *v)
  532. {
  533. struct pyml_closure *valptr = unwrap_capsule(v, "ocaml-closure");
  534. const char *ml_doc = valptr->method.ml_doc;
  535. const char *ml_name = valptr->method.ml_name;
  536. caml_remove_global_root((value *)valptr);
  537. free(valptr);
  538. free((void *) ml_doc);
  539. if (ml_name != anon_closure) free((void *) ml_name);
  540. }
  541. CAMLprim value
  542. pyml_wrap_closure(value name, value docstring, value closure)
  543. {
  544. CAMLparam3(name, docstring, closure);
  545. pyml_assert_initialized();
  546. PyMethodDef ml;
  547. PyObject *obj;
  548. PyMethodDef *ml_def;
  549. ml.ml_name = anon_closure;
  550. if (name != Val_int(0)) {
  551. ml.ml_name = strdup(String_val(Field(name, 0)));
  552. }
  553. if (Tag_val(closure) == 0) {
  554. ml.ml_flags = 1;
  555. ml.ml_meth = pycall_callback;
  556. }
  557. else {
  558. ml.ml_flags = 3;
  559. ml.ml_meth = (PyCFunction) pycall_callback_with_keywords;
  560. }
  561. ml.ml_doc = strdup(String_val(docstring));
  562. struct pyml_closure *v = malloc(sizeof(struct pyml_closure));
  563. v->value = Field(closure, 0);
  564. v->method = ml;
  565. caml_register_global_root(&v->value);
  566. obj = wrap_capsule(v, "ocaml-closure", camldestr_closure);
  567. ml_def = (PyMethodDef *) caml_aux(obj);
  568. PyObject *f = Python_PyCFunction_NewEx(ml_def, obj, NULL);
  569. Py_DECREF(obj);
  570. CAMLreturn(pyml_wrap(f, true));
  571. }
  572. int debug_build;
  573. CAMLprim value
  574. py_load_library(value filename_ocaml, value debug_build_ocaml)
  575. {
  576. CAMLparam2(filename_ocaml, debug_build_ocaml);
  577. if (Is_block(filename_ocaml)) {
  578. const char *filename = String_val(Field(filename_ocaml, 0));
  579. library = open_library(filename);
  580. if (!library) {
  581. failwith("Library not found");
  582. }
  583. }
  584. else {
  585. library = get_default_library();
  586. }
  587. Python_Py_GetVersion = find_symbol(library, "Py_GetVersion");
  588. if (!Python_Py_GetVersion) {
  589. failwith("No Python symbol");
  590. }
  591. const char *version = Python_Py_GetVersion();
  592. version_major = version[0] - '0';
  593. version_minor = version[2] - '0';
  594. Python_PyCFunction_NewEx = resolve("PyCFunction_NewEx");
  595. if ((version_major == 2 && version_minor >= 7) || version_major >= 3) {
  596. Python27_PyCapsule_New = resolve("PyCapsule_New");
  597. Python27_PyCapsule_GetPointer = resolve("PyCapsule_GetPointer");
  598. Python27_PyCapsule_IsValid = resolve("PyCapsule_IsValid");
  599. Python27__PyObject_NextNotImplemented =
  600. resolve("_PyObject_NextNotImplemented");
  601. }
  602. Python_PyObject_CallFunctionObjArgs =
  603. resolve("PyObject_CallFunctionObjArgs");
  604. Python_PyObject_CallMethodObjArgs =
  605. resolve("PyObject_CallMethodObjArgs");
  606. Python_PyErr_Fetch = resolve("PyErr_Fetch");
  607. Python_PyErr_NormalizeException = resolve("PyErr_NormalizeException");
  608. Python_PyObject_AsCharBuffer = resolve_optional("PyObject_AsCharBuffer");
  609. Python_PyObject_AsReadBuffer = resolve_optional("PyObject_AsReadBuffer");
  610. Python_PyObject_AsWriteBuffer = resolve_optional("PyObject_AsWriteBuffer");
  611. if (version_major >= 3) {
  612. Python__Py_FalseStruct = resolve("_Py_FalseStruct");
  613. Python_PyString_AsStringAndSize = resolve("PyBytes_AsStringAndSize");
  614. }
  615. else {
  616. Python__Py_FalseStruct = resolve("_Py_ZeroStruct");
  617. Python_PyString_AsStringAndSize = resolve("PyString_AsStringAndSize");
  618. }
  619. Python_PyLong_FromString = resolve("PyLong_FromString");
  620. Python_PyMem_Free = resolve("PyMem_Free");
  621. if (version_major >= 3) {
  622. Python__Py_wfopen = resolve_optional("_Py_wfopen"); /* Python >=3.10 */
  623. Python__Py_fopen = resolve_optional("_Py_fopen");
  624. }
  625. else {
  626. Python2_PyCObject_FromVoidPtr = resolve("PyCObject_FromVoidPtr");
  627. Python2_PyCObject_AsVoidPtr = resolve("PyCObject_AsVoidPtr");
  628. }
  629. if (find_symbol(library, "PyUnicodeUCS2_AsEncodedString")) {
  630. ucs = UCS2;
  631. }
  632. else if (find_symbol(library, "PyUnicodeUCS4_AsEncodedString")) {
  633. ucs = UCS4;
  634. }
  635. else {
  636. ucs = UCS_NONE;
  637. }
  638. #include "pyml_dlsyms.inc"
  639. Python_Py_Initialize();
  640. if (Is_block(debug_build_ocaml)) {
  641. debug_build = Int_val(Field(debug_build_ocaml, 0));
  642. }
  643. else {
  644. PyObject *sysconfig = Python_PyImport_ImportModule("sysconfig");
  645. PyObject *get_config_var =
  646. Python_PyObject_GetAttrString(sysconfig, "get_config_var");
  647. PyObject *args;
  648. PyObject *py_debug;
  649. PyObject *debug_build_py;
  650. char *py_debug_str = "Py_DEBUG";
  651. if (version_major >= 3) {
  652. py_debug = Python3_PyUnicode_FromStringAndSize(py_debug_str, 8);
  653. }
  654. else {
  655. py_debug = Python2_PyString_FromStringAndSize(py_debug_str, 8);
  656. }
  657. if (!py_debug) {
  658. failwith("py_debug");
  659. }
  660. args = Python_PyTuple_New(1);
  661. if (!args) {
  662. failwith("PyTuple_New");
  663. }
  664. if (Python_PyTuple_SetItem(args, 0, py_debug)) {
  665. failwith("PyTuple_SetItem");
  666. }
  667. debug_build_py =
  668. Python_PyEval_CallObjectWithKeywords(get_config_var, args, NULL);
  669. if (!debug_build_py) {
  670. failwith("PyEval_CallObjectWithKeywords");
  671. }
  672. if (version_major >= 3) {
  673. debug_build = Python_PyLong_AsLong(debug_build_py);
  674. }
  675. else {
  676. debug_build = Python2_PyInt_AsLong(debug_build_py);
  677. }
  678. if (debug_build == -1) {
  679. failwith("AsLong");
  680. }
  681. }
  682. tuple_empty = Python_PyTuple_New(0);
  683. CAMLreturn(Val_unit);
  684. }
  685. struct PyObjectDebug {
  686. PyObject *_ob_next; \
  687. PyObject *_ob_prev;
  688. PyObjectDescr descr;
  689. };
  690. PyObjectDescr *pyobjectdescr(PyObject *obj) {
  691. if (debug_build) {
  692. return &((struct PyObjectDebug *) obj)->descr;
  693. }
  694. else {
  695. return (PyObjectDescr *) obj;
  696. }
  697. }
  698. CAMLprim value
  699. py_is_debug_build()
  700. {
  701. CAMLparam0();
  702. CAMLreturn(Val_int(debug_build));
  703. }
  704. CAMLprim value
  705. py_finalize_library(value unit)
  706. {
  707. CAMLparam1(unit);
  708. pyml_assert_initialized();
  709. Py_DECREF(tuple_empty);
  710. if (library != get_default_library()) {
  711. close_library(library);
  712. }
  713. version_major = 0;
  714. ucs = UCS_NONE;
  715. CAMLreturn(Val_unit);
  716. }
  717. CAMLprim value
  718. py_unsetenv(value name_ocaml)
  719. {
  720. CAMLparam1(name_ocaml);
  721. const char *name = String_val(name_ocaml);
  722. if (unsetenv(name) == -1) {
  723. failwith(strerror(errno));
  724. }
  725. CAMLreturn(Val_unit);
  726. }
  727. CAMLprim value
  728. py_get_UCS(value unit)
  729. {
  730. CAMLparam1(unit);
  731. pyml_assert_initialized();
  732. CAMLreturn(Val_int(ucs));
  733. }
  734. CAMLprim value
  735. PyNull_wrapper(value unit)
  736. {
  737. CAMLparam1(unit);
  738. CAMLreturn(Val_int(CODE_NULL));
  739. }
  740. CAMLprim value
  741. PyNone_wrapper(value unit)
  742. {
  743. CAMLparam1(unit);
  744. CAMLreturn(Val_int(CODE_NONE));
  745. }
  746. CAMLprim value
  747. PyTrue_wrapper(value unit)
  748. {
  749. CAMLparam1(unit);
  750. CAMLreturn(Val_int(CODE_TRUE));
  751. }
  752. CAMLprim value
  753. PyFalse_wrapper(value unit)
  754. {
  755. CAMLparam1(unit);
  756. CAMLreturn(Val_int(CODE_FALSE));
  757. }
  758. CAMLprim value
  759. PyTuple_Empty_wrapper(value unit)
  760. {
  761. CAMLparam1(unit);
  762. CAMLreturn(Val_int(CODE_TUPLE_EMPTY));
  763. }
  764. enum pytype_labels {
  765. PyUnknown,
  766. Bool,
  767. Bytes,
  768. Callable,
  769. Capsule,
  770. Closure,
  771. Dict,
  772. Float,
  773. List,
  774. Int,
  775. Long,
  776. Module,
  777. NoneType,
  778. Null,
  779. Tuple,
  780. Type,
  781. Unicode,
  782. Iter,
  783. Set
  784. };
  785. CAMLprim value
  786. pytype(value object_ocaml)
  787. {
  788. CAMLparam1(object_ocaml);
  789. pyml_assert_initialized();
  790. PyObject *object = pyml_unwrap(object_ocaml);
  791. if (!object) {
  792. CAMLreturn(Val_int(Null));
  793. }
  794. PyObject *ob_type = pyobjectdescr(object)->ob_type;
  795. struct _typeobject *typeobj = (struct _typeobject *) pyobjectdescr(ob_type);
  796. unsigned long flags = typeobj->tp_flags;
  797. int result;
  798. if (ob_type == Python_PyBool_Type) {
  799. result = Bool;
  800. }
  801. else if (flags & Py_TPFLAGS_BYTES_SUBCLASS) {
  802. result = Bytes;
  803. }
  804. else if (Python_PyCallable_Check(object)) {
  805. result = Callable;
  806. }
  807. else if (Python27_PyCapsule_IsValid
  808. && Python27_PyCapsule_IsValid(object, "ocaml-capsule")) {
  809. result = Capsule;
  810. }
  811. else if (Python27_PyCapsule_IsValid
  812. && Python27_PyCapsule_IsValid(object, "ocaml-closure")) {
  813. result = Closure;
  814. }
  815. else if (flags & Py_TPFLAGS_DICT_SUBCLASS) {
  816. result = Dict;
  817. }
  818. else if (ob_type == Python_PyFloat_Type ||
  819. Python_PyType_IsSubtype(ob_type, Python_PyFloat_Type)) {
  820. result = Float;
  821. }
  822. else if (flags & Py_TPFLAGS_LIST_SUBCLASS) {
  823. result = List;
  824. }
  825. else if (flags & Py_TPFLAGS_INT_SUBCLASS) {
  826. result = Int;
  827. }
  828. else if (flags & Py_TPFLAGS_LONG_SUBCLASS) {
  829. result = Long;
  830. }
  831. else if (ob_type == Python_PyModule_Type ||
  832. Python_PyType_IsSubtype(ob_type, Python_PyModule_Type)) {
  833. result = Module;
  834. }
  835. else if (object == Python__Py_NoneStruct) {
  836. result = NoneType;
  837. }
  838. else if (flags & Py_TPFLAGS_TUPLE_SUBCLASS) {
  839. result = Tuple;
  840. }
  841. else if (flags & Py_TPFLAGS_TYPE_SUBCLASS) {
  842. result = Type;
  843. }
  844. else if (flags & Py_TPFLAGS_UNICODE_SUBCLASS) {
  845. result = Unicode;
  846. }
  847. else if (ob_type == Python_PySet_Type) {
  848. result = Set;
  849. }
  850. else if (typeobj->tp_iternext != NULL &&
  851. typeobj->tp_iternext != &Python27__PyObject_NextNotImplemented) {
  852. result = Iter;
  853. }
  854. else {
  855. result = PyUnknown;
  856. }
  857. CAMLreturn(Val_int(result));
  858. }
  859. CAMLprim value
  860. PyObject_CallFunctionObjArgs_wrapper(
  861. value callable_ocaml, value arguments_ocaml)
  862. {
  863. CAMLparam2(callable_ocaml, arguments_ocaml);
  864. pyml_assert_initialized();
  865. PyObject *callable = pyml_unwrap(callable_ocaml);
  866. PyObject *result;
  867. mlsize_t argument_count = Wosize_val(arguments_ocaml);
  868. switch (argument_count) {
  869. case 0:
  870. result = Python_PyObject_CallFunctionObjArgs(callable, NULL);
  871. break;
  872. case 1:
  873. result = Python_PyObject_CallFunctionObjArgs
  874. (callable,
  875. pyml_unwrap(Field(arguments_ocaml, 0)),
  876. NULL);
  877. break;
  878. case 2:
  879. result = Python_PyObject_CallFunctionObjArgs
  880. (callable,
  881. pyml_unwrap(Field(arguments_ocaml, 0)),
  882. pyml_unwrap(Field(arguments_ocaml, 1)),
  883. NULL);
  884. break;
  885. case 3:
  886. result = Python_PyObject_CallFunctionObjArgs
  887. (callable,
  888. pyml_unwrap(Field(arguments_ocaml, 0)),
  889. pyml_unwrap(Field(arguments_ocaml, 1)),
  890. pyml_unwrap(Field(arguments_ocaml, 2)),
  891. NULL);
  892. break;
  893. case 4:
  894. result = Python_PyObject_CallFunctionObjArgs
  895. (callable,
  896. pyml_unwrap(Field(arguments_ocaml, 0)),
  897. pyml_unwrap(Field(arguments_ocaml, 1)),
  898. pyml_unwrap(Field(arguments_ocaml, 2)),
  899. pyml_unwrap(Field(arguments_ocaml, 3)),
  900. NULL);
  901. break;
  902. case 5:
  903. result = Python_PyObject_CallFunctionObjArgs
  904. (callable,
  905. pyml_unwrap(Field(arguments_ocaml, 0)),
  906. pyml_unwrap(Field(arguments_ocaml, 1)),
  907. pyml_unwrap(Field(arguments_ocaml, 2)),
  908. pyml_unwrap(Field(arguments_ocaml, 3)),
  909. pyml_unwrap(Field(arguments_ocaml, 4)),
  910. NULL);
  911. break;
  912. default:
  913. fprintf(stderr,
  914. "PyObject_CallFunctionObjArgs_wrapper not implemented for more "
  915. "than 5 arguments\n");
  916. exit(EXIT_FAILURE);
  917. }
  918. CAMLreturn(pyml_wrap(result, true));
  919. }
  920. CAMLprim value
  921. PyObject_CallMethodObjArgs_wrapper(
  922. value object_ocaml, value name_ocaml, value arguments_ocaml)
  923. {
  924. CAMLparam3(object_ocaml, name_ocaml, arguments_ocaml);
  925. pyml_assert_initialized();
  926. PyObject *object = pyml_unwrap(object_ocaml);
  927. PyObject *name = pyml_unwrap(name_ocaml);
  928. PyObject *result;
  929. mlsize_t argument_count = Wosize_val(arguments_ocaml);
  930. switch (argument_count) {
  931. case 0:
  932. result = Python_PyObject_CallMethodObjArgs(object, name, NULL);
  933. break;
  934. case 1:
  935. result = Python_PyObject_CallMethodObjArgs
  936. (object, name,
  937. pyml_unwrap(Field(arguments_ocaml, 0)),
  938. NULL);
  939. break;
  940. case 2:
  941. result = Python_PyObject_CallMethodObjArgs
  942. (object, name,
  943. pyml_unwrap(Field(arguments_ocaml, 0)),
  944. pyml_unwrap(Field(arguments_ocaml, 1)),
  945. NULL);
  946. break;
  947. case 3:
  948. result = Python_PyObject_CallMethodObjArgs
  949. (object, name,
  950. pyml_unwrap(Field(arguments_ocaml, 0)),
  951. pyml_unwrap(Field(arguments_ocaml, 1)),
  952. pyml_unwrap(Field(arguments_ocaml, 2)),
  953. NULL);
  954. break;
  955. case 4:
  956. result = Python_PyObject_CallMethodObjArgs
  957. (object, name,
  958. pyml_unwrap(Field(arguments_ocaml, 0)),
  959. pyml_unwrap(Field(arguments_ocaml, 1)),
  960. pyml_unwrap(Field(arguments_ocaml, 2)),
  961. pyml_unwrap(Field(arguments_ocaml, 3)),
  962. NULL);
  963. break;
  964. case 5:
  965. result = Python_PyObject_CallMethodObjArgs
  966. (object, name,
  967. pyml_unwrap(Field(arguments_ocaml, 0)),
  968. pyml_unwrap(Field(arguments_ocaml, 1)),
  969. pyml_unwrap(Field(arguments_ocaml, 2)),
  970. pyml_unwrap(Field(arguments_ocaml, 3)),
  971. pyml_unwrap(Field(arguments_ocaml, 4)),
  972. NULL);
  973. break;
  974. default:
  975. fprintf(stderr,
  976. "PyObject_CallMethodObjArgs_wrapper not implemented for more "
  977. "than 5 arguments\n");
  978. exit(EXIT_FAILURE);
  979. }
  980. CAMLreturn(pyml_wrap(result, true));
  981. }
  982. CAMLprim value
  983. pyml_capsule_check(value v)
  984. {
  985. CAMLparam1(v);
  986. pyml_assert_initialized();
  987. PyObject *o = getcustom(v);
  988. PyObject *ob_type = pyobjectdescr(o)->ob_type;
  989. int check_result = ob_type == Python_PyCapsule_Type;
  990. CAMLreturn(Val_int(check_result));
  991. }
  992. CAMLprim value
  993. pyml_wrap_value(value v)
  994. {
  995. CAMLparam1(v);
  996. pyml_assert_initialized();
  997. PyObject *result = camlwrap_capsule(v, NULL, 0);
  998. CAMLreturn(pyml_wrap(result, true));
  999. }
  1000. CAMLprim value
  1001. pyml_unwrap_value(value x_ocaml)
  1002. {
  1003. CAMLparam1(x_ocaml);
  1004. CAMLlocal1(v);
  1005. pyml_assert_initialized();
  1006. PyObject *x = pyml_unwrap(x_ocaml);
  1007. void *p = unwrap_capsule(x, "ocaml-capsule");
  1008. if (!p) {
  1009. fprintf(stderr, "pyml_unwrap_value: type mismatch");
  1010. exit(EXIT_FAILURE);
  1011. }
  1012. v = *(value *) p;
  1013. CAMLreturn(v);
  1014. }
  1015. CAMLprim value
  1016. PyErr_Fetch_wrapper(value unit)
  1017. {
  1018. CAMLparam1(unit);
  1019. CAMLlocal1(result);
  1020. pyml_assert_initialized();
  1021. PyObject *excType, *excValue, *excTraceback;
  1022. Python_PyErr_Fetch(&excType, &excValue, &excTraceback);
  1023. Python_PyErr_NormalizeException(&excType, &excValue, &excTraceback);
  1024. result = caml_alloc_tuple(3);
  1025. Store_field(result, 0, pyml_wrap(excType, false));
  1026. Store_field(result, 1, pyml_wrap(excValue, false));
  1027. Store_field(result, 2, pyml_wrap(excTraceback, false));
  1028. CAMLreturn(result);
  1029. }
  1030. CAMLprim value
  1031. pyml_wrap_string_option(const char *s)
  1032. {
  1033. CAMLparam0();
  1034. CAMLlocal1(result);
  1035. if (!s) {
  1036. CAMLreturn(Val_int(0));
  1037. }
  1038. result = caml_alloc_tuple(1);
  1039. Store_field(result, 0, caml_copy_string(s));
  1040. CAMLreturn(result);
  1041. }
  1042. CAMLprim value
  1043. pyrefcount(value pyobj)
  1044. {
  1045. CAMLparam1(pyobj);
  1046. PyObject *obj = pyml_unwrap(pyobj);
  1047. CAMLreturn(Val_int(pyobjectdescr(obj)->ob_refcnt));
  1048. }
  1049. static value
  1050. pyml_wrap_wide_string(wchar_t *ws)
  1051. {
  1052. CAMLparam0();
  1053. CAMLlocal1(result);
  1054. size_t n = wcstombs(NULL, ws, 0);
  1055. if (n == (size_t) -1) {
  1056. fprintf(stderr, "pyml_wrap_wide_string failure.\n");
  1057. exit(EXIT_FAILURE);
  1058. }
  1059. char *s = xmalloc((n + 1) * sizeof (char));
  1060. wcstombs(s, ws, n);
  1061. result = caml_copy_string(s);
  1062. free(s);
  1063. CAMLreturn(result);
  1064. }
  1065. static wchar_t *
  1066. wide_string_of_string(const char *s)
  1067. {
  1068. size_t n = mbstowcs(NULL, s, 0);
  1069. if (n == (size_t) -1) {
  1070. fprintf(stderr, "wide_string_of_string failure.\n");
  1071. exit(EXIT_FAILURE);
  1072. }
  1073. wchar_t *ws = xmalloc((n + 1) * sizeof (wchar_t));
  1074. mbstowcs(ws, s, n);
  1075. return ws;
  1076. }
  1077. static wchar_t *
  1078. pyml_unwrap_wide_string(value string_ocaml)
  1079. {
  1080. CAMLparam1(string_ocaml);
  1081. wchar_t *ws = wide_string_of_string(String_val(string_ocaml));
  1082. CAMLreturnT(wchar_t *, ws);
  1083. }
  1084. static int16_t *
  1085. pyml_unwrap_ucs2(value array_ocaml)
  1086. {
  1087. CAMLparam1(array_ocaml);
  1088. mlsize_t len = Wosize_val(array_ocaml);
  1089. int16_t *result = xmalloc(len * sizeof(int16_t));
  1090. size_t i;
  1091. for (i = 0; i < len; i++) {
  1092. result[i] = Field(array_ocaml, i);
  1093. }
  1094. CAMLreturnT(int16_t *, result);
  1095. }
  1096. static int32_t *
  1097. pyml_unwrap_ucs4(value array_ocaml)
  1098. {
  1099. CAMLparam1(array_ocaml);
  1100. mlsize_t len = Wosize_val(array_ocaml);
  1101. int32_t *result = xmalloc(len * sizeof(int32_t));
  1102. size_t i;
  1103. for (i = 0; i < len; i++) {
  1104. result[i] = Field(array_ocaml, i);
  1105. }
  1106. CAMLreturnT(int32_t *, result);
  1107. }
  1108. static value
  1109. pyml_wrap_ucs2_option(int16_t *buffer)
  1110. {
  1111. CAMLparam0();
  1112. CAMLlocal2(result, array);
  1113. mlsize_t len;
  1114. if (buffer == NULL) {
  1115. CAMLreturn(Val_int(0));
  1116. }
  1117. len = 0;
  1118. while (buffer[len]) {
  1119. len++;
  1120. }
  1121. array = caml_alloc_tuple(len);
  1122. size_t i;
  1123. for (i = 0; i < len; i++) {
  1124. Store_field(array, i, buffer[i]);
  1125. }
  1126. result = caml_alloc_tuple(1);
  1127. Store_field(result, 0, array);
  1128. CAMLreturn(result);
  1129. }
  1130. static value
  1131. pyml_wrap_ucs4_option_and_free(int32_t *buffer, bool free)
  1132. {
  1133. CAMLparam0();
  1134. CAMLlocal2(result, array);
  1135. mlsize_t len;
  1136. if (buffer == NULL) {
  1137. CAMLreturn(Val_int(0));
  1138. }
  1139. len = 0;
  1140. while (buffer[len]) {
  1141. len++;
  1142. }
  1143. array = caml_alloc_tuple(len);
  1144. size_t i;
  1145. for (i = 0; i < len; i++) {
  1146. Store_field(array, i, buffer[i]);
  1147. }
  1148. result = caml_alloc_tuple(1);
  1149. Store_field(result, 0, array);
  1150. if (free) {
  1151. Python_PyMem_Free(buffer);
  1152. }
  1153. CAMLreturn(result);
  1154. }
  1155. #define StringAndSize_wrapper(func, byte_type) \
  1156. CAMLprim value \
  1157. func##_wrapper(value arg_ocaml) \
  1158. { \
  1159. CAMLparam1(arg_ocaml); \
  1160. CAMLlocal2(result, string); \
  1161. PyObject *arg = pyml_unwrap(arg_ocaml); \
  1162. byte_type *buffer; \
  1163. Py_ssize_t length; \
  1164. int return_value; \
  1165. return_value = Python_##func(arg, &buffer, &length); \
  1166. if (return_value == -1) { \
  1167. CAMLreturn(Val_int(0)); \
  1168. } \
  1169. string = caml_alloc_initialized_string(length, buffer); \
  1170. result = caml_alloc_tuple(1); \
  1171. Store_field(result, 0, string); \
  1172. CAMLreturn(result); \
  1173. }
  1174. StringAndSize_wrapper(PyString_AsStringAndSize, char);
  1175. StringAndSize_wrapper(PyObject_AsCharBuffer, const char);
  1176. StringAndSize_wrapper(PyObject_AsReadBuffer, const void);
  1177. StringAndSize_wrapper(PyObject_AsWriteBuffer, void);
  1178. static FILE *
  1179. open_file(value file, const char *mode)
  1180. {
  1181. CAMLparam1(file);
  1182. FILE *result;
  1183. if (Tag_val(file) == 0) {
  1184. const char *filename = String_val(Field(file, 0));
  1185. if (Python__Py_fopen != NULL) {
  1186. result = Python__Py_fopen(filename, mode);
  1187. }
  1188. else if (Python__Py_wfopen != NULL) {
  1189. wchar_t *wide_filename = wide_string_of_string(filename);
  1190. result = Python__Py_wfopen(wide_filename, mode);
  1191. free(wide_filename);
  1192. }
  1193. else {
  1194. result = fopen(filename, mode);
  1195. }
  1196. }
  1197. else {
  1198. result = file_of_file_descr(Field(file, 0), mode);
  1199. }
  1200. CAMLreturnT(FILE *, result);
  1201. }
  1202. static void
  1203. close_file(value file, FILE *file_struct)
  1204. {
  1205. CAMLparam1(file);
  1206. fclose(file_struct);
  1207. CAMLreturn0;
  1208. }
  1209. /* Numpy */
  1210. void **
  1211. pyml_get_pyarray_api(PyObject *c_api)
  1212. {
  1213. if (version_major >= 3) {
  1214. return (void **)Python27_PyCapsule_GetPointer(c_api, NULL);
  1215. }
  1216. else {
  1217. return (void **)Python2_PyCObject_AsVoidPtr(c_api);
  1218. }
  1219. }
  1220. CAMLprim value
  1221. get_pyarray_type(value numpy_api_ocaml)
  1222. {
  1223. CAMLparam1(numpy_api_ocaml);
  1224. PyObject *c_api = pyml_unwrap(numpy_api_ocaml);
  1225. void **PyArray_API = pyml_get_pyarray_api(c_api);
  1226. PyObject *result = PyArray_API[2];
  1227. CAMLreturn(pyml_wrap(result, true));
  1228. }
  1229. CAMLprim value
  1230. pyarray_of_floatarray_wrapper(
  1231. value numpy_api_ocaml, value array_type_ocaml, value array_ocaml)
  1232. {
  1233. CAMLparam3(numpy_api_ocaml, array_type_ocaml, array_ocaml);
  1234. pyml_assert_initialized();
  1235. PyObject *c_api = pyml_unwrap(numpy_api_ocaml);
  1236. void **PyArray_API = pyml_get_pyarray_api(c_api);
  1237. PyObject *(*PyArray_New)
  1238. (PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int,
  1239. PyObject *) = PyArray_API[93];
  1240. npy_intp length = Wosize_val(array_ocaml);
  1241. void *data = (double *) array_ocaml;
  1242. PyTypeObject (*PyArray_SubType) =
  1243. (PyTypeObject *) pyml_unwrap(array_type_ocaml);
  1244. PyObject *result = PyArray_New(
  1245. PyArray_SubType, 1, &length, NPY_DOUBLE, NULL, data, 0,
  1246. NPY_ARRAY_CARRAY, NULL);
  1247. CAMLreturn(pyml_wrap(result, true));
  1248. }
  1249. CAMLprim value
  1250. pyarray_move_floatarray_wrapper(value numpy_array_ocaml, value array_ocaml)
  1251. {
  1252. CAMLparam2(numpy_array_ocaml, array_ocaml);
  1253. pyml_assert_initialized();
  1254. PyObject *numpy_array = pyml_unwrap(numpy_array_ocaml);
  1255. PyArrayObject_fields *fields =
  1256. (PyArrayObject_fields *) pyobjectdescr(numpy_array);
  1257. fields->data = (void *) array_ocaml;
  1258. CAMLreturn(Val_unit);
  1259. }
  1260. CAMLprim value
  1261. PyLong_FromString_wrapper(value str_ocaml, value base_ocaml)
  1262. {
  1263. CAMLparam2(str_ocaml, base_ocaml);
  1264. CAMLlocal1(result);
  1265. pyml_assert_initialized();
  1266. const char *str = String_val(str_ocaml);
  1267. const char *pend;
  1268. int base = Int_val(base_ocaml);
  1269. PyObject *l = Python_PyLong_FromString(str, &pend, base);
  1270. ssize_t len = pend - str;
  1271. result = caml_alloc_tuple(2);
  1272. Store_field(result, 0, pyml_wrap(l, true));
  1273. Store_field(result, 1, Val_int(len));
  1274. CAMLreturn(result);
  1275. }
  1276. CAMLprim value
  1277. Python27_PyCapsule_IsValid_wrapper(value arg0_ocaml, value arg1_ocaml)
  1278. {
  1279. CAMLparam2(arg0_ocaml, arg1_ocaml);
  1280. pyml_assert_initialized();
  1281. if (!Python27_PyCapsule_IsValid) {
  1282. failwith("PyCapsule_IsValid is only available in Python >2.7");
  1283. }
  1284. PyObject *arg0 = pyml_unwrap(arg0_ocaml);
  1285. const char *arg1 = String_val(arg1_ocaml);
  1286. int result = Python27_PyCapsule_IsValid(arg0, arg1);
  1287. CAMLreturn(Val_int(result));
  1288. }
  1289. #include "pyml_wrappers.inc"