From: Daniel Veillard Date: Mon, 13 Jan 2003 22:28:34 +0000 (+0000) Subject: fixing bug #101602 for extension modules init and shutdown callbacks, X-Git-Tag: v1.1.28~757 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d932aafe73a9072dd44d4cd97a8cf44e9d4ef879;p=platform%2Fupstream%2Flibxslt.git 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 --- diff --git a/ChangeLog b/ChangeLog index 74db91c..00b4842 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Mon Jan 13 23:25:59 CET 2003 Daniel Veillard + + * 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 * libxslt/attributes.c libxslt/xsltInternals.h libxslt/imports.c diff --git a/libxslt/extensions.c b/libxslt/extensions.c index b597e57..11b27d2 100644 --- a/libxslt/extensions.c +++ b/libxslt/extensions.c @@ -306,6 +306,10 @@ xsltRegisterExtPrefix(xsltStylesheetPtr style, if ((style == NULL) || (prefix == NULL) | (URI == NULL)) return(-1); +#ifdef WITH_XSLT_DEBUG_EXTENSIONS + xsltGenericDebug(xsltGenericDebugContext, + "Registering extension prefix %s : %s\n", prefix, URI); +#endif def = (xsltExtDefPtr) style->nsDefs; while (def != NULL) { if (xmlStrEqual(prefix, def->prefix)) @@ -317,6 +321,21 @@ xsltRegisterExtPrefix(xsltStylesheetPtr style, return(-1); ret->next = (xsltExtDefPtr) style->nsDefs; 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); } @@ -438,17 +457,19 @@ xsltStyleGetExtData(xsltStylesheetPtr style, const xmlChar * URI) { #endif return(NULL); } else { - if (module->styleInitFunc == NULL) - return(NULL); - + if (module->styleInitFunc == NULL) { #ifdef WITH_XSLT_DEBUG_EXTENSIONS - xsltGenericDebug(xsltGenericDebugContext, - "Initializing module: %s\n", URI); + xsltGenericDebug(xsltGenericDebugContext, + "Registering style module: %s\n", URI); #endif - - extData = module->styleInitFunc(style, URI); - if (extData == NULL) - return(NULL); + extData = NULL; + } else { +#ifdef WITH_XSLT_DEBUG_EXTENSIONS + xsltGenericDebug(xsltGenericDebugContext, + "Initializing module: %s\n", URI); +#endif + extData = module->styleInitFunc(style, URI); + } data = xsltNewExtData(module, extData); if (data == NULL) @@ -576,7 +597,6 @@ xsltInitCtxtExt (xsltExtDataPtr styleData, xsltInitExtCtxt *ctxt, xsltGenericDebug(xsltGenericDebugContext, "xsltInitCtxtExt: no extData\n"); #endif - return; } ctxtData = xsltNewExtData(module, extData); if (ctxtData == NULL) { diff --git a/libxslt/transform.c b/libxslt/transform.c index 7d4aa98..813eba6 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -401,7 +401,6 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { cur->extrasMax = 0; } - XSLT_REGISTER_VARIABLE_LOOKUP(cur); XSLT_REGISTER_FUNCTION_LOOKUP(cur); cur->xpathCtxt->nsHash = style->nsHash; @@ -420,6 +419,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { cur->xinclude = xsltDoXIncludeDefault; cur->outputFile = NULL; cur->sec = xsltGetDefaultSecurityPrefs(); + return(cur); } @@ -433,6 +433,13 @@ void xsltFreeTransformContext(xsltTransformContextPtr ctxt) { if (ctxt == NULL) return; + + /* + * Shutdown the extension modules associated to the stylesheet + * used if needed. + */ + xsltShutdownCtxtExts(ctxt); + if (ctxt->xpathCtxt != NULL) { ctxt->xpathCtxt->nsHash = NULL; xmlXPathFreeContext(ctxt->xpathCtxt); diff --git a/python/libxsl.py b/python/libxsl.py index ef88cad..8fd263e 100644 --- a/python/libxsl.py +++ b/python/libxsl.py @@ -49,6 +49,37 @@ else: import libxsltmod 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 # diff --git a/python/libxslt-python-api.xml b/python/libxslt-python-api.xml index 7fa4b09..ecdc526 100644 --- a/python/libxslt-python-api.xml +++ b/python/libxslt-python-api.xml @@ -31,6 +31,12 @@ + + Register a Python written extension class to the XSLT engine + + + + Cleanup all libxslt and libxml2 memory allocated diff --git a/python/libxslt.c b/python/libxslt.c index 1e51791..aeda2e4 100644 --- a/python/libxslt.c +++ b/python/libxslt.c @@ -24,9 +24,10 @@ #endif /* #define DEBUG */ -/* #define DEBUG_XPATH */ +#define DEBUG_XPATH */ /* #define DEBUG_ERROR */ /* #define DEBUG_MEMORY */ +#define DEBUG_EXTENSIONS */ void initlibxsltmod(void); @@ -131,7 +132,7 @@ libxslt_xsltRegisterExtModuleFunction(PyObject *self ATTRIBUTE_UNUSED, xmlChar *ns_uri; PyObject *pyobj_f; - if (!PyArg_ParseTuple(args, (char *)"szO:registerXPathFunction", + if (!PyArg_ParseTuple(args, (char *)"szO:registerExtModuleFunction", &name, &ns_uri, &pyobj_f)) return(NULL); @@ -411,6 +412,195 @@ libxslt_xsltRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self, /************************************************************************ * * + * 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 * * * ************************************************************************/ @@ -422,6 +612,9 @@ libxslt_xsltCleanup(PyObject *self ATTRIBUTE_UNUSED, if (libxslt_extModuleFunctions != NULL) { xmlHashFree(libxslt_extModuleFunctions, deallocateCallback); } + if (libxslt_extModuleClasses != NULL) { + xmlHashFree(libxslt_extModuleClasses, deallocateClasse); + } xsltCleanupGlobals(); xmlCleanupParser(); Py_INCREF(Py_None); diff --git a/python/libxsltclass.txt b/python/libxsltclass.txt index ef2bc6c..1a0dd42 100644 --- a/python/libxsltclass.txt +++ b/python/libxsltclass.txt @@ -20,6 +20,7 @@ registerAllExtras() cleanup() registerErrorHandler() registerExtModuleFunction() +registerExtensionClass() # functions from module transform setXIncludeDefault()