Home | History | Annotate | Download | only in python
      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 (at) 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 
     27 FILE *
     28 libxml_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 
     83 void libxml_PyFileRelease(FILE *f) {
     84     if (f != NULL)
     85         fclose(f);
     86 }
     87 #endif
     88 
     89 PyObject *
     90 libxml_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 
    101 PyObject *
    102 libxml_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 
    113 PyObject *
    114 libxml_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 
    125 PyObject *
    126 libxml_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 
    142 PyObject *
    143 libxml_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 
    158 PyObject *
    159 libxml_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 
    175 PyObject *
    176 libxml_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 
    191 PyObject *
    192 libxml_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 
    207 PyObject *
    208 libxml_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 
    223 PyObject *
    224 libxml_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 
    240 PyObject *
    241 libxml_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 
    256 PyObject *
    257 libxml_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 
    272 PyObject *
    273 libxml_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 
    288 PyObject *
    289 libxml_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 
    304 PyObject *
    305 libxml_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 
    320 PyObject *
    321 libxml_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 
    336 PyObject *
    337 libxml_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 
    352 PyObject *
    353 libxml_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 
    368 PyObject *
    369 libxml_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
    395 static void
    396 libxml_xmlXPathDestructNsNode(void *cap, void *desc ATTRIBUTE_UNUSED)
    397 #else
    398 static void
    399 libxml_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 
    412 PyObject *
    413 libxml_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 
    596 xmlXPathObjectPtr
    597 libxml_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 
    699 PyObject *
    700 libxml_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 
    719 PyObject *
    720 libxml_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 
    737 PyObject *
    738 libxml_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 
    755 PyObject *
    756 libxml_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
    774 PyObject *
    775 libxml_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
    794 PyObject *
    795 libxml_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 
    812 PyObject *
    813 libxml_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
    832 PyObject *
    833 libxml_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 
    850 PyObject *
    851 libxml_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 }
    867 PyObject *
    868 libxml_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 
    885 PyObject *
    886 libxml_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 
    903 PyObject *
    904 libxml_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 
    922 PyObject *
    923 libxml_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 
    943 PyObject *
    944 libxml_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