1 /*
2 * types.c: converter functions between the internal representation
3 * and the Python objects
4 *
5 * See Copyright for the status of this software.
6 *
7 * [email protected]
8 */
9 #include "libxml_wrap.h"
10 #include <libxml/xpathInternals.h>
11 #include <string.h>
12
13 #if PY_MAJOR_VERSION >= 3
14 #define PY_IMPORT_STRING_SIZE PyUnicode_FromStringAndSize
15 #define PY_IMPORT_STRING PyUnicode_FromString
16 #define PY_IMPORT_INT PyLong_FromLong
17 #else
18 #define PY_IMPORT_STRING_SIZE PyString_FromStringAndSize
19 #define PY_IMPORT_STRING PyString_FromString
20 #define PY_IMPORT_INT PyInt_FromLong
21 #endif
22
23 #if PY_MAJOR_VERSION >= 3
24 #include <stdio.h>
25 #include <stdint.h>
26
27 #ifdef _WIN32
28
29 #include <windows.h>
30 #include <crtdbg.h>
31
32 /* Taken from info on MSDN site, as we may not have the Windows WDK/DDK headers */
33 typedef struct _IO_STATUS_BLOCK {
34 union {
35 NTSTATUS Status;
36 PVOID Pointer;
37 } DUMMYUNIONNAME;
38 ULONG_PTR Information;
39 } IO_STATUS_BLOCK;
40
41 typedef struct _FILE_ACCESS_INFORMATION {
42 ACCESS_MASK AccessFlags;
43 } FILE_ACCESS_INFORMATION;
44
45 typedef NTSTATUS (*t_NtQueryInformationFile) (HANDLE FileHandle,
46 IO_STATUS_BLOCK *IoStatusBlock,
47 PVOID FileInformation,
48 ULONG Length,
49 int FileInformationClass); /* this is an Enum */
50
51 #if (defined (_MSC_VER) && _MSC_VER >= 1400)
52 /*
53 * This is the (empty) invalid parameter handler
54 * that is used for Visual C++ 2005 (and later) builds
55 * so that we can use this instead of the system automatically
56 * aborting the process.
57 *
58 * This is necessary as we use _get_oshandle() to check the validity
59 * of the file descriptors as we close them, so when an invalid file
60 * descriptor is passed into that function as we check on it, we get
61 * -1 as the result, instead of the gspawn helper program aborting.
62 *
63 * Please see http://msdn.microsoft.com/zh-tw/library/ks2530z6%28v=vs.80%29.aspx
64 * for an explanation on this.
65 */
66 void
myInvalidParameterHandler(const wchar_t * expression,const wchar_t * function,const wchar_t * file,unsigned int line,uintptr_t pReserved)67 myInvalidParameterHandler(const wchar_t *expression,
68 const wchar_t *function,
69 const wchar_t *file,
70 unsigned int line,
71 uintptr_t pReserved)
72 {
73 }
74 #endif
75 #else
76 #include <unistd.h>
77 #include <fcntl.h>
78 #endif
79
80 FILE *
libxml_PyFileGet(PyObject * f)81 libxml_PyFileGet(PyObject *f) {
82 FILE *res;
83 const char *mode;
84 int fd = PyObject_AsFileDescriptor(f);
85
86 #ifdef _WIN32
87 intptr_t w_fh = -1;
88 HMODULE hntdll = NULL;
89 IO_STATUS_BLOCK status_block;
90 FILE_ACCESS_INFORMATION ai;
91 t_NtQueryInformationFile NtQueryInformationFile;
92 BOOL is_read = FALSE;
93 BOOL is_write = FALSE;
94 BOOL is_append = FALSE;
95
96 #if (defined (_MSC_VER) && _MSC_VER >= 1400)
97 /* set up our empty invalid parameter handler */
98 _invalid_parameter_handler oldHandler, newHandler;
99 newHandler = myInvalidParameterHandler;
100 oldHandler = _set_invalid_parameter_handler(newHandler);
101
102 /* Disable the message box for assertions. */
103 _CrtSetReportMode(_CRT_ASSERT, 0);
104 #endif
105
106 w_fh = _get_osfhandle(fd);
107
108 if (w_fh == -1)
109 return(NULL);
110
111 hntdll = GetModuleHandleW(L"ntdll.dll");
112
113 if (hntdll == NULL)
114 return(NULL);
115 XML_IGNORE_FPTR_CAST_WARNINGS
116 NtQueryInformationFile = (t_NtQueryInformationFile)GetProcAddress(hntdll, "NtQueryInformationFile");
117 XML_POP_WARNINGS
118
119 if (NtQueryInformationFile != NULL &&
120 (NtQueryInformationFile((HANDLE)w_fh,
121 &status_block,
122 &ai,
123 sizeof(FILE_ACCESS_INFORMATION),
124 8) == 0)) /* 8 means "FileAccessInformation" */
125 {
126 if (ai.AccessFlags & FILE_READ_DATA)
127 is_read = TRUE;
128 if (ai.AccessFlags & FILE_WRITE_DATA)
129 is_write = TRUE;
130 if (ai.AccessFlags & FILE_APPEND_DATA)
131 is_append = TRUE;
132
133 if (is_write) {
134 if (is_read) {
135 if (is_append)
136 mode = "a+";
137 else
138 mode = "rw";
139 } else {
140 if (is_append)
141 mode = "a";
142 else
143 mode = "w";
144 }
145 } else {
146 if (is_append)
147 mode = "r+";
148 else
149 mode = "r";
150 }
151 }
152
153 FreeLibrary(hntdll);
154
155 if (!is_write && !is_read) /* also happens if we did not load or run NtQueryInformationFile() successfully */
156 return(NULL);
157 #else
158 int flags;
159
160 /*
161 * macOS returns O_RDWR for standard streams, but fails to write to
162 * stdout or stderr when opened with fdopen(dup_fd, "rw").
163 */
164 switch (fd) {
165 case STDIN_FILENO:
166 mode = "r";
167 break;
168 case STDOUT_FILENO:
169 case STDERR_FILENO:
170 mode = "w";
171 break;
172 default:
173 /*
174 * Get the flags on the fd to understand how it was opened
175 */
176 flags = fcntl(fd, F_GETFL, 0);
177 switch (flags & O_ACCMODE) {
178 case O_RDWR:
179 if (flags & O_APPEND)
180 mode = "a+";
181 else
182 mode = "rw";
183 break;
184 case O_RDONLY:
185 if (flags & O_APPEND)
186 mode = "r+";
187 else
188 mode = "r";
189 break;
190 case O_WRONLY:
191 if (flags & O_APPEND)
192 mode = "a";
193 else
194 mode = "w";
195 break;
196 default:
197 return(NULL);
198 }
199 }
200 #endif
201
202 /*
203 * the FILE struct gets a new fd, so that it can be closed
204 * independently of the file descriptor given. The risk though is
205 * lack of sync. So at the python level sync must be implemented
206 * before and after a conversion took place. No way around it
207 * in the Python3 infrastructure !
208 * The duplicated fd and FILE * will be released in the subsequent
209 * call to libxml_PyFileRelease() which must be generated accordingly
210 */
211 fd = dup(fd);
212 if (fd == -1)
213 return(NULL);
214 res = fdopen(fd, mode);
215 if (res == NULL) {
216 close(fd);
217 return(NULL);
218 }
219 return(res);
220 }
221
libxml_PyFileRelease(FILE * f)222 void libxml_PyFileRelease(FILE *f) {
223 if (f != NULL)
224 fclose(f);
225 }
226 #endif
227
228 PyObject *
libxml_intWrap(int val)229 libxml_intWrap(int val)
230 {
231 PyObject *ret;
232
233 ret = PY_IMPORT_INT((long) val);
234 return (ret);
235 }
236
237 PyObject *
libxml_longWrap(long val)238 libxml_longWrap(long val)
239 {
240 PyObject *ret;
241
242 ret = PyLong_FromLong(val);
243 return (ret);
244 }
245
246 PyObject *
libxml_doubleWrap(double val)247 libxml_doubleWrap(double val)
248 {
249 PyObject *ret;
250
251 ret = PyFloat_FromDouble((double) val);
252 return (ret);
253 }
254
255 PyObject *
libxml_charPtrWrap(char * str)256 libxml_charPtrWrap(char *str)
257 {
258 PyObject *ret;
259
260 if (str == NULL) {
261 Py_INCREF(Py_None);
262 return (Py_None);
263 }
264 ret = PY_IMPORT_STRING(str);
265 xmlFree(str);
266 return (ret);
267 }
268
269 PyObject *
libxml_charPtrConstWrap(const char * str)270 libxml_charPtrConstWrap(const char *str)
271 {
272 PyObject *ret;
273
274 if (str == NULL) {
275 Py_INCREF(Py_None);
276 return (Py_None);
277 }
278 ret = PY_IMPORT_STRING(str);
279 return (ret);
280 }
281
282 PyObject *
libxml_xmlCharPtrWrap(xmlChar * str)283 libxml_xmlCharPtrWrap(xmlChar * str)
284 {
285 PyObject *ret;
286
287 if (str == NULL) {
288 Py_INCREF(Py_None);
289 return (Py_None);
290 }
291 ret = PY_IMPORT_STRING((char *) str);
292 xmlFree(str);
293 return (ret);
294 }
295
296 PyObject *
libxml_xmlCharPtrConstWrap(const xmlChar * str)297 libxml_xmlCharPtrConstWrap(const xmlChar * str)
298 {
299 PyObject *ret;
300
301 if (str == NULL) {
302 Py_INCREF(Py_None);
303 return (Py_None);
304 }
305 ret = PY_IMPORT_STRING((char *) str);
306 return (ret);
307 }
308
309 PyObject *
libxml_constcharPtrWrap(const char * str)310 libxml_constcharPtrWrap(const char *str)
311 {
312 PyObject *ret;
313
314 if (str == NULL) {
315 Py_INCREF(Py_None);
316 return (Py_None);
317 }
318 ret = PY_IMPORT_STRING(str);
319 return (ret);
320 }
321
322 PyObject *
libxml_constxmlCharPtrWrap(const xmlChar * str)323 libxml_constxmlCharPtrWrap(const xmlChar * str)
324 {
325 PyObject *ret;
326
327 if (str == NULL) {
328 Py_INCREF(Py_None);
329 return (Py_None);
330 }
331 ret = PY_IMPORT_STRING((char *) str);
332 return (ret);
333 }
334
335 PyObject *
libxml_xmlDocPtrWrap(xmlDocPtr doc)336 libxml_xmlDocPtrWrap(xmlDocPtr doc)
337 {
338 PyObject *ret;
339
340 if (doc == NULL) {
341 Py_INCREF(Py_None);
342 return (Py_None);
343 }
344 /* TODO: look at deallocation */
345 ret = PyCapsule_New((void *) doc, (char *) "xmlDocPtr", NULL);
346 return (ret);
347 }
348
349 PyObject *
libxml_xmlNodePtrWrap(xmlNodePtr node)350 libxml_xmlNodePtrWrap(xmlNodePtr node)
351 {
352 PyObject *ret;
353
354 if (node == NULL) {
355 Py_INCREF(Py_None);
356 return (Py_None);
357 }
358 ret = PyCapsule_New((void *) node, (char *) "xmlNodePtr", NULL);
359 return (ret);
360 }
361
362 PyObject *
libxml_xmlURIPtrWrap(xmlURIPtr uri)363 libxml_xmlURIPtrWrap(xmlURIPtr uri)
364 {
365 PyObject *ret;
366
367 if (uri == NULL) {
368 Py_INCREF(Py_None);
369 return (Py_None);
370 }
371 ret = PyCapsule_New((void *) uri, (char *) "xmlURIPtr", NULL);
372 return (ret);
373 }
374
375 PyObject *
libxml_xmlNsPtrWrap(xmlNsPtr ns)376 libxml_xmlNsPtrWrap(xmlNsPtr ns)
377 {
378 PyObject *ret;
379
380 if (ns == NULL) {
381 Py_INCREF(Py_None);
382 return (Py_None);
383 }
384 ret = PyCapsule_New((void *) ns, (char *) "xmlNsPtr", NULL);
385 return (ret);
386 }
387
388 PyObject *
libxml_xmlAttrPtrWrap(xmlAttrPtr attr)389 libxml_xmlAttrPtrWrap(xmlAttrPtr attr)
390 {
391 PyObject *ret;
392
393 if (attr == NULL) {
394 Py_INCREF(Py_None);
395 return (Py_None);
396 }
397 ret = PyCapsule_New((void *) attr, (char *) "xmlAttrPtr", NULL);
398 return (ret);
399 }
400
401 PyObject *
libxml_xmlAttributePtrWrap(xmlAttributePtr attr)402 libxml_xmlAttributePtrWrap(xmlAttributePtr attr)
403 {
404 PyObject *ret;
405
406 if (attr == NULL) {
407 Py_INCREF(Py_None);
408 return (Py_None);
409 }
410 ret = PyCapsule_New((void *) attr, (char *) "xmlAttributePtr", NULL);
411 return (ret);
412 }
413
414 PyObject *
libxml_xmlElementPtrWrap(xmlElementPtr elem)415 libxml_xmlElementPtrWrap(xmlElementPtr elem)
416 {
417 PyObject *ret;
418
419 if (elem == NULL) {
420 Py_INCREF(Py_None);
421 return (Py_None);
422 }
423 ret = PyCapsule_New((void *) elem, (char *) "xmlElementPtr", NULL);
424 return (ret);
425 }
426
427 PyObject *
libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt)428 libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt)
429 {
430 PyObject *ret;
431
432 if (ctxt == NULL) {
433 Py_INCREF(Py_None);
434 return (Py_None);
435 }
436
437 ret = PyCapsule_New((void *) ctxt, (char *) "xmlParserCtxtPtr", NULL);
438 return (ret);
439 }
440
441 #ifdef LIBXML_XPATH_ENABLED
442 PyObject *
libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt)443 libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt)
444 {
445 PyObject *ret;
446
447 if (ctxt == NULL) {
448 Py_INCREF(Py_None);
449 return (Py_None);
450 }
451 ret = PyCapsule_New((void *) ctxt, (char *) "xmlXPathContextPtr", NULL);
452 return (ret);
453 }
454
455 PyObject *
libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt)456 libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt)
457 {
458 PyObject *ret;
459
460 if (ctxt == NULL) {
461 Py_INCREF(Py_None);
462 return (Py_None);
463 }
464 ret = PyCapsule_New((void *)ctxt, (char *)"xmlXPathParserContextPtr", NULL);
465 return (ret);
466 }
467
468 /**
469 * libxml_xmlXPathDestructNsNode:
470 * cap: xmlNsPtr namespace node capsule object
471 *
472 * This function is called if and when a namespace node returned in
473 * an XPath node set is to be destroyed. That's the only kind of
474 * object returned in node set not directly linked to the original
475 * xmlDoc document, see xmlXPathNodeSetDupNs.
476 */
477 #if PY_VERSION_HEX < 0x02070000
478 static void
libxml_xmlXPathDestructNsNode(void * cap,void * desc ATTRIBUTE_UNUSED)479 libxml_xmlXPathDestructNsNode(void *cap, void *desc ATTRIBUTE_UNUSED)
480 #else
481 static void
482 libxml_xmlXPathDestructNsNode(PyObject *cap)
483 #endif
484 {
485 #if PY_VERSION_HEX < 0x02070000
486 xmlXPathNodeSetFreeNs((xmlNsPtr) cap);
487 #else
488 xmlXPathNodeSetFreeNs((xmlNsPtr) PyCapsule_GetPointer(cap, "xmlNsPtr"));
489 #endif
490 }
491
492 PyObject *
libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)493 libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)
494 {
495 PyObject *ret;
496
497 if (obj == NULL) {
498 Py_INCREF(Py_None);
499 return (Py_None);
500 }
501 switch (obj->type) {
502 case XPATH_XSLT_TREE: {
503 if ((obj->nodesetval == NULL) ||
504 (obj->nodesetval->nodeNr == 0) ||
505 (obj->nodesetval->nodeTab == NULL)) {
506 ret = PyList_New(0);
507 } else {
508 int i, len = 0;
509 xmlNodePtr node;
510
511 node = obj->nodesetval->nodeTab[0]->children;
512 while (node != NULL) {
513 len++;
514 node = node->next;
515 }
516 ret = PyList_New(len);
517 node = obj->nodesetval->nodeTab[0]->children;
518 for (i = 0;i < len;i++) {
519 PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
520 node = node->next;
521 }
522 }
523 /*
524 * Return now, do not free the object passed down
525 */
526 return (ret);
527 }
528 case XPATH_NODESET:
529 if ((obj->nodesetval == NULL)
530 || (obj->nodesetval->nodeNr == 0)) {
531 ret = PyList_New(0);
532 } else {
533 int i;
534 xmlNodePtr node;
535
536 ret = PyList_New(obj->nodesetval->nodeNr);
537 for (i = 0; i < obj->nodesetval->nodeNr; i++) {
538 node = obj->nodesetval->nodeTab[i];
539 if (node->type == XML_NAMESPACE_DECL) {
540 PyObject *ns = PyCapsule_New((void *) node,
541 (char *) "xmlNsPtr",
542 libxml_xmlXPathDestructNsNode);
543 PyList_SetItem(ret, i, ns);
544 /* make sure the xmlNsPtr is not destroyed now */
545 obj->nodesetval->nodeTab[i] = NULL;
546 } else {
547 PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
548 }
549 }
550 }
551 break;
552 case XPATH_BOOLEAN:
553 ret = PY_IMPORT_INT((long) obj->boolval);
554 break;
555 case XPATH_NUMBER:
556 ret = PyFloat_FromDouble(obj->floatval);
557 break;
558 case XPATH_STRING:
559 ret = PY_IMPORT_STRING((char *) obj->stringval);
560 break;
561 default:
562 Py_INCREF(Py_None);
563 ret = Py_None;
564 }
565 xmlXPathFreeObject(obj);
566 return (ret);
567 }
568
569 xmlXPathObjectPtr
libxml_xmlXPathObjectPtrConvert(PyObject * obj)570 libxml_xmlXPathObjectPtrConvert(PyObject *obj)
571 {
572 xmlXPathObjectPtr ret = NULL;
573
574 if (obj == NULL) {
575 return (NULL);
576 }
577 if (PyFloat_Check (obj)) {
578 ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
579 } else if (PyLong_Check(obj)) {
580 #ifdef PyLong_AS_LONG
581 ret = xmlXPathNewFloat((double) PyLong_AS_LONG(obj));
582 #else
583 ret = xmlXPathNewFloat((double) PyInt_AS_LONG(obj));
584 #endif
585 #ifdef PyBool_Check
586 } else if (PyBool_Check (obj)) {
587
588 if (obj == Py_True) {
589 ret = xmlXPathNewBoolean(1);
590 }
591 else {
592 ret = xmlXPathNewBoolean(0);
593 }
594 #endif
595 } else if (PyBytes_Check (obj)) {
596 xmlChar *str;
597
598 str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(obj),
599 PyBytes_GET_SIZE(obj));
600 ret = xmlXPathWrapString(str);
601 #ifdef PyUnicode_Check
602 } else if (PyUnicode_Check (obj)) {
603 #if PY_VERSION_HEX >= 0x03030000
604 xmlChar *str;
605 const char *tmp;
606 Py_ssize_t size;
607
608 /* tmp doesn't need to be deallocated */
609 tmp = PyUnicode_AsUTF8AndSize(obj, &size);
610 str = xmlStrndup((const xmlChar *) tmp, (int) size);
611 ret = xmlXPathWrapString(str);
612 #else
613 xmlChar *str = NULL;
614 PyObject *b;
615
616 b = PyUnicode_AsUTF8String(obj);
617 if (b != NULL) {
618 str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(b),
619 PyBytes_GET_SIZE(b));
620 Py_DECREF(b);
621 }
622 ret = xmlXPathWrapString(str);
623 #endif
624 #endif
625 } else if (PyList_Check (obj)) {
626 int i;
627 PyObject *node;
628 xmlNodePtr cur;
629 xmlNodeSetPtr set;
630
631 set = xmlXPathNodeSetCreate(NULL);
632
633 for (i = 0; i < PyList_Size(obj); i++) {
634 node = PyList_GetItem(obj, i);
635 if ((node == NULL) || (node->ob_type == NULL))
636 continue;
637
638 cur = NULL;
639 if (PyCapsule_CheckExact(node)) {
640 cur = PyxmlNode_Get(node);
641 } else if ((PyObject_HasAttrString(node, (char *) "_o")) &&
642 (PyObject_HasAttrString(node, (char *) "get_doc"))) {
643 PyObject *wrapper;
644
645 wrapper = PyObject_GetAttrString(node, (char *) "_o");
646 if (wrapper != NULL)
647 cur = PyxmlNode_Get(wrapper);
648 } else {
649 }
650 if (cur != NULL) {
651 xmlXPathNodeSetAdd(set, cur);
652 }
653 }
654 ret = xmlXPathWrapNodeSet(set);
655 } else {
656 }
657 return (ret);
658 }
659 #endif /* LIBXML_XPATH_ENABLED */
660
661 PyObject *
libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid)662 libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid)
663 {
664 PyObject *ret;
665
666 if (valid == NULL) {
667 Py_INCREF(Py_None);
668 return (Py_None);
669 }
670
671 ret =
672 PyCapsule_New((void *) valid,
673 (char *) "xmlValidCtxtPtr", NULL);
674
675 return (ret);
676 }
677
678 #ifdef LIBXML_CATALOG_ENABLED
679 PyObject *
libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)680 libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)
681 {
682 PyObject *ret;
683
684 if (catal == NULL) {
685 Py_INCREF(Py_None);
686 return (Py_None);
687 }
688 ret =
689 PyCapsule_New((void *) catal,
690 (char *) "xmlCatalogPtr", NULL);
691 return (ret);
692 }
693 #endif /* LIBXML_CATALOG_ENABLED */
694
695 PyObject *
libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer)696 libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer)
697 {
698 PyObject *ret;
699
700 if (buffer == NULL) {
701 Py_INCREF(Py_None);
702 return (Py_None);
703 }
704 ret =
705 PyCapsule_New((void *) buffer,
706 (char *) "xmlOutputBufferPtr", NULL);
707 return (ret);
708 }
709
710 PyObject *
libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer)711 libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer)
712 {
713 PyObject *ret;
714
715 if (buffer == NULL) {
716 Py_INCREF(Py_None);
717 return (Py_None);
718 }
719 ret =
720 PyCapsule_New((void *) buffer,
721 (char *) "xmlParserInputBufferPtr", NULL);
722 return (ret);
723 }
724
725 #ifdef LIBXML_REGEXP_ENABLED
726 PyObject *
libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp)727 libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp)
728 {
729 PyObject *ret;
730
731 if (regexp == NULL) {
732 Py_INCREF(Py_None);
733 return (Py_None);
734 }
735 ret =
736 PyCapsule_New((void *) regexp,
737 (char *) "xmlRegexpPtr", NULL);
738 return (ret);
739 }
740 #endif /* LIBXML_REGEXP_ENABLED */
741
742 #ifdef LIBXML_READER_ENABLED
743 PyObject *
libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)744 libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)
745 {
746 PyObject *ret;
747
748 if (reader == NULL) {
749 Py_INCREF(Py_None);
750 return (Py_None);
751 }
752 ret =
753 PyCapsule_New((void *) reader,
754 (char *) "xmlTextReaderPtr", NULL);
755 return (ret);
756 }
757
758 PyObject *
libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator)759 libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator)
760 {
761 PyObject *ret;
762
763 if (locator == NULL) {
764 Py_INCREF(Py_None);
765 return (Py_None);
766 }
767 ret =
768 PyCapsule_New((void *) locator,
769 (char *) "xmlTextReaderLocatorPtr", NULL);
770 return (ret);
771 }
772 #endif /* LIBXML_READER_ENABLED */
773
774 #ifdef LIBXML_SCHEMAS_ENABLED
775 PyObject *
libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt)776 libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt)
777 {
778 PyObject *ret;
779
780 if (ctxt == NULL) {
781 Py_INCREF(Py_None);
782 return (Py_None);
783 }
784 ret =
785 PyCapsule_New((void *) ctxt,
786 (char *) "xmlRelaxNGPtr", NULL);
787 return (ret);
788 }
789
790 PyObject *
libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt)791 libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt)
792 {
793 PyObject *ret;
794
795 if (ctxt == NULL) {
796 Py_INCREF(Py_None);
797 return (Py_None);
798 }
799 ret =
800 PyCapsule_New((void *) ctxt,
801 (char *) "xmlRelaxNGParserCtxtPtr", NULL);
802 return (ret);
803 }
804 PyObject *
libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid)805 libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid)
806 {
807 PyObject *ret;
808
809 if (valid == NULL) {
810 Py_INCREF(Py_None);
811 return (Py_None);
812 }
813 ret =
814 PyCapsule_New((void *) valid,
815 (char *) "xmlRelaxNGValidCtxtPtr", NULL);
816 return (ret);
817 }
818
819 PyObject *
libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt)820 libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt)
821 {
822 PyObject *ret;
823
824 if (ctxt == NULL) {
825 Py_INCREF(Py_None);
826 return (Py_None);
827 }
828 ret =
829 PyCapsule_New((void *) ctxt,
830 (char *) "xmlSchemaPtr", NULL);
831 return (ret);
832 }
833
834 PyObject *
libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt)835 libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt)
836 {
837 PyObject *ret;
838
839 if (ctxt == NULL) {
840 Py_INCREF(Py_None);
841 return (Py_None);
842 }
843 ret =
844 PyCapsule_New((void *) ctxt,
845 (char *) "xmlSchemaParserCtxtPtr", NULL);
846
847 return (ret);
848 }
849
850 PyObject *
libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid)851 libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid)
852 {
853 PyObject *ret;
854
855 if (valid == NULL) {
856 Py_INCREF(Py_None);
857 return (Py_None);
858 }
859
860 ret =
861 PyCapsule_New((void *) valid,
862 (char *) "xmlSchemaValidCtxtPtr", NULL);
863
864 return (ret);
865 }
866 #endif /* LIBXML_SCHEMAS_ENABLED */
867
868 static void
libxml_xmlDestructError(PyObject * cap)869 libxml_xmlDestructError(PyObject *cap) {
870 xmlErrorPtr err = (xmlErrorPtr) PyCapsule_GetPointer(cap, "xmlErrorPtr");
871 xmlResetError(err);
872 xmlFree(err);
873 }
874
875 PyObject *
libxml_xmlErrorPtrWrap(const xmlError * error)876 libxml_xmlErrorPtrWrap(const xmlError *error)
877 {
878 PyObject *ret;
879 xmlErrorPtr copy;
880
881 if (error == NULL) {
882 Py_INCREF(Py_None);
883 return (Py_None);
884 }
885 copy = xmlMalloc(sizeof(*copy));
886 if (copy == NULL) {
887 Py_INCREF(Py_None);
888 return (Py_None);
889 }
890 memset(copy, 0, sizeof(*copy));
891 xmlCopyError(error, copy);
892 ret = PyCapsule_New(copy, "xmlErrorPtr", libxml_xmlDestructError);
893 return (ret);
894 }
895