OLD | NEW |
(Empty) | |
| 1 /* |
| 2 libxslt.c: this module implements the main part of the glue of the |
| 3 * libxslt 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 "config.h" */ |
| 16 #include <libxml/xmlmemory.h> |
| 17 #include <libxml/tree.h> |
| 18 #include <libxml/xpath.h> |
| 19 #include "libexslt/exslt.h" |
| 20 #include "libxslt_wrap.h" |
| 21 #include "libxslt-py.h" |
| 22 |
| 23 #include <stdio.h> |
| 24 |
| 25 #if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(vsnprintf) |
| 26 #define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a) |
| 27 #elif defined(XSLT_NEED_TRIO) |
| 28 #include "trio.h" |
| 29 #define vsnprintf trio_vsnprintf |
| 30 #endif |
| 31 |
| 32 /* #define DEBUG */ |
| 33 /* #define DEBUG_XPATH */ |
| 34 /* #define DEBUG_ERROR */ |
| 35 /* #define DEBUG_MEMORY */ |
| 36 /* #define DEBUG_EXTENSIONS */ |
| 37 /* #define DEBUG_EXTENSIONS */ |
| 38 |
| 39 void initlibxsltmod(void); |
| 40 |
| 41 /************************************************************************ |
| 42 * * |
| 43 * Per type specific glue * |
| 44 * * |
| 45 ************************************************************************/ |
| 46 |
| 47 PyObject * |
| 48 libxslt_xsltStylesheetPtrWrap(xsltStylesheetPtr style) { |
| 49 PyObject *ret; |
| 50 |
| 51 #ifdef DEBUG |
| 52 printf("libxslt_xsltStylesheetPtrWrap: style = %p\n", style); |
| 53 #endif |
| 54 if (style == NULL) { |
| 55 Py_INCREF(Py_None); |
| 56 return(Py_None); |
| 57 } |
| 58 ret = PyCObject_FromVoidPtrAndDesc((void *) style, |
| 59 (char *)"xsltStylesheetPtr", NULL); |
| 60 |
| 61 return(ret); |
| 62 } |
| 63 |
| 64 PyObject * |
| 65 libxslt_xsltTransformContextPtrWrap(xsltTransformContextPtr ctxt) { |
| 66 PyObject *ret; |
| 67 |
| 68 #ifdef DEBUG |
| 69 printf("libxslt_xsltTransformContextPtrWrap: ctxt = %p\n", ctxt); |
| 70 #endif |
| 71 if (ctxt == NULL) { |
| 72 Py_INCREF(Py_None); |
| 73 return(Py_None); |
| 74 } |
| 75 ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt, |
| 76 (char *)"xsltTransformContextPtr", NULL); |
| 77 return(ret); |
| 78 } |
| 79 |
| 80 PyObject * |
| 81 libxslt_xsltElemPreCompPtrWrap(xsltElemPreCompPtr ctxt) { |
| 82 PyObject *ret; |
| 83 |
| 84 #ifdef DEBUG |
| 85 printf("libxslt_xsltElemPreCompPtrWrap: ctxt = %p\n", ctxt); |
| 86 #endif |
| 87 if (ctxt == NULL) { |
| 88 Py_INCREF(Py_None); |
| 89 return(Py_None); |
| 90 } |
| 91 ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt, |
| 92 (char *)"xsltElemPreCompPtr", NULL); |
| 93 return(ret); |
| 94 } |
| 95 |
| 96 PyObject * |
| 97 libxslt_xsltGetTransformContextHashCode(PyObject *self ATTRIBUTE_UNUSED, PyObjec
t *args) { |
| 98 PyObject *py_tctxt; |
| 99 PyObject *ret; |
| 100 long hash_code; |
| 101 xsltTransformContextPtr tctxt; |
| 102 |
| 103 if (!PyArg_ParseTuple(args, (char *)"O:getTransformContextHashCode", |
| 104 &py_tctxt)) |
| 105 return NULL; |
| 106 |
| 107 tctxt = (xsltTransformContextPtr) PytransformCtxt_Get(py_tctxt); |
| 108 hash_code = (long) tctxt; |
| 109 |
| 110 ret = PyInt_FromLong(hash_code); |
| 111 return ret; |
| 112 } |
| 113 |
| 114 PyObject * |
| 115 libxslt_xsltCompareTransformContextsEqual(PyObject *self ATTRIBUTE_UNUSED, PyObj
ect *args) { |
| 116 |
| 117 PyObject *py_tctxt1, *py_tctxt2; |
| 118 xsltTransformContextPtr tctxt1, tctxt2; |
| 119 |
| 120 if (!PyArg_ParseTuple(args, (char *)"OO:compareTransformContextsEqual", |
| 121 &py_tctxt1, &py_tctxt2)) |
| 122 return NULL; |
| 123 |
| 124 tctxt1 = (xsltTransformContextPtr) PytransformCtxt_Get(py_tctxt1); |
| 125 tctxt2 = (xsltTransformContextPtr) PytransformCtxt_Get(py_tctxt2); |
| 126 |
| 127 if ( tctxt1 == tctxt2 ) |
| 128 return Py_BuildValue((char *)"i", 1); |
| 129 else |
| 130 return Py_BuildValue((char *)"i", 0); |
| 131 } |
| 132 |
| 133 PyObject * |
| 134 libxslt_xsltGetStylesheetHashCode(PyObject *self ATTRIBUTE_UNUSED, PyObject *arg
s) { |
| 135 PyObject *py_style; |
| 136 PyObject *ret; |
| 137 long hash_code; |
| 138 xsltStylesheetPtr style; |
| 139 |
| 140 if (!PyArg_ParseTuple(args, (char *)"O:getStylesheetHashCode", |
| 141 &py_style)) |
| 142 return NULL; |
| 143 |
| 144 style = (xsltStylesheetPtr) Pystylesheet_Get(py_style); |
| 145 hash_code = (long) style; |
| 146 |
| 147 ret = PyInt_FromLong(hash_code); |
| 148 return ret; |
| 149 } |
| 150 |
| 151 |
| 152 PyObject * |
| 153 libxslt_xsltCompareStylesheetsEqual(PyObject *self ATTRIBUTE_UNUSED, PyObject *a
rgs) { |
| 154 |
| 155 PyObject *py_style1, *py_style2; |
| 156 xsltStylesheetPtr style1, style2; |
| 157 |
| 158 if (!PyArg_ParseTuple(args, (char *)"OO:compareStylesheetsEqual", |
| 159 &py_style1, &py_style2)) |
| 160 return NULL; |
| 161 |
| 162 style1 = (xsltStylesheetPtr) Pystylesheet_Get(py_style1); |
| 163 style2 = (xsltStylesheetPtr) Pystylesheet_Get(py_style2); |
| 164 |
| 165 if ( style1 == style2 ) |
| 166 return Py_BuildValue((char *)"i", 1); |
| 167 else |
| 168 return Py_BuildValue((char *)"i", 0); |
| 169 } |
| 170 |
| 171 /************************************************************************ |
| 172 * * |
| 173 * Extending the API * |
| 174 * * |
| 175 ************************************************************************/ |
| 176 |
| 177 static xmlHashTablePtr libxslt_extModuleFunctions = NULL; |
| 178 static xmlHashTablePtr libxslt_extModuleElements = NULL; |
| 179 static xmlHashTablePtr libxslt_extModuleElementPreComp = NULL; |
| 180 |
| 181 static void |
| 182 deallocateCallback(void *payload, xmlChar *name ATTRIBUTE_UNUSED) { |
| 183 PyObject *function = (PyObject *) payload; |
| 184 |
| 185 #ifdef DEBUG_EXTENSIONS |
| 186 printf("deallocateCallback(%s) called\n", name); |
| 187 #endif |
| 188 |
| 189 Py_XDECREF(function); |
| 190 } |
| 191 |
| 192 static void |
| 193 deallocateClasse(void *payload, xmlChar *name ATTRIBUTE_UNUSED) { |
| 194 PyObject *class = (PyObject *) payload; |
| 195 |
| 196 #ifdef DEBUG_EXTENSIONS |
| 197 printf("deallocateClasse(%s) called\n", name); |
| 198 #endif |
| 199 |
| 200 Py_XDECREF(class); |
| 201 } |
| 202 |
| 203 |
| 204 /** |
| 205 * libxslt_xsltElementPreCompCallback |
| 206 * @style: the stylesheet |
| 207 * @inst: the instruction in the stylesheet |
| 208 * |
| 209 * Callback for preprocessing of a custom element |
| 210 */ |
| 211 static xsltElemPreCompPtr |
| 212 libxslt_xsltElementPreCompCallback(xsltStylesheetPtr style, xmlNodePtr inst, |
| 213 xsltTransformFunction function) { |
| 214 xsltElemPreCompPtr ret; |
| 215 const xmlChar *name; |
| 216 PyObject *args; |
| 217 PyObject *result; |
| 218 PyObject *pyobj_element_f; |
| 219 PyObject *pyobj_precomp_f; |
| 220 |
| 221 const xmlChar *ns_uri; |
| 222 |
| 223 |
| 224 #ifdef DEBUG_EXTENSIONS |
| 225 printf("libxslt_xsltElementPreCompCallback called\n"); |
| 226 #endif |
| 227 |
| 228 if (style == NULL) { |
| 229 xsltTransformError(NULL, NULL, inst, |
| 230 "libxslt_xsltElementPreCompCallback: no transformation context\n"); |
| 231 return (NULL); |
| 232 } |
| 233 |
| 234 if (inst == NULL) { |
| 235 xsltTransformError(NULL, style, inst, |
| 236 "libxslt_xsltElementPreCompCallback: no instruction\n"); |
| 237 if (style != NULL) style->errors++; |
| 238 return (NULL); |
| 239 } |
| 240 |
| 241 if (style == NULL) |
| 242 return (NULL); |
| 243 |
| 244 if (inst != NULL && inst->ns != NULL) { |
| 245 name = inst->name; |
| 246 ns_uri = inst->ns->href; |
| 247 } else { |
| 248 xsltTransformError(NULL, style, inst, |
| 249 "libxslt_xsltElementPreCompCallback: internal error bad paramete
r\n"); |
| 250 printf("libxslt_xsltElementPreCompCallback: internal error bad p
arameter\n"); |
| 251 if (style != NULL) style->errors++; |
| 252 return (NULL); |
| 253 } |
| 254 |
| 255 /* |
| 256 * Find the functions, they should be there it was there at lookup |
| 257 */ |
| 258 pyobj_precomp_f = xmlHashLookup2(libxslt_extModuleElementPreComp, |
| 259 name, ns_uri); |
| 260 if (pyobj_precomp_f == NULL) { |
| 261 xsltTransformError(NULL, style, inst, |
| 262 "libxslt_xsltElementPreCompCallback: internal error, could not f
ind precompile python function!\n"); |
| 263 if (style != NULL) style->errors++; |
| 264 return (NULL); |
| 265 } |
| 266 |
| 267 pyobj_element_f = xmlHashLookup2(libxslt_extModuleElements, |
| 268 name, ns_uri); |
| 269 if (pyobj_element_f == NULL) { |
| 270 xsltTransformError(NULL, style, inst, |
| 271 "libxslt_xsltElementPreCompCallback: internal error, could not f
ind element python function!\n"); |
| 272 if (style != NULL) style->errors++; |
| 273 return (NULL); |
| 274 } |
| 275 |
| 276 args = Py_BuildValue((char *)"(OOO)", |
| 277 libxslt_xsltStylesheetPtrWrap(style), |
| 278 libxml_xmlNodePtrWrap(inst), |
| 279 pyobj_element_f); |
| 280 |
| 281 Py_INCREF(pyobj_precomp_f); /* Protect refcount against reentrant manipulati
on of callback hash */ |
| 282 result = PyEval_CallObject(pyobj_precomp_f, args); |
| 283 Py_DECREF(pyobj_precomp_f); |
| 284 Py_DECREF(args); |
| 285 |
| 286 /* FIXME allow callbacks to return meaningful information to modify compile
process */ |
| 287 /* If error, do we need to check the result and throw exception? */ |
| 288 |
| 289 Py_XDECREF(result); |
| 290 |
| 291 ret = xsltNewElemPreComp (style, inst, function); |
| 292 return (ret); |
| 293 } |
| 294 |
| 295 |
| 296 static void |
| 297 libxslt_xsltElementTransformCallback(xsltTransformContextPtr ctxt, |
| 298 xmlNodePtr node, |
| 299 xmlNodePtr inst, |
| 300 xsltElemPreCompPtr comp) |
| 301 { |
| 302 PyObject *args, *result; |
| 303 PyObject *func = NULL; |
| 304 const xmlChar *name; |
| 305 const xmlChar *ns_uri; |
| 306 |
| 307 if (ctxt == NULL) |
| 308 return; |
| 309 |
| 310 if (inst != NULL && inst->name != NULL && inst->ns != NULL && inst->ns->href
!= NULL) { |
| 311 name = inst->name; |
| 312 ns_uri = inst->ns->href; |
| 313 } else { |
| 314 printf("libxslt_xsltElementTransformCallback: internal error bad paramet
er\n"); |
| 315 return; |
| 316 } |
| 317 |
| 318 #ifdef DEBUG_EXTENSIONS |
| 319 printf("libxslt_xsltElementTransformCallback called name %s URI %s\n", name,
ns_uri); |
| 320 #endif |
| 321 |
| 322 /* |
| 323 * Find the function, it should be there it was there at lookup |
| 324 */ |
| 325 func = xmlHashLookup2(libxslt_extModuleElements, |
| 326 name, ns_uri); |
| 327 if (func == NULL) { |
| 328 printf("libxslt_xsltElementTransformCallback: internal error %s not foun
d !\n", |
| 329 name); |
| 330 return; |
| 331 } |
| 332 |
| 333 args = Py_BuildValue((char *)"OOOO", |
| 334 libxslt_xsltTransformContextPtrWrap(ctxt), |
| 335 libxml_xmlNodePtrWrap(node), |
| 336 libxml_xmlNodePtrWrap(inst), |
| 337 libxslt_xsltElemPreCompPtrWrap(comp)); |
| 338 |
| 339 Py_INCREF(func); /* Protect refcount against reentrant manipulation of callb
ack hash */ |
| 340 result = PyEval_CallObject(func, args); |
| 341 Py_DECREF(func); |
| 342 Py_DECREF(args); |
| 343 |
| 344 /* FIXME Check result of callobject and set exception if fail */ |
| 345 |
| 346 Py_XDECREF(result); |
| 347 } |
| 348 |
| 349 PyObject * |
| 350 libxslt_xsltRegisterExtModuleElement(PyObject *self ATTRIBUTE_UNUSED, |
| 351 PyObject *args) { |
| 352 PyObject *py_retval; |
| 353 int ret = 0; |
| 354 xmlChar *name; |
| 355 xmlChar *ns_uri; |
| 356 PyObject *pyobj_element_f; |
| 357 PyObject *pyobj_precomp_f; |
| 358 |
| 359 if (!PyArg_ParseTuple(args, (char *)"szOO:registerExtModuleElement", |
| 360 &name, &ns_uri, &pyobj_precomp_f, &pyobj_element_f)) |
| 361 return(NULL); |
| 362 |
| 363 #ifdef DEBUG_EXTENSIONS |
| 364 printf("libxslt_xsltRegisterExtModuleElement called: %s %s\n", |
| 365 name, ns_uri); |
| 366 #endif |
| 367 |
| 368 if ((name == NULL) || (pyobj_element_f == NULL) || (pyobj_precomp_f == NULL)
) { |
| 369 py_retval = libxml_intWrap(-1); |
| 370 return(py_retval); |
| 371 } |
| 372 |
| 373 #ifdef DEBUG_EXTENSIONS |
| 374 printf("libxslt_xsltRegisterExtModuleElement(%s, %s) called\n", |
| 375 name, ns_uri); |
| 376 #endif |
| 377 |
| 378 if (libxslt_extModuleElements == NULL) |
| 379 libxslt_extModuleElements = xmlHashCreate(10); |
| 380 |
| 381 if (libxslt_extModuleElementPreComp == NULL) |
| 382 libxslt_extModuleElementPreComp = xmlHashCreate(10); |
| 383 |
| 384 if (libxslt_extModuleElements == NULL || libxslt_extModuleElementPreComp ==
NULL) { |
| 385 py_retval = libxml_intWrap(-1); |
| 386 return(py_retval); |
| 387 } |
| 388 |
| 389 ret = xmlHashAddEntry2(libxslt_extModuleElements, name, ns_uri, pyobj_elemen
t_f); |
| 390 if (ret != 0) { |
| 391 py_retval = libxml_intWrap(-1); |
| 392 return(py_retval); |
| 393 } |
| 394 Py_XINCREF(pyobj_element_f); |
| 395 |
| 396 ret = xmlHashAddEntry2(libxslt_extModuleElementPreComp, name, ns_uri, pyobj_
precomp_f); |
| 397 if (ret != 0) { |
| 398 xmlHashRemoveEntry2(libxslt_extModuleElements, name, ns_uri, deallocateC
allback); |
| 399 py_retval = libxml_intWrap(-1); |
| 400 return(py_retval); |
| 401 } |
| 402 Py_XINCREF(pyobj_precomp_f); |
| 403 |
| 404 ret = xsltRegisterExtModuleElement(name, ns_uri, |
| 405 libxslt_xsltElementPreCompCallback, |
| 406 libxslt_xsltElementTransformCallback); |
| 407 py_retval = libxml_intWrap((int) ret); |
| 408 return(py_retval); |
| 409 } |
| 410 static void |
| 411 libxslt_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs) { |
| 412 PyObject *list, *cur, *result; |
| 413 xmlXPathObjectPtr obj; |
| 414 xmlXPathContextPtr rctxt; |
| 415 PyObject *current_function = NULL; |
| 416 const xmlChar *name; |
| 417 const xmlChar *ns_uri; |
| 418 int i; |
| 419 |
| 420 if (ctxt == NULL) |
| 421 return; |
| 422 rctxt = ctxt->context; |
| 423 if (rctxt == NULL) |
| 424 return; |
| 425 name = rctxt->function; |
| 426 ns_uri = rctxt->functionURI; |
| 427 #ifdef DEBUG_XPATH |
| 428 printf("libxslt_xmlXPathFuncCallback called name %s URI %s\n", name, ns_uri)
; |
| 429 #endif |
| 430 |
| 431 /* |
| 432 * Find the function, it should be there it was there at lookup |
| 433 */ |
| 434 current_function = xmlHashLookup2(libxslt_extModuleFunctions, |
| 435 name, ns_uri); |
| 436 if (current_function == NULL) { |
| 437 printf("libxslt_xmlXPathFuncCallback: internal error %s not found !\n", |
| 438 name); |
| 439 return; |
| 440 } |
| 441 |
| 442 list = PyTuple_New(nargs + 1); |
| 443 PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt)); |
| 444 for (i = nargs - 1;i >= 0;i--) { |
| 445 obj = valuePop(ctxt); |
| 446 cur = libxml_xmlXPathObjectPtrWrap(obj); |
| 447 PyTuple_SetItem(list, i + 1, cur); |
| 448 } |
| 449 |
| 450 Py_INCREF(current_function); |
| 451 result = PyEval_CallObject(current_function, list); |
| 452 Py_DECREF(current_function); |
| 453 Py_DECREF(list); |
| 454 |
| 455 /* Check for null in case of exception */ |
| 456 if (result != NULL) { |
| 457 obj = libxml_xmlXPathObjectPtrConvert(result); |
| 458 valuePush(ctxt, obj); |
| 459 } |
| 460 } |
| 461 |
| 462 PyObject * |
| 463 libxslt_xsltRegisterExtModuleFunction(PyObject *self ATTRIBUTE_UNUSED, |
| 464 PyObject *args) { |
| 465 PyObject *py_retval; |
| 466 int ret = 0; |
| 467 xmlChar *name; |
| 468 xmlChar *ns_uri; |
| 469 PyObject *pyobj_f; |
| 470 |
| 471 if (!PyArg_ParseTuple(args, (char *)"szO:registerExtModuleFunction", |
| 472 &name, &ns_uri, &pyobj_f)) |
| 473 return(NULL); |
| 474 |
| 475 if ((name == NULL) || (pyobj_f == NULL)) { |
| 476 py_retval = libxml_intWrap(-1); |
| 477 return(py_retval); |
| 478 } |
| 479 |
| 480 #ifdef DEBUG_XPATH |
| 481 printf("libxslt_xsltRegisterExtModuleFunction(%s, %s) called\n", |
| 482 name, ns_uri); |
| 483 #endif |
| 484 |
| 485 if (libxslt_extModuleFunctions == NULL) |
| 486 libxslt_extModuleFunctions = xmlHashCreate(10); |
| 487 if (libxslt_extModuleFunctions == NULL) { |
| 488 py_retval = libxml_intWrap(-1); |
| 489 return(py_retval); |
| 490 } |
| 491 ret = xmlHashAddEntry2(libxslt_extModuleFunctions, name, ns_uri, pyobj_f); |
| 492 if (ret != 0) { |
| 493 py_retval = libxml_intWrap(-1); |
| 494 return(py_retval); |
| 495 } |
| 496 Py_XINCREF(pyobj_f); |
| 497 |
| 498 ret = xsltRegisterExtModuleFunction(name, ns_uri, |
| 499 libxslt_xmlXPathFuncCallback); |
| 500 py_retval = libxml_intWrap((int) ret); |
| 501 return(py_retval); |
| 502 } |
| 503 |
| 504 |
| 505 /************************************************************************ |
| 506 * * |
| 507 * Document loading front-ends * |
| 508 * * |
| 509 ************************************************************************/ |
| 510 |
| 511 static PyObject *pythonDocLoaderObject = NULL; |
| 512 |
| 513 static xmlDocPtr |
| 514 pythonDocLoaderFuncWrapper(const xmlChar * URI, xmlDictPtr dict, int options, |
| 515 void *ctxt ATTRIBUTE_UNUSED, |
| 516 xsltLoadType type ATTRIBUTE_UNUSED) |
| 517 { |
| 518 xmlParserCtxtPtr pctxt; |
| 519 xmlDocPtr doc=NULL; |
| 520 |
| 521 pctxt = xmlNewParserCtxt(); |
| 522 if (pctxt == NULL) |
| 523 return(NULL); |
| 524 if ((dict != NULL) && (pctxt->dict != NULL)) { |
| 525 xmlDictFree(pctxt->dict); |
| 526 pctxt->dict = NULL; |
| 527 } |
| 528 if (dict != NULL) { |
| 529 pctxt->dict = dict; |
| 530 xmlDictReference(pctxt->dict); |
| 531 #ifdef WITH_XSLT_DEBUG |
| 532 xsltGenericDebug(xsltGenericDebugContext, |
| 533 "Reusing dictionary for document\n"); |
| 534 #endif |
| 535 } |
| 536 xmlCtxtUseOptions(pctxt, options); |
| 537 |
| 538 /* |
| 539 * Now pass to python the URI, the xsltParserContext and the context |
| 540 * (either a transformContext or a stylesheet) and get back an xmlDocPtr |
| 541 */ |
| 542 if (pythonDocLoaderObject != NULL) { |
| 543 PyObject *ctxtobj, *pctxtobj, *result; |
| 544 pctxtobj = libxml_xmlParserCtxtPtrWrap(pctxt); |
| 545 |
| 546 if (type == XSLT_LOAD_DOCUMENT) { |
| 547 ctxtobj = libxslt_xsltTransformContextPtrWrap(ctxt); |
| 548 result = PyObject_CallFunction(pythonDocLoaderObject, |
| 549 (char *) "(sOOi)", URI, pctxtobj, ctxto
bj, 0); |
| 550 } |
| 551 else { |
| 552 ctxtobj = libxslt_xsltStylesheetPtrWrap(ctxt); |
| 553 result = PyObject_CallFunction(pythonDocLoaderObject, |
| 554 (char *) "(sOOi)", URI, pctxtobj, ctxto
bj, 1); |
| 555 } |
| 556 |
| 557 Py_XDECREF(pctxtobj); |
| 558 |
| 559 if (result != NULL) { |
| 560 /* |
| 561 * The return value should be the document |
| 562 * Should we test it somehow before getting the C object from it? |
| 563 */ |
| 564 PyObject *py_doc = PyObject_GetAttrString(result, (char *) "_o"); |
| 565 doc = (xmlDocPtr) PyxmlNode_Get(py_doc); |
| 566 /* do we have to DECCREF the result?? */ |
| 567 } |
| 568 } |
| 569 |
| 570 if (! pctxt->wellFormed) { |
| 571 if (doc != NULL) { |
| 572 xmlFreeDoc(doc); |
| 573 doc = NULL; |
| 574 } |
| 575 if (pctxt->myDoc != NULL) { |
| 576 xmlFreeDoc(pctxt->myDoc); |
| 577 pctxt->myDoc = NULL; |
| 578 } |
| 579 } |
| 580 /* |
| 581 * xmlFreeParserCtxt(pctxt); |
| 582 * libc complains about double free-ing with this line |
| 583 */ |
| 584 |
| 585 return(doc); |
| 586 } |
| 587 |
| 588 |
| 589 PyObject * |
| 590 libxslt_xsltSetLoaderFunc(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { |
| 591 PyObject *py_retval; |
| 592 PyObject *loader; |
| 593 |
| 594 if (!PyArg_ParseTuple(args, (char *)"O:libxslt_xsltSetLoaderFunc", |
| 595 &loader)) |
| 596 return(NULL); |
| 597 |
| 598 pythonDocLoaderObject = loader; |
| 599 xsltSetLoaderFunc(pythonDocLoaderFuncWrapper); |
| 600 |
| 601 py_retval = PyInt_FromLong(0); |
| 602 return(py_retval); |
| 603 } |
| 604 |
| 605 PyObject * |
| 606 libxslt_xsltGetLoaderFunc(void) { |
| 607 PyObject *py_retval; |
| 608 |
| 609 py_retval = pythonDocLoaderObject; |
| 610 return(py_retval); |
| 611 } |
| 612 |
| 613 |
| 614 /************************************************************************ |
| 615 * * |
| 616 * Some customized front-ends * |
| 617 * * |
| 618 ************************************************************************/ |
| 619 |
| 620 PyObject * |
| 621 libxslt_xsltNewTransformContext(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
{ |
| 622 PyObject *py_retval; |
| 623 PyObject *pyobj_style; |
| 624 PyObject *pyobj_doc; |
| 625 xsltStylesheetPtr style; |
| 626 xmlDocPtr doc; |
| 627 xsltTransformContextPtr c_retval; |
| 628 |
| 629 if (!PyArg_ParseTuple(args, (char *) "OO:xsltNewTransformContext", |
| 630 &pyobj_style, &pyobj_doc)) |
| 631 return(NULL); |
| 632 |
| 633 style = (xsltStylesheetPtr) Pystylesheet_Get(pyobj_style); |
| 634 doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc); |
| 635 |
| 636 c_retval = xsltNewTransformContext(style, doc); |
| 637 py_retval = libxslt_xsltTransformContextPtrWrap((xsltTransformContextPtr) c_
retval); |
| 638 return (py_retval); |
| 639 } |
| 640 |
| 641 PyObject * |
| 642 libxslt_xsltFreeTransformContext(PyObject *self ATTRIBUTE_UNUSED, PyObject *args
) { |
| 643 PyObject *py_tctxt; |
| 644 xsltTransformContextPtr tctxt; |
| 645 |
| 646 if (!PyArg_ParseTuple(args, (char *) "O:xsltFreeTransformContext", &py_tctxt
)) |
| 647 return(NULL); |
| 648 |
| 649 tctxt = (xsltTransformContextPtr) PytransformCtxt_Get(py_tctxt); |
| 650 xsltFreeTransformContext(tctxt); |
| 651 |
| 652 /* Return None */ |
| 653 Py_INCREF(Py_None); |
| 654 return(Py_None); |
| 655 } |
| 656 |
| 657 PyObject * |
| 658 libxslt_xsltApplyStylesheetUser(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
{ |
| 659 PyObject *py_retval; |
| 660 xmlDocPtr c_retval; |
| 661 xsltStylesheetPtr style; |
| 662 PyObject *pyobj_style; |
| 663 xmlDocPtr doc; |
| 664 xsltTransformContextPtr transformCtxt; |
| 665 PyObject *pyobj_doc; |
| 666 PyObject *pyobj_params; |
| 667 PyObject *pyobj_transformCtxt; |
| 668 const char **params = NULL; |
| 669 int len = 0, i, j; |
| 670 ssize_t ppos = 0; |
| 671 PyObject *name; |
| 672 PyObject *value; |
| 673 |
| 674 if (!PyArg_ParseTuple(args, (char *) "OOOO:xsltApplyStylesheetUser", |
| 675 &pyobj_style, &pyobj_doc, &pyobj_params, &pyobj_transf
ormCtxt)) |
| 676 return(NULL); |
| 677 |
| 678 if (pyobj_params != Py_None) { |
| 679 if (PyDict_Check(pyobj_params)) { |
| 680 len = PyDict_Size(pyobj_params); |
| 681 if (len > 0) { |
| 682 params = (const char **) xmlMalloc((len + 1) * 2 * |
| 683 sizeof(char *)); |
| 684 if (params == NULL) { |
| 685 printf("libxslt_xsltApplyStylesheet: out of memory\n"); |
| 686 Py_INCREF(Py_None); |
| 687 return(Py_None); |
| 688 } |
| 689 j = 0; |
| 690 while (PyDict_Next(pyobj_params, &ppos, &name, &value)) { |
| 691 const char *tmp; |
| 692 int size; |
| 693 |
| 694 tmp = PyString_AS_STRING(name); |
| 695 size = PyString_GET_SIZE(name); |
| 696 params[j * 2] = (char *) xmlCharStrndup(tmp, size); |
| 697 if (PyString_Check(value)) { |
| 698 tmp = PyString_AS_STRING(value); |
| 699 size = PyString_GET_SIZE(value); |
| 700 params[(j * 2) + 1] = (char *) |
| 701 xmlCharStrndup(tmp, size); |
| 702 } else { |
| 703 params[(j * 2) + 1] = NULL; |
| 704 } |
| 705 j = j + 1; |
| 706 } |
| 707 params[j * 2] = NULL; |
| 708 params[(j * 2) + 1] = NULL; |
| 709 } |
| 710 } else { |
| 711 printf("libxslt_xsltApplyStylesheet: parameters not a dict\n"); |
| 712 Py_INCREF(Py_None); |
| 713 return(Py_None); |
| 714 } |
| 715 } |
| 716 style = (xsltStylesheetPtr) Pystylesheet_Get(pyobj_style); |
| 717 doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc); |
| 718 transformCtxt = (xsltTransformContextPtr) PytransformCtxt_Get(pyobj_transfor
mCtxt); |
| 719 |
| 720 c_retval = xsltApplyStylesheetUser(style, doc, params, NULL, NULL, transform
Ctxt); |
| 721 py_retval = libxml_xmlDocPtrWrap((xmlDocPtr) c_retval); |
| 722 if (params != NULL) { |
| 723 if (len > 0) { |
| 724 for (i = 0;i < 2 * len;i++) { |
| 725 if (params[i] != NULL) |
| 726 xmlFree((char *)params[i]); |
| 727 } |
| 728 xmlFree(params); |
| 729 } |
| 730 } |
| 731 return(py_retval); |
| 732 } |
| 733 |
| 734 PyObject * |
| 735 libxslt_xsltApplyStylesheet(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { |
| 736 PyObject *py_retval; |
| 737 xmlDocPtr c_retval; |
| 738 xsltStylesheetPtr style; |
| 739 PyObject *pyobj_style; |
| 740 xmlDocPtr doc; |
| 741 PyObject *pyobj_doc; |
| 742 PyObject *pyobj_params; |
| 743 const char **params = NULL; |
| 744 int len = 0, i, j, params_size; |
| 745 ssize_t ppos = 0; |
| 746 PyObject *name; |
| 747 PyObject *value; |
| 748 |
| 749 if (!PyArg_ParseTuple(args, (char *) "OOO:xsltApplyStylesheet", |
| 750 &pyobj_style, &pyobj_doc, &pyobj_params)) |
| 751 return(NULL); |
| 752 |
| 753 if (pyobj_params != Py_None) { |
| 754 if (PyDict_Check(pyobj_params)) { |
| 755 len = PyDict_Size(pyobj_params); |
| 756 if (len > 0) { |
| 757 params_size = (len + 1) * 2 * sizeof(char *); |
| 758 params = (const char **) xmlMalloc(params_size); |
| 759 if (params == NULL) { |
| 760 printf("libxslt_xsltApplyStylesheet: out of memory\n"); |
| 761 Py_INCREF(Py_None); |
| 762 return(Py_None); |
| 763 } |
| 764 memset(params, 0, params_size); |
| 765 j = 0; |
| 766 while (PyDict_Next(pyobj_params, &ppos, &name, &value)) { |
| 767 const char *tmp; |
| 768 int size; |
| 769 |
| 770 tmp = PyString_AS_STRING(name); |
| 771 size = PyString_GET_SIZE(name); |
| 772 params[j * 2] = (char *) xmlCharStrndup(tmp, size); |
| 773 if (PyString_Check(value)) { |
| 774 tmp = PyString_AS_STRING(value); |
| 775 size = PyString_GET_SIZE(value); |
| 776 params[(j * 2) + 1] = (char *) |
| 777 xmlCharStrndup(tmp, size); |
| 778 } else { |
| 779 params[(j * 2) + 1] = NULL; |
| 780 } |
| 781 j = j + 1; |
| 782 } |
| 783 params[j * 2] = NULL; |
| 784 params[(j * 2) + 1] = NULL; |
| 785 } |
| 786 } else { |
| 787 printf("libxslt_xsltApplyStylesheet: parameters not a dict\n"); |
| 788 Py_INCREF(Py_None); |
| 789 return(Py_None); |
| 790 } |
| 791 } |
| 792 style = (xsltStylesheetPtr) Pystylesheet_Get(pyobj_style); |
| 793 doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc); |
| 794 |
| 795 c_retval = xsltApplyStylesheet(style, doc, params); |
| 796 py_retval = libxml_xmlDocPtrWrap((xmlDocPtr) c_retval); |
| 797 if (params != NULL) { |
| 798 if (len > 0) { |
| 799 for (i = 0;i < 2 * len;i++) { |
| 800 if (params[i] != NULL) |
| 801 xmlFree((char *)params[i]); |
| 802 } |
| 803 xmlFree(params); |
| 804 } |
| 805 } |
| 806 return(py_retval); |
| 807 } |
| 808 |
| 809 PyObject * |
| 810 libxslt_xsltSaveResultToString(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
{ |
| 811 PyObject *py_retval; /* our final return value, a python string */ |
| 812 xmlChar *buffer; |
| 813 int size = 0; |
| 814 int emitted = 0; |
| 815 xmlDocPtr result; |
| 816 PyObject *pyobj_result; |
| 817 xsltStylesheetPtr style; |
| 818 PyObject *pyobj_style; |
| 819 |
| 820 if (!PyArg_ParseTuple(args, (char *)"OO:xsltSaveResultToString", &pyobj_styl
e, &pyobj_result)) |
| 821 goto FAIL; |
| 822 result = (xmlDocPtr) PyxmlNode_Get(pyobj_result); |
| 823 style = (xsltStylesheetPtr) Pystylesheet_Get(pyobj_style); |
| 824 |
| 825 |
| 826 /* FIXME: We should probably add more restrictive error checking |
| 827 * and raise an error instead of "just" returning NULL. |
| 828 * FIXME: Documentation and code for xsltSaveResultToString diff |
| 829 * -> emmitted will never be positive non-null. |
| 830 */ |
| 831 emitted = xsltSaveResultToString(&buffer, &size, result, style); |
| 832 if(!buffer || emitted < 0) |
| 833 goto FAIL; |
| 834 /* We haven't tested the aberrant case of a transformation that |
| 835 * renders to an empty string. For now we try to play it safe. |
| 836 */ |
| 837 if(size) |
| 838 { |
| 839 buffer[size] = '\0'; |
| 840 py_retval = PyString_FromString((char *) buffer); |
| 841 xmlFree(buffer); |
| 842 } |
| 843 else |
| 844 py_retval = PyString_FromString(""); |
| 845 return(py_retval); |
| 846 FAIL: |
| 847 return(0); |
| 848 } |
| 849 |
| 850 |
| 851 /************************************************************************ |
| 852 * * |
| 853 * Error message callback * |
| 854 * * |
| 855 ************************************************************************/ |
| 856 |
| 857 static PyObject *libxslt_xsltPythonErrorFuncHandler = NULL; |
| 858 static PyObject *libxslt_xsltPythonErrorFuncCtxt = NULL; |
| 859 |
| 860 static void |
| 861 libxslt_xsltErrorFuncHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, |
| 862 ...) |
| 863 { |
| 864 int size; |
| 865 int chars; |
| 866 char *larger; |
| 867 va_list ap; |
| 868 char *str; |
| 869 PyObject *list; |
| 870 PyObject *message; |
| 871 PyObject *result; |
| 872 |
| 873 #ifdef DEBUG_ERROR |
| 874 printf("libxslt_xsltErrorFuncHandler(%p, %s, ...) called\n", ctx, msg); |
| 875 #endif |
| 876 |
| 877 |
| 878 if (libxslt_xsltPythonErrorFuncHandler == NULL) { |
| 879 va_start(ap, msg); |
| 880 vfprintf(stderr, msg, ap); |
| 881 va_end(ap); |
| 882 } else { |
| 883 str = (char *) xmlMalloc(150); |
| 884 if (str == NULL) |
| 885 return; |
| 886 |
| 887 size = 150; |
| 888 |
| 889 while (1) { |
| 890 va_start(ap, msg); |
| 891 chars = vsnprintf(str, size, msg, ap); |
| 892 va_end(ap); |
| 893 if ((chars > -1) && (chars < size)) |
| 894 break; |
| 895 if (chars > -1) |
| 896 size += chars + 1; |
| 897 else |
| 898 size += 100; |
| 899 if ((larger = (char *) xmlRealloc(str, size)) == NULL) { |
| 900 xmlFree(str); |
| 901 return; |
| 902 } |
| 903 str = larger; |
| 904 } |
| 905 |
| 906 list = PyTuple_New(2); |
| 907 PyTuple_SetItem(list, 0, libxslt_xsltPythonErrorFuncCtxt); |
| 908 Py_XINCREF(libxslt_xsltPythonErrorFuncCtxt); |
| 909 message = libxml_charPtrWrap(str); |
| 910 PyTuple_SetItem(list, 1, message); |
| 911 result = PyEval_CallObject(libxslt_xsltPythonErrorFuncHandler, list); |
| 912 Py_XDECREF(list); |
| 913 Py_XDECREF(result); |
| 914 } |
| 915 } |
| 916 |
| 917 static void |
| 918 libxslt_xsltErrorInitialize(void) |
| 919 { |
| 920 #ifdef DEBUG_ERROR |
| 921 printf("libxslt_xsltErrorInitialize() called\n"); |
| 922 #endif |
| 923 xmlSetGenericErrorFunc(NULL, libxslt_xsltErrorFuncHandler); |
| 924 xsltSetGenericErrorFunc(NULL, libxslt_xsltErrorFuncHandler); |
| 925 } |
| 926 |
| 927 PyObject * |
| 928 libxslt_xsltRegisterErrorHandler(PyObject * self ATTRIBUTE_UNUSED, |
| 929 PyObject * args) |
| 930 { |
| 931 PyObject *py_retval; |
| 932 PyObject *pyobj_f; |
| 933 PyObject *pyobj_ctx; |
| 934 |
| 935 if (!PyArg_ParseTuple |
| 936 (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f, |
| 937 &pyobj_ctx)) |
| 938 return (NULL); |
| 939 |
| 940 #ifdef DEBUG_ERROR |
| 941 printf("libxml_registerXPathFunction(%p, %p) called\n", pyobj_ctx, |
| 942 pyobj_f); |
| 943 #endif |
| 944 |
| 945 if (libxslt_xsltPythonErrorFuncHandler != NULL) { |
| 946 Py_XDECREF(libxslt_xsltPythonErrorFuncHandler); |
| 947 } |
| 948 if (libxslt_xsltPythonErrorFuncCtxt != NULL) { |
| 949 Py_XDECREF(libxslt_xsltPythonErrorFuncCtxt); |
| 950 } |
| 951 |
| 952 Py_XINCREF(pyobj_ctx); |
| 953 Py_XINCREF(pyobj_f); |
| 954 |
| 955 /* TODO: check f is a function ! */ |
| 956 libxslt_xsltPythonErrorFuncHandler = pyobj_f; |
| 957 libxslt_xsltPythonErrorFuncCtxt = pyobj_ctx; |
| 958 |
| 959 py_retval = libxml_intWrap(1); |
| 960 return (py_retval); |
| 961 } |
| 962 |
| 963 /************************************************************************ |
| 964 * * |
| 965 * Extension classes * |
| 966 * * |
| 967 ************************************************************************/ |
| 968 |
| 969 static xmlHashTablePtr libxslt_extModuleClasses = NULL; |
| 970 |
| 971 static void * |
| 972 libxslt_xsltPythonExtModuleStyleInit(xsltStylesheetPtr style, |
| 973 const xmlChar * URI) { |
| 974 PyObject *result = NULL; |
| 975 PyObject *class = NULL; |
| 976 |
| 977 #ifdef DEBUG_EXTENSIONS |
| 978 printf("libxslt_xsltPythonExtModuleStyleInit(%p, %s) called\n", |
| 979 style, URI); |
| 980 #endif |
| 981 |
| 982 if ((style == NULL) || (URI == NULL)) |
| 983 return(NULL); |
| 984 |
| 985 /* |
| 986 * Find the function, it should be there it was there at lookup |
| 987 */ |
| 988 class = xmlHashLookup(libxslt_extModuleClasses, URI); |
| 989 if (class == NULL) { |
| 990 fprintf(stderr, "libxslt_xsltPythonExtModuleStyleInit: internal error %s
not found !\n", URI); |
| 991 return(NULL); |
| 992 } |
| 993 |
| 994 if (PyObject_HasAttrString(class, (char *) "_styleInit")) { |
| 995 result = PyObject_CallMethod(class, (char *) "_styleInit", |
| 996 (char *) "Os", libxslt_xsltStylesheetPtrWrap(style), URI); |
| 997 } |
| 998 return((void *)result); |
| 999 } |
| 1000 static void |
| 1001 libxslt_xsltPythonExtModuleStyleShutdown(xsltStylesheetPtr style, |
| 1002 const xmlChar * URI, void *data) { |
| 1003 PyObject *class = NULL; |
| 1004 PyObject *result; |
| 1005 |
| 1006 #ifdef DEBUG_EXTENSIONS |
| 1007 printf("libxslt_xsltPythonExtModuleStyleShutdown(%p, %s, %p) called\n", |
| 1008 style, URI, data); |
| 1009 #endif |
| 1010 |
| 1011 if ((style == NULL) || (URI == NULL)) |
| 1012 return; |
| 1013 |
| 1014 /* |
| 1015 * Find the function, it should be there it was there at lookup |
| 1016 */ |
| 1017 class = xmlHashLookup(libxslt_extModuleClasses, URI); |
| 1018 if (class == NULL) { |
| 1019 fprintf(stderr, "libxslt_xsltPythonExtModuleStyleShutdown: internal erro
r %s not found !\n", URI); |
| 1020 return; |
| 1021 } |
| 1022 |
| 1023 if (PyObject_HasAttrString(class, (char *) "_styleShutdown")) { |
| 1024 result = PyObject_CallMethod(class, (char *) "_styleShutdown", |
| 1025 (char *) "OsO", libxslt_xsltStylesheetPtrWrap(style), |
| 1026 URI, (PyObject *) data); |
| 1027 Py_XDECREF(result); |
| 1028 Py_XDECREF((PyObject *)data); |
| 1029 } |
| 1030 } |
| 1031 |
| 1032 static void * |
| 1033 libxslt_xsltPythonExtModuleCtxtInit(xsltTransformContextPtr ctxt, |
| 1034 const xmlChar * URI) { |
| 1035 PyObject *result = NULL; |
| 1036 PyObject *class = NULL; |
| 1037 |
| 1038 #ifdef DEBUG_EXTENSIONS |
| 1039 printf("libxslt_xsltPythonExtModuleCtxtInit(%p, %s) called\n", |
| 1040 ctxt, URI); |
| 1041 #endif |
| 1042 |
| 1043 if ((ctxt == NULL) || (URI == NULL)) |
| 1044 return(NULL); |
| 1045 |
| 1046 /* |
| 1047 * Find the function, it should be there it was there at lookup |
| 1048 */ |
| 1049 class = xmlHashLookup(libxslt_extModuleClasses, URI); |
| 1050 if (class == NULL) { |
| 1051 fprintf(stderr, "libxslt_xsltPythonExtModuleCtxtInit: internal error %s
not found !\n", URI); |
| 1052 return(NULL); |
| 1053 } |
| 1054 |
| 1055 if (PyObject_HasAttrString(class, (char *) "_ctxtInit")) { |
| 1056 result = PyObject_CallMethod(class, (char *) "_ctxtInit", |
| 1057 (char *) "Os", libxslt_xsltTransformContextPtrWrap(ctxt), |
| 1058 URI); |
| 1059 } |
| 1060 return((void *)result); |
| 1061 } |
| 1062 static void |
| 1063 libxslt_xsltPythonExtModuleCtxtShutdown(xsltTransformContextPtr ctxt, |
| 1064 const xmlChar * URI, void *data) { |
| 1065 PyObject *class = NULL; |
| 1066 PyObject *result; |
| 1067 |
| 1068 #ifdef DEBUG_EXTENSIONS |
| 1069 printf("libxslt_xsltPythonExtModuleCtxtShutdown(%p, %s, %p) called\n", |
| 1070 ctxt, URI, data); |
| 1071 #endif |
| 1072 |
| 1073 if ((ctxt == NULL) || (URI == NULL)) |
| 1074 return; |
| 1075 |
| 1076 /* |
| 1077 * Find the function, it should be there it was there at lookup |
| 1078 */ |
| 1079 class = xmlHashLookup(libxslt_extModuleClasses, URI); |
| 1080 if (class == NULL) { |
| 1081 fprintf(stderr, "libxslt_xsltPythonExtModuleCtxtShutdown: internal error
%s not found !\n", URI); |
| 1082 return; |
| 1083 } |
| 1084 |
| 1085 if (PyObject_HasAttrString(class, (char *) "_ctxtShutdown")) { |
| 1086 result = PyObject_CallMethod(class, (char *) "_ctxtShutdown", |
| 1087 (char *) "OsO", libxslt_xsltTransformContextPtrWrap(ctxt), |
| 1088 URI, (PyObject *) data); |
| 1089 Py_XDECREF(result); |
| 1090 Py_XDECREF((PyObject *)data); |
| 1091 } |
| 1092 } |
| 1093 |
| 1094 PyObject * |
| 1095 libxslt_xsltRegisterExtensionClass(PyObject *self ATTRIBUTE_UNUSED, |
| 1096 PyObject *args) { |
| 1097 PyObject *py_retval; |
| 1098 int ret = 0; |
| 1099 xmlChar *ns_uri; |
| 1100 PyObject *pyobj_c; |
| 1101 |
| 1102 if (!PyArg_ParseTuple(args, (char *)"zO:registerExtensionClass", |
| 1103 &ns_uri, &pyobj_c)) |
| 1104 return(NULL); |
| 1105 |
| 1106 if ((ns_uri == NULL) || (pyobj_c == NULL)) { |
| 1107 py_retval = libxml_intWrap(-1); |
| 1108 return(py_retval); |
| 1109 } |
| 1110 |
| 1111 #ifdef DEBUG_EXTENSIONS |
| 1112 printf("libxslt_xsltRegisterExtensionClass(%s) called\n", ns_uri); |
| 1113 #endif |
| 1114 |
| 1115 if (libxslt_extModuleClasses == NULL) |
| 1116 libxslt_extModuleClasses = xmlHashCreate(10); |
| 1117 if (libxslt_extModuleClasses == NULL) { |
| 1118 py_retval = libxml_intWrap(-1); |
| 1119 return(py_retval); |
| 1120 } |
| 1121 ret = xmlHashAddEntry(libxslt_extModuleClasses, ns_uri, pyobj_c); |
| 1122 if (ret != 0) { |
| 1123 py_retval = libxml_intWrap(-1); |
| 1124 return(py_retval); |
| 1125 } |
| 1126 Py_XINCREF(pyobj_c); |
| 1127 |
| 1128 ret = xsltRegisterExtModuleFull(ns_uri, |
| 1129 (xsltExtInitFunction) libxslt_xsltPythonExtModuleCtxtInit, |
| 1130 (xsltExtShutdownFunction) libxslt_xsltPythonExtModuleCtxtShutdown, |
| 1131 (xsltStyleExtInitFunction) libxslt_xsltPythonExtModuleStyleInit, |
| 1132 (xsltStyleExtShutdownFunction) libxslt_xsltPythonExtModuleStyleShutdown); |
| 1133 py_retval = libxml_intWrap((int) ret); |
| 1134 if (ret < 0) { |
| 1135 Py_XDECREF(pyobj_c); |
| 1136 } |
| 1137 return(py_retval); |
| 1138 } |
| 1139 |
| 1140 /************************************************************************ |
| 1141 * * |
| 1142 * Integrated cleanup * |
| 1143 * * |
| 1144 ************************************************************************/ |
| 1145 |
| 1146 PyObject * |
| 1147 libxslt_xsltPythonCleanup(PyObject *self ATTRIBUTE_UNUSED, |
| 1148 PyObject *args ATTRIBUTE_UNUSED) { |
| 1149 |
| 1150 if (libxslt_extModuleFunctions != NULL) { |
| 1151 xmlHashFree(libxslt_extModuleFunctions, deallocateCallback); |
| 1152 } |
| 1153 if (libxslt_extModuleElements != NULL) { |
| 1154 xmlHashFree(libxslt_extModuleElements, deallocateCallback); |
| 1155 } |
| 1156 if (libxslt_extModuleElementPreComp != NULL) { |
| 1157 xmlHashFree(libxslt_extModuleElementPreComp, deallocateCallback); |
| 1158 } |
| 1159 if (libxslt_extModuleClasses != NULL) { |
| 1160 xmlHashFree(libxslt_extModuleClasses, deallocateClasse); |
| 1161 } |
| 1162 xsltCleanupGlobals(); |
| 1163 Py_INCREF(Py_None); |
| 1164 return(Py_None); |
| 1165 } |
| 1166 |
| 1167 /************************************************************************ |
| 1168 * * |
| 1169 * The registration stuff * |
| 1170 * * |
| 1171 ************************************************************************/ |
| 1172 static PyMethodDef libxsltMethods[] = { |
| 1173 #include "libxslt-export.c" |
| 1174 { NULL, NULL, 0, NULL } |
| 1175 }; |
| 1176 |
| 1177 #ifdef MERGED_MODULES |
| 1178 extern void initlibxml2mod(void); |
| 1179 #endif |
| 1180 |
| 1181 void initlibxsltmod(void) { |
| 1182 static int initialized = 0; |
| 1183 PyObject *m; |
| 1184 |
| 1185 #ifdef MERGED_MODULES |
| 1186 initlibxml2mod(); |
| 1187 #endif |
| 1188 |
| 1189 if (initialized != 0) |
| 1190 return; |
| 1191 m = Py_InitModule((char *)"libxsltmod", libxsltMethods); |
| 1192 initialized = 1; |
| 1193 /* |
| 1194 * Specific XSLT initializations |
| 1195 */ |
| 1196 libxslt_xsltErrorInitialize(); |
| 1197 xmlInitMemory(); |
| 1198 xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; |
| 1199 xmlDefaultSAXHandler.cdataBlock = NULL; |
| 1200 /* |
| 1201 * Register the EXSLT extensions and the test module |
| 1202 */ |
| 1203 exsltRegisterAll(); |
| 1204 } |
| 1205 |
| 1206 |
OLD | NEW |