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