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 * daniel@veillard.com
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
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 *
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
222 void libxml_PyFileRelease(FILE *f) {
223 if (f != NULL)
224 fclose(f);
225 }
226 #endif
227
228 PyObject *
229 libxml_intWrap(int val)
230 {
231 PyObject *ret;
232
233 ret = PY_IMPORT_INT((long) val);
234 return (ret);
235 }
236
237 PyObject *
238 libxml_longWrap(long val)
239 {
240 PyObject *ret;
241
242 ret = PyLong_FromLong(val);
243 return (ret);
244 }
245
246 PyObject *
247 libxml_doubleWrap(double val)
248 {
249 PyObject *ret;
250
251 ret = PyFloat_FromDouble((double) val);
252 return (ret);
253 }
254
255 PyObject *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
428 libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt)
429 {
430 PyObject *ret;
431
432 if (ctxt == NULL) {
433 Py_INCREF(Py_None);
434 return (Py_None);
435 }
436 ret = PyCapsule_New((void *) ctxt, (char *) "xmlXPathContextPtr", NULL);
437 return (ret);
438 }
439
440 PyObject *
441 libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt)
442 {
443 PyObject *ret;
444
445 if (ctxt == NULL) {
446 Py_INCREF(Py_None);
447 return (Py_None);
448 }
449 ret = PyCapsule_New((void *)ctxt, (char *)"xmlXPathParserContextPtr", NULL);
450 return (ret);
451 }
452
453 PyObject *
454 libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt)
455 {
456 PyObject *ret;
457
458 if (ctxt == NULL) {
459 Py_INCREF(Py_None);
460 return (Py_None);
461 }
462
463 ret = PyCapsule_New((void *) ctxt, (char *) "xmlParserCtxtPtr", NULL);
464 return (ret);
465 }
466
467 /**
468 * libxml_xmlXPathDestructNsNode:
469 * cap: xmlNsPtr namespace node capsule object
470 *
471 * This function is called if and when a namespace node returned in
472 * an XPath node set is to be destroyed. That's the only kind of
473 * object returned in node set not directly linked to the original
474 * xmlDoc document, see xmlXPathNodeSetDupNs.
475 */
476 #if PY_VERSION_HEX < 0x02070000
477 static void
478 libxml_xmlXPathDestructNsNode(void *cap, void *desc ATTRIBUTE_UNUSED)
479 #else
480 static void
481 libxml_xmlXPathDestructNsNode(PyObject *cap)
482 #endif
483 {
484 #if PY_VERSION_HEX < 0x02070000
485 xmlXPathNodeSetFreeNs((xmlNsPtr) cap);
486 #else
487 xmlXPathNodeSetFreeNs((xmlNsPtr) PyCapsule_GetPointer(cap, "xmlNsPtr"));
488 #endif
489 }
490
491 PyObject *
492 libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)
493 {
494 PyObject *ret;
495
496 if (obj == NULL) {
497 Py_INCREF(Py_None);
498 return (Py_None);
499 }
500 switch (obj->type) {
501 case XPATH_XSLT_TREE: {
502 if ((obj->nodesetval == NULL) ||
503 (obj->nodesetval->nodeNr == 0) ||
504 (obj->nodesetval->nodeTab == NULL)) {
505 ret = PyList_New(0);
506 } else {
507 int i, len = 0;
508 xmlNodePtr node;
509
510 node = obj->nodesetval->nodeTab[0]->children;
511 while (node != NULL) {
512 len++;
513 node = node->next;
514 }
515 ret = PyList_New(len);
516 node = obj->nodesetval->nodeTab[0]->children;
517 for (i = 0;i < len;i++) {
518 PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
519 node = node->next;
520 }
521 }
522 /*
523 * Return now, do not free the object passed down
524 */
525 return (ret);
526 }
527 case XPATH_NODESET:
528 if ((obj->nodesetval == NULL)
529 || (obj->nodesetval->nodeNr == 0)) {
530 ret = PyList_New(0);
531 } else {
532 int i;
533 xmlNodePtr node;
534
535 ret = PyList_New(obj->nodesetval->nodeNr);
536 for (i = 0; i < obj->nodesetval->nodeNr; i++) {
537 node = obj->nodesetval->nodeTab[i];
538 if (node->type == XML_NAMESPACE_DECL) {
539 PyObject *ns = PyCapsule_New((void *) node,
540 (char *) "xmlNsPtr",
541 libxml_xmlXPathDestructNsNode);
542 PyList_SetItem(ret, i, ns);
543 /* make sure the xmlNsPtr is not destroyed now */
544 obj->nodesetval->nodeTab[i] = NULL;
545 } else {
546 PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
547 }
548 }
549 }
550 break;
551 case XPATH_BOOLEAN:
552 ret = PY_IMPORT_INT((long) obj->boolval);
553 break;
554 case XPATH_NUMBER:
555 ret = PyFloat_FromDouble(obj->floatval);
556 break;
557 case XPATH_STRING:
558 ret = PY_IMPORT_STRING((char *) obj->stringval);
559 break;
560 #ifdef LIBXML_XPTR_LOCS_ENABLED
561 case XPATH_POINT:
562 {
563 PyObject *node;
564 PyObject *indexIntoNode;
565 PyObject *tuple;
566
567 node = libxml_xmlNodePtrWrap(obj->user);
568 indexIntoNode = PY_IMPORT_INT((long) obj->index);
569
570 tuple = PyTuple_New(2);
571 PyTuple_SetItem(tuple, 0, node);
572 PyTuple_SetItem(tuple, 1, indexIntoNode);
573
574 ret = tuple;
575 break;
576 }
577 case XPATH_RANGE:
578 {
579 unsigned short bCollapsedRange;
580
581 bCollapsedRange = ( (obj->user2 == NULL) ||
582 ((obj->user2 == obj->user) && (obj->index == obj->index2)) );
583 if ( bCollapsedRange ) {
584 PyObject *node;
585 PyObject *indexIntoNode;
586 PyObject *tuple;
587 PyObject *list;
588
589 list = PyList_New(1);
590
591 node = libxml_xmlNodePtrWrap(obj->user);
592 indexIntoNode = PY_IMPORT_INT((long) obj->index);
593
594 tuple = PyTuple_New(2);
595 PyTuple_SetItem(tuple, 0, node);
596 PyTuple_SetItem(tuple, 1, indexIntoNode);
597
598 PyList_SetItem(list, 0, tuple);
599
600 ret = list;
601 } else {
602 PyObject *node;
603 PyObject *indexIntoNode;
604 PyObject *tuple;
605 PyObject *list;
606
607 list = PyList_New(2);
608
609 node = libxml_xmlNodePtrWrap(obj->user);
610 indexIntoNode = PY_IMPORT_INT((long) obj->index);
611
612 tuple = PyTuple_New(2);
613 PyTuple_SetItem(tuple, 0, node);
614 PyTuple_SetItem(tuple, 1, indexIntoNode);
615
616 PyList_SetItem(list, 0, tuple);
617
618 node = libxml_xmlNodePtrWrap(obj->user2);
619 indexIntoNode = PY_IMPORT_INT((long) obj->index2);
620
621 tuple = PyTuple_New(2);
622 PyTuple_SetItem(tuple, 0, node);
623 PyTuple_SetItem(tuple, 1, indexIntoNode);
624
625 PyList_SetItem(list, 1, tuple);
626
627 ret = list;
628 }
629 break;
630 }
631 case XPATH_LOCATIONSET:
632 {
633 xmlLocationSetPtr set;
634
635 set = obj->user;
636 if ( set && set->locNr > 0 ) {
637 int i;
638 PyObject *list;
639
640 list = PyList_New(set->locNr);
641
642 for (i=0; i<set->locNr; i++) {
643 xmlXPathObjectPtr setobj;
644 PyObject *pyobj;
645
646 setobj = set->locTab[i]; /*xmlXPathObjectPtr setobj*/
647
648 pyobj = libxml_xmlXPathObjectPtrWrap(setobj);
649 /* xmlXPathFreeObject(setobj) is called */
650 set->locTab[i] = NULL;
651
652 PyList_SetItem(list, i, pyobj);
653 }
654 set->locNr = 0;
655 ret = list;
656 } else {
657 Py_INCREF(Py_None);
658 ret = Py_None;
659 }
660 break;
661 }
662 #endif /* LIBXML_XPTR_LOCS_ENABLED */
663 default:
664 Py_INCREF(Py_None);
665 ret = Py_None;
666 }
667 xmlXPathFreeObject(obj);
668 return (ret);
669 }
670
671 xmlXPathObjectPtr
672 libxml_xmlXPathObjectPtrConvert(PyObject *obj)
673 {
674 xmlXPathObjectPtr ret = NULL;
675
676 if (obj == NULL) {
677 return (NULL);
678 }
679 if (PyFloat_Check (obj)) {
680 ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
681 } else if (PyLong_Check(obj)) {
682 #ifdef PyLong_AS_LONG
683 ret = xmlXPathNewFloat((double) PyLong_AS_LONG(obj));
684 #else
685 ret = xmlXPathNewFloat((double) PyInt_AS_LONG(obj));
686 #endif
687 #ifdef PyBool_Check
688 } else if (PyBool_Check (obj)) {
689
690 if (obj == Py_True) {
691 ret = xmlXPathNewBoolean(1);
692 }
693 else {
694 ret = xmlXPathNewBoolean(0);
695 }
696 #endif
697 } else if (PyBytes_Check (obj)) {
698 xmlChar *str;
699
700 str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(obj),
701 PyBytes_GET_SIZE(obj));
702 ret = xmlXPathWrapString(str);
703 #ifdef PyUnicode_Check
704 } else if (PyUnicode_Check (obj)) {
705 #if PY_VERSION_HEX >= 0x03030000
706 xmlChar *str;
707 const char *tmp;
708 Py_ssize_t size;
709
710 /* tmp doesn't need to be deallocated */
711 tmp = PyUnicode_AsUTF8AndSize(obj, &size);
712 str = xmlStrndup((const xmlChar *) tmp, (int) size);
713 ret = xmlXPathWrapString(str);
714 #else
715 xmlChar *str = NULL;
716 PyObject *b;
717
718 b = PyUnicode_AsUTF8String(obj);
719 if (b != NULL) {
720 str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(b),
721 PyBytes_GET_SIZE(b));
722 Py_DECREF(b);
723 }
724 ret = xmlXPathWrapString(str);
725 #endif
726 #endif
727 } else if (PyList_Check (obj)) {
728 int i;
729 PyObject *node;
730 xmlNodePtr cur;
731 xmlNodeSetPtr set;
732
733 set = xmlXPathNodeSetCreate(NULL);
734
735 for (i = 0; i < PyList_Size(obj); i++) {
736 node = PyList_GetItem(obj, i);
737 if ((node == NULL) || (node->ob_type == NULL))
738 continue;
739
740 cur = NULL;
741 if (PyCapsule_CheckExact(node)) {
742 cur = PyxmlNode_Get(node);
743 } else if ((PyObject_HasAttrString(node, (char *) "_o")) &&
744 (PyObject_HasAttrString(node, (char *) "get_doc"))) {
745 PyObject *wrapper;
746
747 wrapper = PyObject_GetAttrString(node, (char *) "_o");
748 if (wrapper != NULL)
749 cur = PyxmlNode_Get(wrapper);
750 } else {
751 }
752 if (cur != NULL) {
753 xmlXPathNodeSetAdd(set, cur);
754 }
755 }
756 ret = xmlXPathWrapNodeSet(set);
757 } else {
758 }
759 return (ret);
760 }
761
762 PyObject *
763 libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid)
764 {
765 PyObject *ret;
766
767 if (valid == NULL) {
768 Py_INCREF(Py_None);
769 return (Py_None);
770 }
771
772 ret =
773 PyCapsule_New((void *) valid,
774 (char *) "xmlValidCtxtPtr", NULL);
775
776 return (ret);
777 }
778
779 PyObject *
780 libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)
781 {
782 PyObject *ret;
783
784 if (catal == NULL) {
785 Py_INCREF(Py_None);
786 return (Py_None);
787 }
788 ret =
789 PyCapsule_New((void *) catal,
790 (char *) "xmlCatalogPtr", NULL);
791 return (ret);
792 }
793
794 PyObject *
795 libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer)
796 {
797 PyObject *ret;
798
799 if (buffer == NULL) {
800 Py_INCREF(Py_None);
801 return (Py_None);
802 }
803 ret =
804 PyCapsule_New((void *) buffer,
805 (char *) "xmlOutputBufferPtr", NULL);
806 return (ret);
807 }
808
809 PyObject *
810 libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer)
811 {
812 PyObject *ret;
813
814 if (buffer == NULL) {
815 Py_INCREF(Py_None);
816 return (Py_None);
817 }
818 ret =
819 PyCapsule_New((void *) buffer,
820 (char *) "xmlParserInputBufferPtr", NULL);
821 return (ret);
822 }
823
824 #ifdef LIBXML_REGEXP_ENABLED
825 PyObject *
826 libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp)
827 {
828 PyObject *ret;
829
830 if (regexp == NULL) {
831 Py_INCREF(Py_None);
832 return (Py_None);
833 }
834 ret =
835 PyCapsule_New((void *) regexp,
836 (char *) "xmlRegexpPtr", NULL);
837 return (ret);
838 }
839 #endif /* LIBXML_REGEXP_ENABLED */
840
841 #ifdef LIBXML_READER_ENABLED
842 PyObject *
843 libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)
844 {
845 PyObject *ret;
846
847 if (reader == NULL) {
848 Py_INCREF(Py_None);
849 return (Py_None);
850 }
851 ret =
852 PyCapsule_New((void *) reader,
853 (char *) "xmlTextReaderPtr", NULL);
854 return (ret);
855 }
856
857 PyObject *
858 libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator)
859 {
860 PyObject *ret;
861
862 if (locator == NULL) {
863 Py_INCREF(Py_None);
864 return (Py_None);
865 }
866 ret =
867 PyCapsule_New((void *) locator,
868 (char *) "xmlTextReaderLocatorPtr", NULL);
869 return (ret);
870 }
871 #endif /* LIBXML_READER_ENABLED */
872
873 #ifdef LIBXML_SCHEMAS_ENABLED
874 PyObject *
875 libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt)
876 {
877 PyObject *ret;
878
879 if (ctxt == NULL) {
880 Py_INCREF(Py_None);
881 return (Py_None);
882 }
883 ret =
884 PyCapsule_New((void *) ctxt,
885 (char *) "xmlRelaxNGPtr", NULL);
886 return (ret);
887 }
888
889 PyObject *
890 libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt)
891 {
892 PyObject *ret;
893
894 if (ctxt == NULL) {
895 Py_INCREF(Py_None);
896 return (Py_None);
897 }
898 ret =
899 PyCapsule_New((void *) ctxt,
900 (char *) "xmlRelaxNGParserCtxtPtr", NULL);
901 return (ret);
902 }
903 PyObject *
904 libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid)
905 {
906 PyObject *ret;
907
908 if (valid == NULL) {
909 Py_INCREF(Py_None);
910 return (Py_None);
911 }
912 ret =
913 PyCapsule_New((void *) valid,
914 (char *) "xmlRelaxNGValidCtxtPtr", NULL);
915 return (ret);
916 }
917
918 PyObject *
919 libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt)
920 {
921 PyObject *ret;
922
923 if (ctxt == NULL) {
924 Py_INCREF(Py_None);
925 return (Py_None);
926 }
927 ret =
928 PyCapsule_New((void *) ctxt,
929 (char *) "xmlSchemaPtr", NULL);
930 return (ret);
931 }
932
933 PyObject *
934 libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt)
935 {
936 PyObject *ret;
937
938 if (ctxt == NULL) {
939 Py_INCREF(Py_None);
940 return (Py_None);
941 }
942 ret =
943 PyCapsule_New((void *) ctxt,
944 (char *) "xmlSchemaParserCtxtPtr", NULL);
945
946 return (ret);
947 }
948
949 PyObject *
950 libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid)
951 {
952 PyObject *ret;
953
954 if (valid == NULL) {
955 Py_INCREF(Py_None);
956 return (Py_None);
957 }
958
959 ret =
960 PyCapsule_New((void *) valid,
961 (char *) "xmlSchemaValidCtxtPtr", NULL);
962
963 return (ret);
964 }
965 #endif /* LIBXML_SCHEMAS_ENABLED */
966
967 static void
968 libxml_xmlDestructError(PyObject *cap) {
969 xmlErrorPtr err = (xmlErrorPtr) PyCapsule_GetPointer(cap, "xmlErrorPtr");
970 xmlResetError(err);
971 xmlFree(err);
972 }
973
974 PyObject *
975 libxml_xmlErrorPtrWrap(const xmlError *error)
976 {
977 PyObject *ret;
978 xmlErrorPtr copy;
979
980 if (error == NULL) {
981 Py_INCREF(Py_None);
982 return (Py_None);
983 }
984 copy = xmlMalloc(sizeof(*copy));
985 if (copy == NULL) {
986 Py_INCREF(Py_None);
987 return (Py_None);
988 }
989 memset(copy, 0, sizeof(*copy));
990 xmlCopyError(error, copy);
991 ret = PyCapsule_New(copy, "xmlErrorPtr", libxml_xmlDestructError);
992 return (ret);
993 }