fixed bug 114812
authorWilliam M. Brack <wbrack@src.gnome.org>
Wed, 9 Jul 2003 13:28:47 +0000 (13:28 +0000)
committerWilliam M. Brack <wbrack@src.gnome.org>
Wed, 9 Jul 2003 13:28:47 +0000 (13:28 +0000)
ChangeLog
libexslt/functions.c
libxslt/extensions.c
libxslt/extensions.h

index 88289b6..9d65451 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Wed Jul  9 21:27:43 HKT 2003 William Brack <wbrack@mmm.com.hk>
+
+       * fixed bug 114812, trouble with imported exslt functions
+         added lookup function in libxslt/extension.c
+         enhanced exsltInitFunc in libexslt/functions.c to take
+         better care of imports
+
 Wed Jul  9 12:19:34 CEST 2003 Daniel Veillard <daniel@veillard.com>
 
        * python/generator.py python/libxslt-python-api.xml python/libxslt.c
index b2f9da4..c5ef0b0 100644 (file)
@@ -20,6 +20,7 @@
 #include <libxslt/xsltInternals.h>
 #include <libxslt/extensions.h>
 #include <libxslt/transform.h>
+#include <libxslt/imports.h>
 
 #include "exslt.h"
 
@@ -42,8 +43,16 @@ struct _exsltFuncResultPreComp {
     xmlXPathCompExprPtr select;
 };
 
+/* Used for callback function in exsltInitFunc */
+typedef struct _exsltFuncImportRegData exsltFuncImportRegData;
+struct _exsltFuncImportRegData {
+    xsltTransformContextPtr ctxt;
+    xmlHashTablePtr hash;
+};
+
 static void exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt,
                                       int nargs);
+static exsltFuncFunctionData *exsltFuncNewFunctionData(void);
 
 /**
  * exsltFuncRegisterFunc:
@@ -68,6 +77,48 @@ exsltFuncRegisterFunc (exsltFuncFunctionData *data,
                            exsltFuncFunctionFunction);
 }
 
+/*
+ * exsltFuncRegisterImportFunc
+ * @data:    the exsltFuncFunctionData for the function
+ * @ch:             structure containing context and hash table
+ * @URI:     the function namespace URI
+ * @name:    the function name
+ *
+ * Checks if imported function is already registered in top-level
+ * stylesheet.  If not, copies function data and registers function
+ */
+static void
+exsltFuncRegisterImportFunc (exsltFuncFunctionData *data,
+                            exsltFuncImportRegData *ch,
+                            const xmlChar *URI, const xmlChar *name) {
+    exsltFuncFunctionData *func=NULL;
+
+    if ((data == NULL) || (ch == NULL) || (URI == NULL) || (name == NULL))
+            return;
+
+    if (ch->ctxt == NULL || ch->hash == NULL)
+       return;
+
+    /* Check if already present */
+    func = (exsltFuncFunctionData*)xmlHashLookup2(ch->hash,
+          URI, name);
+    if (func == NULL) {                /* Not yet present - copy it in */
+       func = exsltFuncNewFunctionData();
+       memcpy(func, data, sizeof(exsltFuncFunctionData));
+       if (xmlHashAddEntry2(ch->hash, URI, name, func) < 0) {
+           xsltGenericError(xsltGenericErrorContext,
+                   "Failed to register function {%s}%s\n",
+                   URI, name);
+       } else {                /* Do the registration */
+           xsltGenericDebug(xsltGenericDebugContext,
+                   "exsltFuncRegisterImportFunc: register {%s}%s\n",
+                   URI, name);
+           xsltRegisterExtFunction(ch->ctxt, name, URI,
+                   exsltFuncFunctionFunction);
+       }
+    }
+}
+
 /**
  * exsltFuncInit:
  * @ctxt: an XSLT transformation context
@@ -79,9 +130,11 @@ exsltFuncRegisterFunc (exsltFuncFunctionData *data,
  */
 static exsltFuncData *
 exsltFuncInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
-    xmlHashTablePtr hash;
     exsltFuncData *ret;
-
+    xsltStylesheetPtr tmp;
+    exsltFuncImportRegData ch;
+    xmlHashTablePtr hash;
+    
     ret = (exsltFuncData *) xmlMalloc (sizeof(exsltFuncData));
     if (ret == NULL) {
        xsltGenericError(xsltGenericErrorContext,
@@ -93,10 +146,18 @@ exsltFuncInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
     ret->result = NULL;
     ret->error = 0;
 
-    hash = (xmlHashTablePtr) xsltStyleGetExtData(ctxt->style, URI);
-    xmlHashScanFull(hash, (xmlHashScannerFull) exsltFuncRegisterFunc, ctxt);
-
-    ret->funcs = hash;
+    ch.hash = (xmlHashTablePtr) xsltStyleGetExtData(ctxt->style, URI);
+    ret->funcs = ch.hash;
+    xmlHashScanFull(ch.hash, (xmlHashScannerFull) exsltFuncRegisterFunc, ctxt);
+    tmp = ctxt->style;
+    ch.ctxt = ctxt;
+    while ((tmp=xsltNextImport(tmp))!=NULL) {
+       hash = xsltGetExtInfo(tmp, URI);
+       if (hash != NULL) {
+           xmlHashScanFull(hash, 
+                   (xmlHashScannerFull) exsltFuncRegisterImportFunc, &ch);
+       }
+    }
 
     return(ret);
 }
@@ -128,8 +189,8 @@ exsltFuncShutdown (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
  * Returns the allocated data
  */
 static xmlHashTablePtr
-exsltFuncStyleInit (xsltStylesheetPtr style ATTRIBUTE_UNUSED,
-                   const xmlChar *URI ATTRIBUTE_UNUSED) {
+exsltFuncStyleInit (xsltStylesheetPtr style,
+                   const xmlChar *URI) {
     return xmlHashCreate(1);
 }
 
index 437722b..666378c 100644 (file)
@@ -1296,6 +1296,26 @@ xsltUnregisterAllExtModuleTopLevel (void) {
     xsltTopLevelsHash = NULL;
 }
 
+/**
+ * xsltGetExtInfo:
+ * @style:  pointer to a stylesheet
+ * @URI:    the namespace URI desired
+ *
+ * looks up URI in extInfos of the stylesheet
+ *
+ * returns a pointer to the hash table if found, else NULL
+ */
+xmlHashTablePtr
+xsltGetExtInfo (xsltStylesheetPtr style, const xmlChar *URI) {
+    xsltExtDataPtr data;
+    
+    if (style != NULL && style->extInfos != NULL) {
+       data = xmlHashLookup(style->extInfos, URI);
+       if (data != NULL && data->extData != NULL)
+           return data->extData;
+    }
+    return NULL;
+}
 
 /************************************************************************
  *                                                                     *
index 01f0473..0a54044 100644 (file)
@@ -181,6 +181,12 @@ void               xsltFreeExts            (xsltStylesheetPtr style);
 
 xsltElemPreCompPtr xsltPreComputeExtModuleElement(xsltStylesheetPtr style,
                                         xmlNodePtr inst);
+/*
+ * Extension Infos access.
+ * Used by exslt initialisation
+ */
+
+xmlHashTablePtr xsltGetExtInfo (xsltStylesheetPtr style, const xmlChar *URI);
 
 /**
  * Test module http://xmlsoft.org/XSLT/