mirror of
https://gitlab.gnome.org/GNOME/libxslt
synced 2025-07-31 02:43:06 +03:00
fixing bug #101602 for extension modules init and shutdown callbacks,
* libxslt/extensions.c libxslt/transform.c: fixing bug #101602 for extension modules init and shutdown callbacks, check that they are now called when needed. * python/libxsl.py python/libxslt-python-api.xml python/libxslt.c: started adding the extension module support at the Python level. Still a strange bug to hunt down left. Daniel
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
Mon Jan 13 23:25:59 CET 2003 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
|
* libxslt/extensions.c libxslt/transform.c: fixing bug #101602
|
||||||
|
for extension modules init and shutdown callbacks, check that
|
||||||
|
they are now called when needed.
|
||||||
|
* python/libxsl.py python/libxslt-python-api.xml python/libxslt.c:
|
||||||
|
started adding the extension module support at the Python level.
|
||||||
|
Still a strange bug to hunt down left.
|
||||||
|
|
||||||
Sun Jan 12 23:56:18 CET 2003 Daniel Veillard <daniel@veillard.com>
|
Sun Jan 12 23:56:18 CET 2003 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
* libxslt/attributes.c libxslt/xsltInternals.h libxslt/imports.c
|
* libxslt/attributes.c libxslt/xsltInternals.h libxslt/imports.c
|
||||||
|
@ -306,6 +306,10 @@ xsltRegisterExtPrefix(xsltStylesheetPtr style,
|
|||||||
if ((style == NULL) || (prefix == NULL) | (URI == NULL))
|
if ((style == NULL) || (prefix == NULL) | (URI == NULL))
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
|
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
|
||||||
|
xsltGenericDebug(xsltGenericDebugContext,
|
||||||
|
"Registering extension prefix %s : %s\n", prefix, URI);
|
||||||
|
#endif
|
||||||
def = (xsltExtDefPtr) style->nsDefs;
|
def = (xsltExtDefPtr) style->nsDefs;
|
||||||
while (def != NULL) {
|
while (def != NULL) {
|
||||||
if (xmlStrEqual(prefix, def->prefix))
|
if (xmlStrEqual(prefix, def->prefix))
|
||||||
@ -317,6 +321,21 @@ xsltRegisterExtPrefix(xsltStylesheetPtr style,
|
|||||||
return(-1);
|
return(-1);
|
||||||
ret->next = (xsltExtDefPtr) style->nsDefs;
|
ret->next = (xsltExtDefPtr) style->nsDefs;
|
||||||
style->nsDefs = ret;
|
style->nsDefs = ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check wether there is an extension module with a stylesheet
|
||||||
|
* initialization function.
|
||||||
|
*/
|
||||||
|
if (xsltExtensionsHash != NULL) {
|
||||||
|
xsltExtModulePtr module;
|
||||||
|
|
||||||
|
module = xmlHashLookup(xsltExtensionsHash, URI);
|
||||||
|
if (module != NULL) {
|
||||||
|
xsltExtDataPtr data;
|
||||||
|
|
||||||
|
data = xsltStyleGetExtData(style, URI);
|
||||||
|
}
|
||||||
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,17 +457,19 @@ xsltStyleGetExtData(xsltStylesheetPtr style, const xmlChar * URI) {
|
|||||||
#endif
|
#endif
|
||||||
return(NULL);
|
return(NULL);
|
||||||
} else {
|
} else {
|
||||||
if (module->styleInitFunc == NULL)
|
if (module->styleInitFunc == NULL) {
|
||||||
return(NULL);
|
|
||||||
|
|
||||||
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
|
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
|
||||||
xsltGenericDebug(xsltGenericDebugContext,
|
xsltGenericDebug(xsltGenericDebugContext,
|
||||||
"Initializing module: %s\n", URI);
|
"Registering style module: %s\n", URI);
|
||||||
#endif
|
#endif
|
||||||
|
extData = NULL;
|
||||||
extData = module->styleInitFunc(style, URI);
|
} else {
|
||||||
if (extData == NULL)
|
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
|
||||||
return(NULL);
|
xsltGenericDebug(xsltGenericDebugContext,
|
||||||
|
"Initializing module: %s\n", URI);
|
||||||
|
#endif
|
||||||
|
extData = module->styleInitFunc(style, URI);
|
||||||
|
}
|
||||||
|
|
||||||
data = xsltNewExtData(module, extData);
|
data = xsltNewExtData(module, extData);
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
@ -576,7 +597,6 @@ xsltInitCtxtExt (xsltExtDataPtr styleData, xsltInitExtCtxt *ctxt,
|
|||||||
xsltGenericDebug(xsltGenericDebugContext,
|
xsltGenericDebug(xsltGenericDebugContext,
|
||||||
"xsltInitCtxtExt: no extData\n");
|
"xsltInitCtxtExt: no extData\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
ctxtData = xsltNewExtData(module, extData);
|
ctxtData = xsltNewExtData(module, extData);
|
||||||
if (ctxtData == NULL) {
|
if (ctxtData == NULL) {
|
||||||
|
@ -401,7 +401,6 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
|
|||||||
cur->extrasMax = 0;
|
cur->extrasMax = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XSLT_REGISTER_VARIABLE_LOOKUP(cur);
|
XSLT_REGISTER_VARIABLE_LOOKUP(cur);
|
||||||
XSLT_REGISTER_FUNCTION_LOOKUP(cur);
|
XSLT_REGISTER_FUNCTION_LOOKUP(cur);
|
||||||
cur->xpathCtxt->nsHash = style->nsHash;
|
cur->xpathCtxt->nsHash = style->nsHash;
|
||||||
@ -420,6 +419,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
|
|||||||
cur->xinclude = xsltDoXIncludeDefault;
|
cur->xinclude = xsltDoXIncludeDefault;
|
||||||
cur->outputFile = NULL;
|
cur->outputFile = NULL;
|
||||||
cur->sec = xsltGetDefaultSecurityPrefs();
|
cur->sec = xsltGetDefaultSecurityPrefs();
|
||||||
|
|
||||||
return(cur);
|
return(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,6 +433,13 @@ void
|
|||||||
xsltFreeTransformContext(xsltTransformContextPtr ctxt) {
|
xsltFreeTransformContext(xsltTransformContextPtr ctxt) {
|
||||||
if (ctxt == NULL)
|
if (ctxt == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shutdown the extension modules associated to the stylesheet
|
||||||
|
* used if needed.
|
||||||
|
*/
|
||||||
|
xsltShutdownCtxtExts(ctxt);
|
||||||
|
|
||||||
if (ctxt->xpathCtxt != NULL) {
|
if (ctxt->xpathCtxt != NULL) {
|
||||||
ctxt->xpathCtxt->nsHash = NULL;
|
ctxt->xpathCtxt->nsHash = NULL;
|
||||||
xmlXPathFreeContext(ctxt->xpathCtxt);
|
xmlXPathFreeContext(ctxt->xpathCtxt);
|
||||||
|
@ -49,6 +49,37 @@ else:
|
|||||||
import libxsltmod
|
import libxsltmod
|
||||||
import libxml2
|
import libxml2
|
||||||
|
|
||||||
|
class extensionModule:
|
||||||
|
def _styleInit(self, style, URI):
|
||||||
|
return self.styleInit(stylesheet(_obj=style), URI)
|
||||||
|
|
||||||
|
def _styleShutdown(self, style, URI, data):
|
||||||
|
return self.styleShutdown(stylesheet(_obj=style), URI, data)
|
||||||
|
|
||||||
|
def _ctxtInit(self, ctxt, URI):
|
||||||
|
return self.ctxtInit(transformCtxt(_obj=ctxt), URI)
|
||||||
|
|
||||||
|
def _ctxtShutdown(self, ctxt, URI, data):
|
||||||
|
return self.ctxtShutdown(transformCtxt(_obj=ctxt), URI, data)
|
||||||
|
|
||||||
|
def styleInit(self, style, URI):
|
||||||
|
"""Callback function when used in a newly compiled stylesheet,
|
||||||
|
the return value is passed in subsequent calls"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def styleShutdown(self, style, URI, data):
|
||||||
|
"""Callback function when a stylesheet using it is destroyed"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def ctxtInit(self, ctxt, URI):
|
||||||
|
"""Callback function when used in a new transformation process,
|
||||||
|
the return value is passed in subsequent calls"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def ctxtShutdown(self, ctxt, URI, data):
|
||||||
|
"""Callback function when a transformation using it finishes"""
|
||||||
|
pass
|
||||||
|
|
||||||
#
|
#
|
||||||
# Everything below this point is automatically generated
|
# Everything below this point is automatically generated
|
||||||
#
|
#
|
||||||
|
@ -31,6 +31,12 @@
|
|||||||
<arg name='URI' type='xmlChar *' info='the namespace or NULL'/>
|
<arg name='URI' type='xmlChar *' info='the namespace or NULL'/>
|
||||||
<arg name='f' type='pythonObject' info='the python function'/>
|
<arg name='f' type='pythonObject' info='the python function'/>
|
||||||
</function>
|
</function>
|
||||||
|
<function name='xsltRegisterExtensionClass' file='python'>
|
||||||
|
<info>Register a Python written extension class to the XSLT engine</info>
|
||||||
|
<return type='int' info="0 in case of success, -1 in case of error"/>
|
||||||
|
<arg name='URI' type='xmlChar *' info='the namespace or NULL'/>
|
||||||
|
<arg name='c' type='pythonObject' info='the python class instance'/>
|
||||||
|
</function>
|
||||||
<function name='xsltCleanup' file='python'>
|
<function name='xsltCleanup' file='python'>
|
||||||
<info>Cleanup all libxslt and libxml2 memory allocated</info>
|
<info>Cleanup all libxslt and libxml2 memory allocated</info>
|
||||||
<return type='void'/>
|
<return type='void'/>
|
||||||
|
197
python/libxslt.c
197
python/libxslt.c
@ -24,9 +24,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* #define DEBUG */
|
/* #define DEBUG */
|
||||||
/* #define DEBUG_XPATH */
|
#define DEBUG_XPATH */
|
||||||
/* #define DEBUG_ERROR */
|
/* #define DEBUG_ERROR */
|
||||||
/* #define DEBUG_MEMORY */
|
/* #define DEBUG_MEMORY */
|
||||||
|
#define DEBUG_EXTENSIONS */
|
||||||
|
|
||||||
void initlibxsltmod(void);
|
void initlibxsltmod(void);
|
||||||
|
|
||||||
@ -131,7 +132,7 @@ libxslt_xsltRegisterExtModuleFunction(PyObject *self ATTRIBUTE_UNUSED,
|
|||||||
xmlChar *ns_uri;
|
xmlChar *ns_uri;
|
||||||
PyObject *pyobj_f;
|
PyObject *pyobj_f;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, (char *)"szO:registerXPathFunction",
|
if (!PyArg_ParseTuple(args, (char *)"szO:registerExtModuleFunction",
|
||||||
&name, &ns_uri, &pyobj_f))
|
&name, &ns_uri, &pyobj_f))
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
@ -409,6 +410,195 @@ libxslt_xsltRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
|
|||||||
return (py_retval);
|
return (py_retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Extension classes *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
static xmlHashTablePtr libxslt_extModuleClasses = NULL;
|
||||||
|
|
||||||
|
static void *
|
||||||
|
libxslt_xsltPythonExtModuleStyleInit(xsltStylesheetPtr style,
|
||||||
|
const xmlChar * URI) {
|
||||||
|
PyObject *result;
|
||||||
|
PyObject *class = NULL;
|
||||||
|
|
||||||
|
#ifdef DEBUG_EXTENSIONS
|
||||||
|
printf("libxslt_xsltPythonExtModuleStyleInit(%p, %s) called\n",
|
||||||
|
style, URI);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((style == NULL) || (URI == NULL))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the function, it should be there it was there at lookup
|
||||||
|
*/
|
||||||
|
class = xmlHashLookup(libxslt_extModuleClasses, URI);
|
||||||
|
if (class == NULL) {
|
||||||
|
fprintf(stderr, "libxslt_xsltPythonExtModuleStyleInit: internal error %s not found !\n", URI);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyObject_HasAttrString(class, (char *) "_styleInit")) {
|
||||||
|
result = PyObject_CallMethod(class, (char *) "_styleInit",
|
||||||
|
(char *) "Os", libxslt_xsltStylesheetPtrWrap(style), URI);
|
||||||
|
}
|
||||||
|
return((void *)result);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
libxslt_xsltPythonExtModuleStyleShutdown(xsltStylesheetPtr style,
|
||||||
|
const xmlChar * URI, void *data) {
|
||||||
|
PyObject *class = NULL;
|
||||||
|
PyObject *result;
|
||||||
|
|
||||||
|
#ifdef DEBUG_EXTENSIONS
|
||||||
|
printf("libxslt_xsltPythonExtModuleStyleShutdown(%p, %s, %p) called\n",
|
||||||
|
style, URI, data);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((style == NULL) || (URI == NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the function, it should be there it was there at lookup
|
||||||
|
*/
|
||||||
|
class = xmlHashLookup(libxslt_extModuleClasses, URI);
|
||||||
|
if (class == NULL) {
|
||||||
|
fprintf(stderr, "libxslt_xsltPythonExtModuleStyleShutdown: internal error %s not found !\n", URI);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyObject_HasAttrString(class, (char *) "_styleShutdown")) {
|
||||||
|
result = PyObject_CallMethod(class, (char *) "_styleShutdown",
|
||||||
|
(char *) "OsO", libxslt_xsltStylesheetPtrWrap(style),
|
||||||
|
URI, (PyObject *) data);
|
||||||
|
Py_XDECREF(result);
|
||||||
|
Py_XDECREF((PyObject *)data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
libxslt_xsltPythonExtModuleCtxtInit(xsltTransformContextPtr ctxt,
|
||||||
|
const xmlChar * URI) {
|
||||||
|
PyObject *result;
|
||||||
|
PyObject *class = NULL;
|
||||||
|
|
||||||
|
#ifdef DEBUG_EXTENSIONS
|
||||||
|
printf("libxslt_xsltPythonExtModuleCtxtInit(%p, %s) called\n",
|
||||||
|
ctxt, URI);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((ctxt == NULL) || (URI == NULL))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the function, it should be there it was there at lookup
|
||||||
|
*/
|
||||||
|
class = xmlHashLookup(libxslt_extModuleClasses, URI);
|
||||||
|
if (class == NULL) {
|
||||||
|
fprintf(stderr, "libxslt_xsltPythonExtModuleCtxtInit: internal error %s not found !\n", URI);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyObject_HasAttrString(class, (char *) "_ctxtInit")) {
|
||||||
|
result = PyObject_CallMethod(class, (char *) "_ctxtInit",
|
||||||
|
(char *) "Os", libxslt_xsltTransformContextPtrWrap(ctxt),
|
||||||
|
URI);
|
||||||
|
}
|
||||||
|
return((void *)result);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
libxslt_xsltPythonExtModuleCtxtShutdown(xsltTransformContextPtr ctxt,
|
||||||
|
const xmlChar * URI, void *data) {
|
||||||
|
PyObject *class = NULL;
|
||||||
|
PyObject *result;
|
||||||
|
|
||||||
|
#ifdef DEBUG_EXTENSIONS
|
||||||
|
printf("libxslt_xsltPythonExtModuleCtxtShutdown(%p, %s, %p) called\n",
|
||||||
|
ctxt, URI, data);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((ctxt == NULL) || (URI == NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the function, it should be there it was there at lookup
|
||||||
|
*/
|
||||||
|
class = xmlHashLookup(libxslt_extModuleClasses, URI);
|
||||||
|
if (class == NULL) {
|
||||||
|
fprintf(stderr, "libxslt_xsltPythonExtModuleCtxtShutdown: internal error %s not found !\n", URI);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyObject_HasAttrString(class, (char *) "_ctxtShutdown")) {
|
||||||
|
result = PyObject_CallMethod(class, (char *) "_ctxtShutdown",
|
||||||
|
(char *) "OsO", libxslt_xsltTransformContextPtrWrap(ctxt),
|
||||||
|
URI, (PyObject *) data);
|
||||||
|
Py_XDECREF(result);
|
||||||
|
Py_XDECREF((PyObject *)data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
libxslt_xsltRegisterExtensionClass(PyObject *self ATTRIBUTE_UNUSED,
|
||||||
|
PyObject *args) {
|
||||||
|
PyObject *py_retval;
|
||||||
|
int ret = 0;
|
||||||
|
xmlChar *name;
|
||||||
|
xmlChar *ns_uri;
|
||||||
|
PyObject *pyobj_c;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, (char *)"zO:registerExtensionClass",
|
||||||
|
&ns_uri, &pyobj_c))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
if ((ns_uri == NULL) || (pyobj_c == NULL)) {
|
||||||
|
py_retval = libxml_intWrap(-1);
|
||||||
|
return(py_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_EXTENSIONS
|
||||||
|
printf("libxslt_xsltRegisterExtensionClass(%s) called\n", ns_uri);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (libxslt_extModuleClasses == NULL)
|
||||||
|
libxslt_extModuleClasses = xmlHashCreate(10);
|
||||||
|
if (libxslt_extModuleClasses == NULL) {
|
||||||
|
py_retval = libxml_intWrap(-1);
|
||||||
|
return(py_retval);
|
||||||
|
}
|
||||||
|
ret = xmlHashAddEntry(libxslt_extModuleClasses, ns_uri, pyobj_c);
|
||||||
|
if (ret != 0) {
|
||||||
|
py_retval = libxml_intWrap(-1);
|
||||||
|
return(py_retval);
|
||||||
|
}
|
||||||
|
Py_XINCREF(pyobj_c);
|
||||||
|
|
||||||
|
ret = xsltRegisterExtModuleFull(ns_uri,
|
||||||
|
(xsltExtInitFunction) libxslt_xsltPythonExtModuleCtxtInit,
|
||||||
|
(xsltExtShutdownFunction) libxslt_xsltPythonExtModuleCtxtShutdown,
|
||||||
|
(xsltStyleExtInitFunction) libxslt_xsltPythonExtModuleStyleInit,
|
||||||
|
(xsltStyleExtShutdownFunction) libxslt_xsltPythonExtModuleStyleShutdown);
|
||||||
|
py_retval = libxml_intWrap((int) ret);
|
||||||
|
if (ret < 0) {
|
||||||
|
Py_XDECREF(pyobj_c);
|
||||||
|
}
|
||||||
|
return(py_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
deallocateClasse(void *payload, xmlChar *name ATTRIBUTE_UNUSED) {
|
||||||
|
PyObject *class = (PyObject *) payload;
|
||||||
|
|
||||||
|
#ifdef DEBUG_EXTENSIONS
|
||||||
|
printf("deallocateClasse(%s) called\n", name);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Py_XDECREF(class);
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
* Integrated cleanup *
|
* Integrated cleanup *
|
||||||
@ -422,6 +612,9 @@ libxslt_xsltCleanup(PyObject *self ATTRIBUTE_UNUSED,
|
|||||||
if (libxslt_extModuleFunctions != NULL) {
|
if (libxslt_extModuleFunctions != NULL) {
|
||||||
xmlHashFree(libxslt_extModuleFunctions, deallocateCallback);
|
xmlHashFree(libxslt_extModuleFunctions, deallocateCallback);
|
||||||
}
|
}
|
||||||
|
if (libxslt_extModuleClasses != NULL) {
|
||||||
|
xmlHashFree(libxslt_extModuleClasses, deallocateClasse);
|
||||||
|
}
|
||||||
xsltCleanupGlobals();
|
xsltCleanupGlobals();
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
|
@ -20,6 +20,7 @@ registerAllExtras()
|
|||||||
cleanup()
|
cleanup()
|
||||||
registerErrorHandler()
|
registerErrorHandler()
|
||||||
registerExtModuleFunction()
|
registerExtModuleFunction()
|
||||||
|
registerExtensionClass()
|
||||||
|
|
||||||
# functions from module transform
|
# functions from module transform
|
||||||
setXIncludeDefault()
|
setXIncludeDefault()
|
||||||
|
Reference in New Issue
Block a user