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