- libxslt/Makefile.am libxslt/extensions.[ch]: started working
authorDaniel Veillard <veillard@src.gnome.org>
Mon, 26 Feb 2001 07:42:50 +0000 (07:42 +0000)
committerDaniel Veillard <veillard@src.gnome.org>
Mon, 26 Feb 2001 07:42:50 +0000 (07:42 +0000)
  on functions and element extensions. First on list will be
  a document element.
Daniel

ChangeLog
libxslt/Makefile.am
libxslt/extensions.c [new file with mode: 0644]
libxslt/extensions.h [new file with mode: 0644]
libxslt/pattern.c
libxslt/transform.c
libxslt/xsltInternals.h
libxslt/xsltproc.c
tests/docbook/Makefile.am

index 952b3ac..2b190fc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Mon Feb 26 09:41:04 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+       * libxslt/Makefile.am libxslt/extensions.[ch]: started working
+         on functions and element extensions. First on list will be
+         a document element.
+
 Sun Feb 25 06:52:14 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
        * configure.in libxslt.spec.in: releasing 0.3.0
index 27d3b3b..b1e132d 100644 (file)
@@ -13,6 +13,7 @@ xsltinc_HEADERS =                     \
        variables.h                     \
        keys.h                          \
        numbersInternals.h              \
+       extensions.h                    \
        functions.h                     \
        namespaces.h                    \
        imports.h                       \
@@ -29,6 +30,7 @@ libxslt_la_SOURCES =                  \
        variables.c                     \
        keys.c                          \
        numbers.c                       \
+       extensions.c                    \
        functions.c                     \
        namespaces.c                    \
        imports.c                       \
diff --git a/libxslt/extensions.c b/libxslt/extensions.c
new file mode 100644 (file)
index 0000000..787c529
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * extensions.c: Implemetation of the extensions support
+ *
+ * Reference:
+ *   http://www.w3.org/TR/1999/REC-xslt-19991116
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@imag.fr
+ */
+
+#include "xsltconfig.h"
+
+#include <string.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/hash.h>
+#include <libxml/xmlerror.h>
+#include <libxml/parserInternals.h>
+#include "xslt.h"
+#include "xsltInternals.h"
+#include "xsltutils.h"
+#include "extensions.h"
+
+#define DEBUG_EXTENSIONS
+
+typedef struct _xsltExtDef xsltExtDef;
+typedef xsltExtDef *xsltExtDefPtr;
+struct _xsltExtDef {
+    struct _xsltExtDef *next;
+    xmlChar *prefix;
+    xmlChar *URI;
+};
+
+
+/************************************************************************
+ *                                                                     *
+ *                     Type functions                                  *
+ *                                                                     *
+ ************************************************************************/
+
+/**
+ * xsltNewExtDef:
+ * @prefix:  the extension prefix
+ * @URI:  the namespace URI
+ *
+ * Create a new XSLT ExtDef
+ *
+ * Returns the newly allocated xsltExtDefPtr or NULL in case of error
+ */
+xsltExtDefPtr
+xsltNewExtDef(const xmlChar *prefix, const xmlChar *URI) {
+    xsltExtDefPtr cur;
+
+    cur = (xsltExtDefPtr) xmlMalloc(sizeof(xsltExtDef));
+    if (cur == NULL) {
+        xsltGenericError(xsltGenericErrorContext,
+               "xsltNewExtDef : malloc failed\n");
+       return(NULL);
+    }
+    memset(cur, 0, sizeof(xsltExtDef));
+    if (prefix != NULL)
+       cur->prefix = xmlStrdup(prefix);
+    if (URI != NULL)
+       cur->URI = xmlStrdup(URI);
+    return(cur);
+}
+
+/**
+ * xsltFreeExtDef:
+ * @extensiond:  an XSLT extension definition
+ *
+ * Free up the memory allocated by @extensiond
+ */
+void
+xsltFreeExtDef(xsltExtDefPtr extensiond) {
+    if (extensiond == NULL)
+       return;
+    if (extensiond->prefix != NULL)
+       xmlFree(extensiond->prefix);
+    if (extensiond->URI != NULL)
+       xmlFree(extensiond->URI);
+    memset(extensiond, -1, sizeof(xsltExtDef));
+    xmlFree(extensiond);
+}
+
+/**
+ * xsltFreeExtDefList:
+ * @extensiond:  an XSLT extension definition list
+ *
+ * Free up the memory allocated by all the elements of @extensiond
+ */
+void
+xsltFreeExtDefList(xsltExtDefPtr extensiond) {
+    xsltExtDefPtr cur;
+
+    while (extensiond != NULL) {
+       cur = extensiond;
+       extensiond = extensiond->next;
+       xsltFreeExtDef(cur);
+    }
+}
+
+
+/************************************************************************
+ *                                                                     *
+ *             The interpreter for the precompiled patterns            *
+ *                                                                     *
+ ************************************************************************/
+
+
+/**
+ * xsltFreeExtPrefix:
+ * @style: an XSLT stylesheet
+ *
+ * Free up the memory used by XSLT extensions in a stylesheet
+ */
+void
+xsltFreeExts(xsltStylesheetPtr style) {
+    if (style->nsDefs != NULL)
+       xsltFreeExtDefList((xsltExtDefPtr) style->nsDefs);
+}
+
+/*
+ * xsltRegisterExtPrefix:
+ * @style: an XSLT stylesheet
+ * @prefix: the prefix used
+ * @URI: the URI associated to the extension
+ *
+ * Registers an extension namespace
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+int
+xsltRegisterExtPrefix(xsltStylesheetPtr style,
+                     const xmlChar *prefix, const xmlChar *URI) {
+    xsltExtDefPtr def, ret;
+
+    if ((style == NULL) || (prefix == NULL) | (URI == NULL))
+       return(-1);
+
+    def = (xsltExtDefPtr) style->nsDefs;
+    while (def != NULL) {
+       if (xmlStrEqual(prefix, def->prefix))
+           return(-1);
+       def = def->next;
+    }
+    ret = xsltNewExtDef(prefix, URI);
+    if (ret == NULL)
+       return(-1);
+    ret->next = (xsltExtDefPtr) style->nsDefs;
+    style->nsDefs = ret;
+    return(0);
+}
+
+/*
+ * xsltRegisterExtFunction:
+ * @ctxt: an XSLT transformation context
+ * @name: the name of the element
+ * @URI: the URI associated to the element
+ * @function: the actual implementation which should be called 
+ *
+ * Registers an extension function
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+int
+xsltRegisterExtFunction(xsltTransformContextPtr ctxt, const xmlChar *name,
+                       const xmlChar *URI, xmlXPathEvalFunc function) {
+    if ((ctxt == NULL) || (name == NULL) ||
+       (URI == NULL) || (function == NULL))
+       return(-1);
+    if (ctxt->extFunctions == NULL)
+       ctxt->extFunctions = xmlHashCreate(10);
+    return(xmlHashAddEntry2(ctxt->extFunctions, name, URI, (void *) function));
+}
+
+/*
+ * xsltRegisterExtElement:
+ * @ctxt: an XSLT transformation context
+ * @name: the name of the element
+ * @URI: the URI associated to the element
+ * @function: the actual implementation which should be called 
+ *
+ * Registers an extension element
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+int    
+xsltRegisterExtElement(xsltTransformContextPtr ctxt, const xmlChar *name,
+                      const xmlChar *URI, xsltTransformFunction function) {
+    if ((ctxt == NULL) || (name == NULL) ||
+       (URI == NULL) || (function == NULL))
+       return(-1);
+    if (ctxt->extElements == NULL)
+       ctxt->extElements = xmlHashCreate(10);
+    return(xmlHashAddEntry2(ctxt->extElements, name, URI, (void *) function));
+}
+
+/*
+ * xsltInitCtxtExts:
+ * @ctxt: an XSLT transformation context
+ *
+ * Initialize the XSLT extension support
+ */
+void
+xsltInitCtxtExts(xsltTransformContextPtr ctxt) {
+    if (ctxt->extElements == NULL)
+       xmlHashFree(ctxt->extElements, NULL);
+    if (ctxt->extFunctions == NULL)
+       xmlHashFree(ctxt->extFunctions, NULL);
+}
+
diff --git a/libxslt/extensions.h b/libxslt/extensions.h
new file mode 100644 (file)
index 0000000..5522d53
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * extension.h: interface for the extension support
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@imag.fr
+ */
+
+#ifndef __XML_XSLT_EXTENSION_H__
+#define __XML_XSLT_EXTENSION_H__
+
+#include "libxml/xpath.h"
+#include "xsltInternals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int            xsltRegisterExtPrefix   (xsltStylesheetPtr style,
+                                        const xmlChar *prefix,
+                                        const xmlChar *URI);
+int            xsltRegisterExtFunction (xsltTransformContextPtr ctxt,
+                                        const xmlChar *name,
+                                        const xmlChar *URI,
+                                        xmlXPathEvalFunc function);
+int            xsltRegisterExtElement  (xsltTransformContextPtr ctxt,
+                                        const xmlChar *name,
+                                        const xmlChar *URI,
+                                        xsltTransformFunction function);
+void           xsltInitCtxtExts        (xsltTransformContextPtr ctxt);
+void           xsltFreeExts            (xsltStylesheetPtr style);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_XSLT_EXTENSION_H__ */
+
index 94c803d..5110a2d 100644 (file)
@@ -1574,9 +1574,14 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur,
            return(-1);
        }
 #ifdef DEBUG_PATTERN
-       xsltGenericDebug(xsltGenericDebugContext,
-                    "added pattern : '%s' priority %f\n",
-                        pat->template->match, pat->priority);
+       if (mode)
+           xsltGenericDebug(xsltGenericDebugContext,
+                        "added pattern : '%s' mode '%s' priority %f\n",
+                            pat->template->match, pat->mode, pat->priority);
+       else
+           xsltGenericDebug(xsltGenericDebugContext,
+                        "added pattern : '%s' priority %f\n",
+                            pat->template->match, pat->priority);
 #endif
 
        pat = next;
@@ -1653,7 +1658,8 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
             */
            list = (xsltCompMatchPtr) xmlHashLookup3(curstyle->templatesHash,
                                             name, ctxt->mode, ctxt->modeURI);
-       }
+       } else
+           list = NULL;
        while (list != NULL) {
            if (xsltTestCompMatch(ctxt, list, node,
                                  ctxt->mode, ctxt->modeURI)) {
index 0a26d78..1884cbf 100644 (file)
@@ -1016,16 +1016,16 @@ xsltNumber(xsltTransformContextPtr ctxt,
     
     prop = xmlGetNsProp(cur, (const xmlChar *)"lang", XSLT_NAMESPACE);
     if (prop != NULL) {
-       TODO;
+       TODO; /* xsl:number lang attribute */
        xmlFree(prop);
     }
     
     prop = xmlGetNsProp(cur, (const xmlChar *)"letter-value", XSLT_NAMESPACE);
     if (prop != NULL) {
        if (xmlStrEqual(prop, BAD_CAST("alphabetic"))) {
-           TODO;
+           TODO; /* xsl:number letter-value attribute alphabetic */
        } else if (xmlStrEqual(prop, BAD_CAST("traditional"))) {
-           TODO;
+           TODO; /* xsl:number letter-value attribute traditional */
        } else {
            xsltGenericError(xsltGenericErrorContext,
                             "invalid value %s for letter-value\n", prop);
@@ -1855,7 +1855,6 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
            } else {
                xsltGenericError(xsltGenericDebugContext,
                     "xsltApplyOneTemplate: found xslt:%s\n", cur->name);
-               TODO
            }
            CHECK_STOPPED;
            goto skip_children;
index c97e667..43bb807 100644 (file)
@@ -151,9 +151,10 @@ struct _xsltStylesheet {
     xmlHashTablePtr attributeSets;/* the attribute sets hash tables */
 
     /*
-     * Attribute sets
+     * Namespaces
      */
     xmlHashTablePtr nsHash;     /* the set of namespaces in use */
+    void           *nsDefs;     /* the namespaces defined */
 
     /*
      * Key definitions
index 5a3b793..0b24740 100644 (file)
@@ -38,14 +38,14 @@ main(int argc, char **argv) {
        printf("   Options:\n");
        printf("      --verbose or -v: show logs of what's happening\n");
        printf("      --timing: display the time used\n");
-       printf("      --repeat: run the transformation 100 times\n");
+       printf("      --repeat: run the transformation 20 times\n");
        printf("      --debug: dump the tree of the result instead\n");
        printf("      --novalid: skip the Dtd loading phase\n");
        printf("      --noout: do not dump the result\n");
        printf("      --maxdepth val : increase the maximum depth\n");
        return(0);
     }
-    /* --repeat : repeat 100 times, for timing or profiling */
+    /* --repeat : repeat 20 times, for timing or profiling */
     LIBXML_TEST_VERSION
     for (i = 1; i < argc ; i++) {
 #ifdef LIBXML_DEBUG_ENABLED
@@ -132,17 +132,17 @@ main(int argc, char **argv) {
                fprintf(stderr, "Parsing document %s took %ld ms\n",
                        argv[i], msec);
            }
+           if (timing)
+               gettimeofday(&begin, NULL);
            if (repeat) {
                int j;
-               for (j = 0;j < 99; j++) {
+               for (j = 0;j < 19; j++) {
                    res = xsltApplyStylesheet(cur, doc);
                    xmlFreeDoc(res);
                    xmlFreeDoc(doc);
                    doc = xmlParseFile(argv[i]);
                }
            }
-           if (timing)
-               gettimeofday(&begin, NULL);
            res = xsltApplyStylesheet(cur, doc);
            if (timing) {
                long msec;
@@ -150,8 +150,13 @@ main(int argc, char **argv) {
                msec = end.tv_sec - begin.tv_sec;
                msec *= 1000;
                msec += (end.tv_usec - begin.tv_usec) / 1000;
-               fprintf(stderr, "Applying stylesheet took %ld ms\n",
-                       msec);
+               if (repeat)
+                   fprintf(stderr,
+                           "Applying stylesheet 20 times took %ld ms\n",
+                           msec);
+               else
+                   fprintf(stderr, "Applying stylesheet took %ld ms\n",
+                           msec);
            }
            xmlFreeDoc(doc);
            if (res == NULL) {
index bc9f0c3..3a71738 100644 (file)
@@ -17,7 +17,11 @@ html: ../../libxslt/xsltproc
          out=result/html/`basename $$i .xml`.tst; \
          html=result/html/`basename $$i .xml`.html; \
          ../../libxslt/xsltproc html/docbook.xsl $$i > $$out ; \
-         if [ -f $$html ] ; then diff $$html $$out ; \
+         if [ -f $$html ] ; then \
+             grep -v id < $$html > $$html.noid ; \
+             grep -v id < $$out > $$out.noid ; \
+             diff $$html.noid $$out.noid ; \
+             rm -f $$html.noid $$out.noid ; \
          else mv $$out $$html ; fi ; \
          grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
          rm -f $$out ; done )