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