blob: 1a212791784d3c2d63bc8c63836d4c0b76a44fd2 [file] [log] [blame]
Daniel Veillard3ce52572002-02-03 15:08:05 +00001/*
2 * libxml.c: this modules implements the main part of the glue of the
3 * libxml2 library and the Python interpreter. It provides the
4 * entry points where an automatically generated stub is either
5 * unpractical or would not match cleanly the Python model.
6 *
7 * See Copyright for the status of this software.
8 *
9 * daniel@veillard.com
10 */
Daniel Veillardd2897fd2002-01-30 16:37:32 +000011#include <Python.h>
Daniel Veillardf1d0e6b2002-01-31 23:42:44 +000012#include <libxml/xmlmemory.h>
Daniel Veillardd2897fd2002-01-30 16:37:32 +000013#include <libxml/parser.h>
14#include <libxml/tree.h>
Daniel Veillarda7340c82002-02-01 17:56:45 +000015#include <libxml/xpath.h>
Daniel Veillard5d819032002-02-02 21:49:17 +000016#include <libxml/xmlerror.h>
Daniel Veillarda7340c82002-02-01 17:56:45 +000017#include <libxml/xpathInternals.h>
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000018#include <libxml/xmlmemory.h>
Daniel Veillardd2897fd2002-01-30 16:37:32 +000019#include "libxml_wrap.h"
Daniel Veillard96fe0952002-01-30 20:52:23 +000020#include "libxml2-py.h"
Daniel Veillardd2897fd2002-01-30 16:37:32 +000021
22/* #define DEBUG */
Daniel Veillard797a5652002-02-12 13:46:21 +000023/* #define DEBUG_SAX */
Daniel Veillarda7340c82002-02-01 17:56:45 +000024/* #define DEBUG_XPATH */
Daniel Veillard5d819032002-02-02 21:49:17 +000025/* #define DEBUG_ERROR */
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000026/* #define DEBUG_MEMORY */
27
28/************************************************************************
29 * *
30 * Memory debug interface *
31 * *
32 ************************************************************************/
33
34extern void xmlMemFree(void *ptr);
35extern void *xmlMemMalloc(size_t size);
36extern void *xmlMemRealloc(void *ptr,size_t size);
37extern char *xmlMemoryStrdup(const char *str);
38
39static int libxmlMemoryDebugActivated = 0;
40static long libxmlMemoryAllocatedBase = 0;
41
42static int libxmlMemoryDebug = 0;
43static xmlFreeFunc freeFunc = NULL;
44static xmlMallocFunc mallocFunc = NULL;
45static xmlReallocFunc reallocFunc = NULL;
46static xmlStrdupFunc strdupFunc = NULL;
47
48PyObject *
49libxml_xmlDebugMemory(PyObject *self, PyObject *args) {
50 int activate;
51 PyObject *py_retval;
52 long ret;
53
54 if (!PyArg_ParseTuple(args, "i:xmlDebugMemory", &activate))
55 return(NULL);
56
57#ifdef DEBUG_MEMORY
58 printf("libxml_xmlDebugMemory(%d) called\n", activate);
59#endif
60
61 if (activate != 0) {
62 if (libxmlMemoryDebug == 0) {
63 /*
64 * First initialize the library and grab the old memory handlers
65 * and switch the library to memory debugging
66 */
67 xmlMemGet((xmlFreeFunc *) &freeFunc,
68 (xmlMallocFunc *)&mallocFunc,
69 (xmlReallocFunc *)&reallocFunc,
70 (xmlStrdupFunc *) &strdupFunc);
71 if ((freeFunc == xmlMemFree) && (mallocFunc == xmlMemMalloc) &&
72 (reallocFunc == xmlMemRealloc) &&
73 (strdupFunc == xmlMemoryStrdup)) {
74 libxmlMemoryAllocatedBase = xmlMemUsed();
75 } else {
76 ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc,
77 xmlMemRealloc, xmlMemoryStrdup);
78 if (ret < 0)
79 goto error;
80 libxmlMemoryAllocatedBase = xmlMemUsed();
81 }
82 xmlInitParser();
83 ret = 0;
84 } else if (libxmlMemoryDebugActivated == 0) {
85 libxmlMemoryAllocatedBase = xmlMemUsed();
86 ret = 0;
87 } else {
88 ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
89 }
90 libxmlMemoryDebug = 1;
91 libxmlMemoryDebugActivated = 1;
92 } else {
93 if (libxmlMemoryDebugActivated == 1)
94 ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
95 else
96 ret = 0;
97 libxmlMemoryDebugActivated = 0;
98 }
99error:
100 py_retval = libxml_longWrap(ret);
101 return(py_retval);
102}
103
104PyObject *
105libxml_xmlDumpMemory(PyObject *self, PyObject *args) {
106
107 if (libxmlMemoryDebug != 0)
108 xmlMemoryDump();
109 Py_INCREF(Py_None);
110 return(Py_None);
111}
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000112
113/************************************************************************
114 * *
Daniel Veillard3ce52572002-02-03 15:08:05 +0000115 * Handling SAX/xmllib/sgmlop callback interfaces *
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000116 * *
117 ************************************************************************/
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000118
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000119static void
120pythonStartElement(void *user_data, const xmlChar * name,
121 const xmlChar ** attrs)
122{
123 int i;
124 PyObject *handler;
125 PyObject *dict;
126 PyObject *attrname;
127 PyObject *attrvalue;
128 PyObject *result;
129 int type = 0;
130
Daniel Veillard797a5652002-02-12 13:46:21 +0000131#ifdef DEBUG_SAX
132 printf("pythonStartElement(%s) called\n", name);
133#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000134 handler = (PyObject *) user_data;
135 if (PyObject_HasAttrString(handler, "startElement"))
136 type = 1;
137 else if (PyObject_HasAttrString(handler, "start"))
138 type = 2;
139 if (type != 0) {
140 /*
141 * the xmllib interface always generate a dictionnary,
142 * possibly empty
143 */
144 if ((attrs == NULL) && (type == 1)) {
145 Py_XINCREF(Py_None);
146 dict = Py_None;
Daniel Veillard797a5652002-02-12 13:46:21 +0000147 } else if (attrs == NULL) {
148 dict = PyDict_New();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000149 } else {
150 dict = PyDict_New();
151 for (i = 0; attrs[i] != NULL; i++) {
152 attrname = PyString_FromString(attrs[i]);
153 i++;
154 if (attrs[i] != NULL) {
155 attrvalue = PyString_FromString(attrs[i]);
156 } else {
157 Py_XINCREF(Py_None);
158 attrvalue = Py_None;
159 }
160 PyDict_SetItem(dict, attrname, attrvalue);
161 }
162 }
163
164 if (type == 1)
165 result = PyObject_CallMethod(handler, "startElement",
166 "sO", name, dict);
167 else if (type == 2)
168 result = PyObject_CallMethod(handler, "start",
169 "sO", name, dict);
170 if (PyErr_Occurred())
171 PyErr_Print();
172 Py_XDECREF(dict);
173 Py_XDECREF(result);
174 }
175}
176
177static void
178pythonStartDocument(void *user_data)
179{
180 PyObject *handler;
181 PyObject *result;
182
Daniel Veillard797a5652002-02-12 13:46:21 +0000183#ifdef DEBUG_SAX
184 printf("pythonStartDocument() called\n");
185#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000186 handler = (PyObject *) user_data;
187 if (PyObject_HasAttrString(handler, "startDocument")) {
188 result = PyObject_CallMethod(handler, "startDocument", NULL);
189 if (PyErr_Occurred())
190 PyErr_Print();
191 Py_XDECREF(result);
192 }
193}
194
195static void
196pythonEndDocument(void *user_data)
197{
198 PyObject *handler;
199 PyObject *result;
200
Daniel Veillard797a5652002-02-12 13:46:21 +0000201#ifdef DEBUG_SAX
202 printf("pythonEndDocument() called\n");
203#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000204 handler = (PyObject *) user_data;
205 if (PyObject_HasAttrString(handler, "endDocument")) {
206 result = PyObject_CallMethod(handler, "endDocument", NULL);
207 if (PyErr_Occurred())
208 PyErr_Print();
209 Py_XDECREF(result);
210 }
211 /*
212 * The reference to the handler is released there
213 */
214 Py_XDECREF(handler);
215}
216
217static void
218pythonEndElement(void *user_data, const xmlChar * name)
219{
220 PyObject *handler;
221 PyObject *result;
222
Daniel Veillard797a5652002-02-12 13:46:21 +0000223#ifdef DEBUG_SAX
224 printf("pythonEndElement(%s) called\n", name);
225#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000226 handler = (PyObject *) user_data;
227 if (PyObject_HasAttrString(handler, "endElement")) {
228 result = PyObject_CallMethod(handler, "endElement", "s", name);
229 if (PyErr_Occurred())
230 PyErr_Print();
231 Py_XDECREF(result);
Daniel Veillard797a5652002-02-12 13:46:21 +0000232 } else if (PyObject_HasAttrString(handler, "end")) {
233 result = PyObject_CallMethod(handler, "end", "s", name);
234 if (PyErr_Occurred())
235 PyErr_Print();
236 Py_XDECREF(result);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000237 }
238}
239
240static void
241pythonReference(void *user_data, const xmlChar * name)
242{
243 PyObject *handler;
244 PyObject *result;
245
Daniel Veillard797a5652002-02-12 13:46:21 +0000246#ifdef DEBUG_SAX
247 printf("pythonReference(%s) called\n", name);
248#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000249 handler = (PyObject *) user_data;
250 if (PyObject_HasAttrString(handler, "reference")) {
251 result = PyObject_CallMethod(handler, "reference", "s", name);
252 if (PyErr_Occurred())
253 PyErr_Print();
254 Py_XDECREF(result);
255 }
256}
257
258static void
259pythonCharacters(void *user_data, const xmlChar * ch, int len)
260{
261 PyObject *handler;
262 PyObject *result;
263 int type = 0;
264
Daniel Veillard797a5652002-02-12 13:46:21 +0000265#ifdef DEBUG_SAX
266 printf("pythonCharacters(%s, %d) called\n", ch, len);
267#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000268 handler = (PyObject *) user_data;
269 if (PyObject_HasAttrString(handler, "characters"))
270 type = 1;
271 else if (PyObject_HasAttrString(handler, "data"))
272 type = 2;
273 if (type != 0) {
274 if (type == 1)
275 result = PyObject_CallMethod(handler, "characters", "s#", ch, len);
276 else if (type == 2)
277 result = PyObject_CallMethod(handler, "data", "s#", ch, len);
278 if (PyErr_Occurred())
279 PyErr_Print();
280 Py_XDECREF(result);
281 }
282}
283
284static void
285pythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
286{
287 PyObject *handler;
288 PyObject *result;
289 int type = 0;
290
Daniel Veillard797a5652002-02-12 13:46:21 +0000291#ifdef DEBUG_SAX
292 printf("pythonIgnorableWhitespace(%s, %d) called\n", ch, len);
293#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000294 handler = (PyObject *) user_data;
295 if (PyObject_HasAttrString(handler, "ignorableWhitespace"))
296 type = 1;
297 else if (PyObject_HasAttrString(handler, "data"))
298 type = 2;
299 if (type != 0) {
300 if (type == 1)
301 result =
302 PyObject_CallMethod(handler, "ignorableWhitespace", "s#",
303 ch, len);
304 else if (type == 2)
305 result = PyObject_CallMethod(handler, "data", "s#", ch, len);
306 Py_XDECREF(result);
307 }
308}
309
310static void
311pythonProcessingInstruction(void *user_data,
312 const xmlChar * target, const xmlChar * data)
313{
314 PyObject *handler;
315 PyObject *result;
316
Daniel Veillard797a5652002-02-12 13:46:21 +0000317#ifdef DEBUG_SAX
318 printf("pythonProcessingInstruction(%s, %s) called\n", target, data);
319#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000320 handler = (PyObject *) user_data;
321 if (PyObject_HasAttrString(handler, "processingInstruction")) {
322 result =
323 PyObject_CallMethod(handler,
324 "ignorableWhitespace", "ss", target, data);
325 Py_XDECREF(result);
326 }
327}
328
329static void
330pythonComment(void *user_data, const xmlChar * value)
331{
332 PyObject *handler;
333 PyObject *result;
334
Daniel Veillard797a5652002-02-12 13:46:21 +0000335#ifdef DEBUG_SAX
336 printf("pythonComment(%s) called\n", value);
337#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000338 handler = (PyObject *) user_data;
339 if (PyObject_HasAttrString(handler, "comment")) {
340 result = PyObject_CallMethod(handler, "comment", "s", value);
341 if (PyErr_Occurred())
342 PyErr_Print();
343 Py_XDECREF(result);
344 }
345}
346
347static void
348pythonWarning(void *user_data, const char *msg, ...)
349{
350 PyObject *handler;
351 PyObject *result;
352 va_list args;
353 char buf[1024];
354
Daniel Veillard797a5652002-02-12 13:46:21 +0000355#ifdef DEBUG_SAX
356 printf("pythonWarning(%s) called\n", msg);
357#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000358 handler = (PyObject *) user_data;
359 if (PyObject_HasAttrString(handler, "warning")) {
360 va_start(args, msg);
361 vsnprintf(buf, 1023, msg, args);
362 va_end(args);
363 buf[1023] = 0;
364 result = PyObject_CallMethod(handler, "warning", "s", buf);
365 if (PyErr_Occurred())
366 PyErr_Print();
367 Py_XDECREF(result);
368 }
369}
370
371static void
372pythonError(void *user_data, const char *msg, ...)
373{
374 PyObject *handler;
375 PyObject *result;
376 va_list args;
377 char buf[1024];
378
Daniel Veillard797a5652002-02-12 13:46:21 +0000379#ifdef DEBUG_SAX
380 printf("pythonError(%s) called\n", msg);
381#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000382 handler = (PyObject *) user_data;
383 if (PyObject_HasAttrString(handler, "error")) {
384 va_start(args, msg);
385 vsnprintf(buf, 1023, msg, args);
386 va_end(args);
387 buf[1023] = 0;
388 result = PyObject_CallMethod(handler, "error", "s", buf);
389 if (PyErr_Occurred())
390 PyErr_Print();
391 Py_XDECREF(result);
392 }
393}
394
395static void
396pythonFatalError(void *user_data, const char *msg, ...)
397{
398 PyObject *handler;
399 PyObject *result;
400 va_list args;
401 char buf[1024];
402
Daniel Veillard797a5652002-02-12 13:46:21 +0000403#ifdef DEBUG_SAX
404 printf("pythonFatalError(%s) called\n", msg);
405#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000406 handler = (PyObject *) user_data;
407 if (PyObject_HasAttrString(handler, "fatalError")) {
408 va_start(args, msg);
409 vsnprintf(buf, 1023, msg, args);
410 va_end(args);
411 buf[1023] = 0;
412 result = PyObject_CallMethod(handler, "fatalError", "s", buf);
413 if (PyErr_Occurred())
414 PyErr_Print();
415 Py_XDECREF(result);
416 }
417}
418
419static void
420pythonCdataBlock(void *user_data, const xmlChar * ch, int len)
421{
422 PyObject *handler;
423 PyObject *result;
424 int type = 0;
425
Daniel Veillard797a5652002-02-12 13:46:21 +0000426#ifdef DEBUG_SAX
427 printf("pythonCdataBlock(%s, %d) called\n", ch, len);
428#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000429 handler = (PyObject *) user_data;
430 if (PyObject_HasAttrString(handler, "cdataBlock"))
431 type = 1;
432 else if (PyObject_HasAttrString(handler, "cdata"))
433 type = 2;
434 if (type != 0) {
435 if (type == 1)
436 result = PyObject_CallMethod(handler, "cdataBlock", "s#", ch, len);
437 else if (type == 2)
438 result = PyObject_CallMethod(handler, "cdata", "s#", ch, len);
439 if (PyErr_Occurred())
440 PyErr_Print();
441 Py_XDECREF(result);
442 }
443}
444
445static void
446pythonExternalSubset(void *user_data,
447 const xmlChar * name,
448 const xmlChar * externalID, const xmlChar * systemID)
449{
450 PyObject *handler;
451 PyObject *result;
452
Daniel Veillard797a5652002-02-12 13:46:21 +0000453#ifdef DEBUG_SAX
454 printf("pythonExternalSubset(%s, %s, %s) called\n",
455 name, externalID, systemID);
456#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000457 handler = (PyObject *) user_data;
458 if (PyObject_HasAttrString(handler, "externalSubset")) {
459 result =
460 PyObject_CallMethod(handler, "externalSubset",
461 "sss", name, externalID, systemID);
462 Py_XDECREF(result);
463 }
464}
465
466static void
467pythonEntityDecl(void *user_data,
468 const xmlChar * name,
469 int type,
470 const xmlChar * publicId,
471 const xmlChar * systemId, xmlChar * content)
472{
473 PyObject *handler;
474 PyObject *result;
475
476 handler = (PyObject *) user_data;
477 if (PyObject_HasAttrString(handler, "entityDecl")) {
478 result = PyObject_CallMethod(handler, "entityDecl",
479 "sisss", name, type, publicId,
480 systemId, content);
481 if (PyErr_Occurred())
482 PyErr_Print();
483 Py_XDECREF(result);
484 }
485}
486
487
488
489static void
490
491pythonNotationDecl(void *user_data,
492 const xmlChar * name,
493 const xmlChar * publicId, const xmlChar * systemId)
494{
495 PyObject *handler;
496 PyObject *result;
497
498 handler = (PyObject *) user_data;
499 if (PyObject_HasAttrString(handler, "notationDecl")) {
500 result = PyObject_CallMethod(handler, "notationDecl",
501 "sss", name, publicId, systemId);
502 if (PyErr_Occurred())
503 PyErr_Print();
504 Py_XDECREF(result);
505 }
506}
507
508static void
509pythonAttributeDecl(void *user_data,
510 const xmlChar * elem,
511 const xmlChar * name,
512 int type,
513 int def,
514 const xmlChar * defaultValue,
515 xmlEnumerationPtr tree)
516{
517 PyObject *handler;
518 PyObject *nameList;
519 PyObject *newName;
520 xmlEnumerationPtr node;
521 PyObject *result;
522 int count;
523
524 handler = (PyObject *) user_data;
525 if (PyObject_HasAttrString(handler, "attributeDecl")) {
526 count = 0;
527 for (node = tree; node != NULL; node = node->next) {
528 count++;
529 }
530 nameList = PyList_New(count);
531 count = 0;
532 for (node = tree; node != NULL; node = node->next) {
533 newName = PyString_FromString(node->name);
534 PyList_SetItem(nameList, count, newName);
535 count++;
536 }
537 result = PyObject_CallMethod(handler, "attributeDecl",
538 "ssiisO", elem, name, type, def,
539 defaultValue, nameList);
540 if (PyErr_Occurred())
541 PyErr_Print();
542 Py_XDECREF(nameList);
543 Py_XDECREF(result);
544 }
545}
546
547static void
548pythonElementDecl(void *user_data,
549 const xmlChar * name,
550 int type, xmlElementContentPtr content)
551{
552 PyObject *handler;
553 PyObject *obj;
554 PyObject *result;
555
556 handler = (PyObject *) user_data;
557 if (PyObject_HasAttrString(handler, "elementDecl")) {
558 /* TODO: wrap in an elementContent object */
559 printf("pythonElementDecl: xmlElementContentPtr wrapper missing !\n");
560 obj = Py_None;
561 /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */
562 result = PyObject_CallMethod(handler, "elementDecl",
563 "siO", name, type, obj);
564 if (PyErr_Occurred())
565 PyErr_Print();
566 Py_XDECREF(result);
567 }
568}
569
570static void
571pythonUnparsedEntityDecl(void *user_data,
572 const xmlChar * name,
573 const xmlChar * publicId,
574 const xmlChar * systemId,
575 const xmlChar * notationName)
576{
577 PyObject *handler;
578 PyObject *result;
579
580 handler = (PyObject *) user_data;
581 if (PyObject_HasAttrString(handler, "unparsedEntityDecl")) {
582 result = PyObject_CallMethod(handler, "unparsedEntityDecl",
583 "ssss", name, publicId, systemId,
584 notationName);
585 if (PyErr_Occurred())
586 PyErr_Print();
587 Py_XDECREF(result);
588 }
589}
590
591static void
592pythonInternalSubset(void *user_data, const xmlChar * name,
593 const xmlChar * ExternalID, const xmlChar * SystemID)
594{
595 PyObject *handler;
596 PyObject *result;
597
Daniel Veillard797a5652002-02-12 13:46:21 +0000598#ifdef DEBUG_SAX
599 printf("pythonInternalSubset(%s, %s, %s) called\n",
600 name, ExternalID, SystemID);
601#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000602 handler = (PyObject *) user_data;
603 if (PyObject_HasAttrString(handler, "internalSubset")) {
604 result = PyObject_CallMethod(handler, "internalSubset",
605 "sss", name, ExternalID, SystemID);
606 if (PyErr_Occurred())
607 PyErr_Print();
608 Py_XDECREF(result);
609 }
610}
611
612static xmlSAXHandler pythonSaxHandler = {
613 pythonInternalSubset,
614 NULL, /* TODO pythonIsStandalone, */
615 NULL, /* TODO pythonHasInternalSubset, */
616 NULL, /* TODO pythonHasExternalSubset, */
617 NULL, /* TODO pythonResolveEntity, */
618 NULL, /* TODO pythonGetEntity, */
619 pythonEntityDecl,
620 pythonNotationDecl,
621 pythonAttributeDecl,
622 pythonElementDecl,
623 pythonUnparsedEntityDecl,
624 NULL, /* OBSOLETED pythonSetDocumentLocator, */
625 pythonStartDocument,
626 pythonEndDocument,
627 pythonStartElement,
628 pythonEndElement,
629 pythonReference,
630 pythonCharacters,
631 pythonIgnorableWhitespace,
632 pythonProcessingInstruction,
633 pythonComment,
634 pythonWarning,
635 pythonError,
636 pythonFatalError,
637 NULL, /* TODO pythonGetParameterEntity, */
638 pythonCdataBlock,
639 pythonExternalSubset,
640 1
641};
Daniel Veillard3ce52572002-02-03 15:08:05 +0000642
643/************************************************************************
644 * *
645 * Handling of specific parser context *
646 * *
647 ************************************************************************/
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000648
649PyObject *
Daniel Veillard3ce52572002-02-03 15:08:05 +0000650libxml_xmlCreatePushParser(PyObject *self, PyObject *args) {
651 xmlChar *chunk;
652 int size;
653 xmlChar *URI;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000654 PyObject *pyobj_SAX = NULL;
Daniel Veillard3ce52572002-02-03 15:08:05 +0000655 xmlSAXHandlerPtr SAX = NULL;
Daniel Veillard3ce52572002-02-03 15:08:05 +0000656 xmlParserCtxtPtr ret;
657 PyObject *pyret;
Daniel Veillard96fe0952002-01-30 20:52:23 +0000658
Daniel Veillard3ce52572002-02-03 15:08:05 +0000659 if (!PyArg_ParseTuple(args, "Oziz:xmlCreatePushParser", &pyobj_SAX,
660 &chunk, &size, &URI))
661 return(NULL);
662
663#ifdef DEBUG_ERROR
664 printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
665 pyobj_SAX, chunk, size, URI);
Daniel Veillard96fe0952002-01-30 20:52:23 +0000666#endif
Daniel Veillard3ce52572002-02-03 15:08:05 +0000667 if (pyobj_SAX != Py_None) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000668 SAX = &pythonSaxHandler;
669 Py_INCREF(pyobj_SAX);
670 /* The reference is released in pythonEndDocument() */
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000671 }
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000672 ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000673 pyret = libxml_xmlParserCtxtPtrWrap(ret);
674 return(pyret);
Daniel Veillarda7340c82002-02-01 17:56:45 +0000675}
Daniel Veillard5d819032002-02-02 21:49:17 +0000676
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000677PyObject *
678libxml_htmlCreatePushParser(PyObject *self, PyObject *args) {
679 xmlChar *chunk;
680 int size;
681 xmlChar *URI;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000682 PyObject *pyobj_SAX = NULL;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000683 xmlSAXHandlerPtr SAX = NULL;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000684 xmlParserCtxtPtr ret;
685 PyObject *pyret;
686
687 if (!PyArg_ParseTuple(args, "Oziz:htmlCreatePushParser", &pyobj_SAX,
688 &chunk, &size, &URI))
689 return(NULL);
690
691#ifdef DEBUG_ERROR
692 printf("libxml_htmlCreatePushParser(%p, %s, %d, %s) called\n",
693 pyobj_SAX, chunk, size, URI);
694#endif
695 if (pyobj_SAX != Py_None) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000696 SAX = &pythonSaxHandler;
697 Py_INCREF(pyobj_SAX);
698 /* The reference is released in pythonEndDocument() */
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000699 }
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000700 ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI,
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000701 XML_CHAR_ENCODING_NONE);
702 pyret = libxml_xmlParserCtxtPtrWrap(ret);
703 return(pyret);
704}
705
Daniel Veillard5d819032002-02-02 21:49:17 +0000706/************************************************************************
707 * *
708 * Error message callback *
709 * *
710 ************************************************************************/
711
712static PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
713static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
714
715static void
716libxml_xmlErrorFuncHandler(void *ctx, const char *msg, ...) {
717 int size;
718 int chars;
719 char *larger;
720 va_list ap;
721 char *str;
722 PyObject *list;
723 PyObject *message;
724 PyObject *result;
725
726#ifdef DEBUG_ERROR
727 printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
728#endif
729
730
731 if (libxml_xmlPythonErrorFuncHandler == NULL) {
732 va_start(ap, msg);
733 vfprintf(stdout, msg, ap);
734 va_end(ap);
735 } else {
736 str = (char *) xmlMalloc(150);
737 if (str == NULL)
738 return;
739
740 size = 150;
741
742 while (1) {
743 va_start(ap, msg);
744 chars = vsnprintf(str, size, msg, ap);
745 va_end(ap);
746 if ((chars > -1) && (chars < size))
747 break;
748 if (chars > -1)
749 size += chars + 1;
750 else
751 size += 100;
752 if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
753 xmlFree(str);
754 return;
755 }
756 str = larger;
757 }
758
759 list = PyTuple_New(2);
760 PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
761 Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
762 message = libxml_charPtrWrap(str);
763 PyTuple_SetItem(list, 1, message);
764 result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list);
765 Py_XDECREF(list);
766 Py_XDECREF(result);
767 }
768}
769
770static void
771libxml_xmlErrorInitialize(void) {
772#ifdef DEBUG_ERROR
773 printf("libxml_xmlErrorInitialize() called\n");
774#endif
775 xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
776}
777
778PyObject *
779libxml_xmlRegisterErrorHandler(PyObject *self, PyObject *args) {
780 PyObject *py_retval;
781 PyObject *pyobj_f;
782 PyObject *pyobj_ctx;
783
784 if (!PyArg_ParseTuple(args, "OO:xmlRegisterErrorHandler", &pyobj_f,
785 &pyobj_ctx))
786 return(NULL);
787
788#ifdef DEBUG_ERROR
789 printf("libxml_registerXPathFunction(%p, %p) called\n", pyobj_ctx, pyobj_f);
790#endif
791
792 if (libxml_xmlPythonErrorFuncHandler != NULL) {
793 Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
794 }
795 if (libxml_xmlPythonErrorFuncCtxt != NULL) {
796 Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
797 }
798
799 Py_XINCREF(pyobj_ctx);
800 Py_XINCREF(pyobj_f);
801
802 /* TODO: check f is a function ! */
803 libxml_xmlPythonErrorFuncHandler = pyobj_f;
804 libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
805
806 py_retval = libxml_intWrap(1);
807 return(py_retval);
808}
Daniel Veillarda7340c82002-02-01 17:56:45 +0000809/************************************************************************
810 * *
811 * XPath extensions *
812 * *
813 ************************************************************************/
814
815static int libxml_xpathCallbacksInitialized = 0;
816
817typedef struct libxml_xpathCallback {
818 xmlXPathContextPtr ctx;
819 xmlChar *name;
820 xmlChar *ns_uri;
821 PyObject *function;
822} libxml_xpathCallback, *libxml_xpathCallbackPtr;
823static libxml_xpathCallback libxml_xpathCallbacks[10];
824static int libxml_xpathCallbacksNb = 0;
825static int libxml_xpathCallbacksMax = 10;
826
Daniel Veillarda7340c82002-02-01 17:56:45 +0000827static void
828libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs) {
829 PyObject *list, *cur, *result;
830 xmlXPathObjectPtr obj;
Daniel Veillard70cab352002-02-06 16:06:58 +0000831 xmlXPathContextPtr rctxt;
832 PyObject *current_function = NULL;
833 const xmlChar *name;
834 const xmlChar *ns_uri;
Daniel Veillarda7340c82002-02-01 17:56:45 +0000835 int i;
836
Daniel Veillard70cab352002-02-06 16:06:58 +0000837 if (ctxt == NULL)
838 return;
839 rctxt = ctxt->context;
840 if (rctxt == NULL)
841 return;
842 name = rctxt->function;
843 ns_uri = rctxt->functionURI;
Daniel Veillarda7340c82002-02-01 17:56:45 +0000844#ifdef DEBUG_XPATH
Daniel Veillard70cab352002-02-06 16:06:58 +0000845 printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name, ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +0000846#endif
847
Daniel Veillard70cab352002-02-06 16:06:58 +0000848 /*
849 * Find the function, it should be there it was there at lookup
850 */
851 for (i = 0;i < libxml_xpathCallbacksNb;i++) {
852 if (/* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
853 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
854 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
855 current_function = libxml_xpathCallbacks[i].function;
856 }
857 }
858 if (current_function == NULL) {
859 printf("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
860 name);
861 return;
862 }
863
Daniel Veillardc575b992002-02-08 13:28:40 +0000864 list = PyTuple_New(nargs + 1);
865 PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
Daniel Veillarda7340c82002-02-01 17:56:45 +0000866 for (i = 0;i < nargs;i++) {
867 obj = valuePop(ctxt);
868 cur = libxml_xmlXPathObjectPtrWrap(obj);
Daniel Veillardc575b992002-02-08 13:28:40 +0000869 PyTuple_SetItem(list, i + 1, cur);
Daniel Veillarda7340c82002-02-01 17:56:45 +0000870 }
871 result = PyEval_CallObject(current_function, list);
872 Py_DECREF(list);
873
874 obj = libxml_xmlXPathObjectPtrConvert(result);
875 valuePush(ctxt, obj);
876}
877
878static xmlXPathFunction
879libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar *name,
880 const xmlChar *ns_uri) {
881 int i;
882#ifdef DEBUG_XPATH
883 printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
884 ctxt, name, ns_uri);
885#endif
Daniel Veillard70cab352002-02-06 16:06:58 +0000886 /*
887 * This is called once only. The address is then stored in the
888 * XPath expression evaluation, the proper object to call can
889 * then still be found using the execution context function
890 * and functionURI fields.
891 */
Daniel Veillarda7340c82002-02-01 17:56:45 +0000892 for (i = 0;i < libxml_xpathCallbacksNb;i++) {
893 if ((ctxt == libxml_xpathCallbacks[i].ctx) &&
894 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
895 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
Daniel Veillarda7340c82002-02-01 17:56:45 +0000896 return(libxml_xmlXPathFuncCallback);
897 }
898 }
Daniel Veillarda7340c82002-02-01 17:56:45 +0000899 return(NULL);
900}
901
902static void
903libxml_xpathCallbacksInitialize(void) {
904 int i;
905
906 if (libxml_xpathCallbacksInitialized != 0)
907 return;
908
909#ifdef DEBUG_XPATH
910 printf("libxml_xpathCallbacksInitialized called\n");
911#endif
912
913 for (i = 0;i < 10;i++) {
914 libxml_xpathCallbacks[i].ctx = NULL;
915 libxml_xpathCallbacks[i].name = NULL;
916 libxml_xpathCallbacks[i].ns_uri = NULL;
917 libxml_xpathCallbacks[i].function = NULL;
918 }
Daniel Veillarda7340c82002-02-01 17:56:45 +0000919 libxml_xpathCallbacksInitialized = 1;
920}
921
922PyObject *
Daniel Veillard7fd7a942002-02-02 12:19:46 +0000923libxml_xmlRegisterXPathFunction(PyObject *self, PyObject *args) {
Daniel Veillarda7340c82002-02-01 17:56:45 +0000924 PyObject *py_retval;
925 int c_retval = 0;
926 xmlChar *name;
927 xmlChar *ns_uri;
928 xmlXPathContextPtr ctx;
929 PyObject *pyobj_ctx;
930 PyObject *pyobj_f;
931 int i;
932
933 if (!PyArg_ParseTuple(args, "OszO:registerXPathFunction", &pyobj_ctx,
934 &name, &ns_uri, &pyobj_f))
935 return(NULL);
936
937 ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
938 if (libxml_xpathCallbacksInitialized == 0)
939 libxml_xpathCallbacksInitialize();
940 xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
941
942 if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
943 py_retval = libxml_intWrap(-1);
944 return(py_retval);
945 }
946
947#ifdef DEBUG_XPATH
948 printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
949 ctx, name, ns_uri);
950#endif
951 for (i = 0;i < libxml_xpathCallbacksNb;i++) {
952 if ((ctx == libxml_xpathCallbacks[i].ctx) &&
953 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
954 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
955 Py_XINCREF(pyobj_f);
956 Py_XDECREF(libxml_xpathCallbacks[i].function);
957 libxml_xpathCallbacks[i].function = pyobj_f;
958 c_retval = 1;
959 goto done;
960 }
961 }
962 if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksMax) {
963 printf("libxml_registerXPathFunction() table full\n");
964 } else {
965 i = libxml_xpathCallbacksNb++;
966 Py_XINCREF(pyobj_f);
967 libxml_xpathCallbacks[i].ctx = ctx;
968 libxml_xpathCallbacks[i].name = xmlStrdup(name);
969 libxml_xpathCallbacks[i].ns_uri = xmlStrdup(ns_uri);
970 libxml_xpathCallbacks[i].function = pyobj_f;
Daniel Veillard9589d452002-02-02 10:28:17 +0000971 c_retval = 1;
Daniel Veillarda7340c82002-02-01 17:56:45 +0000972 }
973done:
974 py_retval = libxml_intWrap((int) c_retval);
975 return(py_retval);
976}
977
Daniel Veillard1971ee22002-01-31 20:29:19 +0000978/************************************************************************
979 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000980 * Global properties access *
981 * *
982 ************************************************************************/
983static PyObject *
984libxml_name(PyObject *self, PyObject *args)
985{
986 PyObject *resultobj, *obj;
987 xmlNodePtr cur;
988 const xmlChar *res;
989
990 if (!PyArg_ParseTuple(args, "O:name", &obj))
991 return NULL;
992 cur = PyxmlNode_Get(obj);
993
994#ifdef DEBUG
995 printf("libxml_name: cur = %p type %d\n", cur, cur->type);
996#endif
997
998 switch(cur->type) {
999 case XML_DOCUMENT_NODE:
1000#ifdef LIBXML_DOCB_ENABLED
1001 case XML_DOCB_DOCUMENT_NODE:
1002#endif
1003 case XML_HTML_DOCUMENT_NODE: {
1004 xmlDocPtr doc = (xmlDocPtr) cur;
1005 res = doc->URL;
1006 break;
1007 }
1008 case XML_ATTRIBUTE_NODE: {
1009 xmlAttrPtr attr = (xmlAttrPtr) cur;
1010 res = attr->name;
1011 break;
1012 }
1013 case XML_NAMESPACE_DECL: {
1014 xmlNsPtr ns = (xmlNsPtr) cur;
1015 res = ns->prefix;
1016 break;
1017 }
1018 default:
1019 res = cur->name;
1020 break;
1021 }
Daniel Veillard1971ee22002-01-31 20:29:19 +00001022 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001023
1024 return resultobj;
1025}
1026
1027static PyObject *
1028libxml_doc(PyObject *self, PyObject *args)
1029{
1030 PyObject *resultobj, *obj;
1031 xmlNodePtr cur;
1032 xmlDocPtr res;
1033
1034 if (!PyArg_ParseTuple(args, "O:doc", &obj))
1035 return NULL;
1036 cur = PyxmlNode_Get(obj);
1037
1038#ifdef DEBUG
1039 printf("libxml_doc: cur = %p\n", cur);
1040#endif
1041
1042 switch(cur->type) {
1043 case XML_DOCUMENT_NODE:
1044#ifdef LIBXML_DOCB_ENABLED
1045 case XML_DOCB_DOCUMENT_NODE:
1046#endif
1047 case XML_HTML_DOCUMENT_NODE:
1048 res = NULL;
1049 break;
1050 case XML_ATTRIBUTE_NODE: {
1051 xmlAttrPtr attr = (xmlAttrPtr) cur;
1052 res = attr->doc;
1053 break;
1054 }
1055 case XML_NAMESPACE_DECL:
1056 res = NULL;
1057 break;
1058 default:
1059 res = cur->doc;
1060 break;
1061 }
1062 resultobj = libxml_xmlDocPtrWrap(res);
1063 return resultobj;
1064}
1065
1066static PyObject *
1067libxml_properties(PyObject *self, PyObject *args)
1068{
1069 PyObject *resultobj, *obj;
1070 xmlNodePtr cur = NULL;
1071 xmlAttrPtr res;
1072
1073 if (!PyArg_ParseTuple(args, "O:properties", &obj))
1074 return NULL;
1075 cur = PyxmlNode_Get(obj);
1076 if (cur->type == XML_ELEMENT_NODE)
1077 res = cur->properties;
1078 else
1079 res = NULL;
1080 resultobj = libxml_xmlAttrPtrWrap(res);
1081 return resultobj;
1082}
1083
1084static PyObject *
1085libxml_next(PyObject *self, PyObject *args)
1086{
1087 PyObject *resultobj, *obj;
1088 xmlNodePtr cur;
1089 xmlNodePtr res;
1090
1091 if (!PyArg_ParseTuple(args, "O:next", &obj))
1092 return NULL;
1093 cur = PyxmlNode_Get(obj);
1094
1095#ifdef DEBUG
1096 printf("libxml_next: cur = %p\n", cur);
1097#endif
1098
1099 switch(cur->type) {
1100 case XML_DOCUMENT_NODE:
1101#ifdef LIBXML_DOCB_ENABLED
1102 case XML_DOCB_DOCUMENT_NODE:
1103#endif
1104 case XML_HTML_DOCUMENT_NODE:
1105 res = NULL;
1106 break;
1107 case XML_ATTRIBUTE_NODE: {
1108 xmlAttrPtr attr = (xmlAttrPtr) cur;
1109 res = (xmlNodePtr) attr->next;
1110 break;
1111 }
1112 case XML_NAMESPACE_DECL: {
1113 xmlNsPtr ns = (xmlNsPtr) cur;
1114 res = (xmlNodePtr) ns->next;
1115 break;
1116 }
1117 default:
1118 res = cur->next;
1119 break;
1120
1121 }
1122 resultobj = libxml_xmlNodePtrWrap(res);
1123 return resultobj;
1124}
1125
1126static PyObject *
1127libxml_prev(PyObject *self, PyObject *args)
1128{
1129 PyObject *resultobj, *obj;
1130 xmlNodePtr cur;
1131 xmlNodePtr res;
1132
1133 if (!PyArg_ParseTuple(args, "O:prev", &obj))
1134 return NULL;
1135 cur = PyxmlNode_Get(obj);
1136
1137#ifdef DEBUG
1138 printf("libxml_prev: cur = %p\n", cur);
1139#endif
1140
1141 switch(cur->type) {
1142 case XML_DOCUMENT_NODE:
1143#ifdef LIBXML_DOCB_ENABLED
1144 case XML_DOCB_DOCUMENT_NODE:
1145#endif
1146 case XML_HTML_DOCUMENT_NODE:
1147 res = NULL;
1148 break;
1149 case XML_ATTRIBUTE_NODE: {
1150 xmlAttrPtr attr = (xmlAttrPtr) cur;
1151 res = (xmlNodePtr) attr->next;
1152 }
1153 case XML_NAMESPACE_DECL:
1154 res = NULL;
1155 break;
1156 default:
1157 res = cur->next;
1158 break;
1159 }
1160 resultobj = libxml_xmlNodePtrWrap(res);
1161 return resultobj;
1162}
1163
1164static PyObject *
1165libxml_children(PyObject *self, PyObject *args)
1166{
1167 PyObject *resultobj, *obj;
1168 xmlNodePtr cur;
1169 xmlNodePtr res;
1170
1171 if (!PyArg_ParseTuple(args, "O:children", &obj))
1172 return NULL;
1173 cur = PyxmlNode_Get(obj);
1174
1175#ifdef DEBUG
1176 printf("libxml_children: cur = %p\n", cur);
1177#endif
1178
1179 switch(cur->type) {
1180 case XML_ELEMENT_NODE:
1181 case XML_ENTITY_REF_NODE:
1182 case XML_ENTITY_NODE:
1183 case XML_PI_NODE:
1184 case XML_COMMENT_NODE:
1185 case XML_DOCUMENT_NODE:
1186#ifdef LIBXML_DOCB_ENABLED
1187 case XML_DOCB_DOCUMENT_NODE:
1188#endif
1189 case XML_HTML_DOCUMENT_NODE:
1190 case XML_DTD_NODE:
1191 res = cur->children;
1192 break;
1193 case XML_ATTRIBUTE_NODE: {
1194 xmlAttrPtr attr = (xmlAttrPtr) cur;
1195 res = attr->children;
1196 break;
1197 }
1198 default:
1199 res = NULL;
1200 break;
1201 }
1202 resultobj = libxml_xmlNodePtrWrap(res);
1203 return resultobj;
1204}
1205
1206static PyObject *
1207libxml_last(PyObject *self, PyObject *args)
1208{
1209 PyObject *resultobj, *obj;
1210 xmlNodePtr cur;
1211 xmlNodePtr res;
1212
1213 if (!PyArg_ParseTuple(args, "O:last", &obj))
1214 return NULL;
1215 cur = PyxmlNode_Get(obj);
1216
1217#ifdef DEBUG
1218 printf("libxml_last: cur = %p\n", cur);
1219#endif
1220
1221 switch(cur->type) {
1222 case XML_ELEMENT_NODE:
1223 case XML_ENTITY_REF_NODE:
1224 case XML_ENTITY_NODE:
1225 case XML_PI_NODE:
1226 case XML_COMMENT_NODE:
1227 case XML_DOCUMENT_NODE:
1228#ifdef LIBXML_DOCB_ENABLED
1229 case XML_DOCB_DOCUMENT_NODE:
1230#endif
1231 case XML_HTML_DOCUMENT_NODE:
1232 case XML_DTD_NODE:
1233 res = cur->last;
1234 break;
1235 case XML_ATTRIBUTE_NODE: {
1236 xmlAttrPtr attr = (xmlAttrPtr) cur;
1237 res = attr->last;
1238 }
1239 default:
1240 res = NULL;
1241 break;
1242 }
1243 resultobj = libxml_xmlNodePtrWrap(res);
1244 return resultobj;
1245}
1246
1247static PyObject *
1248libxml_parent(PyObject *self, PyObject *args)
1249{
1250 PyObject *resultobj, *obj;
1251 xmlNodePtr cur;
1252 xmlNodePtr res;
1253
1254 if (!PyArg_ParseTuple(args, "O:parent", &obj))
1255 return NULL;
1256 cur = PyxmlNode_Get(obj);
1257
1258#ifdef DEBUG
1259 printf("libxml_parent: cur = %p\n", cur);
1260#endif
1261
1262 switch(cur->type) {
1263 case XML_DOCUMENT_NODE:
1264 case XML_HTML_DOCUMENT_NODE:
1265#ifdef LIBXML_DOCB_ENABLED
1266 case XML_DOCB_DOCUMENT_NODE:
1267#endif
1268 res = NULL;
1269 break;
1270 case XML_ATTRIBUTE_NODE: {
1271 xmlAttrPtr attr = (xmlAttrPtr) cur;
1272 res = attr->parent;
1273 }
1274 case XML_ENTITY_DECL:
1275 case XML_NAMESPACE_DECL:
1276 case XML_XINCLUDE_START:
1277 case XML_XINCLUDE_END:
1278 res = NULL;
1279 break;
1280 default:
1281 res = cur->parent;
1282 break;
1283 }
1284 resultobj = libxml_xmlNodePtrWrap(res);
1285 return resultobj;
1286}
1287
1288static PyObject *
1289libxml_type(PyObject *self, PyObject *args)
1290{
1291 PyObject *resultobj, *obj;
1292 xmlNodePtr cur;
1293 const xmlChar *res;
1294
1295 if (!PyArg_ParseTuple(args, "O:last", &obj))
1296 return NULL;
1297 cur = PyxmlNode_Get(obj);
1298
1299#ifdef DEBUG
1300 printf("libxml_type: cur = %p\n", cur);
1301#endif
1302
1303 switch(cur->type) {
1304 case XML_ELEMENT_NODE:
1305 res = (const xmlChar *) "element"; break;
1306 case XML_ATTRIBUTE_NODE:
1307 res = (const xmlChar *) "attribute"; break;
1308 case XML_TEXT_NODE:
1309 res = (const xmlChar *) "text"; break;
1310 case XML_CDATA_SECTION_NODE:
1311 res = (const xmlChar *) "cdata"; break;
1312 case XML_ENTITY_REF_NODE:
1313 res = (const xmlChar *) "entity_ref"; break;
1314 case XML_ENTITY_NODE:
1315 res = (const xmlChar *) "entity"; break;
1316 case XML_PI_NODE:
1317 res = (const xmlChar *) "pi"; break;
1318 case XML_COMMENT_NODE:
1319 res = (const xmlChar *) "comment"; break;
1320 case XML_DOCUMENT_NODE:
1321 res = (const xmlChar *) "document_xml"; break;
1322 case XML_DOCUMENT_TYPE_NODE:
1323 res = (const xmlChar *) "doctype"; break;
1324 case XML_DOCUMENT_FRAG_NODE:
1325 res = (const xmlChar *) "fragment"; break;
1326 case XML_NOTATION_NODE:
1327 res = (const xmlChar *) "notation"; break;
1328 case XML_HTML_DOCUMENT_NODE:
1329 res = (const xmlChar *) "document_html"; break;
1330 case XML_DTD_NODE:
1331 res = (const xmlChar *) "dtd"; break;
1332 case XML_ELEMENT_DECL:
1333 res = (const xmlChar *) "elem_decl"; break;
1334 case XML_ATTRIBUTE_DECL:
1335 res = (const xmlChar *) "attribute_decl"; break;
1336 case XML_ENTITY_DECL:
1337 res = (const xmlChar *) "entity_decl"; break;
1338 case XML_NAMESPACE_DECL:
1339 res = (const xmlChar *) "namespace"; break;
1340 case XML_XINCLUDE_START:
1341 res = (const xmlChar *) "xinclude_start"; break;
1342 case XML_XINCLUDE_END:
1343 res = (const xmlChar *) "xinclude_end"; break;
1344#ifdef LIBXML_DOCB_ENABLED
1345 case XML_DOCB_DOCUMENT_NODE:
1346 res = (const xmlChar *) "document_docbook"; break;
1347#endif
1348 }
1349#ifdef DEBUG
1350 printf("libxml_type: cur = %p: %s\n", cur, res);
1351#endif
1352
Daniel Veillard1971ee22002-01-31 20:29:19 +00001353 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001354 return resultobj;
1355}
1356
1357/************************************************************************
1358 * *
Daniel Veillard36eea2d2002-02-04 00:17:01 +00001359 * Specific accessor functions *
1360 * *
1361 ************************************************************************/
1362PyObject *
1363libxml_xmlNodeGetNsDefs(PyObject *self, PyObject *args) {
1364 PyObject *py_retval;
1365 xmlNsPtr c_retval;
1366 xmlNodePtr node;
1367 PyObject *pyobj_node;
1368
1369 if (!PyArg_ParseTuple(args, "O:xmlNodeGetNsDefs", &pyobj_node))
1370 return(NULL);
1371 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
1372
1373 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
1374 Py_INCREF(Py_None);
1375 return(Py_None);
1376 }
1377 c_retval = node->nsDef;
1378 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
1379 return(py_retval);
1380}
1381
1382PyObject *
1383libxml_xmlNodeGetNs(PyObject *self, PyObject *args) {
1384 PyObject *py_retval;
1385 xmlNsPtr c_retval;
1386 xmlNodePtr node;
1387 PyObject *pyobj_node;
1388
1389 if (!PyArg_ParseTuple(args, "O:xmlNodeGetNs", &pyobj_node))
1390 return(NULL);
1391 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
1392
1393 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
1394 Py_INCREF(Py_None);
1395 return(Py_None);
1396 }
1397 c_retval = node->ns;
1398 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
1399 return(py_retval);
1400}
1401
1402/************************************************************************
1403 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001404 * The registration stuff *
1405 * *
1406 ************************************************************************/
1407static PyMethodDef libxmlMethods[] = {
Daniel Veillard96fe0952002-01-30 20:52:23 +00001408#include "libxml2-export.c"
Daniel Veillard5e5c2d02002-02-09 18:03:01 +00001409 { "name", libxml_name, METH_VARARGS, NULL },
1410 { "children", libxml_children, METH_VARARGS, NULL },
1411 { "properties", libxml_properties, METH_VARARGS, NULL },
1412 { "last", libxml_last, METH_VARARGS, NULL },
1413 { "prev", libxml_prev, METH_VARARGS, NULL },
1414 { "next", libxml_next, METH_VARARGS, NULL },
1415 { "parent", libxml_parent, METH_VARARGS, NULL },
1416 { "type", libxml_type, METH_VARARGS, NULL },
1417 { "doc", libxml_doc, METH_VARARGS, NULL },
Daniel Veillard0ba59232002-02-10 13:20:39 +00001418 { NULL }
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001419};
1420
Daniel Veillard5e5c2d02002-02-09 18:03:01 +00001421void initlibxml2mod(void) {
Daniel Veillard3ce52572002-02-03 15:08:05 +00001422 PyObject *m;
Daniel Veillard5e5c2d02002-02-09 18:03:01 +00001423 m = Py_InitModule("libxml2mod", libxmlMethods);
Daniel Veillard5d819032002-02-02 21:49:17 +00001424 libxml_xmlErrorInitialize();
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001425}
1426