1/* 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 * If compiled with MERGED_MODULES, the entry point will be used to 8 * initialize both the libxml2 and the libxslt wrappers 9 * 10 * See Copyright for the status of this software. 11 * 12 * daniel@veillard.com 13 */ 14#include <Python.h> 15#include <fileobject.h> 16/* #include "config.h" */ 17#include <libxml/xmlmemory.h> 18#include <libxml/parser.h> 19#include <libxml/tree.h> 20#include <libxml/xpath.h> 21#include <libxml/xmlerror.h> 22#include <libxml/xpathInternals.h> 23#include <libxml/xmlmemory.h> 24#include <libxml/xmlIO.h> 25#include <libxml/c14n.h> 26#include <libxml/xmlreader.h> 27#include <libxml/xmlsave.h> 28#include "libxml_wrap.h" 29#include "libxml2-py.h" 30 31#if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(vsnprintf) 32#define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a) 33#elif defined(WITH_TRIO) 34#include "trio.h" 35#define vsnprintf trio_vsnprintf 36#endif 37 38/* #define DEBUG */ 39/* #define DEBUG_SAX */ 40/* #define DEBUG_XPATH */ 41/* #define DEBUG_ERROR */ 42/* #define DEBUG_MEMORY */ 43/* #define DEBUG_FILES */ 44/* #define DEBUG_LOADER */ 45 46void initlibxml2mod(void); 47 48/** 49 * TODO: 50 * 51 * macro to flag unimplemented blocks 52 */ 53#define TODO \ 54 xmlGenericError(xmlGenericErrorContext, \ 55 "Unimplemented block at %s:%d\n", \ 56 __FILE__, __LINE__); 57/* 58 * the following vars are used for XPath extensions, but 59 * are also referenced within the parser cleanup routine. 60 */ 61static int libxml_xpathCallbacksInitialized = 0; 62 63typedef struct libxml_xpathCallback { 64 xmlXPathContextPtr ctx; 65 xmlChar *name; 66 xmlChar *ns_uri; 67 PyObject *function; 68} libxml_xpathCallback, *libxml_xpathCallbackPtr; 69typedef libxml_xpathCallback libxml_xpathCallbackArray[]; 70static int libxml_xpathCallbacksAllocd = 10; 71static libxml_xpathCallbackArray *libxml_xpathCallbacks = NULL; 72static int libxml_xpathCallbacksNb = 0; 73 74/************************************************************************ 75 * * 76 * Memory debug interface * 77 * * 78 ************************************************************************/ 79 80#if 0 81extern void xmlMemFree(void *ptr); 82extern void *xmlMemMalloc(size_t size); 83extern void *xmlMemRealloc(void *ptr, size_t size); 84extern char *xmlMemoryStrdup(const char *str); 85#endif 86 87static int libxmlMemoryDebugActivated = 0; 88static long libxmlMemoryAllocatedBase = 0; 89 90static int libxmlMemoryDebug = 0; 91static xmlFreeFunc freeFunc = NULL; 92static xmlMallocFunc mallocFunc = NULL; 93static xmlReallocFunc reallocFunc = NULL; 94static xmlStrdupFunc strdupFunc = NULL; 95 96static void 97libxml_xmlErrorInitialize(void); /* forward declare */ 98 99PyObject * 100libxml_xmlMemoryUsed(PyObject * self ATTRIBUTE_UNUSED, 101 PyObject * args ATTRIBUTE_UNUSED) 102{ 103 long ret; 104 PyObject *py_retval; 105 106 ret = xmlMemUsed(); 107 108 py_retval = libxml_longWrap(ret); 109 return (py_retval); 110} 111 112PyObject * 113libxml_xmlDebugMemory(PyObject * self ATTRIBUTE_UNUSED, PyObject * args) 114{ 115 int activate; 116 PyObject *py_retval; 117 long ret; 118 119 if (!PyArg_ParseTuple(args, (char *) "i:xmlDebugMemory", &activate)) 120 return (NULL); 121 122#ifdef DEBUG_MEMORY 123 printf("libxml_xmlDebugMemory(%d) called\n", activate); 124#endif 125 126 if (activate != 0) { 127 if (libxmlMemoryDebug == 0) { 128 /* 129 * First initialize the library and grab the old memory handlers 130 * and switch the library to memory debugging 131 */ 132 xmlMemGet((xmlFreeFunc *) & freeFunc, 133 (xmlMallocFunc *) & mallocFunc, 134 (xmlReallocFunc *) & reallocFunc, 135 (xmlStrdupFunc *) & strdupFunc); 136 if ((freeFunc == xmlMemFree) && (mallocFunc == xmlMemMalloc) && 137 (reallocFunc == xmlMemRealloc) && 138 (strdupFunc == xmlMemoryStrdup)) { 139 libxmlMemoryAllocatedBase = xmlMemUsed(); 140 } else { 141 /* 142 * cleanup first, because some memory has been 143 * allocated with the non-debug malloc in xmlInitParser 144 * when the python module was imported 145 */ 146 xmlCleanupParser(); 147 ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc, 148 xmlMemRealloc, xmlMemoryStrdup); 149 if (ret < 0) 150 goto error; 151 libxmlMemoryAllocatedBase = xmlMemUsed(); 152 /* reinitialize */ 153 xmlInitParser(); 154 libxml_xmlErrorInitialize(); 155 } 156 ret = 0; 157 } else if (libxmlMemoryDebugActivated == 0) { 158 libxmlMemoryAllocatedBase = xmlMemUsed(); 159 ret = 0; 160 } else { 161 ret = xmlMemUsed() - libxmlMemoryAllocatedBase; 162 } 163 libxmlMemoryDebug = 1; 164 libxmlMemoryDebugActivated = 1; 165 } else { 166 if (libxmlMemoryDebugActivated == 1) 167 ret = xmlMemUsed() - libxmlMemoryAllocatedBase; 168 else 169 ret = 0; 170 libxmlMemoryDebugActivated = 0; 171 } 172 error: 173 py_retval = libxml_longWrap(ret); 174 return (py_retval); 175} 176 177PyObject * 178libxml_xmlPythonCleanupParser(PyObject *self ATTRIBUTE_UNUSED, 179 PyObject *args ATTRIBUTE_UNUSED) { 180 181 int ix; 182 long freed = -1; 183 184 if (libxmlMemoryDebug) { 185 freed = xmlMemUsed(); 186 } 187 188 xmlCleanupParser(); 189 /* 190 * Need to confirm whether we really want to do this (required for 191 * memcheck) in all cases... 192 */ 193 194 if (libxml_xpathCallbacks != NULL) { /* if ext funcs declared */ 195 for (ix=0; ix<libxml_xpathCallbacksNb; ix++) { 196 if ((*libxml_xpathCallbacks)[ix].name != NULL) 197 xmlFree((*libxml_xpathCallbacks)[ix].name); 198 if ((*libxml_xpathCallbacks)[ix].ns_uri != NULL) 199 xmlFree((*libxml_xpathCallbacks)[ix].ns_uri); 200 } 201 libxml_xpathCallbacksNb = 0; 202 xmlFree(libxml_xpathCallbacks); 203 libxml_xpathCallbacks = NULL; 204 } 205 206 if (libxmlMemoryDebug) { 207 freed -= xmlMemUsed(); 208 libxmlMemoryAllocatedBase -= freed; 209 if (libxmlMemoryAllocatedBase < 0) 210 libxmlMemoryAllocatedBase = 0; 211 } 212 213 Py_INCREF(Py_None); 214 return(Py_None); 215} 216 217PyObject * 218libxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self, 219 ATTRIBUTE_UNUSED PyObject * args) 220{ 221 222 if (libxmlMemoryDebug != 0) 223 xmlMemoryDump(); 224 Py_INCREF(Py_None); 225 return (Py_None); 226} 227 228/************************************************************************ 229 * * 230 * Handling Python FILE I/O at the C level * 231 * The raw I/O attack diectly the File objects, while the * 232 * other routines address the ioWrapper instance instead * 233 * * 234 ************************************************************************/ 235 236/** 237 * xmlPythonFileCloseUnref: 238 * @context: the I/O context 239 * 240 * Close an I/O channel 241 */ 242static int 243xmlPythonFileCloseRaw (void * context) { 244 PyObject *file, *ret; 245 246#ifdef DEBUG_FILES 247 printf("xmlPythonFileCloseUnref\n"); 248#endif 249 file = (PyObject *) context; 250 if (file == NULL) return(-1); 251 ret = PyEval_CallMethod(file, (char *) "close", (char *) "()"); 252 if (ret != NULL) { 253 Py_DECREF(ret); 254 } 255 Py_DECREF(file); 256 return(0); 257} 258 259/** 260 * xmlPythonFileReadRaw: 261 * @context: the I/O context 262 * @buffer: where to drop data 263 * @len: number of bytes to write 264 * 265 * Read @len bytes to @buffer from the Python file in the I/O channel 266 * 267 * Returns the number of bytes read 268 */ 269static int 270xmlPythonFileReadRaw (void * context, char * buffer, int len) { 271 PyObject *file; 272 PyObject *ret; 273 int lenread = -1; 274 char *data; 275 276#ifdef DEBUG_FILES 277 printf("xmlPythonFileReadRaw: %d\n", len); 278#endif 279 file = (PyObject *) context; 280 if (file == NULL) return(-1); 281 ret = PyEval_CallMethod(file, (char *) "read", (char *) "(i)", len); 282 if (ret == NULL) { 283 printf("xmlPythonFileReadRaw: result is NULL\n"); 284 return(-1); 285 } else if (PyString_Check(ret)) { 286 lenread = PyString_Size(ret); 287 data = PyString_AsString(ret); 288 if (lenread > len) 289 memcpy(buffer, data, len); 290 else 291 memcpy(buffer, data, lenread); 292 Py_DECREF(ret); 293 } else { 294 printf("xmlPythonFileReadRaw: result is not a String\n"); 295 Py_DECREF(ret); 296 } 297 return(lenread); 298} 299 300/** 301 * xmlPythonFileRead: 302 * @context: the I/O context 303 * @buffer: where to drop data 304 * @len: number of bytes to write 305 * 306 * Read @len bytes to @buffer from the I/O channel. 307 * 308 * Returns the number of bytes read 309 */ 310static int 311xmlPythonFileRead (void * context, char * buffer, int len) { 312 PyObject *file; 313 PyObject *ret; 314 int lenread = -1; 315 char *data; 316 317#ifdef DEBUG_FILES 318 printf("xmlPythonFileRead: %d\n", len); 319#endif 320 file = (PyObject *) context; 321 if (file == NULL) return(-1); 322 ret = PyEval_CallMethod(file, (char *) "io_read", (char *) "(i)", len); 323 if (ret == NULL) { 324 printf("xmlPythonFileRead: result is NULL\n"); 325 return(-1); 326 } else if (PyString_Check(ret)) { 327 lenread = PyString_Size(ret); 328 data = PyString_AsString(ret); 329 if (lenread > len) 330 memcpy(buffer, data, len); 331 else 332 memcpy(buffer, data, lenread); 333 Py_DECREF(ret); 334 } else { 335 printf("xmlPythonFileRead: result is not a String\n"); 336 Py_DECREF(ret); 337 } 338 return(lenread); 339} 340 341/** 342 * xmlFileWrite: 343 * @context: the I/O context 344 * @buffer: where to drop data 345 * @len: number of bytes to write 346 * 347 * Write @len bytes from @buffer to the I/O channel. 348 * 349 * Returns the number of bytes written 350 */ 351static int 352xmlPythonFileWrite (void * context, const char * buffer, int len) { 353 PyObject *file; 354 PyObject *string; 355 PyObject *ret = NULL; 356 int written = -1; 357 358#ifdef DEBUG_FILES 359 printf("xmlPythonFileWrite: %d\n", len); 360#endif 361 file = (PyObject *) context; 362 if (file == NULL) return(-1); 363 string = PyString_FromStringAndSize(buffer, len); 364 if (string == NULL) return(-1); 365 if (PyObject_HasAttrString(file, (char *) "io_write")) { 366 ret = PyEval_CallMethod(file, (char *) "io_write", (char *) "(O)", 367 string); 368 } else if (PyObject_HasAttrString(file, (char *) "write")) { 369 ret = PyEval_CallMethod(file, (char *) "write", (char *) "(O)", 370 string); 371 } 372 Py_DECREF(string); 373 if (ret == NULL) { 374 printf("xmlPythonFileWrite: result is NULL\n"); 375 return(-1); 376 } else if (PyInt_Check(ret)) { 377 written = (int) PyInt_AsLong(ret); 378 Py_DECREF(ret); 379 } else if (ret == Py_None) { 380 written = len; 381 Py_DECREF(ret); 382 } else { 383 printf("xmlPythonFileWrite: result is not an Int nor None\n"); 384 Py_DECREF(ret); 385 } 386 return(written); 387} 388 389/** 390 * xmlPythonFileClose: 391 * @context: the I/O context 392 * 393 * Close an I/O channel 394 */ 395static int 396xmlPythonFileClose (void * context) { 397 PyObject *file, *ret = NULL; 398 399#ifdef DEBUG_FILES 400 printf("xmlPythonFileClose\n"); 401#endif 402 file = (PyObject *) context; 403 if (file == NULL) return(-1); 404 if (PyObject_HasAttrString(file, (char *) "io_close")) { 405 ret = PyEval_CallMethod(file, (char *) "io_close", (char *) "()"); 406 } else if (PyObject_HasAttrString(file, (char *) "flush")) { 407 ret = PyEval_CallMethod(file, (char *) "flush", (char *) "()"); 408 } 409 if (ret != NULL) { 410 Py_DECREF(ret); 411 } 412 return(0); 413} 414 415#ifdef LIBXML_OUTPUT_ENABLED 416/** 417 * xmlOutputBufferCreatePythonFile: 418 * @file: a PyFile_Type 419 * @encoder: the encoding converter or NULL 420 * 421 * Create a buffered output for the progressive saving to a PyFile_Type 422 * buffered C I/O 423 * 424 * Returns the new parser output or NULL 425 */ 426static xmlOutputBufferPtr 427xmlOutputBufferCreatePythonFile(PyObject *file, 428 xmlCharEncodingHandlerPtr encoder) { 429 xmlOutputBufferPtr ret; 430 431 if (file == NULL) return(NULL); 432 433 ret = xmlAllocOutputBuffer(encoder); 434 if (ret != NULL) { 435 ret->context = file; 436 /* Py_INCREF(file); */ 437 ret->writecallback = xmlPythonFileWrite; 438 ret->closecallback = xmlPythonFileClose; 439 } 440 441 return(ret); 442} 443 444PyObject * 445libxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) { 446 PyObject *py_retval; 447 PyObject *file; 448 xmlChar *encoding; 449 xmlCharEncodingHandlerPtr handler = NULL; 450 xmlOutputBufferPtr buffer; 451 452 453 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate", 454 &file, &encoding)) 455 return(NULL); 456 if ((encoding != NULL) && (encoding[0] != 0)) { 457 handler = xmlFindCharEncodingHandler((const char *) encoding); 458 } 459 buffer = xmlOutputBufferCreatePythonFile(file, handler); 460 if (buffer == NULL) 461 printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n"); 462 py_retval = libxml_xmlOutputBufferPtrWrap(buffer); 463 return(py_retval); 464} 465 466/** 467 * libxml_outputBufferGetPythonFile: 468 * @buffer: the I/O buffer 469 * 470 * read the Python I/O from the CObject 471 * 472 * Returns the new parser output or NULL 473 */ 474static PyObject * 475libxml_outputBufferGetPythonFile(ATTRIBUTE_UNUSED PyObject *self, 476 PyObject *args) { 477 PyObject *buffer; 478 PyObject *file; 479 xmlOutputBufferPtr obj; 480 481 if (!PyArg_ParseTuple(args, (char *)"O:outputBufferGetPythonFile", 482 &buffer)) 483 return(NULL); 484 485 obj = PyoutputBuffer_Get(buffer); 486 if (obj == NULL) { 487 fprintf(stderr, 488 "outputBufferGetPythonFile: obj == NULL\n"); 489 Py_INCREF(Py_None); 490 return(Py_None); 491 } 492 if (obj->closecallback != xmlPythonFileClose) { 493 fprintf(stderr, 494 "outputBufferGetPythonFile: not a python file wrapper\n"); 495 Py_INCREF(Py_None); 496 return(Py_None); 497 } 498 file = (PyObject *) obj->context; 499 if (file == NULL) { 500 Py_INCREF(Py_None); 501 return(Py_None); 502 } 503 Py_INCREF(file); 504 return(file); 505} 506 507static PyObject * 508libxml_xmlOutputBufferClose(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { 509 PyObject *py_retval; 510 int c_retval; 511 xmlOutputBufferPtr out; 512 PyObject *pyobj_out; 513 514 if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferClose", &pyobj_out)) 515 return(NULL); 516 out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out); 517 /* Buffer may already have been destroyed elsewhere. This is harmless. */ 518 if (out == NULL) { 519 Py_INCREF(Py_None); 520 return(Py_None); 521 } 522 523 c_retval = xmlOutputBufferClose(out); 524 py_retval = libxml_intWrap((int) c_retval); 525 return(py_retval); 526} 527 528static PyObject * 529libxml_xmlOutputBufferFlush(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { 530 PyObject *py_retval; 531 int c_retval; 532 xmlOutputBufferPtr out; 533 PyObject *pyobj_out; 534 535 if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferFlush", &pyobj_out)) 536 return(NULL); 537 out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out); 538 539 c_retval = xmlOutputBufferFlush(out); 540 py_retval = libxml_intWrap((int) c_retval); 541 return(py_retval); 542} 543 544static PyObject * 545libxml_xmlSaveFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { 546 PyObject *py_retval; 547 int c_retval; 548 xmlOutputBufferPtr buf; 549 PyObject *pyobj_buf; 550 xmlDocPtr cur; 551 PyObject *pyobj_cur; 552 char * encoding; 553 554 if (!PyArg_ParseTuple(args, (char *)"OOz:xmlSaveFileTo", &pyobj_buf, &pyobj_cur, &encoding)) 555 return(NULL); 556 buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf); 557 cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur); 558 559 c_retval = xmlSaveFileTo(buf, cur, encoding); 560 /* xmlSaveTo() freed the memory pointed to by buf, so record that in the 561 * Python object. */ 562 ((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL; 563 py_retval = libxml_intWrap((int) c_retval); 564 return(py_retval); 565} 566 567static PyObject * 568libxml_xmlSaveFormatFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { 569 PyObject *py_retval; 570 int c_retval; 571 xmlOutputBufferPtr buf; 572 PyObject *pyobj_buf; 573 xmlDocPtr cur; 574 PyObject *pyobj_cur; 575 char * encoding; 576 int format; 577 578 if (!PyArg_ParseTuple(args, (char *)"OOzi:xmlSaveFormatFileTo", &pyobj_buf, &pyobj_cur, &encoding, &format)) 579 return(NULL); 580 buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf); 581 cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur); 582 583 c_retval = xmlSaveFormatFileTo(buf, cur, encoding, format); 584 /* xmlSaveFormatFileTo() freed the memory pointed to by buf, so record that 585 * in the Python object */ 586 ((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL; 587 py_retval = libxml_intWrap((int) c_retval); 588 return(py_retval); 589} 590#endif /* LIBXML_OUTPUT_ENABLED */ 591 592 593/** 594 * xmlParserInputBufferCreatePythonFile: 595 * @file: a PyFile_Type 596 * @encoder: the encoding converter or NULL 597 * 598 * Create a buffered output for the progressive saving to a PyFile_Type 599 * buffered C I/O 600 * 601 * Returns the new parser output or NULL 602 */ 603static xmlParserInputBufferPtr 604xmlParserInputBufferCreatePythonFile(PyObject *file, 605 xmlCharEncoding encoding) { 606 xmlParserInputBufferPtr ret; 607 608 if (file == NULL) return(NULL); 609 610 ret = xmlAllocParserInputBuffer(encoding); 611 if (ret != NULL) { 612 ret->context = file; 613 /* Py_INCREF(file); */ 614 ret->readcallback = xmlPythonFileRead; 615 ret->closecallback = xmlPythonFileClose; 616 } 617 618 return(ret); 619} 620 621PyObject * 622libxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) { 623 PyObject *py_retval; 624 PyObject *file; 625 xmlChar *encoding; 626 xmlCharEncoding enc = XML_CHAR_ENCODING_NONE; 627 xmlParserInputBufferPtr buffer; 628 629 630 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate", 631 &file, &encoding)) 632 return(NULL); 633 if ((encoding != NULL) && (encoding[0] != 0)) { 634 enc = xmlParseCharEncoding((const char *) encoding); 635 } 636 buffer = xmlParserInputBufferCreatePythonFile(file, enc); 637 if (buffer == NULL) 638 printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n"); 639 py_retval = libxml_xmlParserInputBufferPtrWrap(buffer); 640 return(py_retval); 641} 642 643/************************************************************************ 644 * * 645 * Providing the resolver at the Python level * 646 * * 647 ************************************************************************/ 648 649static xmlExternalEntityLoader defaultExternalEntityLoader = NULL; 650static PyObject *pythonExternalEntityLoaderObjext; 651 652static xmlParserInputPtr 653pythonExternalEntityLoader(const char *URL, const char *ID, 654 xmlParserCtxtPtr ctxt) { 655 xmlParserInputPtr result = NULL; 656 if (pythonExternalEntityLoaderObjext != NULL) { 657 PyObject *ret; 658 PyObject *ctxtobj; 659 660 ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt); 661#ifdef DEBUG_LOADER 662 printf("pythonExternalEntityLoader: ready to call\n"); 663#endif 664 665 ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext, 666 (char *) "(ssO)", URL, ID, ctxtobj); 667 Py_XDECREF(ctxtobj); 668#ifdef DEBUG_LOADER 669 printf("pythonExternalEntityLoader: result "); 670 PyObject_Print(ret, stderr, 0); 671 printf("\n"); 672#endif 673 674 if (ret != NULL) { 675 if (PyObject_HasAttrString(ret, (char *) "read")) { 676 xmlParserInputBufferPtr buf; 677 678 buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE); 679 if (buf != NULL) { 680 buf->context = ret; 681 buf->readcallback = xmlPythonFileReadRaw; 682 buf->closecallback = xmlPythonFileCloseRaw; 683 result = xmlNewIOInputStream(ctxt, buf, 684 XML_CHAR_ENCODING_NONE); 685 } 686#if 0 687 } else { 688 if (URL != NULL) 689 printf("pythonExternalEntityLoader: can't read %s\n", 690 URL); 691#endif 692 } 693 if (result == NULL) { 694 Py_DECREF(ret); 695 } else if (URL != NULL) { 696 result->filename = (char *) xmlStrdup((const xmlChar *)URL); 697 result->directory = xmlParserGetDirectory((const char *) URL); 698 } 699 } 700 } 701 if ((result == NULL) && (defaultExternalEntityLoader != NULL)) { 702 result = defaultExternalEntityLoader(URL, ID, ctxt); 703 } 704 return(result); 705} 706 707PyObject * 708libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) { 709 PyObject *py_retval; 710 PyObject *loader; 711 712 if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader", 713 &loader)) 714 return(NULL); 715 716#ifdef DEBUG_LOADER 717 printf("libxml_xmlSetEntityLoader\n"); 718#endif 719 if (defaultExternalEntityLoader == NULL) 720 defaultExternalEntityLoader = xmlGetExternalEntityLoader(); 721 722 pythonExternalEntityLoaderObjext = loader; 723 xmlSetExternalEntityLoader(pythonExternalEntityLoader); 724 725 py_retval = PyInt_FromLong(0); 726 return(py_retval); 727} 728 729 730/************************************************************************ 731 * * 732 * Handling SAX/xmllib/sgmlop callback interfaces * 733 * * 734 ************************************************************************/ 735 736static void 737pythonStartElement(void *user_data, const xmlChar * name, 738 const xmlChar ** attrs) 739{ 740 int i; 741 PyObject *handler; 742 PyObject *dict; 743 PyObject *attrname; 744 PyObject *attrvalue; 745 PyObject *result = NULL; 746 int type = 0; 747 748#ifdef DEBUG_SAX 749 printf("pythonStartElement(%s) called\n", name); 750#endif 751 handler = (PyObject *) user_data; 752 if (PyObject_HasAttrString(handler, (char *) "startElement")) 753 type = 1; 754 else if (PyObject_HasAttrString(handler, (char *) "start")) 755 type = 2; 756 if (type != 0) { 757 /* 758 * the xmllib interface always generate a dictionnary, 759 * possibly empty 760 */ 761 if ((attrs == NULL) && (type == 1)) { 762 Py_XINCREF(Py_None); 763 dict = Py_None; 764 } else if (attrs == NULL) { 765 dict = PyDict_New(); 766 } else { 767 dict = PyDict_New(); 768 for (i = 0; attrs[i] != NULL; i++) { 769 attrname = PyString_FromString((char *) attrs[i]); 770 i++; 771 if (attrs[i] != NULL) { 772 attrvalue = PyString_FromString((char *) attrs[i]); 773 } else { 774 Py_XINCREF(Py_None); 775 attrvalue = Py_None; 776 } 777 PyDict_SetItem(dict, attrname, attrvalue); 778 Py_DECREF(attrname); 779 Py_DECREF(attrvalue); 780 } 781 } 782 783 if (type == 1) 784 result = PyObject_CallMethod(handler, (char *) "startElement", 785 (char *) "sO", name, dict); 786 else if (type == 2) 787 result = PyObject_CallMethod(handler, (char *) "start", 788 (char *) "sO", name, dict); 789 if (PyErr_Occurred()) 790 PyErr_Print(); 791 Py_XDECREF(dict); 792 Py_XDECREF(result); 793 } 794} 795 796static void 797pythonStartDocument(void *user_data) 798{ 799 PyObject *handler; 800 PyObject *result; 801 802#ifdef DEBUG_SAX 803 printf("pythonStartDocument() called\n"); 804#endif 805 handler = (PyObject *) user_data; 806 if (PyObject_HasAttrString(handler, (char *) "startDocument")) { 807 result = 808 PyObject_CallMethod(handler, (char *) "startDocument", NULL); 809 if (PyErr_Occurred()) 810 PyErr_Print(); 811 Py_XDECREF(result); 812 } 813} 814 815static void 816pythonEndDocument(void *user_data) 817{ 818 PyObject *handler; 819 PyObject *result; 820 821#ifdef DEBUG_SAX 822 printf("pythonEndDocument() called\n"); 823#endif 824 handler = (PyObject *) user_data; 825 if (PyObject_HasAttrString(handler, (char *) "endDocument")) { 826 result = 827 PyObject_CallMethod(handler, (char *) "endDocument", NULL); 828 if (PyErr_Occurred()) 829 PyErr_Print(); 830 Py_XDECREF(result); 831 } 832 /* 833 * The reference to the handler is released there 834 */ 835 Py_XDECREF(handler); 836} 837 838static void 839pythonEndElement(void *user_data, const xmlChar * name) 840{ 841 PyObject *handler; 842 PyObject *result; 843 844#ifdef DEBUG_SAX 845 printf("pythonEndElement(%s) called\n", name); 846#endif 847 handler = (PyObject *) user_data; 848 if (PyObject_HasAttrString(handler, (char *) "endElement")) { 849 result = PyObject_CallMethod(handler, (char *) "endElement", 850 (char *) "s", name); 851 if (PyErr_Occurred()) 852 PyErr_Print(); 853 Py_XDECREF(result); 854 } else if (PyObject_HasAttrString(handler, (char *) "end")) { 855 result = PyObject_CallMethod(handler, (char *) "end", 856 (char *) "s", name); 857 if (PyErr_Occurred()) 858 PyErr_Print(); 859 Py_XDECREF(result); 860 } 861} 862 863static void 864pythonReference(void *user_data, const xmlChar * name) 865{ 866 PyObject *handler; 867 PyObject *result; 868 869#ifdef DEBUG_SAX 870 printf("pythonReference(%s) called\n", name); 871#endif 872 handler = (PyObject *) user_data; 873 if (PyObject_HasAttrString(handler, (char *) "reference")) { 874 result = PyObject_CallMethod(handler, (char *) "reference", 875 (char *) "s", name); 876 if (PyErr_Occurred()) 877 PyErr_Print(); 878 Py_XDECREF(result); 879 } 880} 881 882static void 883pythonCharacters(void *user_data, const xmlChar * ch, int len) 884{ 885 PyObject *handler; 886 PyObject *result = NULL; 887 int type = 0; 888 889#ifdef DEBUG_SAX 890 printf("pythonCharacters(%s, %d) called\n", ch, len); 891#endif 892 handler = (PyObject *) user_data; 893 if (PyObject_HasAttrString(handler, (char *) "characters")) 894 type = 1; 895 else if (PyObject_HasAttrString(handler, (char *) "data")) 896 type = 2; 897 if (type != 0) { 898 if (type == 1) 899 result = PyObject_CallMethod(handler, (char *) "characters", 900 (char *) "s#", ch, len); 901 else if (type == 2) 902 result = PyObject_CallMethod(handler, (char *) "data", 903 (char *) "s#", ch, len); 904 if (PyErr_Occurred()) 905 PyErr_Print(); 906 Py_XDECREF(result); 907 } 908} 909 910static void 911pythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len) 912{ 913 PyObject *handler; 914 PyObject *result = NULL; 915 int type = 0; 916 917#ifdef DEBUG_SAX 918 printf("pythonIgnorableWhitespace(%s, %d) called\n", ch, len); 919#endif 920 handler = (PyObject *) user_data; 921 if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace")) 922 type = 1; 923 else if (PyObject_HasAttrString(handler, (char *) "data")) 924 type = 2; 925 if (type != 0) { 926 if (type == 1) 927 result = 928 PyObject_CallMethod(handler, 929 (char *) "ignorableWhitespace", 930 (char *) "s#", ch, len); 931 else if (type == 2) 932 result = 933 PyObject_CallMethod(handler, (char *) "data", 934 (char *) "s#", ch, len); 935 Py_XDECREF(result); 936 } 937} 938 939static void 940pythonProcessingInstruction(void *user_data, 941 const xmlChar * target, const xmlChar * data) 942{ 943 PyObject *handler; 944 PyObject *result; 945 946#ifdef DEBUG_SAX 947 printf("pythonProcessingInstruction(%s, %s) called\n", target, data); 948#endif 949 handler = (PyObject *) user_data; 950 if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) { 951 result = PyObject_CallMethod(handler, (char *) 952 "processingInstruction", 953 (char *) "ss", target, data); 954 Py_XDECREF(result); 955 } 956} 957 958static void 959pythonComment(void *user_data, const xmlChar * value) 960{ 961 PyObject *handler; 962 PyObject *result; 963 964#ifdef DEBUG_SAX 965 printf("pythonComment(%s) called\n", value); 966#endif 967 handler = (PyObject *) user_data; 968 if (PyObject_HasAttrString(handler, (char *) "comment")) { 969 result = 970 PyObject_CallMethod(handler, (char *) "comment", (char *) "s", 971 value); 972 if (PyErr_Occurred()) 973 PyErr_Print(); 974 Py_XDECREF(result); 975 } 976} 977 978static void 979pythonWarning(void *user_data, const char *msg, ...) 980{ 981 PyObject *handler; 982 PyObject *result; 983 va_list args; 984 char buf[1024]; 985 986#ifdef DEBUG_SAX 987 printf("pythonWarning(%s) called\n", msg); 988#endif 989 handler = (PyObject *) user_data; 990 if (PyObject_HasAttrString(handler, (char *) "warning")) { 991 va_start(args, msg); 992 vsnprintf(buf, 1023, msg, args); 993 va_end(args); 994 buf[1023] = 0; 995 result = 996 PyObject_CallMethod(handler, (char *) "warning", (char *) "s", 997 buf); 998 if (PyErr_Occurred()) 999 PyErr_Print(); 1000 Py_XDECREF(result); 1001 } 1002} 1003 1004static void 1005pythonError(void *user_data, const char *msg, ...) 1006{ 1007 PyObject *handler; 1008 PyObject *result; 1009 va_list args; 1010 char buf[1024]; 1011 1012#ifdef DEBUG_SAX 1013 printf("pythonError(%s) called\n", msg); 1014#endif 1015 handler = (PyObject *) user_data; 1016 if (PyObject_HasAttrString(handler, (char *) "error")) { 1017 va_start(args, msg); 1018 vsnprintf(buf, 1023, msg, args); 1019 va_end(args); 1020 buf[1023] = 0; 1021 result = 1022 PyObject_CallMethod(handler, (char *) "error", (char *) "s", 1023 buf); 1024 if (PyErr_Occurred()) 1025 PyErr_Print(); 1026 Py_XDECREF(result); 1027 } 1028} 1029 1030static void 1031pythonFatalError(void *user_data, const char *msg, ...) 1032{ 1033 PyObject *handler; 1034 PyObject *result; 1035 va_list args; 1036 char buf[1024]; 1037 1038#ifdef DEBUG_SAX 1039 printf("pythonFatalError(%s) called\n", msg); 1040#endif 1041 handler = (PyObject *) user_data; 1042 if (PyObject_HasAttrString(handler, (char *) "fatalError")) { 1043 va_start(args, msg); 1044 vsnprintf(buf, 1023, msg, args); 1045 va_end(args); 1046 buf[1023] = 0; 1047 result = 1048 PyObject_CallMethod(handler, (char *) "fatalError", 1049 (char *) "s", buf); 1050 if (PyErr_Occurred()) 1051 PyErr_Print(); 1052 Py_XDECREF(result); 1053 } 1054} 1055 1056static void 1057pythonCdataBlock(void *user_data, const xmlChar * ch, int len) 1058{ 1059 PyObject *handler; 1060 PyObject *result = NULL; 1061 int type = 0; 1062 1063#ifdef DEBUG_SAX 1064 printf("pythonCdataBlock(%s, %d) called\n", ch, len); 1065#endif 1066 handler = (PyObject *) user_data; 1067 if (PyObject_HasAttrString(handler, (char *) "cdataBlock")) 1068 type = 1; 1069 else if (PyObject_HasAttrString(handler, (char *) "cdata")) 1070 type = 2; 1071 if (type != 0) { 1072 if (type == 1) 1073 result = 1074 PyObject_CallMethod(handler, (char *) "cdataBlock", 1075 (char *) "s#", ch, len); 1076 else if (type == 2) 1077 result = 1078 PyObject_CallMethod(handler, (char *) "cdata", 1079 (char *) "s#", ch, len); 1080 if (PyErr_Occurred()) 1081 PyErr_Print(); 1082 Py_XDECREF(result); 1083 } 1084} 1085 1086static void 1087pythonExternalSubset(void *user_data, 1088 const xmlChar * name, 1089 const xmlChar * externalID, const xmlChar * systemID) 1090{ 1091 PyObject *handler; 1092 PyObject *result; 1093 1094#ifdef DEBUG_SAX 1095 printf("pythonExternalSubset(%s, %s, %s) called\n", 1096 name, externalID, systemID); 1097#endif 1098 handler = (PyObject *) user_data; 1099 if (PyObject_HasAttrString(handler, (char *) "externalSubset")) { 1100 result = 1101 PyObject_CallMethod(handler, (char *) "externalSubset", 1102 (char *) "sss", name, externalID, 1103 systemID); 1104 Py_XDECREF(result); 1105 } 1106} 1107 1108static void 1109pythonEntityDecl(void *user_data, 1110 const xmlChar * name, 1111 int type, 1112 const xmlChar * publicId, 1113 const xmlChar * systemId, xmlChar * content) 1114{ 1115 PyObject *handler; 1116 PyObject *result; 1117 1118 handler = (PyObject *) user_data; 1119 if (PyObject_HasAttrString(handler, (char *) "entityDecl")) { 1120 result = PyObject_CallMethod(handler, (char *) "entityDecl", 1121 (char *) "sisss", name, type, 1122 publicId, systemId, content); 1123 if (PyErr_Occurred()) 1124 PyErr_Print(); 1125 Py_XDECREF(result); 1126 } 1127} 1128 1129 1130 1131static void 1132 1133pythonNotationDecl(void *user_data, 1134 const xmlChar * name, 1135 const xmlChar * publicId, const xmlChar * systemId) 1136{ 1137 PyObject *handler; 1138 PyObject *result; 1139 1140 handler = (PyObject *) user_data; 1141 if (PyObject_HasAttrString(handler, (char *) "notationDecl")) { 1142 result = PyObject_CallMethod(handler, (char *) "notationDecl", 1143 (char *) "sss", name, publicId, 1144 systemId); 1145 if (PyErr_Occurred()) 1146 PyErr_Print(); 1147 Py_XDECREF(result); 1148 } 1149} 1150 1151static void 1152pythonAttributeDecl(void *user_data, 1153 const xmlChar * elem, 1154 const xmlChar * name, 1155 int type, 1156 int def, 1157 const xmlChar * defaultValue, xmlEnumerationPtr tree) 1158{ 1159 PyObject *handler; 1160 PyObject *nameList; 1161 PyObject *newName; 1162 xmlEnumerationPtr node; 1163 PyObject *result; 1164 int count; 1165 1166 handler = (PyObject *) user_data; 1167 if (PyObject_HasAttrString(handler, (char *) "attributeDecl")) { 1168 count = 0; 1169 for (node = tree; node != NULL; node = node->next) { 1170 count++; 1171 } 1172 nameList = PyList_New(count); 1173 count = 0; 1174 for (node = tree; node != NULL; node = node->next) { 1175 newName = PyString_FromString((char *) node->name); 1176 PyList_SetItem(nameList, count, newName); 1177 Py_DECREF(newName); 1178 count++; 1179 } 1180 result = PyObject_CallMethod(handler, (char *) "attributeDecl", 1181 (char *) "ssiisO", elem, name, type, 1182 def, defaultValue, nameList); 1183 if (PyErr_Occurred()) 1184 PyErr_Print(); 1185 Py_XDECREF(nameList); 1186 Py_XDECREF(result); 1187 } 1188} 1189 1190static void 1191pythonElementDecl(void *user_data, 1192 const xmlChar * name, 1193 int type, ATTRIBUTE_UNUSED xmlElementContentPtr content) 1194{ 1195 PyObject *handler; 1196 PyObject *obj; 1197 PyObject *result; 1198 1199 handler = (PyObject *) user_data; 1200 if (PyObject_HasAttrString(handler, (char *) "elementDecl")) { 1201 /* TODO: wrap in an elementContent object */ 1202 printf 1203 ("pythonElementDecl: xmlElementContentPtr wrapper missing !\n"); 1204 obj = Py_None; 1205 /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */ 1206 result = PyObject_CallMethod(handler, (char *) "elementDecl", 1207 (char *) "siO", name, type, obj); 1208 if (PyErr_Occurred()) 1209 PyErr_Print(); 1210 Py_XDECREF(result); 1211 } 1212} 1213 1214static void 1215pythonUnparsedEntityDecl(void *user_data, 1216 const xmlChar * name, 1217 const xmlChar * publicId, 1218 const xmlChar * systemId, 1219 const xmlChar * notationName) 1220{ 1221 PyObject *handler; 1222 PyObject *result; 1223 1224 handler = (PyObject *) user_data; 1225 if (PyObject_HasAttrString(handler, (char *) "unparsedEntityDecl")) { 1226 result = 1227 PyObject_CallMethod(handler, (char *) "unparsedEntityDecl", 1228 (char *) "ssss", name, publicId, systemId, 1229 notationName); 1230 if (PyErr_Occurred()) 1231 PyErr_Print(); 1232 Py_XDECREF(result); 1233 } 1234} 1235 1236static void 1237pythonInternalSubset(void *user_data, const xmlChar * name, 1238 const xmlChar * ExternalID, const xmlChar * SystemID) 1239{ 1240 PyObject *handler; 1241 PyObject *result; 1242 1243#ifdef DEBUG_SAX 1244 printf("pythonInternalSubset(%s, %s, %s) called\n", 1245 name, ExternalID, SystemID); 1246#endif 1247 handler = (PyObject *) user_data; 1248 if (PyObject_HasAttrString(handler, (char *) "internalSubset")) { 1249 result = PyObject_CallMethod(handler, (char *) "internalSubset", 1250 (char *) "sss", name, ExternalID, 1251 SystemID); 1252 if (PyErr_Occurred()) 1253 PyErr_Print(); 1254 Py_XDECREF(result); 1255 } 1256} 1257 1258static xmlSAXHandler pythonSaxHandler = { 1259 pythonInternalSubset, 1260 NULL, /* TODO pythonIsStandalone, */ 1261 NULL, /* TODO pythonHasInternalSubset, */ 1262 NULL, /* TODO pythonHasExternalSubset, */ 1263 NULL, /* TODO pythonResolveEntity, */ 1264 NULL, /* TODO pythonGetEntity, */ 1265 pythonEntityDecl, 1266 pythonNotationDecl, 1267 pythonAttributeDecl, 1268 pythonElementDecl, 1269 pythonUnparsedEntityDecl, 1270 NULL, /* OBSOLETED pythonSetDocumentLocator, */ 1271 pythonStartDocument, 1272 pythonEndDocument, 1273 pythonStartElement, 1274 pythonEndElement, 1275 pythonReference, 1276 pythonCharacters, 1277 pythonIgnorableWhitespace, 1278 pythonProcessingInstruction, 1279 pythonComment, 1280 pythonWarning, 1281 pythonError, 1282 pythonFatalError, 1283 NULL, /* TODO pythonGetParameterEntity, */ 1284 pythonCdataBlock, 1285 pythonExternalSubset, 1286 1, 1287 NULL, /* TODO mograte to SAX2 */ 1288 NULL, 1289 NULL, 1290 NULL 1291}; 1292 1293/************************************************************************ 1294 * * 1295 * Handling of specific parser context * 1296 * * 1297 ************************************************************************/ 1298 1299PyObject * 1300libxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self, 1301 PyObject * args) 1302{ 1303 const char *chunk; 1304 int size; 1305 const char *URI; 1306 PyObject *pyobj_SAX = NULL; 1307 xmlSAXHandlerPtr SAX = NULL; 1308 xmlParserCtxtPtr ret; 1309 PyObject *pyret; 1310 1311 if (!PyArg_ParseTuple 1312 (args, (char *) "Oziz:xmlCreatePushParser", &pyobj_SAX, &chunk, 1313 &size, &URI)) 1314 return (NULL); 1315 1316#ifdef DEBUG 1317 printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n", 1318 pyobj_SAX, chunk, size, URI); 1319#endif 1320 if (pyobj_SAX != Py_None) { 1321 SAX = &pythonSaxHandler; 1322 Py_INCREF(pyobj_SAX); 1323 /* The reference is released in pythonEndDocument() */ 1324 } 1325 ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI); 1326 pyret = libxml_xmlParserCtxtPtrWrap(ret); 1327 return (pyret); 1328} 1329 1330PyObject * 1331libxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self, 1332 PyObject * args) 1333{ 1334#ifdef LIBXML_HTML_ENABLED 1335 const char *chunk; 1336 int size; 1337 const char *URI; 1338 PyObject *pyobj_SAX = NULL; 1339 xmlSAXHandlerPtr SAX = NULL; 1340 xmlParserCtxtPtr ret; 1341 PyObject *pyret; 1342 1343 if (!PyArg_ParseTuple 1344 (args, (char *) "Oziz:htmlCreatePushParser", &pyobj_SAX, &chunk, 1345 &size, &URI)) 1346 return (NULL); 1347 1348#ifdef DEBUG 1349 printf("libxml_htmlCreatePushParser(%p, %s, %d, %s) called\n", 1350 pyobj_SAX, chunk, size, URI); 1351#endif 1352 if (pyobj_SAX != Py_None) { 1353 SAX = &pythonSaxHandler; 1354 Py_INCREF(pyobj_SAX); 1355 /* The reference is released in pythonEndDocument() */ 1356 } 1357 ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI, 1358 XML_CHAR_ENCODING_NONE); 1359 pyret = libxml_xmlParserCtxtPtrWrap(ret); 1360 return (pyret); 1361#else 1362 Py_INCREF(Py_None); 1363 return (Py_None); 1364#endif /* LIBXML_HTML_ENABLED */ 1365} 1366 1367PyObject * 1368libxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 1369{ 1370 int recover; 1371 const char *URI; 1372 PyObject *pyobj_SAX = NULL; 1373 xmlSAXHandlerPtr SAX = NULL; 1374 1375 if (!PyArg_ParseTuple(args, (char *) "Osi:xmlSAXParseFile", &pyobj_SAX, 1376 &URI, &recover)) 1377 return (NULL); 1378 1379#ifdef DEBUG 1380 printf("libxml_xmlSAXParseFile(%p, %s, %d) called\n", 1381 pyobj_SAX, URI, recover); 1382#endif 1383 if (pyobj_SAX == Py_None) { 1384 Py_INCREF(Py_None); 1385 return (Py_None); 1386 } 1387 SAX = &pythonSaxHandler; 1388 Py_INCREF(pyobj_SAX); 1389 /* The reference is released in pythonEndDocument() */ 1390 xmlSAXUserParseFile(SAX, pyobj_SAX, URI); 1391 Py_INCREF(Py_None); 1392 return (Py_None); 1393} 1394 1395PyObject * 1396libxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 1397{ 1398#ifdef LIBXML_HTML_ENABLED 1399 const char *URI; 1400 const char *encoding; 1401 PyObject *pyobj_SAX = NULL; 1402 xmlSAXHandlerPtr SAX = NULL; 1403 1404 if (!PyArg_ParseTuple 1405 (args, (char *) "Osz:htmlSAXParseFile", &pyobj_SAX, &URI, 1406 &encoding)) 1407 return (NULL); 1408 1409#ifdef DEBUG 1410 printf("libxml_htmlSAXParseFile(%p, %s, %s) called\n", 1411 pyobj_SAX, URI, encoding); 1412#endif 1413 if (pyobj_SAX == Py_None) { 1414 Py_INCREF(Py_None); 1415 return (Py_None); 1416 } 1417 SAX = &pythonSaxHandler; 1418 Py_INCREF(pyobj_SAX); 1419 /* The reference is released in pythonEndDocument() */ 1420 htmlSAXParseFile(URI, encoding, SAX, pyobj_SAX); 1421 Py_INCREF(Py_None); 1422 return (Py_None); 1423#else 1424 Py_INCREF(Py_None); 1425 return (Py_None); 1426#endif /* LIBXML_HTML_ENABLED */ 1427} 1428 1429/************************************************************************ 1430 * * 1431 * Error message callback * 1432 * * 1433 ************************************************************************/ 1434 1435static PyObject *libxml_xmlPythonErrorFuncHandler = NULL; 1436static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL; 1437 1438/* helper to build a xmlMalloc'ed string from a format and va_list */ 1439/* 1440 * disabled the loop, the repeated call to vsnprintf without reset of ap 1441 * in case the initial buffer was too small segfaulted on x86_64 1442 * we now directly vsnprintf on a large buffer. 1443 */ 1444static char * 1445libxml_buildMessage(const char *msg, va_list ap) 1446{ 1447 int chars; 1448 char *str; 1449 1450 str = (char *) xmlMalloc(1000); 1451 if (str == NULL) 1452 return NULL; 1453 1454 chars = vsnprintf(str, 999, msg, ap); 1455 if (chars >= 998) 1456 str[999] = 0; 1457 1458 return str; 1459} 1460 1461static void 1462libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg, 1463 ...) 1464{ 1465 va_list ap; 1466 PyObject *list; 1467 PyObject *message; 1468 PyObject *result; 1469 char str[1000]; 1470 1471#ifdef DEBUG_ERROR 1472 printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg); 1473#endif 1474 1475 1476 if (libxml_xmlPythonErrorFuncHandler == NULL) { 1477 va_start(ap, msg); 1478 vfprintf(stderr, msg, ap); 1479 va_end(ap); 1480 } else { 1481 va_start(ap, msg); 1482 if (vsnprintf(str, 999, msg, ap) >= 998) 1483 str[999] = 0; 1484 va_end(ap); 1485 1486 list = PyTuple_New(2); 1487 PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt); 1488 Py_XINCREF(libxml_xmlPythonErrorFuncCtxt); 1489 message = libxml_charPtrConstWrap(str); 1490 PyTuple_SetItem(list, 1, message); 1491 result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list); 1492 Py_XDECREF(list); 1493 Py_XDECREF(result); 1494 } 1495} 1496 1497static void 1498libxml_xmlErrorInitialize(void) 1499{ 1500#ifdef DEBUG_ERROR 1501 printf("libxml_xmlErrorInitialize() called\n"); 1502#endif 1503 xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler); 1504 xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler); 1505} 1506 1507static PyObject * 1508libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self, 1509 PyObject * args) 1510{ 1511 PyObject *py_retval; 1512 PyObject *pyobj_f; 1513 PyObject *pyobj_ctx; 1514 1515 if (!PyArg_ParseTuple 1516 (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f, 1517 &pyobj_ctx)) 1518 return (NULL); 1519 1520#ifdef DEBUG_ERROR 1521 printf("libxml_xmlRegisterErrorHandler(%p, %p) called\n", pyobj_ctx, 1522 pyobj_f); 1523#endif 1524 1525 if (libxml_xmlPythonErrorFuncHandler != NULL) { 1526 Py_XDECREF(libxml_xmlPythonErrorFuncHandler); 1527 } 1528 if (libxml_xmlPythonErrorFuncCtxt != NULL) { 1529 Py_XDECREF(libxml_xmlPythonErrorFuncCtxt); 1530 } 1531 1532 Py_XINCREF(pyobj_ctx); 1533 Py_XINCREF(pyobj_f); 1534 1535 /* TODO: check f is a function ! */ 1536 libxml_xmlPythonErrorFuncHandler = pyobj_f; 1537 libxml_xmlPythonErrorFuncCtxt = pyobj_ctx; 1538 1539 py_retval = libxml_intWrap(1); 1540 return (py_retval); 1541} 1542 1543 1544/************************************************************************ 1545 * * 1546 * Per parserCtxt error handler * 1547 * * 1548 ************************************************************************/ 1549 1550typedef struct 1551{ 1552 PyObject *f; 1553 PyObject *arg; 1554} xmlParserCtxtPyCtxt; 1555typedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr; 1556 1557static void 1558libxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str) 1559{ 1560 PyObject *list; 1561 PyObject *result; 1562 xmlParserCtxtPtr ctxt; 1563 xmlParserCtxtPyCtxtPtr pyCtxt; 1564 1565#ifdef DEBUG_ERROR 1566 printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str); 1567#endif 1568 1569 ctxt = (xmlParserCtxtPtr)ctx; 1570 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private; 1571 1572 list = PyTuple_New(4); 1573 PyTuple_SetItem(list, 0, pyCtxt->arg); 1574 Py_XINCREF(pyCtxt->arg); 1575 PyTuple_SetItem(list, 1, libxml_charPtrWrap(str)); 1576 PyTuple_SetItem(list, 2, libxml_intWrap(severity)); 1577 PyTuple_SetItem(list, 3, Py_None); 1578 Py_INCREF(Py_None); 1579 result = PyEval_CallObject(pyCtxt->f, list); 1580 if (result == NULL) 1581 { 1582 /* TODO: manage for the exception to be propagated... */ 1583 PyErr_Print(); 1584 } 1585 Py_XDECREF(list); 1586 Py_XDECREF(result); 1587} 1588 1589static void 1590libxml_xmlParserCtxtErrorFuncHandler(void *ctx, const char *msg, ...) 1591{ 1592 va_list ap; 1593 1594 va_start(ap, msg); 1595 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_ERROR,libxml_buildMessage(msg,ap)); 1596 va_end(ap); 1597} 1598 1599static void 1600libxml_xmlParserCtxtWarningFuncHandler(void *ctx, const char *msg, ...) 1601{ 1602 va_list ap; 1603 1604 va_start(ap, msg); 1605 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_WARNING,libxml_buildMessage(msg,ap)); 1606 va_end(ap); 1607} 1608 1609static void 1610libxml_xmlParserCtxtValidityErrorFuncHandler(void *ctx, const char *msg, ...) 1611{ 1612 va_list ap; 1613 1614 va_start(ap, msg); 1615 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap)); 1616 va_end(ap); 1617} 1618 1619static void 1620libxml_xmlParserCtxtValidityWarningFuncHandler(void *ctx, const char *msg, ...) 1621{ 1622 va_list ap; 1623 1624 va_start(ap, msg); 1625 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap)); 1626 va_end(ap); 1627} 1628 1629static PyObject * 1630libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) 1631{ 1632 PyObject *py_retval; 1633 xmlParserCtxtPtr ctxt; 1634 xmlParserCtxtPyCtxtPtr pyCtxt; 1635 PyObject *pyobj_ctxt; 1636 PyObject *pyobj_f; 1637 PyObject *pyobj_arg; 1638 1639 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler", 1640 &pyobj_ctxt, &pyobj_f, &pyobj_arg)) 1641 return(NULL); 1642 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); 1643 if (ctxt->_private == NULL) { 1644 pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt)); 1645 if (pyCtxt == NULL) { 1646 py_retval = libxml_intWrap(-1); 1647 return(py_retval); 1648 } 1649 memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt)); 1650 ctxt->_private = pyCtxt; 1651 } 1652 else { 1653 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private; 1654 } 1655 /* TODO: check f is a function ! */ 1656 Py_XDECREF(pyCtxt->f); 1657 Py_XINCREF(pyobj_f); 1658 pyCtxt->f = pyobj_f; 1659 Py_XDECREF(pyCtxt->arg); 1660 Py_XINCREF(pyobj_arg); 1661 pyCtxt->arg = pyobj_arg; 1662 1663 if (pyobj_f != Py_None) { 1664 ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler; 1665 ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler; 1666 ctxt->vctxt.error = libxml_xmlParserCtxtValidityErrorFuncHandler; 1667 ctxt->vctxt.warning = libxml_xmlParserCtxtValidityWarningFuncHandler; 1668 } 1669 else { 1670 ctxt->sax->error = xmlParserError; 1671 ctxt->vctxt.error = xmlParserValidityError; 1672 ctxt->sax->warning = xmlParserWarning; 1673 ctxt->vctxt.warning = xmlParserValidityWarning; 1674 } 1675 1676 py_retval = libxml_intWrap(1); 1677 return(py_retval); 1678} 1679 1680static PyObject * 1681libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) 1682{ 1683 PyObject *py_retval; 1684 xmlParserCtxtPtr ctxt; 1685 xmlParserCtxtPyCtxtPtr pyCtxt; 1686 PyObject *pyobj_ctxt; 1687 1688 if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler", 1689 &pyobj_ctxt)) 1690 return(NULL); 1691 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); 1692 py_retval = PyTuple_New(2); 1693 if (ctxt->_private != NULL) { 1694 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private; 1695 1696 PyTuple_SetItem(py_retval, 0, pyCtxt->f); 1697 Py_XINCREF(pyCtxt->f); 1698 PyTuple_SetItem(py_retval, 1, pyCtxt->arg); 1699 Py_XINCREF(pyCtxt->arg); 1700 } 1701 else { 1702 /* no python error handler registered */ 1703 PyTuple_SetItem(py_retval, 0, Py_None); 1704 Py_XINCREF(Py_None); 1705 PyTuple_SetItem(py_retval, 1, Py_None); 1706 Py_XINCREF(Py_None); 1707 } 1708 return(py_retval); 1709} 1710 1711static PyObject * 1712libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) { 1713 xmlParserCtxtPtr ctxt; 1714 PyObject *pyobj_ctxt; 1715 xmlParserCtxtPyCtxtPtr pyCtxt; 1716 1717 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt)) 1718 return(NULL); 1719 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); 1720 1721 if (ctxt != NULL) { 1722 pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private; 1723 if (pyCtxt) { 1724 Py_XDECREF(pyCtxt->f); 1725 Py_XDECREF(pyCtxt->arg); 1726 xmlFree(pyCtxt); 1727 } 1728 xmlFreeParserCtxt(ctxt); 1729 } 1730 1731 Py_INCREF(Py_None); 1732 return(Py_None); 1733} 1734 1735/*** 1736 * xmlValidCtxt stuff 1737 */ 1738 1739typedef struct 1740{ 1741 PyObject *warn; 1742 PyObject *error; 1743 PyObject *arg; 1744} xmlValidCtxtPyCtxt; 1745typedef xmlValidCtxtPyCtxt *xmlValidCtxtPyCtxtPtr; 1746 1747static void 1748libxml_xmlValidCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str) 1749{ 1750 PyObject *list; 1751 PyObject *result; 1752 xmlValidCtxtPyCtxtPtr pyCtxt; 1753 1754#ifdef DEBUG_ERROR 1755 printf("libxml_xmlValidCtxtGenericErrorFuncHandler(%p, %d, %s, ...) called\n", ctx, severity, str); 1756#endif 1757 1758 pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx; 1759 1760 list = PyTuple_New(2); 1761 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str)); 1762 PyTuple_SetItem(list, 1, pyCtxt->arg); 1763 Py_XINCREF(pyCtxt->arg); 1764 result = PyEval_CallObject(pyCtxt->error, list); 1765 if (result == NULL) 1766 { 1767 /* TODO: manage for the exception to be propagated... */ 1768 PyErr_Print(); 1769 } 1770 Py_XDECREF(list); 1771 Py_XDECREF(result); 1772} 1773 1774static void 1775libxml_xmlValidCtxtGenericWarningFuncHandler(void *ctx, int severity, char *str) 1776{ 1777 PyObject *list; 1778 PyObject *result; 1779 xmlValidCtxtPyCtxtPtr pyCtxt; 1780 1781#ifdef DEBUG_ERROR 1782 printf("libxml_xmlValidCtxtGenericWarningFuncHandler(%p, %d, %s, ...) called\n", ctx, severity, str); 1783#endif 1784 1785 pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx; 1786 1787 list = PyTuple_New(2); 1788 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str)); 1789 PyTuple_SetItem(list, 1, pyCtxt->arg); 1790 Py_XINCREF(pyCtxt->arg); 1791 result = PyEval_CallObject(pyCtxt->warn, list); 1792 if (result == NULL) 1793 { 1794 /* TODO: manage for the exception to be propagated... */ 1795 PyErr_Print(); 1796 } 1797 Py_XDECREF(list); 1798 Py_XDECREF(result); 1799} 1800 1801static void 1802libxml_xmlValidCtxtErrorFuncHandler(void *ctx, const char *msg, ...) 1803{ 1804 va_list ap; 1805 1806 va_start(ap, msg); 1807 libxml_xmlValidCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap)); 1808 va_end(ap); 1809} 1810 1811static void 1812libxml_xmlValidCtxtWarningFuncHandler(void *ctx, const char *msg, ...) 1813{ 1814 va_list ap; 1815 1816 va_start(ap, msg); 1817 libxml_xmlValidCtxtGenericWarningFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap)); 1818 va_end(ap); 1819} 1820 1821static PyObject * 1822libxml_xmlSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 1823{ 1824 PyObject *py_retval; 1825 PyObject *pyobj_error; 1826 PyObject *pyobj_warn; 1827 PyObject *pyobj_ctx; 1828 PyObject *pyobj_arg = Py_None; 1829 xmlValidCtxtPtr ctxt; 1830 xmlValidCtxtPyCtxtPtr pyCtxt; 1831 1832 if (!PyArg_ParseTuple 1833 (args, (char *) "OOO|O:xmlSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg)) 1834 return (NULL); 1835 1836#ifdef DEBUG_ERROR 1837 printf("libxml_xmlSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn); 1838#endif 1839 1840 ctxt = PyValidCtxt_Get(pyobj_ctx); 1841 pyCtxt = xmlMalloc(sizeof(xmlValidCtxtPyCtxt)); 1842 if (pyCtxt == NULL) { 1843 py_retval = libxml_intWrap(-1); 1844 return(py_retval); 1845 } 1846 memset(pyCtxt, 0, sizeof(xmlValidCtxtPyCtxt)); 1847 1848 1849 /* TODO: check warn and error is a function ! */ 1850 Py_XDECREF(pyCtxt->error); 1851 Py_XINCREF(pyobj_error); 1852 pyCtxt->error = pyobj_error; 1853 1854 Py_XDECREF(pyCtxt->warn); 1855 Py_XINCREF(pyobj_warn); 1856 pyCtxt->warn = pyobj_warn; 1857 1858 Py_XDECREF(pyCtxt->arg); 1859 Py_XINCREF(pyobj_arg); 1860 pyCtxt->arg = pyobj_arg; 1861 1862 ctxt->error = libxml_xmlValidCtxtErrorFuncHandler; 1863 ctxt->warning = libxml_xmlValidCtxtWarningFuncHandler; 1864 ctxt->userData = pyCtxt; 1865 1866 py_retval = libxml_intWrap(1); 1867 return (py_retval); 1868} 1869 1870 1871static PyObject * 1872libxml_xmlFreeValidCtxt(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { 1873 xmlValidCtxtPtr cur; 1874 xmlValidCtxtPyCtxtPtr pyCtxt; 1875 PyObject *pyobj_cur; 1876 1877 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeValidCtxt", &pyobj_cur)) 1878 return(NULL); 1879 cur = (xmlValidCtxtPtr) PyValidCtxt_Get(pyobj_cur); 1880 1881 pyCtxt = (xmlValidCtxtPyCtxtPtr)(cur->userData); 1882 if (pyCtxt != NULL) 1883 { 1884 Py_XDECREF(pyCtxt->error); 1885 Py_XDECREF(pyCtxt->warn); 1886 Py_XDECREF(pyCtxt->arg); 1887 xmlFree(pyCtxt); 1888 } 1889 1890 xmlFreeValidCtxt(cur); 1891 Py_INCREF(Py_None); 1892 return(Py_None); 1893} 1894 1895#ifdef LIBXML_READER_ENABLED 1896/************************************************************************ 1897 * * 1898 * Per xmlTextReader error handler * 1899 * * 1900 ************************************************************************/ 1901 1902typedef struct 1903{ 1904 PyObject *f; 1905 PyObject *arg; 1906} xmlTextReaderPyCtxt; 1907typedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr; 1908 1909static void 1910libxml_xmlTextReaderErrorCallback(void *arg, 1911 const char *msg, 1912 int severity, 1913 xmlTextReaderLocatorPtr locator) 1914{ 1915 xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg; 1916 PyObject *list; 1917 PyObject *result; 1918 1919 list = PyTuple_New(4); 1920 PyTuple_SetItem(list, 0, pyCtxt->arg); 1921 Py_XINCREF(pyCtxt->arg); 1922 PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg)); 1923 PyTuple_SetItem(list, 2, libxml_intWrap(severity)); 1924 PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator)); 1925 result = PyEval_CallObject(pyCtxt->f, list); 1926 if (result == NULL) 1927 { 1928 /* TODO: manage for the exception to be propagated... */ 1929 PyErr_Print(); 1930 } 1931 Py_XDECREF(list); 1932 Py_XDECREF(result); 1933} 1934 1935static PyObject * 1936libxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) 1937{ 1938 xmlTextReaderPtr reader; 1939 xmlTextReaderPyCtxtPtr pyCtxt; 1940 xmlTextReaderErrorFunc f; 1941 void *arg; 1942 PyObject *pyobj_reader; 1943 PyObject *pyobj_f; 1944 PyObject *pyobj_arg; 1945 PyObject *py_retval; 1946 1947 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlTextReaderSetErrorHandler", &pyobj_reader, &pyobj_f, &pyobj_arg)) 1948 return(NULL); 1949 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader); 1950 /* clear previous error handler */ 1951 xmlTextReaderGetErrorHandler(reader,&f,&arg); 1952 if (arg != NULL) { 1953 if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) { 1954 /* ok, it's our error handler! */ 1955 pyCtxt = (xmlTextReaderPyCtxtPtr)arg; 1956 Py_XDECREF(pyCtxt->f); 1957 Py_XDECREF(pyCtxt->arg); 1958 xmlFree(pyCtxt); 1959 } 1960 else { 1961 /* 1962 * there already an arg, and it's not ours, 1963 * there is definitely something wrong going on here... 1964 * we don't know how to free it, so we bail out... 1965 */ 1966 py_retval = libxml_intWrap(-1); 1967 return(py_retval); 1968 } 1969 } 1970 xmlTextReaderSetErrorHandler(reader,NULL,NULL); 1971 /* set new error handler */ 1972 if (pyobj_f != Py_None) 1973 { 1974 pyCtxt = (xmlTextReaderPyCtxtPtr)xmlMalloc(sizeof(xmlTextReaderPyCtxt)); 1975 if (pyCtxt == NULL) { 1976 py_retval = libxml_intWrap(-1); 1977 return(py_retval); 1978 } 1979 Py_XINCREF(pyobj_f); 1980 pyCtxt->f = pyobj_f; 1981 Py_XINCREF(pyobj_arg); 1982 pyCtxt->arg = pyobj_arg; 1983 xmlTextReaderSetErrorHandler(reader, 1984 (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback, 1985 pyCtxt); 1986 } 1987 1988 py_retval = libxml_intWrap(1); 1989 return(py_retval); 1990} 1991 1992static PyObject * 1993libxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) 1994{ 1995 xmlTextReaderPtr reader; 1996 xmlTextReaderPyCtxtPtr pyCtxt; 1997 xmlTextReaderErrorFunc f; 1998 void *arg; 1999 PyObject *pyobj_reader; 2000 PyObject *py_retval; 2001 2002 if (!PyArg_ParseTuple(args, (char *)"O:xmlTextReaderSetErrorHandler", &pyobj_reader)) 2003 return(NULL); 2004 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader); 2005 xmlTextReaderGetErrorHandler(reader,&f,&arg); 2006 py_retval = PyTuple_New(2); 2007 if (f == (xmlTextReaderErrorFunc)libxml_xmlTextReaderErrorCallback) { 2008 /* ok, it's our error handler! */ 2009 pyCtxt = (xmlTextReaderPyCtxtPtr)arg; 2010 PyTuple_SetItem(py_retval, 0, pyCtxt->f); 2011 Py_XINCREF(pyCtxt->f); 2012 PyTuple_SetItem(py_retval, 1, pyCtxt->arg); 2013 Py_XINCREF(pyCtxt->arg); 2014 } 2015 else 2016 { 2017 /* f is null or it's not our error handler */ 2018 PyTuple_SetItem(py_retval, 0, Py_None); 2019 Py_XINCREF(Py_None); 2020 PyTuple_SetItem(py_retval, 1, Py_None); 2021 Py_XINCREF(Py_None); 2022 } 2023 return(py_retval); 2024} 2025 2026static PyObject * 2027libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) { 2028 xmlTextReaderPtr reader; 2029 PyObject *pyobj_reader; 2030 xmlTextReaderPyCtxtPtr pyCtxt; 2031 xmlTextReaderErrorFunc f; 2032 void *arg; 2033 2034 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader)) 2035 return(NULL); 2036 if (!PyCObject_Check(pyobj_reader)) { 2037 Py_INCREF(Py_None); 2038 return(Py_None); 2039 } 2040 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader); 2041 if (reader == NULL) { 2042 Py_INCREF(Py_None); 2043 return(Py_None); 2044 } 2045 2046 xmlTextReaderGetErrorHandler(reader,&f,&arg); 2047 if (arg != NULL) { 2048 if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) { 2049 /* ok, it's our error handler! */ 2050 pyCtxt = (xmlTextReaderPyCtxtPtr)arg; 2051 Py_XDECREF(pyCtxt->f); 2052 Py_XDECREF(pyCtxt->arg); 2053 xmlFree(pyCtxt); 2054 } 2055 /* 2056 * else, something wrong happened, because the error handler is 2057 * not owned by the python bindings... 2058 */ 2059 } 2060 2061 xmlFreeTextReader(reader); 2062 Py_INCREF(Py_None); 2063 return(Py_None); 2064} 2065#endif 2066 2067/************************************************************************ 2068 * * 2069 * XPath extensions * 2070 * * 2071 ************************************************************************/ 2072 2073static void 2074libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs) 2075{ 2076 PyObject *list, *cur, *result; 2077 xmlXPathObjectPtr obj; 2078 xmlXPathContextPtr rctxt; 2079 PyObject *current_function = NULL; 2080 const xmlChar *name; 2081 const xmlChar *ns_uri; 2082 int i; 2083 2084 if (ctxt == NULL) 2085 return; 2086 rctxt = ctxt->context; 2087 if (rctxt == NULL) 2088 return; 2089 name = rctxt->function; 2090 ns_uri = rctxt->functionURI; 2091#ifdef DEBUG_XPATH 2092 printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name, 2093 ns_uri); 2094#endif 2095 2096 /* 2097 * Find the function, it should be there it was there at lookup 2098 */ 2099 for (i = 0; i < libxml_xpathCallbacksNb; i++) { 2100 if ( /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */ 2101 (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) && 2102 (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) { 2103 current_function = (*libxml_xpathCallbacks)[i].function; 2104 } 2105 } 2106 if (current_function == NULL) { 2107 printf 2108 ("libxml_xmlXPathFuncCallback: internal error %s not found !\n", 2109 name); 2110 return; 2111 } 2112 2113 list = PyTuple_New(nargs + 1); 2114 PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt)); 2115 for (i = nargs - 1; i >= 0; i--) { 2116 obj = valuePop(ctxt); 2117 cur = libxml_xmlXPathObjectPtrWrap(obj); 2118 PyTuple_SetItem(list, i + 1, cur); 2119 } 2120 result = PyEval_CallObject(current_function, list); 2121 Py_DECREF(list); 2122 2123 obj = libxml_xmlXPathObjectPtrConvert(result); 2124 valuePush(ctxt, obj); 2125} 2126 2127static xmlXPathFunction 2128libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name, 2129 const xmlChar * ns_uri) 2130{ 2131 int i; 2132 2133#ifdef DEBUG_XPATH 2134 printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n", 2135 ctxt, name, ns_uri); 2136#endif 2137 /* 2138 * This is called once only. The address is then stored in the 2139 * XPath expression evaluation, the proper object to call can 2140 * then still be found using the execution context function 2141 * and functionURI fields. 2142 */ 2143 for (i = 0; i < libxml_xpathCallbacksNb; i++) { 2144 if ((ctxt == (*libxml_xpathCallbacks)[i].ctx) && 2145 (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) && 2146 (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) { 2147 return (libxml_xmlXPathFuncCallback); 2148 } 2149 } 2150 return (NULL); 2151} 2152 2153static void 2154libxml_xpathCallbacksInitialize(void) 2155{ 2156 int i; 2157 2158 if (libxml_xpathCallbacksInitialized != 0) 2159 return; 2160 2161#ifdef DEBUG_XPATH 2162 printf("libxml_xpathCallbacksInitialized called\n"); 2163#endif 2164 libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlMalloc( 2165 libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback)); 2166 2167 for (i = 0; i < libxml_xpathCallbacksAllocd; i++) { 2168 (*libxml_xpathCallbacks)[i].ctx = NULL; 2169 (*libxml_xpathCallbacks)[i].name = NULL; 2170 (*libxml_xpathCallbacks)[i].ns_uri = NULL; 2171 (*libxml_xpathCallbacks)[i].function = NULL; 2172 } 2173 libxml_xpathCallbacksInitialized = 1; 2174} 2175 2176PyObject * 2177libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self, 2178 PyObject * args) 2179{ 2180 PyObject *py_retval; 2181 int c_retval = 0; 2182 xmlChar *name; 2183 xmlChar *ns_uri; 2184 xmlXPathContextPtr ctx; 2185 PyObject *pyobj_ctx; 2186 PyObject *pyobj_f; 2187 int i; 2188 2189 if (!PyArg_ParseTuple 2190 (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name, 2191 &ns_uri, &pyobj_f)) 2192 return (NULL); 2193 2194 ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx); 2195 if (libxml_xpathCallbacksInitialized == 0) 2196 libxml_xpathCallbacksInitialize(); 2197 xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx); 2198 2199 if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) { 2200 py_retval = libxml_intWrap(-1); 2201 return (py_retval); 2202 } 2203#ifdef DEBUG_XPATH 2204 printf("libxml_registerXPathFunction(%p, %s, %s) called\n", 2205 ctx, name, ns_uri); 2206#endif 2207 for (i = 0; i < libxml_xpathCallbacksNb; i++) { 2208 if ((ctx == (*libxml_xpathCallbacks)[i].ctx) && 2209 (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) && 2210 (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) { 2211 Py_XINCREF(pyobj_f); 2212 Py_XDECREF((*libxml_xpathCallbacks)[i].function); 2213 (*libxml_xpathCallbacks)[i].function = pyobj_f; 2214 c_retval = 1; 2215 goto done; 2216 } 2217 } 2218 if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksAllocd) { 2219 libxml_xpathCallbacksAllocd+=10; 2220 libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlRealloc( 2221 libxml_xpathCallbacks, 2222 libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback)); 2223 } 2224 i = libxml_xpathCallbacksNb++; 2225 Py_XINCREF(pyobj_f); 2226 (*libxml_xpathCallbacks)[i].ctx = ctx; 2227 (*libxml_xpathCallbacks)[i].name = xmlStrdup(name); 2228 (*libxml_xpathCallbacks)[i].ns_uri = xmlStrdup(ns_uri); 2229 (*libxml_xpathCallbacks)[i].function = pyobj_f; 2230 c_retval = 1; 2231 2232 done: 2233 py_retval = libxml_intWrap((int) c_retval); 2234 return (py_retval); 2235} 2236 2237/************************************************************************ 2238 * * 2239 * Global properties access * 2240 * * 2241 ************************************************************************/ 2242static PyObject * 2243libxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2244{ 2245 PyObject *resultobj, *obj; 2246 xmlNodePtr cur; 2247 const xmlChar *res; 2248 2249 if (!PyArg_ParseTuple(args, (char *) "O:name", &obj)) 2250 return NULL; 2251 cur = PyxmlNode_Get(obj); 2252 2253#ifdef DEBUG 2254 printf("libxml_name: cur = %p type %d\n", cur, cur->type); 2255#endif 2256 2257 switch (cur->type) { 2258 case XML_DOCUMENT_NODE: 2259#ifdef LIBXML_DOCB_ENABLED 2260 case XML_DOCB_DOCUMENT_NODE: 2261#endif 2262 case XML_HTML_DOCUMENT_NODE:{ 2263 xmlDocPtr doc = (xmlDocPtr) cur; 2264 2265 res = doc->URL; 2266 break; 2267 } 2268 case XML_ATTRIBUTE_NODE:{ 2269 xmlAttrPtr attr = (xmlAttrPtr) cur; 2270 2271 res = attr->name; 2272 break; 2273 } 2274 case XML_NAMESPACE_DECL:{ 2275 xmlNsPtr ns = (xmlNsPtr) cur; 2276 2277 res = ns->prefix; 2278 break; 2279 } 2280 default: 2281 res = cur->name; 2282 break; 2283 } 2284 resultobj = libxml_constxmlCharPtrWrap(res); 2285 2286 return resultobj; 2287} 2288 2289static PyObject * 2290libxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2291{ 2292 PyObject *resultobj, *obj; 2293 xmlNodePtr cur; 2294 xmlDocPtr res; 2295 2296 if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj)) 2297 return NULL; 2298 cur = PyxmlNode_Get(obj); 2299 2300#ifdef DEBUG 2301 printf("libxml_doc: cur = %p\n", cur); 2302#endif 2303 2304 switch (cur->type) { 2305 case XML_DOCUMENT_NODE: 2306#ifdef LIBXML_DOCB_ENABLED 2307 case XML_DOCB_DOCUMENT_NODE: 2308#endif 2309 case XML_HTML_DOCUMENT_NODE: 2310 res = NULL; 2311 break; 2312 case XML_ATTRIBUTE_NODE:{ 2313 xmlAttrPtr attr = (xmlAttrPtr) cur; 2314 2315 res = attr->doc; 2316 break; 2317 } 2318 case XML_NAMESPACE_DECL: 2319 res = NULL; 2320 break; 2321 default: 2322 res = cur->doc; 2323 break; 2324 } 2325 resultobj = libxml_xmlDocPtrWrap(res); 2326 return resultobj; 2327} 2328 2329static PyObject * 2330libxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2331{ 2332 PyObject *resultobj, *obj; 2333 xmlNodePtr cur; 2334 xmlAttrPtr res; 2335 2336 if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj)) 2337 return NULL; 2338 cur = PyxmlNode_Get(obj); 2339 if ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) 2340 res = cur->properties; 2341 else 2342 res = NULL; 2343 resultobj = libxml_xmlAttrPtrWrap(res); 2344 return resultobj; 2345} 2346 2347static PyObject * 2348libxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2349{ 2350 PyObject *resultobj, *obj; 2351 xmlNodePtr cur; 2352 xmlNodePtr res; 2353 2354 if (!PyArg_ParseTuple(args, (char *) "O:next", &obj)) 2355 return NULL; 2356 cur = PyxmlNode_Get(obj); 2357 2358#ifdef DEBUG 2359 printf("libxml_next: cur = %p\n", cur); 2360#endif 2361 2362 switch (cur->type) { 2363 case XML_DOCUMENT_NODE: 2364#ifdef LIBXML_DOCB_ENABLED 2365 case XML_DOCB_DOCUMENT_NODE: 2366#endif 2367 case XML_HTML_DOCUMENT_NODE: 2368 res = NULL; 2369 break; 2370 case XML_ATTRIBUTE_NODE:{ 2371 xmlAttrPtr attr = (xmlAttrPtr) cur; 2372 2373 res = (xmlNodePtr) attr->next; 2374 break; 2375 } 2376 case XML_NAMESPACE_DECL:{ 2377 xmlNsPtr ns = (xmlNsPtr) cur; 2378 2379 res = (xmlNodePtr) ns->next; 2380 break; 2381 } 2382 default: 2383 res = cur->next; 2384 break; 2385 2386 } 2387 resultobj = libxml_xmlNodePtrWrap(res); 2388 return resultobj; 2389} 2390 2391static PyObject * 2392libxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2393{ 2394 PyObject *resultobj, *obj; 2395 xmlNodePtr cur; 2396 xmlNodePtr res; 2397 2398 if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj)) 2399 return NULL; 2400 cur = PyxmlNode_Get(obj); 2401 2402#ifdef DEBUG 2403 printf("libxml_prev: cur = %p\n", cur); 2404#endif 2405 2406 switch (cur->type) { 2407 case XML_DOCUMENT_NODE: 2408#ifdef LIBXML_DOCB_ENABLED 2409 case XML_DOCB_DOCUMENT_NODE: 2410#endif 2411 case XML_HTML_DOCUMENT_NODE: 2412 res = NULL; 2413 break; 2414 case XML_ATTRIBUTE_NODE:{ 2415 xmlAttrPtr attr = (xmlAttrPtr) cur; 2416 2417 res = (xmlNodePtr) attr->prev; 2418 } 2419 break; 2420 case XML_NAMESPACE_DECL: 2421 res = NULL; 2422 break; 2423 default: 2424 res = cur->prev; 2425 break; 2426 } 2427 resultobj = libxml_xmlNodePtrWrap(res); 2428 return resultobj; 2429} 2430 2431static PyObject * 2432libxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2433{ 2434 PyObject *resultobj, *obj; 2435 xmlNodePtr cur; 2436 xmlNodePtr res; 2437 2438 if (!PyArg_ParseTuple(args, (char *) "O:children", &obj)) 2439 return NULL; 2440 cur = PyxmlNode_Get(obj); 2441 2442#ifdef DEBUG 2443 printf("libxml_children: cur = %p\n", cur); 2444#endif 2445 2446 switch (cur->type) { 2447 case XML_ELEMENT_NODE: 2448 case XML_ENTITY_REF_NODE: 2449 case XML_ENTITY_NODE: 2450 case XML_PI_NODE: 2451 case XML_COMMENT_NODE: 2452 case XML_DOCUMENT_NODE: 2453#ifdef LIBXML_DOCB_ENABLED 2454 case XML_DOCB_DOCUMENT_NODE: 2455#endif 2456 case XML_HTML_DOCUMENT_NODE: 2457 case XML_DTD_NODE: 2458 res = cur->children; 2459 break; 2460 case XML_ATTRIBUTE_NODE:{ 2461 xmlAttrPtr attr = (xmlAttrPtr) cur; 2462 2463 res = attr->children; 2464 break; 2465 } 2466 default: 2467 res = NULL; 2468 break; 2469 } 2470 resultobj = libxml_xmlNodePtrWrap(res); 2471 return resultobj; 2472} 2473 2474static PyObject * 2475libxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2476{ 2477 PyObject *resultobj, *obj; 2478 xmlNodePtr cur; 2479 xmlNodePtr res; 2480 2481 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj)) 2482 return NULL; 2483 cur = PyxmlNode_Get(obj); 2484 2485#ifdef DEBUG 2486 printf("libxml_last: cur = %p\n", cur); 2487#endif 2488 2489 switch (cur->type) { 2490 case XML_ELEMENT_NODE: 2491 case XML_ENTITY_REF_NODE: 2492 case XML_ENTITY_NODE: 2493 case XML_PI_NODE: 2494 case XML_COMMENT_NODE: 2495 case XML_DOCUMENT_NODE: 2496#ifdef LIBXML_DOCB_ENABLED 2497 case XML_DOCB_DOCUMENT_NODE: 2498#endif 2499 case XML_HTML_DOCUMENT_NODE: 2500 case XML_DTD_NODE: 2501 res = cur->last; 2502 break; 2503 case XML_ATTRIBUTE_NODE:{ 2504 xmlAttrPtr attr = (xmlAttrPtr) cur; 2505 2506 res = attr->last; 2507 } 2508 default: 2509 res = NULL; 2510 break; 2511 } 2512 resultobj = libxml_xmlNodePtrWrap(res); 2513 return resultobj; 2514} 2515 2516static PyObject * 2517libxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2518{ 2519 PyObject *resultobj, *obj; 2520 xmlNodePtr cur; 2521 xmlNodePtr res; 2522 2523 if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj)) 2524 return NULL; 2525 cur = PyxmlNode_Get(obj); 2526 2527#ifdef DEBUG 2528 printf("libxml_parent: cur = %p\n", cur); 2529#endif 2530 2531 switch (cur->type) { 2532 case XML_DOCUMENT_NODE: 2533 case XML_HTML_DOCUMENT_NODE: 2534#ifdef LIBXML_DOCB_ENABLED 2535 case XML_DOCB_DOCUMENT_NODE: 2536#endif 2537 res = NULL; 2538 break; 2539 case XML_ATTRIBUTE_NODE:{ 2540 xmlAttrPtr attr = (xmlAttrPtr) cur; 2541 2542 res = attr->parent; 2543 } 2544 break; 2545 case XML_ENTITY_DECL: 2546 case XML_NAMESPACE_DECL: 2547 case XML_XINCLUDE_START: 2548 case XML_XINCLUDE_END: 2549 res = NULL; 2550 break; 2551 default: 2552 res = cur->parent; 2553 break; 2554 } 2555 resultobj = libxml_xmlNodePtrWrap(res); 2556 return resultobj; 2557} 2558 2559static PyObject * 2560libxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2561{ 2562 PyObject *resultobj, *obj; 2563 xmlNodePtr cur; 2564 const xmlChar *res = NULL; 2565 2566 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj)) 2567 return NULL; 2568 cur = PyxmlNode_Get(obj); 2569 2570#ifdef DEBUG 2571 printf("libxml_type: cur = %p\n", cur); 2572#endif 2573 2574 switch (cur->type) { 2575 case XML_ELEMENT_NODE: 2576 res = (const xmlChar *) "element"; 2577 break; 2578 case XML_ATTRIBUTE_NODE: 2579 res = (const xmlChar *) "attribute"; 2580 break; 2581 case XML_TEXT_NODE: 2582 res = (const xmlChar *) "text"; 2583 break; 2584 case XML_CDATA_SECTION_NODE: 2585 res = (const xmlChar *) "cdata"; 2586 break; 2587 case XML_ENTITY_REF_NODE: 2588 res = (const xmlChar *) "entity_ref"; 2589 break; 2590 case XML_ENTITY_NODE: 2591 res = (const xmlChar *) "entity"; 2592 break; 2593 case XML_PI_NODE: 2594 res = (const xmlChar *) "pi"; 2595 break; 2596 case XML_COMMENT_NODE: 2597 res = (const xmlChar *) "comment"; 2598 break; 2599 case XML_DOCUMENT_NODE: 2600 res = (const xmlChar *) "document_xml"; 2601 break; 2602 case XML_DOCUMENT_TYPE_NODE: 2603 res = (const xmlChar *) "doctype"; 2604 break; 2605 case XML_DOCUMENT_FRAG_NODE: 2606 res = (const xmlChar *) "fragment"; 2607 break; 2608 case XML_NOTATION_NODE: 2609 res = (const xmlChar *) "notation"; 2610 break; 2611 case XML_HTML_DOCUMENT_NODE: 2612 res = (const xmlChar *) "document_html"; 2613 break; 2614 case XML_DTD_NODE: 2615 res = (const xmlChar *) "dtd"; 2616 break; 2617 case XML_ELEMENT_DECL: 2618 res = (const xmlChar *) "elem_decl"; 2619 break; 2620 case XML_ATTRIBUTE_DECL: 2621 res = (const xmlChar *) "attribute_decl"; 2622 break; 2623 case XML_ENTITY_DECL: 2624 res = (const xmlChar *) "entity_decl"; 2625 break; 2626 case XML_NAMESPACE_DECL: 2627 res = (const xmlChar *) "namespace"; 2628 break; 2629 case XML_XINCLUDE_START: 2630 res = (const xmlChar *) "xinclude_start"; 2631 break; 2632 case XML_XINCLUDE_END: 2633 res = (const xmlChar *) "xinclude_end"; 2634 break; 2635#ifdef LIBXML_DOCB_ENABLED 2636 case XML_DOCB_DOCUMENT_NODE: 2637 res = (const xmlChar *) "document_docbook"; 2638 break; 2639#endif 2640 } 2641#ifdef DEBUG 2642 printf("libxml_type: cur = %p: %s\n", cur, res); 2643#endif 2644 2645 resultobj = libxml_constxmlCharPtrWrap(res); 2646 return resultobj; 2647} 2648 2649/************************************************************************ 2650 * * 2651 * Specific accessor functions * 2652 * * 2653 ************************************************************************/ 2654PyObject * 2655libxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2656{ 2657 PyObject *py_retval; 2658 xmlNsPtr c_retval; 2659 xmlNodePtr node; 2660 PyObject *pyobj_node; 2661 2662 if (!PyArg_ParseTuple 2663 (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node)) 2664 return (NULL); 2665 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node); 2666 2667 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) { 2668 Py_INCREF(Py_None); 2669 return (Py_None); 2670 } 2671 c_retval = node->nsDef; 2672 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval); 2673 return (py_retval); 2674} 2675 2676PyObject * 2677libxml_xmlNodeRemoveNsDef(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2678{ 2679 PyObject *py_retval; 2680 xmlNsPtr ns, prev; 2681 xmlNodePtr node; 2682 PyObject *pyobj_node; 2683 xmlChar *href; 2684 xmlNsPtr c_retval; 2685 2686 if (!PyArg_ParseTuple 2687 (args, (char *) "Oz:xmlNodeRemoveNsDef", &pyobj_node, &href)) 2688 return (NULL); 2689 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node); 2690 ns = NULL; 2691 2692 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) { 2693 Py_INCREF(Py_None); 2694 return (Py_None); 2695 } 2696 2697 if (href == NULL) { 2698 ns = node->nsDef; 2699 node->nsDef = NULL; 2700 c_retval = 0; 2701 } 2702 else { 2703 prev = NULL; 2704 ns = node->nsDef; 2705 while (ns != NULL) { 2706 if (xmlStrEqual(ns->href, href)) { 2707 if (prev != NULL) 2708 prev->next = ns->next; 2709 else 2710 node->nsDef = ns->next; 2711 ns->next = NULL; 2712 c_retval = 0; 2713 break; 2714 } 2715 prev = ns; 2716 ns = ns->next; 2717 } 2718 } 2719 2720 c_retval = ns; 2721 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval); 2722 return (py_retval); 2723} 2724 2725PyObject * 2726libxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2727{ 2728 PyObject *py_retval; 2729 xmlNsPtr c_retval; 2730 xmlNodePtr node; 2731 PyObject *pyobj_node; 2732 2733 if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node)) 2734 return (NULL); 2735 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node); 2736 2737 if ((node == NULL) || 2738 ((node->type != XML_ELEMENT_NODE) && 2739 (node->type != XML_ATTRIBUTE_NODE))) { 2740 Py_INCREF(Py_None); 2741 return (Py_None); 2742 } 2743 c_retval = node->ns; 2744 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval); 2745 return (py_retval); 2746} 2747 2748#ifdef LIBXML_OUTPUT_ENABLED 2749/************************************************************************ 2750 * * 2751 * Serialization front-end * 2752 * * 2753 ************************************************************************/ 2754 2755static PyObject * 2756libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2757{ 2758 PyObject *py_retval = NULL; 2759 xmlChar *c_retval; 2760 PyObject *pyobj_node; 2761 xmlNodePtr node; 2762 xmlDocPtr doc; 2763 const char *encoding; 2764 int format; 2765 int len; 2766 xmlSaveCtxtPtr ctxt; 2767 xmlBufferPtr buf; 2768 int options = 0; 2769 2770 if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node, 2771 &encoding, &format)) 2772 return (NULL); 2773 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node); 2774 2775 if (node == NULL) { 2776 Py_INCREF(Py_None); 2777 return (Py_None); 2778 } 2779 if (node->type == XML_DOCUMENT_NODE) { 2780 doc = (xmlDocPtr) node; 2781 node = NULL; 2782#ifdef LIBXML_HTML_ENABLED 2783 } else if (node->type == XML_HTML_DOCUMENT_NODE) { 2784 doc = (xmlDocPtr) node; 2785 node = NULL; 2786#endif 2787 } else { 2788 if (node->type == XML_NAMESPACE_DECL) 2789 doc = NULL; 2790 else 2791 doc = node->doc; 2792 if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) { 2793#ifdef LIBXML_HTML_ENABLED 2794 } else if (doc->type == XML_HTML_DOCUMENT_NODE) { 2795#endif /* LIBXML_HTML_ENABLED */ 2796 } else { 2797 Py_INCREF(Py_None); 2798 return (Py_None); 2799 } 2800 } 2801 2802 2803 buf = xmlBufferCreate(); 2804 if (buf == NULL) { 2805 Py_INCREF(Py_None); 2806 return (Py_None); 2807 } 2808 if (format) options |= XML_SAVE_FORMAT; 2809 ctxt = xmlSaveToBuffer(buf, encoding, options); 2810 if (ctxt == NULL) { 2811 xmlBufferFree(buf); 2812 Py_INCREF(Py_None); 2813 return (Py_None); 2814 } 2815 if (node == NULL) 2816 xmlSaveDoc(ctxt, doc); 2817 else 2818 xmlSaveTree(ctxt, node); 2819 xmlSaveClose(ctxt); 2820 2821 c_retval = buf->content; 2822 buf->content = NULL; 2823 2824 xmlBufferFree(buf); 2825 py_retval = libxml_charPtrWrap((char *) c_retval); 2826 2827 return (py_retval); 2828} 2829 2830static PyObject * 2831libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2832{ 2833 PyObject *py_file = NULL; 2834 FILE *output; 2835 PyObject *pyobj_node; 2836 xmlNodePtr node; 2837 xmlDocPtr doc; 2838 const char *encoding; 2839 int format; 2840 int len; 2841 xmlOutputBufferPtr buf; 2842 xmlCharEncodingHandlerPtr handler = NULL; 2843 2844 if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node, 2845 &py_file, &encoding, &format)) 2846 return (NULL); 2847 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node); 2848 2849 if (node == NULL) { 2850 return (PyInt_FromLong((long) -1)); 2851 } 2852 if ((py_file == NULL) || (!(PyFile_Check(py_file)))) { 2853 return (PyInt_FromLong((long) -1)); 2854 } 2855 output = PyFile_AsFile(py_file); 2856 if (output == NULL) { 2857 return (PyInt_FromLong((long) -1)); 2858 } 2859 2860 if (node->type == XML_DOCUMENT_NODE) { 2861 doc = (xmlDocPtr) node; 2862 } else if (node->type == XML_HTML_DOCUMENT_NODE) { 2863 doc = (xmlDocPtr) node; 2864 } else { 2865 doc = node->doc; 2866 } 2867#ifdef LIBXML_HTML_ENABLED 2868 if (doc->type == XML_HTML_DOCUMENT_NODE) { 2869 if (encoding == NULL) 2870 encoding = (const char *) htmlGetMetaEncoding(doc); 2871 } 2872#endif /* LIBXML_HTML_ENABLED */ 2873 if (encoding != NULL) { 2874 handler = xmlFindCharEncodingHandler(encoding); 2875 if (handler == NULL) { 2876 return (PyInt_FromLong((long) -1)); 2877 } 2878 } 2879 if (doc->type == XML_HTML_DOCUMENT_NODE) { 2880 if (handler == NULL) 2881 handler = xmlFindCharEncodingHandler("HTML"); 2882 if (handler == NULL) 2883 handler = xmlFindCharEncodingHandler("ascii"); 2884 } 2885 2886 buf = xmlOutputBufferCreateFile(output, handler); 2887 if (node->type == XML_DOCUMENT_NODE) { 2888 len = xmlSaveFormatFileTo(buf, doc, encoding, format); 2889#ifdef LIBXML_HTML_ENABLED 2890 } else if (node->type == XML_HTML_DOCUMENT_NODE) { 2891 htmlDocContentDumpFormatOutput(buf, doc, encoding, format); 2892 len = xmlOutputBufferClose(buf); 2893 } else if (doc->type == XML_HTML_DOCUMENT_NODE) { 2894 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format); 2895 len = xmlOutputBufferClose(buf); 2896#endif /* LIBXML_HTML_ENABLED */ 2897 } else { 2898 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding); 2899 len = xmlOutputBufferClose(buf); 2900 } 2901 return (PyInt_FromLong((long) len)); 2902} 2903#endif /* LIBXML_OUTPUT_ENABLED */ 2904 2905/************************************************************************ 2906 * * 2907 * Extra stuff * 2908 * * 2909 ************************************************************************/ 2910PyObject * 2911libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2912{ 2913 PyObject *py_retval; 2914 xmlChar *name; 2915 xmlNodePtr node; 2916 2917 if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name)) 2918 return (NULL); 2919 node = (xmlNodePtr) xmlNewNode(NULL, name); 2920#ifdef DEBUG 2921 printf("NewNode: %s : %p\n", name, (void *) node); 2922#endif 2923 2924 if (node == NULL) { 2925 Py_INCREF(Py_None); 2926 return (Py_None); 2927 } 2928 py_retval = libxml_xmlNodePtrWrap(node); 2929 return (py_retval); 2930} 2931 2932 2933/************************************************************************ 2934 * * 2935 * Local Catalog stuff * 2936 * * 2937 ************************************************************************/ 2938static PyObject * 2939libxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 2940{ 2941 xmlChar *URL; 2942 xmlParserCtxtPtr ctxt; 2943 PyObject *pyobj_ctxt; 2944 2945 if (!PyArg_ParseTuple(args, (char *)"Os:addLocalCatalog", &pyobj_ctxt, &URL)) 2946 return(NULL); 2947 2948 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); 2949 2950 if (URL != NULL) { 2951 ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL); 2952 } 2953 2954#ifdef DEBUG 2955 printf("LocalCatalog: %s\n", URL); 2956#endif 2957 2958 Py_INCREF(Py_None); 2959 return (Py_None); 2960} 2961 2962#ifdef LIBXML_SCHEMAS_ENABLED 2963 2964/************************************************************************ 2965 * * 2966 * RelaxNG error handler registration * 2967 * * 2968 ************************************************************************/ 2969 2970typedef struct 2971{ 2972 PyObject *warn; 2973 PyObject *error; 2974 PyObject *arg; 2975} xmlRelaxNGValidCtxtPyCtxt; 2976typedef xmlRelaxNGValidCtxtPyCtxt *xmlRelaxNGValidCtxtPyCtxtPtr; 2977 2978static void 2979libxml_xmlRelaxNGValidityGenericErrorFuncHandler(void *ctx, char *str) 2980{ 2981 PyObject *list; 2982 PyObject *result; 2983 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt; 2984 2985#ifdef DEBUG_ERROR 2986 printf("libxml_xmlRelaxNGValidityGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str); 2987#endif 2988 2989 pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx; 2990 2991 list = PyTuple_New(2); 2992 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str)); 2993 PyTuple_SetItem(list, 1, pyCtxt->arg); 2994 Py_XINCREF(pyCtxt->arg); 2995 result = PyEval_CallObject(pyCtxt->error, list); 2996 if (result == NULL) 2997 { 2998 /* TODO: manage for the exception to be propagated... */ 2999 PyErr_Print(); 3000 } 3001 Py_XDECREF(list); 3002 Py_XDECREF(result); 3003} 3004 3005static void 3006libxml_xmlRelaxNGValidityGenericWarningFuncHandler(void *ctx, char *str) 3007{ 3008 PyObject *list; 3009 PyObject *result; 3010 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt; 3011 3012#ifdef DEBUG_ERROR 3013 printf("libxml_xmlRelaxNGValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str); 3014#endif 3015 3016 pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx; 3017 3018 list = PyTuple_New(2); 3019 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str)); 3020 PyTuple_SetItem(list, 1, pyCtxt->arg); 3021 Py_XINCREF(pyCtxt->arg); 3022 result = PyEval_CallObject(pyCtxt->warn, list); 3023 if (result == NULL) 3024 { 3025 /* TODO: manage for the exception to be propagated... */ 3026 PyErr_Print(); 3027 } 3028 Py_XDECREF(list); 3029 Py_XDECREF(result); 3030} 3031 3032static void 3033libxml_xmlRelaxNGValidityErrorFunc(void *ctx, const char *msg, ...) 3034{ 3035 va_list ap; 3036 3037 va_start(ap, msg); 3038 libxml_xmlRelaxNGValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap)); 3039 va_end(ap); 3040} 3041 3042static void 3043libxml_xmlRelaxNGValidityWarningFunc(void *ctx, const char *msg, ...) 3044{ 3045 va_list ap; 3046 3047 va_start(ap, msg); 3048 libxml_xmlRelaxNGValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap)); 3049 va_end(ap); 3050} 3051 3052static PyObject * 3053libxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 3054{ 3055 PyObject *py_retval; 3056 PyObject *pyobj_error; 3057 PyObject *pyobj_warn; 3058 PyObject *pyobj_ctx; 3059 PyObject *pyobj_arg = Py_None; 3060 xmlRelaxNGValidCtxtPtr ctxt; 3061 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt; 3062 3063 if (!PyArg_ParseTuple 3064 (args, (char *) "OOO|O:xmlRelaxNGSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg)) 3065 return (NULL); 3066 3067#ifdef DEBUG_ERROR 3068 printf("libxml_xmlRelaxNGSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn); 3069#endif 3070 3071 ctxt = PyrelaxNgValidCtxt_Get(pyobj_ctx); 3072 if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1) 3073 { 3074 py_retval = libxml_intWrap(-1); 3075 return(py_retval); 3076 } 3077 3078 if (pyCtxt == NULL) 3079 { 3080 /* first time to set the error handlers */ 3081 pyCtxt = xmlMalloc(sizeof(xmlRelaxNGValidCtxtPyCtxt)); 3082 if (pyCtxt == NULL) { 3083 py_retval = libxml_intWrap(-1); 3084 return(py_retval); 3085 } 3086 memset(pyCtxt, 0, sizeof(xmlRelaxNGValidCtxtPyCtxt)); 3087 } 3088 3089 /* TODO: check warn and error is a function ! */ 3090 Py_XDECREF(pyCtxt->error); 3091 Py_XINCREF(pyobj_error); 3092 pyCtxt->error = pyobj_error; 3093 3094 Py_XDECREF(pyCtxt->warn); 3095 Py_XINCREF(pyobj_warn); 3096 pyCtxt->warn = pyobj_warn; 3097 3098 Py_XDECREF(pyCtxt->arg); 3099 Py_XINCREF(pyobj_arg); 3100 pyCtxt->arg = pyobj_arg; 3101 3102 xmlRelaxNGSetValidErrors(ctxt, &libxml_xmlRelaxNGValidityErrorFunc, &libxml_xmlRelaxNGValidityWarningFunc, pyCtxt); 3103 3104 py_retval = libxml_intWrap(1); 3105 return (py_retval); 3106} 3107 3108static PyObject * 3109libxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) { 3110 xmlRelaxNGValidCtxtPtr ctxt; 3111 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt; 3112 PyObject *pyobj_ctxt; 3113 3114 if (!PyArg_ParseTuple(args, (char *)"O:xmlRelaxNGFreeValidCtxt", &pyobj_ctxt)) 3115 return(NULL); 3116 ctxt = (xmlRelaxNGValidCtxtPtr) PyrelaxNgValidCtxt_Get(pyobj_ctxt); 3117 3118 if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0) 3119 { 3120 if (pyCtxt != NULL) 3121 { 3122 Py_XDECREF(pyCtxt->error); 3123 Py_XDECREF(pyCtxt->warn); 3124 Py_XDECREF(pyCtxt->arg); 3125 xmlFree(pyCtxt); 3126 } 3127 } 3128 3129 xmlRelaxNGFreeValidCtxt(ctxt); 3130 Py_INCREF(Py_None); 3131 return(Py_None); 3132} 3133 3134typedef struct 3135{ 3136 PyObject *warn; 3137 PyObject *error; 3138 PyObject *arg; 3139} xmlSchemaValidCtxtPyCtxt; 3140typedef xmlSchemaValidCtxtPyCtxt *xmlSchemaValidCtxtPyCtxtPtr; 3141 3142static void 3143libxml_xmlSchemaValidityGenericErrorFuncHandler(void *ctx, char *str) 3144{ 3145 PyObject *list; 3146 PyObject *result; 3147 xmlSchemaValidCtxtPyCtxtPtr pyCtxt; 3148 3149#ifdef DEBUG_ERROR 3150 printf("libxml_xmlSchemaValiditiyGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str); 3151#endif 3152 3153 pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx; 3154 3155 list = PyTuple_New(2); 3156 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str)); 3157 PyTuple_SetItem(list, 1, pyCtxt->arg); 3158 Py_XINCREF(pyCtxt->arg); 3159 result = PyEval_CallObject(pyCtxt->error, list); 3160 if (result == NULL) 3161 { 3162 /* TODO: manage for the exception to be propagated... */ 3163 PyErr_Print(); 3164 } 3165 Py_XDECREF(list); 3166 Py_XDECREF(result); 3167} 3168 3169static void 3170libxml_xmlSchemaValidityGenericWarningFuncHandler(void *ctx, char *str) 3171{ 3172 PyObject *list; 3173 PyObject *result; 3174 xmlSchemaValidCtxtPyCtxtPtr pyCtxt; 3175 3176#ifdef DEBUG_ERROR 3177 printf("libxml_xmlSchemaValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str); 3178#endif 3179 3180 pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx; 3181 3182 list = PyTuple_New(2); 3183 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str)); 3184 PyTuple_SetItem(list, 1, pyCtxt->arg); 3185 Py_XINCREF(pyCtxt->arg); 3186 result = PyEval_CallObject(pyCtxt->warn, list); 3187 if (result == NULL) 3188 { 3189 /* TODO: manage for the exception to be propagated... */ 3190 PyErr_Print(); 3191 } 3192 Py_XDECREF(list); 3193 Py_XDECREF(result); 3194} 3195 3196static void 3197libxml_xmlSchemaValidityErrorFunc(void *ctx, const char *msg, ...) 3198{ 3199 va_list ap; 3200 3201 va_start(ap, msg); 3202 libxml_xmlSchemaValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap)); 3203 va_end(ap); 3204} 3205 3206static void 3207libxml_xmlSchemaValidityWarningFunc(void *ctx, const char *msg, ...) 3208{ 3209 va_list ap; 3210 3211 va_start(ap, msg); 3212 libxml_xmlSchemaValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap)); 3213 va_end(ap); 3214} 3215 3216PyObject * 3217libxml_xmlSchemaSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 3218{ 3219 PyObject *py_retval; 3220 PyObject *pyobj_error; 3221 PyObject *pyobj_warn; 3222 PyObject *pyobj_ctx; 3223 PyObject *pyobj_arg = Py_None; 3224 xmlSchemaValidCtxtPtr ctxt; 3225 xmlSchemaValidCtxtPyCtxtPtr pyCtxt; 3226 3227 if (!PyArg_ParseTuple 3228 (args, (char *) "OOO|O:xmlSchemaSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg)) 3229 return (NULL); 3230 3231#ifdef DEBUG_ERROR 3232 printf("libxml_xmlSchemaSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn); 3233#endif 3234 3235 ctxt = PySchemaValidCtxt_Get(pyobj_ctx); 3236 if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1) 3237 { 3238 py_retval = libxml_intWrap(-1); 3239 return(py_retval); 3240 } 3241 3242 if (pyCtxt == NULL) 3243 { 3244 /* first time to set the error handlers */ 3245 pyCtxt = xmlMalloc(sizeof(xmlSchemaValidCtxtPyCtxt)); 3246 if (pyCtxt == NULL) { 3247 py_retval = libxml_intWrap(-1); 3248 return(py_retval); 3249 } 3250 memset(pyCtxt, 0, sizeof(xmlSchemaValidCtxtPyCtxt)); 3251 } 3252 3253 /* TODO: check warn and error is a function ! */ 3254 Py_XDECREF(pyCtxt->error); 3255 Py_XINCREF(pyobj_error); 3256 pyCtxt->error = pyobj_error; 3257 3258 Py_XDECREF(pyCtxt->warn); 3259 Py_XINCREF(pyobj_warn); 3260 pyCtxt->warn = pyobj_warn; 3261 3262 Py_XDECREF(pyCtxt->arg); 3263 Py_XINCREF(pyobj_arg); 3264 pyCtxt->arg = pyobj_arg; 3265 3266 xmlSchemaSetValidErrors(ctxt, &libxml_xmlSchemaValidityErrorFunc, &libxml_xmlSchemaValidityWarningFunc, pyCtxt); 3267 3268 py_retval = libxml_intWrap(1); 3269 return(py_retval); 3270} 3271 3272static PyObject * 3273libxml_xmlSchemaFreeValidCtxt(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) 3274{ 3275 xmlSchemaValidCtxtPtr ctxt; 3276 xmlSchemaValidCtxtPyCtxtPtr pyCtxt; 3277 PyObject *pyobj_ctxt; 3278 3279 if (!PyArg_ParseTuple(args, (char *)"O:xmlSchemaFreeValidCtxt", &pyobj_ctxt)) 3280 return(NULL); 3281 ctxt = (xmlSchemaValidCtxtPtr) PySchemaValidCtxt_Get(pyobj_ctxt); 3282 3283 if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0) 3284 { 3285 if (pyCtxt != NULL) 3286 { 3287 Py_XDECREF(pyCtxt->error); 3288 Py_XDECREF(pyCtxt->warn); 3289 Py_XDECREF(pyCtxt->arg); 3290 xmlFree(pyCtxt); 3291 } 3292 } 3293 3294 xmlSchemaFreeValidCtxt(ctxt); 3295 Py_INCREF(Py_None); 3296 return(Py_None); 3297} 3298 3299#endif 3300 3301#ifdef LIBXML_C14N_ENABLED 3302#ifdef LIBXML_OUTPUT_ENABLED 3303 3304/************************************************************************ 3305 * * 3306 * XML Canonicalization c14n * 3307 * * 3308 ************************************************************************/ 3309 3310static int 3311PyxmlNodeSet_Convert(PyObject *py_nodeset, xmlNodeSetPtr *result) 3312{ 3313 xmlNodeSetPtr nodeSet; 3314 int is_tuple = 0; 3315 3316 if (PyTuple_Check(py_nodeset)) 3317 is_tuple = 1; 3318 else if (PyList_Check(py_nodeset)) 3319 is_tuple = 0; 3320 else if (py_nodeset == Py_None) { 3321 *result = NULL; 3322 return 0; 3323 } 3324 else { 3325 PyErr_SetString(PyExc_TypeError, 3326 "must be a tuple or list of nodes."); 3327 return -1; 3328 } 3329 3330 nodeSet = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet)); 3331 if (nodeSet == NULL) { 3332 PyErr_SetString(PyExc_MemoryError, ""); 3333 return -1; 3334 } 3335 3336 nodeSet->nodeNr = 0; 3337 nodeSet->nodeMax = (is_tuple 3338 ? PyTuple_GET_SIZE(py_nodeset) 3339 : PyList_GET_SIZE(py_nodeset)); 3340 nodeSet->nodeTab 3341 = (xmlNodePtr *) xmlMalloc (nodeSet->nodeMax 3342 * sizeof(xmlNodePtr)); 3343 if (nodeSet->nodeTab == NULL) { 3344 xmlFree(nodeSet); 3345 PyErr_SetString(PyExc_MemoryError, ""); 3346 return -1; 3347 } 3348 memset(nodeSet->nodeTab, 0 , 3349 nodeSet->nodeMax * sizeof(xmlNodePtr)); 3350 3351 { 3352 int idx; 3353 for (idx=0; idx < nodeSet->nodeMax; ++idx) { 3354 xmlNodePtr pynode = 3355 PyxmlNode_Get (is_tuple 3356 ? PyTuple_GET_ITEM(py_nodeset, idx) 3357 : PyList_GET_ITEM(py_nodeset, idx)); 3358 if (pynode) 3359 nodeSet->nodeTab[nodeSet->nodeNr++] = pynode; 3360 } 3361 } 3362 *result = nodeSet; 3363 return 0; 3364} 3365 3366static int 3367PystringSet_Convert(PyObject *py_strings, xmlChar *** result) 3368{ 3369 /* NOTE: the array should be freed, but the strings are shared 3370 with the python strings and so must not be freed. */ 3371 3372 xmlChar ** strings; 3373 int is_tuple = 0; 3374 int count; 3375 int init_index = 0; 3376 3377 if (PyTuple_Check(py_strings)) 3378 is_tuple = 1; 3379 else if (PyList_Check(py_strings)) 3380 is_tuple = 0; 3381 else if (py_strings == Py_None) { 3382 *result = NULL; 3383 return 0; 3384 } 3385 else { 3386 PyErr_SetString(PyExc_TypeError, 3387 "must be a tuple or list of strings."); 3388 return -1; 3389 } 3390 3391 count = (is_tuple 3392 ? PyTuple_GET_SIZE(py_strings) 3393 : PyList_GET_SIZE(py_strings)); 3394 3395 strings = (xmlChar **) xmlMalloc(sizeof(xmlChar *) * count); 3396 3397 if (strings == NULL) { 3398 PyErr_SetString(PyExc_MemoryError, ""); 3399 return -1; 3400 } 3401 3402 memset(strings, 0 , sizeof(xmlChar *) * count); 3403 3404 { 3405 int idx; 3406 for (idx=0; idx < count; ++idx) { 3407 char* s = PyString_AsString 3408 (is_tuple 3409 ? PyTuple_GET_ITEM(py_strings, idx) 3410 : PyList_GET_ITEM(py_strings, idx)); 3411 if (s) 3412 strings[init_index++] = (xmlChar *)s; 3413 else { 3414 xmlFree(strings); 3415 PyErr_SetString(PyExc_TypeError, 3416 "must be a tuple or list of strings."); 3417 return -1; 3418 } 3419 } 3420 } 3421 3422 *result = strings; 3423 return 0; 3424} 3425 3426static PyObject * 3427libxml_C14NDocDumpMemory(ATTRIBUTE_UNUSED PyObject * self, 3428 PyObject * args) 3429{ 3430 PyObject *py_retval = NULL; 3431 3432 PyObject *pyobj_doc; 3433 PyObject *pyobj_nodes; 3434 int exclusive; 3435 PyObject *pyobj_prefixes; 3436 int with_comments; 3437 3438 xmlDocPtr doc; 3439 xmlNodeSetPtr nodes; 3440 xmlChar **prefixes = NULL; 3441 xmlChar *doc_txt; 3442 3443 int result; 3444 3445 if (!PyArg_ParseTuple(args, (char *) "OOiOi:C14NDocDumpMemory", 3446 &pyobj_doc, 3447 &pyobj_nodes, 3448 &exclusive, 3449 &pyobj_prefixes, 3450 &with_comments)) 3451 return (NULL); 3452 3453 doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc); 3454 if (!doc) { 3455 PyErr_SetString(PyExc_TypeError, "bad document."); 3456 return NULL; 3457 } 3458 3459 result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes); 3460 if (result < 0) return NULL; 3461 3462 if (exclusive) { 3463 result = PystringSet_Convert(pyobj_prefixes, &prefixes); 3464 if (result < 0) { 3465 if (nodes) { 3466 xmlFree(nodes->nodeTab); 3467 xmlFree(nodes); 3468 } 3469 return NULL; 3470 } 3471 } 3472 3473 result = xmlC14NDocDumpMemory(doc, 3474 nodes, 3475 exclusive, 3476 prefixes, 3477 with_comments, 3478 &doc_txt); 3479 3480 if (nodes) { 3481 xmlFree(nodes->nodeTab); 3482 xmlFree(nodes); 3483 } 3484 if (prefixes) { 3485 xmlChar ** idx = prefixes; 3486 while (*idx) xmlFree(*(idx++)); 3487 xmlFree(prefixes); 3488 } 3489 3490 if (result < 0) { 3491 PyErr_SetString(PyExc_Exception, 3492 "libxml2 xmlC14NDocDumpMemory failure."); 3493 return NULL; 3494 } 3495 else { 3496 py_retval = PyString_FromStringAndSize((const char *) doc_txt, 3497 result); 3498 xmlFree(doc_txt); 3499 return py_retval; 3500 } 3501} 3502 3503static PyObject * 3504libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self, 3505 PyObject * args) 3506{ 3507 PyObject *pyobj_doc; 3508 PyObject *py_file; 3509 PyObject *pyobj_nodes; 3510 int exclusive; 3511 PyObject *pyobj_prefixes; 3512 int with_comments; 3513 3514 xmlDocPtr doc; 3515 xmlNodeSetPtr nodes; 3516 xmlChar **prefixes = NULL; 3517 FILE * output; 3518 xmlOutputBufferPtr buf; 3519 3520 int result; 3521 int len; 3522 3523 if (!PyArg_ParseTuple(args, (char *) "OOiOiO:C14NDocSaveTo", 3524 &pyobj_doc, 3525 &pyobj_nodes, 3526 &exclusive, 3527 &pyobj_prefixes, 3528 &with_comments, 3529 &py_file)) 3530 return (NULL); 3531 3532 doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc); 3533 if (!doc) { 3534 PyErr_SetString(PyExc_TypeError, "bad document."); 3535 return NULL; 3536 } 3537 3538 if ((py_file == NULL) || (!(PyFile_Check(py_file)))) { 3539 PyErr_SetString(PyExc_TypeError, "bad file."); 3540 return NULL; 3541 } 3542 output = PyFile_AsFile(py_file); 3543 if (output == NULL) { 3544 PyErr_SetString(PyExc_TypeError, "bad file."); 3545 return NULL; 3546 } 3547 buf = xmlOutputBufferCreateFile(output, NULL); 3548 3549 result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes); 3550 if (result < 0) return NULL; 3551 3552 if (exclusive) { 3553 result = PystringSet_Convert(pyobj_prefixes, &prefixes); 3554 if (result < 0) { 3555 if (nodes) { 3556 xmlFree(nodes->nodeTab); 3557 xmlFree(nodes); 3558 } 3559 return NULL; 3560 } 3561 } 3562 3563 result = xmlC14NDocSaveTo(doc, 3564 nodes, 3565 exclusive, 3566 prefixes, 3567 with_comments, 3568 buf); 3569 3570 if (nodes) { 3571 xmlFree(nodes->nodeTab); 3572 xmlFree(nodes); 3573 } 3574 if (prefixes) { 3575 xmlChar ** idx = prefixes; 3576 while (*idx) xmlFree(*(idx++)); 3577 xmlFree(prefixes); 3578 } 3579 3580 len = xmlOutputBufferClose(buf); 3581 3582 if (result < 0) { 3583 PyErr_SetString(PyExc_Exception, 3584 "libxml2 xmlC14NDocSaveTo failure."); 3585 return NULL; 3586 } 3587 else 3588 return PyInt_FromLong((long) len); 3589} 3590 3591#endif 3592#endif 3593 3594static PyObject * 3595libxml_getObjDesc(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { 3596 3597 PyObject *obj; 3598 char *str; 3599 3600 if (!PyArg_ParseTuple(args, (char *)"O:getObjDesc", &obj)) 3601 return NULL; 3602 str = PyCObject_GetDesc(obj); 3603 return Py_BuildValue((char *)"s", str); 3604} 3605 3606static PyObject * 3607libxml_compareNodesEqual(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { 3608 3609 PyObject *py_node1, *py_node2; 3610 xmlNodePtr node1, node2; 3611 3612 if (!PyArg_ParseTuple(args, (char *)"OO:compareNodesEqual", 3613 &py_node1, &py_node2)) 3614 return NULL; 3615 /* To compare two node objects, we compare their pointer addresses */ 3616 node1 = PyxmlNode_Get(py_node1); 3617 node2 = PyxmlNode_Get(py_node2); 3618 if ( node1 == node2 ) 3619 return Py_BuildValue((char *)"i", 1); 3620 else 3621 return Py_BuildValue((char *)"i", 0); 3622 3623} 3624 3625static PyObject * 3626libxml_nodeHash(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { 3627 3628 PyObject *py_node1; 3629 xmlNodePtr node1; 3630 3631 if (!PyArg_ParseTuple(args, (char *)"O:nodeHash", &py_node1)) 3632 return NULL; 3633 /* For simplicity, we use the node pointer address as a hash value */ 3634 node1 = PyxmlNode_Get(py_node1); 3635 3636 return PyLong_FromVoidPtr(node1); 3637 3638} 3639 3640/************************************************************************ 3641 * * 3642 * The registration stuff * 3643 * * 3644 ************************************************************************/ 3645static PyMethodDef libxmlMethods[] = { 3646#include "libxml2-export.c" 3647 {(char *) "name", libxml_name, METH_VARARGS, NULL}, 3648 {(char *) "children", libxml_children, METH_VARARGS, NULL}, 3649 {(char *) "properties", libxml_properties, METH_VARARGS, NULL}, 3650 {(char *) "last", libxml_last, METH_VARARGS, NULL}, 3651 {(char *) "prev", libxml_prev, METH_VARARGS, NULL}, 3652 {(char *) "next", libxml_next, METH_VARARGS, NULL}, 3653 {(char *) "parent", libxml_parent, METH_VARARGS, NULL}, 3654 {(char *) "type", libxml_type, METH_VARARGS, NULL}, 3655 {(char *) "doc", libxml_doc, METH_VARARGS, NULL}, 3656 {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL}, 3657 {(char *) "xmlNodeRemoveNsDef", libxml_xmlNodeRemoveNsDef, METH_VARARGS, NULL}, 3658 {(char *)"xmlSetValidErrors", libxml_xmlSetValidErrors, METH_VARARGS, NULL}, 3659 {(char *)"xmlFreeValidCtxt", libxml_xmlFreeValidCtxt, METH_VARARGS, NULL}, 3660#ifdef LIBXML_OUTPUT_ENABLED 3661 {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL}, 3662 {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL}, 3663 {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL}, 3664 {(char *) "outputBufferGetPythonFile", libxml_outputBufferGetPythonFile, METH_VARARGS, NULL}, 3665 {(char *) "xmlOutputBufferClose", libxml_xmlOutputBufferClose, METH_VARARGS, NULL}, 3666 { (char *)"xmlOutputBufferFlush", libxml_xmlOutputBufferFlush, METH_VARARGS, NULL }, 3667 { (char *)"xmlSaveFileTo", libxml_xmlSaveFileTo, METH_VARARGS, NULL }, 3668 { (char *)"xmlSaveFormatFileTo", libxml_xmlSaveFormatFileTo, METH_VARARGS, NULL }, 3669#endif /* LIBXML_OUTPUT_ENABLED */ 3670 {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL}, 3671 {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL}, 3672 {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL }, 3673 {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL }, 3674 {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL }, 3675 {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL }, 3676#ifdef LIBXML_READER_ENABLED 3677 {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL }, 3678 {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL }, 3679 {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL }, 3680#endif 3681 {(char *)"addLocalCatalog", libxml_addLocalCatalog, METH_VARARGS, NULL }, 3682#ifdef LIBXML_SCHEMAS_ENABLED 3683 {(char *)"xmlRelaxNGSetValidErrors", libxml_xmlRelaxNGSetValidErrors, METH_VARARGS, NULL}, 3684 {(char *)"xmlRelaxNGFreeValidCtxt", libxml_xmlRelaxNGFreeValidCtxt, METH_VARARGS, NULL}, 3685 {(char *)"xmlSchemaSetValidErrors", libxml_xmlSchemaSetValidErrors, METH_VARARGS, NULL}, 3686 {(char *)"xmlSchemaFreeValidCtxt", libxml_xmlSchemaFreeValidCtxt, METH_VARARGS, NULL}, 3687#endif 3688#ifdef LIBXML_C14N_ENABLED 3689#ifdef LIBXML_OUTPUT_ENABLED 3690 {(char *)"xmlC14NDocDumpMemory", libxml_C14NDocDumpMemory, METH_VARARGS, NULL}, 3691 {(char *)"xmlC14NDocSaveTo", libxml_C14NDocSaveTo, METH_VARARGS, NULL}, 3692#endif 3693#endif 3694 {(char *) "getObjDesc", libxml_getObjDesc, METH_VARARGS, NULL}, 3695 {(char *) "compareNodesEqual", libxml_compareNodesEqual, METH_VARARGS, NULL}, 3696 {(char *) "nodeHash", libxml_nodeHash, METH_VARARGS, NULL}, 3697 {NULL, NULL, 0, NULL} 3698}; 3699 3700#ifdef MERGED_MODULES 3701extern void initlibxsltmod(void); 3702#endif 3703 3704void 3705initlibxml2mod(void) 3706{ 3707 static int initialized = 0; 3708 3709 if (initialized != 0) 3710 return; 3711 3712 /* intialize the python extension module */ 3713 Py_InitModule((char *) "libxml2mod", libxmlMethods); 3714 3715 /* initialize libxml2 */ 3716 xmlInitParser(); 3717 libxml_xmlErrorInitialize(); 3718 3719 initialized = 1; 3720 3721#ifdef MERGED_MODULES 3722 initlibxsltmod(); 3723#endif 3724} 3725