libs: Import code from upstream libxslt 1.1.34.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-10-20 11:33:05 +02:00
parent 9d9d4fcc37
commit c638618cbc
49 changed files with 39562 additions and 0 deletions

26
configure vendored
View File

@ -701,6 +701,8 @@ XMKMF
PTHREAD_LIBS
ZLIB_PE_LIBS
ZLIB_PE_CFLAGS
XSLT_PE_LIBS
XSLT_PE_CFLAGS
XML2_PE_LIBS
XML2_PE_CFLAGS
TIFF_PE_LIBS
@ -1796,6 +1798,7 @@ enable_wbemuuid
enable_wine
enable_wmcodecdspuuid
enable_xml2
enable_xslt
enable_zlib
enable_loader
enable_nls
@ -1937,6 +1940,8 @@ TIFF_PE_CFLAGS
TIFF_PE_LIBS
XML2_PE_CFLAGS
XML2_PE_LIBS
XSLT_PE_CFLAGS
XSLT_PE_LIBS
ZLIB_PE_CFLAGS
ZLIB_PE_LIBS
XMKMF
@ -2735,6 +2740,11 @@ Some influential environment variables:
version
XML2_PE_LIBS
Linker flags for the PE libxml2, overriding the bundled version
XSLT_PE_CFLAGS
C compiler flags for the PE libxslt, overriding the bundled
version
XSLT_PE_LIBS
Linker flags for the PE libxslt, overriding the bundled version
ZLIB_PE_CFLAGS
C compiler flags for the PE zlib, overriding the bundled version
ZLIB_PE_LIBS
@ -10777,6 +10787,19 @@ fi
$as_echo "$as_me:${as_lineno-$LINENO}: libxml2 cflags: $XML2_PE_CFLAGS" >&5
$as_echo "$as_me:${as_lineno-$LINENO}: libxml2 libs: $XML2_PE_LIBS" >&5
if ${XSLT_PE_CFLAGS:+false} :; then :
XSLT_PE_CFLAGS="-I\$(top_srcdir)/libs/xslt"
else
enable_libxslt=no
fi
if ${XSLT_PE_LIBS:+false} :; then :
XSLT_PE_LIBS=xslt
else
enable_libxslt=no
fi
$as_echo "$as_me:${as_lineno-$LINENO}: libxslt cflags: $XSLT_PE_CFLAGS" >&5
$as_echo "$as_me:${as_lineno-$LINENO}: libxslt libs: $XSLT_PE_LIBS" >&5
if ${ZLIB_PE_CFLAGS:+false} :; then :
ZLIB_PE_CFLAGS="-I\$(top_srcdir)/libs/zlib -DFAR= -DZ_SOLO"
else
@ -19432,6 +19455,8 @@ TIFF_PE_CFLAGS = $TIFF_PE_CFLAGS
TIFF_PE_LIBS = $TIFF_PE_LIBS
XML2_PE_CFLAGS = $XML2_PE_CFLAGS
XML2_PE_LIBS = $XML2_PE_LIBS
XSLT_PE_CFLAGS = $XSLT_PE_CFLAGS
XSLT_PE_LIBS = $XSLT_PE_LIBS
ZLIB_PE_CFLAGS = $ZLIB_PE_CFLAGS
ZLIB_PE_LIBS = $ZLIB_PE_LIBS
PTHREAD_LIBS = $PTHREAD_LIBS
@ -20731,6 +20756,7 @@ wine_fn_config_makefile libs/wbemuuid enable_wbemuuid
wine_fn_config_makefile libs/wine enable_wine
wine_fn_config_makefile libs/wmcodecdspuuid enable_wmcodecdspuuid
wine_fn_config_makefile libs/xml2 enable_xml2
wine_fn_config_makefile libs/xslt enable_xslt
wine_fn_config_makefile libs/zlib enable_zlib
wine_fn_config_makefile loader enable_loader
wine_fn_config_makefile nls enable_nls

View File

@ -1065,6 +1065,7 @@ WINE_EXTLIB_FLAGS(LCMS2, lcms2, lcms2, "-I\$(top_srcdir)/libs/lcms2/include")
WINE_EXTLIB_FLAGS(PNG, png, "png \$(ZLIB_PE_LIBS)", "-I\$(top_srcdir)/libs/png")
WINE_EXTLIB_FLAGS(TIFF, tiff, tiff, "-I\$(top_srcdir)/libs/tiff/libtiff")
WINE_EXTLIB_FLAGS(XML2, libxml2, xml2, "-I\$(top_srcdir)/libs/xml2/include -DLIBXML_STATIC")
WINE_EXTLIB_FLAGS(XSLT, libxslt, xslt, "-I\$(top_srcdir)/libs/xslt")
WINE_EXTLIB_FLAGS(ZLIB, zlib, z, "-I\$(top_srcdir)/libs/zlib -DFAR= -DZ_SOLO")
dnl **** Check for pthread ****
@ -3775,6 +3776,7 @@ WINE_CONFIG_MAKEFILE(libs/wbemuuid)
WINE_CONFIG_MAKEFILE(libs/wine)
WINE_CONFIG_MAKEFILE(libs/wmcodecdspuuid)
WINE_CONFIG_MAKEFILE(libs/xml2)
WINE_CONFIG_MAKEFILE(libs/xslt)
WINE_CONFIG_MAKEFILE(libs/zlib)
WINE_CONFIG_MAKEFILE(loader)
WINE_CONFIG_MAKEFILE(nls)

63
libs/xslt/AUTHORS Normal file
View File

@ -0,0 +1,63 @@
Daniel Veillard:
daniel@veillard.com
DV on #gnome IRC channel
http://veillard.com/
Used to work at W3C, now Red Hat
co-chair of W3C XML Linking WG
invited expert on the W3C XML Core WG
Author of libxml2 upon which this library is based.
Bjorn Reese:
breese@users.sourceforge.net
http://home1.stofanet.dk/breese/
Software developer at http://www.systematic.dk/
Member of the XML-MTF Mapping WG.
William Brack <wbrack@mmm.com.hk>
Thomas Broyer <tbroyer@ltgt.net>
Igor Zlatkovic <igor@zlatkovic.com> for the Windows port
Patches gently provided by a multitude of people :
Abhishek Arya <inferno@chromium.org>
Ben Walton <bwalton@artsci.utoronto.ca>
Bjorn Reese <breese@src.gnome.org>
C. M. Sperberg-McQueen <cmsmcq@blackmesatech.com>
Colin Walters <walters@verbum.org>
Daniel Mustieles <daniel.mustieles@gmail.com>
Daniel Richard G <oss@teragram.com>
Darin Adler <darin@src.gnome.org>
ÉRDI Gergo <cactus@src.gnome.org>
Fatih Demir <kabalak@src.gnome.org>
Federico Mena Quintero <federico@ximian.com>
Frederic Crozat <fcrozat@mandriva.com>
Hao Hu <ihaohu@gmail.com>
Havoc Pennington <hp@pobox.com>
IlyaS <astro.courier@gmail.com>
jacob berkman <jacob@ximian.com>
Jason Viers <bean@beanalby.net>
Jérôme Carretero <cJ-xslt@zougloub.eu>
Joachim Breitner <nomeata@debian.org>
Johan Dahlin <zilch@src.gnome.org>
John Fleck <jfleck@inkstain.net>
Jose Maria Celorio <chema@src.gnome.org>
Julio M. Merino Vidal <jmmv@NetBSD.org>
Kasimier T. Buchcik <kbuchcik@src.gnome.org>
Kjartan Maraas <kmaraas@src.gnome.org>
Laurence Rowe <l@lrowe.co.uk>
Malcolm Purvis <malcolm@purvis.id.au>
Martin <gzlist@googlemail.com>
Michael Bonfils <murlock42@gmail.com>
Mike Hommey <mh@glandium.org>
money_seshu Dronamraju <mcseshu@gmail.com>
Nick Wellnhofer <wellnhofer@aevum.de>
Nix <nix@esperi.org.uk>
Pedro F. Giffuni <giffunip@tutopia.com>
Peter Williams <peterw@ximian.com>
Rob Richards <rrichard@src.gnome.org>
Roumen Petrov <bugtrack@roumenpetrov.info>
Stefan Kost <ensonic@users.sf.net>
Tomasz Kłoczko <kloczek@src.gnome.org>
Chris Evans <cevans@chromium.org>

53
libs/xslt/COPYING Normal file
View File

@ -0,0 +1,53 @@
Licence for libxslt except libexslt
----------------------------------------------------------------------
Copyright (C) 2001-2002 Daniel Veillard. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is fur-
nished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Daniel Veillard shall not
be used in advertising or otherwise to promote the sale, use or other deal-
ings in this Software without prior written authorization from him.
----------------------------------------------------------------------
Licence for libexslt
----------------------------------------------------------------------
Copyright (C) 2001-2002 Thomas Broyer, Charlie Bozeman and Daniel Veillard.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is fur-
nished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the authors shall not
be used in advertising or otherwise to promote the sale, use or other deal-
ings in this Software without prior written authorization from him.
----------------------------------------------------------------------

23
libs/xslt/Makefile.in Normal file
View File

@ -0,0 +1,23 @@
EXTLIB = libxslt.a
EXTRAINCL = $(XML2_PE_CFLAGS)
C_SRCS = \
libxslt/attributes.c \
libxslt/attrvt.c \
libxslt/documents.c \
libxslt/extensions.c \
libxslt/extra.c \
libxslt/functions.c \
libxslt/imports.c \
libxslt/keys.c \
libxslt/namespaces.c \
libxslt/numbers.c \
libxslt/pattern.c \
libxslt/preproc.c \
libxslt/security.c \
libxslt/templates.c \
libxslt/transform.c \
libxslt/variables.c \
libxslt/xslt.c \
libxslt/xsltlocale.c \
libxslt/xsltutils.c

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,38 @@
/*
* Summary: interface for the XSLT attribute handling
* Description: this module handles the specificities of attribute
* and attribute groups processing.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_ATTRIBUTES_H__
#define __XML_XSLT_ATTRIBUTES_H__
#include <libxml/tree.h>
#include "xsltexports.h"
#ifdef __cplusplus
extern "C" {
#endif
XSLTPUBFUN void XSLTCALL
xsltParseStylesheetAttributeSet (xsltStylesheetPtr style,
xmlNodePtr cur);
XSLTPUBFUN void XSLTCALL
xsltFreeAttributeSetsHashes (xsltStylesheetPtr style);
XSLTPUBFUN void XSLTCALL
xsltApplyAttributeSet (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
const xmlChar *attributes);
XSLTPUBFUN void XSLTCALL
xsltResolveStylesheetAttributeSet(xsltStylesheetPtr style);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_ATTRIBUTES_H__ */

396
libs/xslt/libxslt/attrvt.c Normal file
View File

@ -0,0 +1,396 @@
/*
* attrvt.c: Implementation of the XSL Transformation 1.0 engine
* attribute value template handling part.
*
* References:
* http://www.w3.org/TR/1999/REC-xslt-19991116
*
* Michael Kay "XSLT Programmer's Reference" pp 637-643
* Writing Multiple Output Files
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#define IN_LIBXSLT
#include "libxslt.h"
#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include "xslt.h"
#include "xsltutils.h"
#include "xsltInternals.h"
#include "templates.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_AVT
#endif
#define MAX_AVT_SEG 10
typedef struct _xsltAttrVT xsltAttrVT;
typedef xsltAttrVT *xsltAttrVTPtr;
struct _xsltAttrVT {
struct _xsltAttrVT *next; /* next xsltAttrVT */
int nb_seg; /* Number of segments */
int max_seg; /* max capacity before re-alloc needed */
int strstart; /* is the start a string */
/*
* the namespaces in scope
*/
xmlNsPtr *nsList;
int nsNr;
/*
* the content is an alternate of string and xmlXPathCompExprPtr
*/
#if __STDC_VERSION__ >= 199901L
/* Using a C99 flexible array member avoids false positives under UBSan */
void *segments[];
#else
void *segments[1];
#endif
};
/**
* xsltNewAttrVT:
* @style: a XSLT process context
*
* Build a new xsltAttrVT structure
*
* Returns the structure or NULL in case of error
*/
static xsltAttrVTPtr
xsltNewAttrVT(xsltStylesheetPtr style) {
xsltAttrVTPtr cur;
size_t size = sizeof(xsltAttrVT) + MAX_AVT_SEG * sizeof(void*);
cur = (xsltAttrVTPtr) xmlMalloc(size);
if (cur == NULL) {
xsltTransformError(NULL, style, NULL,
"xsltNewAttrVTPtr : malloc failed\n");
if (style != NULL) style->errors++;
return(NULL);
}
memset(cur, 0, size);
cur->nb_seg = 0;
cur->max_seg = MAX_AVT_SEG;
cur->strstart = 0;
cur->next = style->attVTs;
/*
* Note: this pointer may be changed by a re-alloc within xsltCompileAttr,
* so that code may change the stylesheet pointer also!
*/
style->attVTs = (xsltAttrVTPtr) cur;
return(cur);
}
/**
* xsltFreeAttrVT:
* @avt: pointer to an xsltAttrVT structure
*
* Free up the memory associated to the attribute value template
*/
static void
xsltFreeAttrVT(xsltAttrVTPtr avt) {
int i;
if (avt == NULL) return;
if (avt->strstart == 1) {
for (i = 0;i < avt->nb_seg; i += 2)
if (avt->segments[i] != NULL)
xmlFree((xmlChar *) avt->segments[i]);
for (i = 1;i < avt->nb_seg; i += 2)
xmlXPathFreeCompExpr((xmlXPathCompExprPtr) avt->segments[i]);
} else {
for (i = 0;i < avt->nb_seg; i += 2)
xmlXPathFreeCompExpr((xmlXPathCompExprPtr) avt->segments[i]);
for (i = 1;i < avt->nb_seg; i += 2)
if (avt->segments[i] != NULL)
xmlFree((xmlChar *) avt->segments[i]);
}
if (avt->nsList != NULL)
xmlFree(avt->nsList);
xmlFree(avt);
}
/**
* xsltFreeAVTList:
* @avt: pointer to an list of AVT structures
*
* Free up the memory associated to the attribute value templates
*/
void
xsltFreeAVTList(void *avt) {
xsltAttrVTPtr cur = (xsltAttrVTPtr) avt, next;
while (cur != NULL) {
next = cur->next;
xsltFreeAttrVT(cur);
cur = next;
}
}
/**
* xsltSetAttrVTsegment:
* @ avt: pointer to an xsltAttrVT structure
* @ val: the value to be set to the next available segment
*
* Within xsltCompileAttr there are several places where a value
* needs to be added to the 'segments' array within the xsltAttrVT
* structure, and at each place the allocated size may have to be
* re-allocated. This routine takes care of that situation.
*
* Returns the avt pointer, which may have been changed by a re-alloc
*/
static xsltAttrVTPtr
xsltSetAttrVTsegment(xsltAttrVTPtr avt, void *val) {
if (avt->nb_seg >= avt->max_seg) {
size_t size = sizeof(xsltAttrVT) +
(avt->max_seg + MAX_AVT_SEG) * sizeof(void *);
xsltAttrVTPtr tmp = (xsltAttrVTPtr) xmlRealloc(avt, size);
if (tmp == NULL) {
xsltFreeAttrVT(avt);
return NULL;
}
avt = tmp;
memset(&avt->segments[avt->nb_seg], 0, MAX_AVT_SEG*sizeof(void *));
avt->max_seg += MAX_AVT_SEG;
}
avt->segments[avt->nb_seg++] = val;
return avt;
}
/**
* xsltCompileAttr:
* @style: a XSLT process context
* @attr: the attribute coming from the stylesheet.
*
* Precompile an attribute in a stylesheet, basically it checks if it is
* an attribute value template, and if yes, establish some structures needed
* to process it at transformation time.
*/
void
xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) {
const xmlChar *str;
const xmlChar *cur;
xmlChar *ret = NULL;
xmlChar *expr = NULL;
xsltAttrVTPtr avt;
int i = 0, lastavt = 0;
if ((style == NULL) || (attr == NULL) || (attr->children == NULL))
return;
if ((attr->children->type != XML_TEXT_NODE) ||
(attr->children->next != NULL)) {
xsltTransformError(NULL, style, attr->parent,
"Attribute '%s': The content is expected to be a single text "
"node when compiling an AVT.\n", attr->name);
style->errors++;
return;
}
str = attr->children->content;
if ((xmlStrchr(str, '{') == NULL) &&
(xmlStrchr(str, '}') == NULL)) return;
#ifdef WITH_XSLT_DEBUG_AVT
xsltGenericDebug(xsltGenericDebugContext,
"Found AVT %s: %s\n", attr->name, str);
#endif
if (attr->psvi != NULL) {
#ifdef WITH_XSLT_DEBUG_AVT
xsltGenericDebug(xsltGenericDebugContext,
"AVT %s: already compiled\n", attr->name);
#endif
return;
}
/*
* Create a new AVT object.
*/
avt = xsltNewAttrVT(style);
if (avt == NULL)
return;
attr->psvi = avt;
avt->nsList = xmlGetNsList(attr->doc, attr->parent);
if (avt->nsList != NULL) {
while (avt->nsList[i] != NULL)
i++;
}
avt->nsNr = i;
cur = str;
while (*cur != 0) {
if (*cur == '{') {
if (*(cur+1) == '{') { /* escaped '{' */
cur++;
ret = xmlStrncat(ret, str, cur - str);
cur++;
str = cur;
continue;
}
if (*(cur+1) == '}') { /* skip empty AVT */
ret = xmlStrncat(ret, str, cur - str);
cur += 2;
str = cur;
continue;
}
if ((ret != NULL) || (cur - str > 0)) {
ret = xmlStrncat(ret, str, cur - str);
str = cur;
if (avt->nb_seg == 0)
avt->strstart = 1;
if ((avt = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL)
goto error;
ret = NULL;
lastavt = 0;
}
cur++;
while ((*cur != 0) && (*cur != '}')) {
/* Need to check for literal (bug539741) */
if ((*cur == '\'') || (*cur == '"')) {
char delim = *(cur++);
while ((*cur != 0) && (*cur != delim))
cur++;
if (*cur != 0)
cur++; /* skip the ending delimiter */
} else
cur++;
}
if (*cur == 0) {
xsltTransformError(NULL, style, attr->parent,
"Attribute '%s': The AVT has an unmatched '{'.\n",
attr->name);
style->errors++;
goto error;
}
str++;
expr = xmlStrndup(str, cur - str);
if (expr == NULL) {
/*
* TODO: What needs to be done here?
*/
XSLT_TODO
goto error;
} else {
xmlXPathCompExprPtr comp;
comp = xsltXPathCompile(style, expr);
if (comp == NULL) {
xsltTransformError(NULL, style, attr->parent,
"Attribute '%s': Failed to compile the expression "
"'%s' in the AVT.\n", attr->name, expr);
style->errors++;
goto error;
}
if (avt->nb_seg == 0)
avt->strstart = 0;
if (lastavt == 1) {
if ((avt = xsltSetAttrVTsegment(avt, NULL)) == NULL)
goto error;
}
if ((avt = xsltSetAttrVTsegment(avt, (void *) comp)) == NULL)
goto error;
lastavt = 1;
xmlFree(expr);
expr = NULL;
}
cur++;
str = cur;
} else if (*cur == '}') {
cur++;
if (*cur == '}') { /* escaped '}' */
ret = xmlStrncat(ret, str, cur - str);
cur++;
str = cur;
continue;
} else {
xsltTransformError(NULL, style, attr->parent,
"Attribute '%s': The AVT has an unmatched '}'.\n",
attr->name);
goto error;
}
} else
cur++;
}
if ((ret != NULL) || (cur - str > 0)) {
ret = xmlStrncat(ret, str, cur - str);
str = cur;
if (avt->nb_seg == 0)
avt->strstart = 1;
if ((avt = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL)
goto error;
ret = NULL;
}
error:
if (avt == NULL) {
xsltTransformError(NULL, style, attr->parent,
"xsltCompileAttr: malloc problem\n");
} else {
if (attr->psvi != avt) { /* may have changed from realloc */
attr->psvi = avt;
/*
* This is a "hack", but I can't see any clean method of
* doing it. If a re-alloc has taken place, then the pointer
* for this AVT may have changed. style->attVTs was set by
* xsltNewAttrVT, so it needs to be re-set to the new value!
*/
style->attVTs = avt;
}
}
if (ret != NULL)
xmlFree(ret);
if (expr != NULL)
xmlFree(expr);
}
/**
* xsltEvalAVT:
* @ctxt: the XSLT transformation context
* @avt: the prevompiled attribute value template info
* @node: the node hosting the attribute
*
* Process the given AVT, and return the new string value.
*
* Returns the computed string value or NULL, must be deallocated by the
* caller.
*/
xmlChar *
xsltEvalAVT(xsltTransformContextPtr ctxt, void *avt, xmlNodePtr node) {
xmlChar *ret = NULL, *tmp;
xmlXPathCompExprPtr comp;
xsltAttrVTPtr cur = (xsltAttrVTPtr) avt;
int i;
int str;
if ((ctxt == NULL) || (avt == NULL) || (node == NULL))
return(NULL);
str = cur->strstart;
for (i = 0;i < cur->nb_seg;i++) {
if (str) {
ret = xmlStrcat(ret, (const xmlChar *) cur->segments[i]);
} else {
comp = (xmlXPathCompExprPtr) cur->segments[i];
tmp = xsltEvalXPathStringNs(ctxt, comp, cur->nsNr, cur->nsList);
if (tmp != NULL) {
if (ret != NULL) {
ret = xmlStrcat(ret, tmp);
xmlFree(tmp);
} else {
ret = tmp;
}
}
}
str = !str;
}
return(ret);
}

View File

@ -0,0 +1,436 @@
/*
* documents.c: Implementation of the documents handling
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#define IN_LIBXSLT
#include "libxslt.h"
#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/hash.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "documents.h"
#include "transform.h"
#include "imports.h"
#include "keys.h"
#include "security.h"
#ifdef LIBXML_XINCLUDE_ENABLED
#include <libxml/xinclude.h>
#endif
#define WITH_XSLT_DEBUG_DOCUMENTS
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_DOCUMENTS
#endif
/************************************************************************
* *
* Hooks for the document loader *
* *
************************************************************************/
/**
* xsltDocDefaultLoaderFunc:
* @URI: the URI of the document to load
* @dict: the dictionary to use when parsing that document
* @options: parsing options, a set of xmlParserOption
* @ctxt: the context, either a stylesheet or a transformation context
* @type: the xsltLoadType indicating the kind of loading required
*
* Default function to load document not provided by the compilation or
* transformation API themselve, for example when an xsl:import,
* xsl:include is found at compilation time or when a document()
* call is made at runtime.
*
* Returns the pointer to the document (which will be modified and
* freed by the engine later), or NULL in case of error.
*/
static xmlDocPtr
xsltDocDefaultLoaderFunc(const xmlChar * URI, xmlDictPtr dict, int options,
void *ctxt ATTRIBUTE_UNUSED,
xsltLoadType type ATTRIBUTE_UNUSED)
{
xmlParserCtxtPtr pctxt;
xmlParserInputPtr inputStream;
xmlDocPtr doc;
pctxt = xmlNewParserCtxt();
if (pctxt == NULL)
return(NULL);
if ((dict != NULL) && (pctxt->dict != NULL)) {
xmlDictFree(pctxt->dict);
pctxt->dict = NULL;
}
if (dict != NULL) {
pctxt->dict = dict;
xmlDictReference(pctxt->dict);
#ifdef WITH_XSLT_DEBUG
xsltGenericDebug(xsltGenericDebugContext,
"Reusing dictionary for document\n");
#endif
}
xmlCtxtUseOptions(pctxt, options);
inputStream = xmlLoadExternalEntity((const char *) URI, NULL, pctxt);
if (inputStream == NULL) {
xmlFreeParserCtxt(pctxt);
return(NULL);
}
inputPush(pctxt, inputStream);
if (pctxt->directory == NULL)
pctxt->directory = xmlParserGetDirectory((const char *) URI);
xmlParseDocument(pctxt);
if (pctxt->wellFormed) {
doc = pctxt->myDoc;
}
else {
doc = NULL;
xmlFreeDoc(pctxt->myDoc);
pctxt->myDoc = NULL;
}
xmlFreeParserCtxt(pctxt);
return(doc);
}
xsltDocLoaderFunc xsltDocDefaultLoader = xsltDocDefaultLoaderFunc;
/**
* xsltSetLoaderFunc:
* @f: the new function to handle document loading.
*
* Set the new function to load document, if NULL it resets it to the
* default function.
*/
void
xsltSetLoaderFunc(xsltDocLoaderFunc f) {
if (f == NULL)
xsltDocDefaultLoader = xsltDocDefaultLoaderFunc;
else
xsltDocDefaultLoader = f;
}
/************************************************************************
* *
* Module interfaces *
* *
************************************************************************/
/**
* xsltNewDocument:
* @ctxt: an XSLT transformation context (or NULL)
* @doc: a parsed XML document
*
* Register a new document, apply key computations
*
* Returns a handler to the document
*/
xsltDocumentPtr
xsltNewDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc) {
xsltDocumentPtr cur;
cur = (xsltDocumentPtr) xmlMalloc(sizeof(xsltDocument));
if (cur == NULL) {
xsltTransformError(ctxt, NULL, (xmlNodePtr) doc,
"xsltNewDocument : malloc failed\n");
return(NULL);
}
memset(cur, 0, sizeof(xsltDocument));
cur->doc = doc;
if (ctxt != NULL) {
if (! XSLT_IS_RES_TREE_FRAG(doc)) {
cur->next = ctxt->docList;
ctxt->docList = cur;
}
/*
* A key with a specific name for a specific document
* will only be computed if there's a call to the key()
* function using that specific name for that specific
* document. I.e. computation of keys will be done in
* xsltGetKey() (keys.c) on an on-demand basis.
*
* xsltInitCtxtKeys(ctxt, cur); not called here anymore
*/
}
return(cur);
}
/**
* xsltNewStyleDocument:
* @style: an XSLT style sheet
* @doc: a parsed XML document
*
* Register a new document, apply key computations
*
* Returns a handler to the document
*/
xsltDocumentPtr
xsltNewStyleDocument(xsltStylesheetPtr style, xmlDocPtr doc) {
xsltDocumentPtr cur;
cur = (xsltDocumentPtr) xmlMalloc(sizeof(xsltDocument));
if (cur == NULL) {
xsltTransformError(NULL, style, (xmlNodePtr) doc,
"xsltNewStyleDocument : malloc failed\n");
return(NULL);
}
memset(cur, 0, sizeof(xsltDocument));
cur->doc = doc;
if (style != NULL) {
cur->next = style->docList;
style->docList = cur;
}
return(cur);
}
/**
* xsltFreeStyleDocuments:
* @style: an XSLT stylesheet (representing a stylesheet-level)
*
* Frees the node-trees (and xsltDocument structures) of all
* stylesheet-modules of the stylesheet-level represented by
* the given @style.
*/
void
xsltFreeStyleDocuments(xsltStylesheetPtr style) {
xsltDocumentPtr doc, cur;
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
xsltNsMapPtr nsMap;
#endif
if (style == NULL)
return;
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
if (XSLT_HAS_INTERNAL_NSMAP(style))
nsMap = XSLT_GET_INTERNAL_NSMAP(style);
else
nsMap = NULL;
#endif
cur = style->docList;
while (cur != NULL) {
doc = cur;
cur = cur->next;
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
/*
* Restore all changed namespace URIs of ns-decls.
*/
if (nsMap)
xsltRestoreDocumentNamespaces(nsMap, doc->doc);
#endif
xsltFreeDocumentKeys(doc);
if (!doc->main)
xmlFreeDoc(doc->doc);
xmlFree(doc);
}
}
/**
* xsltFreeDocuments:
* @ctxt: an XSLT transformation context
*
* Free up all the space used by the loaded documents
*/
void
xsltFreeDocuments(xsltTransformContextPtr ctxt) {
xsltDocumentPtr doc, cur;
cur = ctxt->docList;
while (cur != NULL) {
doc = cur;
cur = cur->next;
xsltFreeDocumentKeys(doc);
if (!doc->main)
xmlFreeDoc(doc->doc);
xmlFree(doc);
}
cur = ctxt->styleList;
while (cur != NULL) {
doc = cur;
cur = cur->next;
xsltFreeDocumentKeys(doc);
if (!doc->main)
xmlFreeDoc(doc->doc);
xmlFree(doc);
}
}
/**
* xsltLoadDocument:
* @ctxt: an XSLT transformation context
* @URI: the computed URI of the document
*
* Try to load a document (not a stylesheet)
* within the XSLT transformation context
*
* Returns the new xsltDocumentPtr or NULL in case of error
*/
xsltDocumentPtr
xsltLoadDocument(xsltTransformContextPtr ctxt, const xmlChar *URI) {
xsltDocumentPtr ret;
xmlDocPtr doc;
if ((ctxt == NULL) || (URI == NULL))
return(NULL);
/*
* Security framework check
*/
if (ctxt->sec != NULL) {
int res;
res = xsltCheckRead(ctxt->sec, ctxt, URI);
if (res <= 0) {
if (res == 0)
xsltTransformError(ctxt, NULL, NULL,
"xsltLoadDocument: read rights for %s denied\n",
URI);
return(NULL);
}
}
/*
* Walk the context list to find the document if preparsed
*/
ret = ctxt->docList;
while (ret != NULL) {
if ((ret->doc != NULL) && (ret->doc->URL != NULL) &&
(xmlStrEqual(ret->doc->URL, URI)))
return(ret);
ret = ret->next;
}
doc = xsltDocDefaultLoader(URI, ctxt->dict, ctxt->parserOptions,
(void *) ctxt, XSLT_LOAD_DOCUMENT);
if (doc == NULL)
return(NULL);
if (ctxt->xinclude != 0) {
#ifdef LIBXML_XINCLUDE_ENABLED
#if LIBXML_VERSION >= 20603
xmlXIncludeProcessFlags(doc, ctxt->parserOptions);
#else
xmlXIncludeProcess(doc);
#endif
#else
xsltTransformError(ctxt, NULL, NULL,
"xsltLoadDocument(%s) : XInclude processing not compiled in\n",
URI);
#endif
}
/*
* Apply white-space stripping if asked for
*/
if (xsltNeedElemSpaceHandling(ctxt))
xsltApplyStripSpaces(ctxt, xmlDocGetRootElement(doc));
if (ctxt->debugStatus == XSLT_DEBUG_NONE)
xmlXPathOrderDocElems(doc);
ret = xsltNewDocument(ctxt, doc);
return(ret);
}
/**
* xsltLoadStyleDocument:
* @style: an XSLT style sheet
* @URI: the computed URI of the document
*
* Try to load a stylesheet document within the XSLT transformation context
*
* Returns the new xsltDocumentPtr or NULL in case of error
*/
xsltDocumentPtr
xsltLoadStyleDocument(xsltStylesheetPtr style, const xmlChar *URI) {
xsltDocumentPtr ret;
xmlDocPtr doc;
xsltSecurityPrefsPtr sec;
if ((style == NULL) || (URI == NULL))
return(NULL);
/*
* Security framework check
*/
sec = xsltGetDefaultSecurityPrefs();
if (sec != NULL) {
int res;
res = xsltCheckRead(sec, NULL, URI);
if (res <= 0) {
if (res == 0)
xsltTransformError(NULL, NULL, NULL,
"xsltLoadStyleDocument: read rights for %s denied\n",
URI);
return(NULL);
}
}
/*
* Walk the context list to find the document if preparsed
*/
ret = style->docList;
while (ret != NULL) {
if ((ret->doc != NULL) && (ret->doc->URL != NULL) &&
(xmlStrEqual(ret->doc->URL, URI)))
return(ret);
ret = ret->next;
}
doc = xsltDocDefaultLoader(URI, style->dict, XSLT_PARSE_OPTIONS,
(void *) style, XSLT_LOAD_STYLESHEET);
if (doc == NULL)
return(NULL);
ret = xsltNewStyleDocument(style, doc);
return(ret);
}
/**
* xsltFindDocument:
* @ctxt: an XSLT transformation context
* @doc: a parsed XML document
*
* Try to find a document within the XSLT transformation context.
* This will not find document infos for temporary
* Result Tree Fragments.
*
* Returns the desired xsltDocumentPtr or NULL in case of error
*/
xsltDocumentPtr
xsltFindDocument (xsltTransformContextPtr ctxt, xmlDocPtr doc) {
xsltDocumentPtr ret;
if ((ctxt == NULL) || (doc == NULL))
return(NULL);
/*
* Walk the context list to find the document
*/
ret = ctxt->docList;
while (ret != NULL) {
if (ret->doc == doc)
return(ret);
ret = ret->next;
}
if (doc == ctxt->style->doc)
return(ctxt->document);
return(NULL);
}

View File

@ -0,0 +1,93 @@
/*
* Summary: interface for the document handling
* Description: implements document loading and cache (multiple
* document() reference for the same resources must
* be equal.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_DOCUMENTS_H__
#define __XML_XSLT_DOCUMENTS_H__
#include <libxml/tree.h>
#include "xsltexports.h"
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
XSLTPUBFUN xsltDocumentPtr XSLTCALL
xsltNewDocument (xsltTransformContextPtr ctxt,
xmlDocPtr doc);
XSLTPUBFUN xsltDocumentPtr XSLTCALL
xsltLoadDocument (xsltTransformContextPtr ctxt,
const xmlChar *URI);
XSLTPUBFUN xsltDocumentPtr XSLTCALL
xsltFindDocument (xsltTransformContextPtr ctxt,
xmlDocPtr doc);
XSLTPUBFUN void XSLTCALL
xsltFreeDocuments (xsltTransformContextPtr ctxt);
XSLTPUBFUN xsltDocumentPtr XSLTCALL
xsltLoadStyleDocument (xsltStylesheetPtr style,
const xmlChar *URI);
XSLTPUBFUN xsltDocumentPtr XSLTCALL
xsltNewStyleDocument (xsltStylesheetPtr style,
xmlDocPtr doc);
XSLTPUBFUN void XSLTCALL
xsltFreeStyleDocuments (xsltStylesheetPtr style);
/*
* Hooks for document loading
*/
/**
* xsltLoadType:
*
* Enum defining the kind of loader requirement.
*/
typedef enum {
XSLT_LOAD_START = 0, /* loading for a top stylesheet */
XSLT_LOAD_STYLESHEET = 1, /* loading for a stylesheet include/import */
XSLT_LOAD_DOCUMENT = 2 /* loading document at transformation time */
} xsltLoadType;
/**
* xsltDocLoaderFunc:
* @URI: the URI of the document to load
* @dict: the dictionary to use when parsing that document
* @options: parsing options, a set of xmlParserOption
* @ctxt: the context, either a stylesheet or a transformation context
* @type: the xsltLoadType indicating the kind of loading required
*
* An xsltDocLoaderFunc is a signature for a function which can be
* registered to load document not provided by the compilation or
* transformation API themselve, for example when an xsl:import,
* xsl:include is found at compilation time or when a document()
* call is made at runtime.
*
* Returns the pointer to the document (which will be modified and
* freed by the engine later), or NULL in case of error.
*/
typedef xmlDocPtr (*xsltDocLoaderFunc) (const xmlChar *URI,
xmlDictPtr dict,
int options,
void *ctxt,
xsltLoadType type);
XSLTPUBFUN void XSLTCALL
xsltSetLoaderFunc (xsltDocLoaderFunc f);
/* the loader may be needed by extension libraries so it is exported */
XSLTPUBVAR xsltDocLoaderFunc xsltDocDefaultLoader;
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_DOCUMENTS_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,262 @@
/*
* Summary: interface for the extension support
* Description: This provide the API needed for simple and module
* extension support.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_EXTENSION_H__
#define __XML_XSLT_EXTENSION_H__
#include <libxml/xpath.h>
#include "xsltexports.h"
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Extension Modules API.
*/
/**
* xsltInitGlobals:
*
* Initialize the global variables for extensions
*
*/
XSLTPUBFUN void XSLTCALL
xsltInitGlobals (void);
/**
* xsltStyleExtInitFunction:
* @ctxt: an XSLT stylesheet
* @URI: the namespace URI for the extension
*
* A function called at initialization time of an XSLT extension module.
*
* Returns a pointer to the module specific data for this transformation.
*/
typedef void * (*xsltStyleExtInitFunction) (xsltStylesheetPtr style,
const xmlChar *URI);
/**
* xsltStyleExtShutdownFunction:
* @ctxt: an XSLT stylesheet
* @URI: the namespace URI for the extension
* @data: the data associated to this module
*
* A function called at shutdown time of an XSLT extension module.
*/
typedef void (*xsltStyleExtShutdownFunction) (xsltStylesheetPtr style,
const xmlChar *URI,
void *data);
/**
* xsltExtInitFunction:
* @ctxt: an XSLT transformation context
* @URI: the namespace URI for the extension
*
* A function called at initialization time of an XSLT extension module.
*
* Returns a pointer to the module specific data for this transformation.
*/
typedef void * (*xsltExtInitFunction) (xsltTransformContextPtr ctxt,
const xmlChar *URI);
/**
* xsltExtShutdownFunction:
* @ctxt: an XSLT transformation context
* @URI: the namespace URI for the extension
* @data: the data associated to this module
*
* A function called at shutdown time of an XSLT extension module.
*/
typedef void (*xsltExtShutdownFunction) (xsltTransformContextPtr ctxt,
const xmlChar *URI,
void *data);
XSLTPUBFUN int XSLTCALL
xsltRegisterExtModule (const xmlChar *URI,
xsltExtInitFunction initFunc,
xsltExtShutdownFunction shutdownFunc);
XSLTPUBFUN int XSLTCALL
xsltRegisterExtModuleFull
(const xmlChar * URI,
xsltExtInitFunction initFunc,
xsltExtShutdownFunction shutdownFunc,
xsltStyleExtInitFunction styleInitFunc,
xsltStyleExtShutdownFunction styleShutdownFunc);
XSLTPUBFUN int XSLTCALL
xsltUnregisterExtModule (const xmlChar * URI);
XSLTPUBFUN void * XSLTCALL
xsltGetExtData (xsltTransformContextPtr ctxt,
const xmlChar *URI);
XSLTPUBFUN void * XSLTCALL
xsltStyleGetExtData (xsltStylesheetPtr style,
const xmlChar *URI);
#ifdef XSLT_REFACTORED
XSLTPUBFUN void * XSLTCALL
xsltStyleStylesheetLevelGetExtData(
xsltStylesheetPtr style,
const xmlChar * URI);
#endif
XSLTPUBFUN void XSLTCALL
xsltShutdownCtxtExts (xsltTransformContextPtr ctxt);
XSLTPUBFUN void XSLTCALL
xsltShutdownExts (xsltStylesheetPtr style);
XSLTPUBFUN xsltTransformContextPtr XSLTCALL
xsltXPathGetTransformContext
(xmlXPathParserContextPtr ctxt);
/*
* extension functions
*/
XSLTPUBFUN int XSLTCALL
xsltRegisterExtModuleFunction
(const xmlChar *name,
const xmlChar *URI,
xmlXPathFunction function);
XSLTPUBFUN xmlXPathFunction XSLTCALL
xsltExtModuleFunctionLookup (const xmlChar *name,
const xmlChar *URI);
XSLTPUBFUN int XSLTCALL
xsltUnregisterExtModuleFunction
(const xmlChar *name,
const xmlChar *URI);
/*
* extension elements
*/
typedef xsltElemPreCompPtr (*xsltPreComputeFunction)
(xsltStylesheetPtr style,
xmlNodePtr inst,
xsltTransformFunction function);
XSLTPUBFUN xsltElemPreCompPtr XSLTCALL
xsltNewElemPreComp (xsltStylesheetPtr style,
xmlNodePtr inst,
xsltTransformFunction function);
XSLTPUBFUN void XSLTCALL
xsltInitElemPreComp (xsltElemPreCompPtr comp,
xsltStylesheetPtr style,
xmlNodePtr inst,
xsltTransformFunction function,
xsltElemPreCompDeallocator freeFunc);
XSLTPUBFUN int XSLTCALL
xsltRegisterExtModuleElement
(const xmlChar *name,
const xmlChar *URI,
xsltPreComputeFunction precomp,
xsltTransformFunction transform);
XSLTPUBFUN xsltTransformFunction XSLTCALL
xsltExtElementLookup (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *URI);
XSLTPUBFUN xsltTransformFunction XSLTCALL
xsltExtModuleElementLookup
(const xmlChar *name,
const xmlChar *URI);
XSLTPUBFUN xsltPreComputeFunction XSLTCALL
xsltExtModuleElementPreComputeLookup
(const xmlChar *name,
const xmlChar *URI);
XSLTPUBFUN int XSLTCALL
xsltUnregisterExtModuleElement
(const xmlChar *name,
const xmlChar *URI);
/*
* top-level elements
*/
typedef void (*xsltTopLevelFunction) (xsltStylesheetPtr style,
xmlNodePtr inst);
XSLTPUBFUN int XSLTCALL
xsltRegisterExtModuleTopLevel
(const xmlChar *name,
const xmlChar *URI,
xsltTopLevelFunction function);
XSLTPUBFUN xsltTopLevelFunction XSLTCALL
xsltExtModuleTopLevelLookup
(const xmlChar *name,
const xmlChar *URI);
XSLTPUBFUN int XSLTCALL
xsltUnregisterExtModuleTopLevel
(const xmlChar *name,
const xmlChar *URI);
/* These 2 functions are deprecated for use within modules. */
XSLTPUBFUN int XSLTCALL
xsltRegisterExtFunction (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *URI,
xmlXPathFunction function);
XSLTPUBFUN int XSLTCALL
xsltRegisterExtElement (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *URI,
xsltTransformFunction function);
/*
* Extension Prefix handling API.
* Those are used by the XSLT (pre)processor.
*/
XSLTPUBFUN int XSLTCALL
xsltRegisterExtPrefix (xsltStylesheetPtr style,
const xmlChar *prefix,
const xmlChar *URI);
XSLTPUBFUN int XSLTCALL
xsltCheckExtPrefix (xsltStylesheetPtr style,
const xmlChar *URI);
XSLTPUBFUN int XSLTCALL
xsltCheckExtURI (xsltStylesheetPtr style,
const xmlChar *URI);
XSLTPUBFUN int XSLTCALL
xsltInitCtxtExts (xsltTransformContextPtr ctxt);
XSLTPUBFUN void XSLTCALL
xsltFreeCtxtExts (xsltTransformContextPtr ctxt);
XSLTPUBFUN void XSLTCALL
xsltFreeExts (xsltStylesheetPtr style);
XSLTPUBFUN xsltElemPreCompPtr XSLTCALL
xsltPreComputeExtModuleElement
(xsltStylesheetPtr style,
xmlNodePtr inst);
/*
* Extension Infos access.
* Used by exslt initialisation
*/
XSLTPUBFUN xmlHashTablePtr XSLTCALL
xsltGetExtInfo (xsltStylesheetPtr style,
const xmlChar *URI);
/**
* Test module http://xmlsoft.org/XSLT/
*/
XSLTPUBFUN void XSLTCALL
xsltRegisterTestModule (void);
XSLTPUBFUN void XSLTCALL
xsltDebugDumpExtensions (FILE * output);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_EXTENSION_H__ */

199
libs/xslt/libxslt/extra.c Normal file
View File

@ -0,0 +1,199 @@
/*
* extra.c: Implementation of non-standard features
*
* Reference:
* Michael Kay "XSLT Programmer's Reference" pp 637-643
* The node-set() extension function
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#define IN_LIBXSLT
#include "libxslt.h"
#include <string.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#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"
#include "variables.h"
#include "transform.h"
#include "extra.h"
#include "preproc.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_EXTRA
#endif
/************************************************************************
* *
* Handling of XSLT debugging *
* *
************************************************************************/
/**
* xsltDebug:
* @ctxt: an XSLT processing context
* @node: The current node
* @inst: the instruction in the stylesheet
* @comp: precomputed information
*
* Process an debug node
*/
void
xsltDebug(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED,
xmlNodePtr inst ATTRIBUTE_UNUSED,
xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
{
int i, j;
xsltGenericError(xsltGenericErrorContext, "Templates:\n");
for (i = 0, j = ctxt->templNr - 1; ((i < 15) && (j >= 0)); i++, j--) {
xsltGenericError(xsltGenericErrorContext, "#%d ", i);
if (ctxt->templTab[j]->name != NULL)
xsltGenericError(xsltGenericErrorContext, "name %s ",
ctxt->templTab[j]->name);
if (ctxt->templTab[j]->match != NULL)
xsltGenericError(xsltGenericErrorContext, "name %s ",
ctxt->templTab[j]->match);
if (ctxt->templTab[j]->mode != NULL)
xsltGenericError(xsltGenericErrorContext, "name %s ",
ctxt->templTab[j]->mode);
xsltGenericError(xsltGenericErrorContext, "\n");
}
xsltGenericError(xsltGenericErrorContext, "Variables:\n");
for (i = 0, j = ctxt->varsNr - 1; ((i < 15) && (j >= 0)); i++, j--) {
xsltStackElemPtr cur;
if (ctxt->varsTab[j] == NULL)
continue;
xsltGenericError(xsltGenericErrorContext, "#%d\n", i);
cur = ctxt->varsTab[j];
while (cur != NULL) {
if (cur->comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
"corrupted !!!\n");
} else if (cur->comp->type == XSLT_FUNC_PARAM) {
xsltGenericError(xsltGenericErrorContext, "param ");
} else if (cur->comp->type == XSLT_FUNC_VARIABLE) {
xsltGenericError(xsltGenericErrorContext, "var ");
}
if (cur->name != NULL)
xsltGenericError(xsltGenericErrorContext, "%s ",
cur->name);
else
xsltGenericError(xsltGenericErrorContext, "noname !!!!");
#ifdef LIBXML_DEBUG_ENABLED
if (cur->value != NULL) {
if ((xsltGenericDebugContext == stdout) ||
(xsltGenericDebugContext == stderr))
xmlXPathDebugDumpObject((FILE*)xsltGenericDebugContext,
cur->value, 1);
} else {
xsltGenericError(xsltGenericErrorContext, "NULL !!!!");
}
#endif
xsltGenericError(xsltGenericErrorContext, "\n");
cur = cur->next;
}
}
}
/************************************************************************
* *
* Classic extensions as described by M. Kay *
* *
************************************************************************/
/**
* xsltFunctionNodeSet:
* @ctxt: the XPath Parser context
* @nargs: the number of arguments
*
* Implement the node-set() XSLT function
* node-set node-set(result-tree)
*
* This function is available in libxslt, saxon or xt namespace.
*/
void
xsltFunctionNodeSet(xmlXPathParserContextPtr ctxt, int nargs){
if (nargs != 1) {
xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
"node-set() : expects one result-tree arg\n");
ctxt->error = XPATH_INVALID_ARITY;
return;
}
if ((ctxt->value == NULL) ||
((ctxt->value->type != XPATH_XSLT_TREE) &&
(ctxt->value->type != XPATH_NODESET))) {
xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
"node-set() invalid arg expecting a result tree\n");
ctxt->error = XPATH_INVALID_TYPE;
return;
}
if (ctxt->value->type == XPATH_XSLT_TREE) {
ctxt->value->type = XPATH_NODESET;
}
}
/**
* xsltRegisterExtras:
* @ctxt: a XSLT process context
*
* Registers the built-in extensions. This function is deprecated, use
* xsltRegisterAllExtras instead.
*/
void
xsltRegisterExtras(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED) {
xsltRegisterAllExtras();
}
/**
* xsltRegisterAllExtras:
*
* Registers the built-in extensions
*/
void
xsltRegisterAllExtras (void) {
xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
XSLT_LIBXSLT_NAMESPACE,
xsltFunctionNodeSet);
xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
XSLT_SAXON_NAMESPACE,
xsltFunctionNodeSet);
xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
XSLT_XT_NAMESPACE,
xsltFunctionNodeSet);
xsltRegisterExtModuleElement((const xmlChar *) "debug",
XSLT_LIBXSLT_NAMESPACE,
NULL,
xsltDebug);
xsltRegisterExtModuleElement((const xmlChar *) "output",
XSLT_SAXON_NAMESPACE,
xsltDocumentComp,
xsltDocumentElem);
xsltRegisterExtModuleElement((const xmlChar *) "write",
XSLT_XALAN_NAMESPACE,
xsltDocumentComp,
xsltDocumentElem);
xsltRegisterExtModuleElement((const xmlChar *) "document",
XSLT_XT_NAMESPACE,
xsltDocumentComp,
xsltDocumentElem);
xsltRegisterExtModuleElement((const xmlChar *) "document",
XSLT_NAMESPACE,
xsltDocumentComp,
xsltDocumentElem);
}

72
libs/xslt/libxslt/extra.h Normal file
View File

@ -0,0 +1,72 @@
/*
* Summary: interface for the non-standard features
* Description: implement some extension outside the XSLT namespace
* but not EXSLT with is in a different library.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_EXTRA_H__
#define __XML_XSLT_EXTRA_H__
#include <libxml/xpath.h>
#include "xsltexports.h"
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* XSLT_LIBXSLT_NAMESPACE:
*
* This is the libxslt namespace for specific extensions.
*/
#define XSLT_LIBXSLT_NAMESPACE ((xmlChar *) "http://xmlsoft.org/XSLT/namespace")
/**
* XSLT_SAXON_NAMESPACE:
*
* This is Michael Kay's Saxon processor namespace for extensions.
*/
#define XSLT_SAXON_NAMESPACE ((xmlChar *) "http://icl.com/saxon")
/**
* XSLT_XT_NAMESPACE:
*
* This is James Clark's XT processor namespace for extensions.
*/
#define XSLT_XT_NAMESPACE ((xmlChar *) "http://www.jclark.com/xt")
/**
* XSLT_XALAN_NAMESPACE:
*
* This is the Apache project XALAN processor namespace for extensions.
*/
#define XSLT_XALAN_NAMESPACE ((xmlChar *) \
"org.apache.xalan.xslt.extensions.Redirect")
XSLTPUBFUN void XSLTCALL
xsltFunctionNodeSet (xmlXPathParserContextPtr ctxt,
int nargs);
XSLTPUBFUN void XSLTCALL
xsltDebug (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltRegisterExtras (xsltTransformContextPtr ctxt);
XSLTPUBFUN void XSLTCALL
xsltRegisterAllExtras (void);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_EXTRA_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
/*
* Summary: interface for the XSLT functions not from XPath
* Description: a set of extra functions coming from XSLT but not in XPath
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard and Bjorn Reese <breese@users.sourceforge.net>
*/
#ifndef __XML_XSLT_FUNCTIONS_H__
#define __XML_XSLT_FUNCTIONS_H__
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include "xsltexports.h"
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* XSLT_REGISTER_FUNCTION_LOOKUP:
*
* Registering macro, not general purpose at all but used in different modules.
*/
#define XSLT_REGISTER_FUNCTION_LOOKUP(ctxt) \
xmlXPathRegisterFuncLookup((ctxt)->xpathCtxt, \
xsltXPathFunctionLookup, \
(void *)(ctxt->xpathCtxt));
XSLTPUBFUN xmlXPathFunction XSLTCALL
xsltXPathFunctionLookup (void *vctxt,
const xmlChar *name,
const xmlChar *ns_uri);
/*
* Interfaces for the functions implementations.
*/
XSLTPUBFUN void XSLTCALL
xsltDocumentFunction (xmlXPathParserContextPtr ctxt,
int nargs);
XSLTPUBFUN void XSLTCALL
xsltKeyFunction (xmlXPathParserContextPtr ctxt,
int nargs);
XSLTPUBFUN void XSLTCALL
xsltUnparsedEntityURIFunction (xmlXPathParserContextPtr ctxt,
int nargs);
XSLTPUBFUN void XSLTCALL
xsltFormatNumberFunction (xmlXPathParserContextPtr ctxt,
int nargs);
XSLTPUBFUN void XSLTCALL
xsltGenerateIdFunction (xmlXPathParserContextPtr ctxt,
int nargs);
XSLTPUBFUN void XSLTCALL
xsltSystemPropertyFunction (xmlXPathParserContextPtr ctxt,
int nargs);
XSLTPUBFUN void XSLTCALL
xsltElementAvailableFunction (xmlXPathParserContextPtr ctxt,
int nargs);
XSLTPUBFUN void XSLTCALL
xsltFunctionAvailableFunction (xmlXPathParserContextPtr ctxt,
int nargs);
/*
* And the registration
*/
XSLTPUBFUN void XSLTCALL
xsltRegisterAllFunctions (xmlXPathContextPtr ctxt);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_FUNCTIONS_H__ */

414
libs/xslt/libxslt/imports.c Normal file
View File

@ -0,0 +1,414 @@
/*
* imports.c: Implementation of the XSLT imports
*
* Reference:
* http://www.w3.org/TR/1999/REC-xslt-19991116
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#define IN_LIBXSLT
#include "libxslt.h"
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_MATH_H
#include <math.h>
#endif
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
#ifdef HAVE_NAN_H
#include <nan.h>
#endif
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/hash.h>
#include <libxml/xmlerror.h>
#include <libxml/uri.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "preproc.h"
#include "imports.h"
#include "documents.h"
#include "security.h"
#include "pattern.h"
/************************************************************************
* *
* Module interfaces *
* *
************************************************************************/
/**
* xsltFixImportedCompSteps:
* @master: the "master" stylesheet
* @style: the stylesheet being imported by the master
*
* normalize the comp steps for the stylesheet being imported
* by the master, together with any imports within that.
*
*/
static void xsltFixImportedCompSteps(xsltStylesheetPtr master,
xsltStylesheetPtr style) {
xsltStylesheetPtr res;
xmlHashScan(style->templatesHash, xsltNormalizeCompSteps, master);
master->extrasNr += style->extrasNr;
for (res = style->imports; res != NULL; res = res->next) {
xsltFixImportedCompSteps(master, res);
}
}
/**
* xsltParseStylesheetImport:
* @style: the XSLT stylesheet
* @cur: the import element
*
* parse an XSLT stylesheet import element
*
* Returns 0 in case of success -1 in case of failure.
*/
int
xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) {
int ret = -1;
xmlDocPtr import = NULL;
xmlChar *base = NULL;
xmlChar *uriRef = NULL;
xmlChar *URI = NULL;
xsltStylesheetPtr res;
xsltSecurityPrefsPtr sec;
if ((cur == NULL) || (style == NULL))
return (ret);
uriRef = xmlGetNsProp(cur, (const xmlChar *)"href", NULL);
if (uriRef == NULL) {
xsltTransformError(NULL, style, cur,
"xsl:import : missing href attribute\n");
goto error;
}
base = xmlNodeGetBase(style->doc, cur);
URI = xmlBuildURI(uriRef, base);
if (URI == NULL) {
xsltTransformError(NULL, style, cur,
"xsl:import : invalid URI reference %s\n", uriRef);
goto error;
}
res = style;
while (res != NULL) {
if (res->doc == NULL)
break;
if (xmlStrEqual(res->doc->URL, URI)) {
xsltTransformError(NULL, style, cur,
"xsl:import : recursion detected on imported URL %s\n", URI);
goto error;
}
res = res->parent;
}
/*
* Security framework check
*/
sec = xsltGetDefaultSecurityPrefs();
if (sec != NULL) {
int secres;
secres = xsltCheckRead(sec, NULL, URI);
if (secres <= 0) {
if (secres == 0)
xsltTransformError(NULL, NULL, NULL,
"xsl:import: read rights for %s denied\n",
URI);
goto error;
}
}
import = xsltDocDefaultLoader(URI, style->dict, XSLT_PARSE_OPTIONS,
(void *) style, XSLT_LOAD_STYLESHEET);
if (import == NULL) {
xsltTransformError(NULL, style, cur,
"xsl:import : unable to load %s\n", URI);
goto error;
}
res = xsltParseStylesheetImportedDoc(import, style);
if (res != NULL) {
res->next = style->imports;
style->imports = res;
if (style->parent == NULL) {
xsltFixImportedCompSteps(style, res);
}
ret = 0;
} else {
xmlFreeDoc(import);
}
error:
if (uriRef != NULL)
xmlFree(uriRef);
if (base != NULL)
xmlFree(base);
if (URI != NULL)
xmlFree(URI);
return (ret);
}
/**
* xsltParseStylesheetInclude:
* @style: the XSLT stylesheet
* @cur: the include node
*
* parse an XSLT stylesheet include element
*
* Returns 0 in case of success -1 in case of failure
*/
int
xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) {
int ret = -1;
xmlDocPtr oldDoc;
xmlChar *base = NULL;
xmlChar *uriRef = NULL;
xmlChar *URI = NULL;
xsltStylesheetPtr result;
xsltDocumentPtr include;
xsltDocumentPtr docptr;
int oldNopreproc;
if ((cur == NULL) || (style == NULL))
return (ret);
uriRef = xmlGetNsProp(cur, (const xmlChar *)"href", NULL);
if (uriRef == NULL) {
xsltTransformError(NULL, style, cur,
"xsl:include : missing href attribute\n");
goto error;
}
base = xmlNodeGetBase(style->doc, cur);
URI = xmlBuildURI(uriRef, base);
if (URI == NULL) {
xsltTransformError(NULL, style, cur,
"xsl:include : invalid URI reference %s\n", uriRef);
goto error;
}
/*
* in order to detect recursion, we check all previously included
* stylesheets.
*/
docptr = style->includes;
while (docptr != NULL) {
if (xmlStrEqual(docptr->doc->URL, URI)) {
xsltTransformError(NULL, style, cur,
"xsl:include : recursion detected on included URL %s\n", URI);
goto error;
}
docptr = docptr->includes;
}
include = xsltLoadStyleDocument(style, URI);
if (include == NULL) {
xsltTransformError(NULL, style, cur,
"xsl:include : unable to load %s\n", URI);
goto error;
}
#ifdef XSLT_REFACTORED
if (IS_XSLT_ELEM_FAST(cur) && (cur->psvi != NULL)) {
((xsltStyleItemIncludePtr) cur->psvi)->include = include;
} else {
xsltTransformError(NULL, style, cur,
"Internal error: (xsltParseStylesheetInclude) "
"The xsl:include element was not compiled.\n", URI);
style->errors++;
}
#endif
oldDoc = style->doc;
style->doc = include->doc;
/* chain to stylesheet for recursion checking */
include->includes = style->includes;
style->includes = include;
oldNopreproc = style->nopreproc;
style->nopreproc = include->preproc;
/*
* TODO: This will change some values of the
* including stylesheet with every included module
* (e.g. excluded-result-prefixes)
* We need to strictly seperate such stylesheet-owned values.
*/
result = xsltParseStylesheetProcess(style, include->doc);
style->nopreproc = oldNopreproc;
include->preproc = 1;
style->includes = include->includes;
style->doc = oldDoc;
if (result == NULL) {
ret = -1;
goto error;
}
ret = 0;
error:
if (uriRef != NULL)
xmlFree(uriRef);
if (base != NULL)
xmlFree(base);
if (URI != NULL)
xmlFree(URI);
return (ret);
}
/**
* xsltNextImport:
* @cur: the current XSLT stylesheet
*
* Find the next stylesheet in import precedence.
*
* Returns the next stylesheet or NULL if it was the last one
*/
xsltStylesheetPtr
xsltNextImport(xsltStylesheetPtr cur) {
if (cur == NULL)
return(NULL);
if (cur->imports != NULL)
return(cur->imports);
if (cur->next != NULL)
return(cur->next) ;
do {
cur = cur->parent;
if (cur == NULL) break;
if (cur->next != NULL) return(cur->next);
} while (cur != NULL);
return(cur);
}
/**
* xsltNeedElemSpaceHandling:
* @ctxt: an XSLT transformation context
*
* Checks whether that stylesheet requires white-space stripping
*
* Returns 1 if space should be stripped, 0 if not
*/
int
xsltNeedElemSpaceHandling(xsltTransformContextPtr ctxt) {
xsltStylesheetPtr style;
if (ctxt == NULL)
return(0);
style = ctxt->style;
while (style != NULL) {
if (style->stripSpaces != NULL)
return(1);
style = xsltNextImport(style);
}
return(0);
}
/**
* xsltFindElemSpaceHandling:
* @ctxt: an XSLT transformation context
* @node: an XML node
*
* Find strip-space or preserve-space information for an element
* respect the import precedence or the wildcards
*
* Returns 1 if space should be stripped, 0 if not, and 2 if everything
* should be CDTATA wrapped.
*/
int
xsltFindElemSpaceHandling(xsltTransformContextPtr ctxt, xmlNodePtr node) {
xsltStylesheetPtr style;
const xmlChar *val;
if ((ctxt == NULL) || (node == NULL))
return(0);
style = ctxt->style;
while (style != NULL) {
if (node->ns != NULL) {
val = (const xmlChar *)
xmlHashLookup2(style->stripSpaces, node->name, node->ns->href);
if (val == NULL) {
val = (const xmlChar *)
xmlHashLookup2(style->stripSpaces, BAD_CAST "*",
node->ns->href);
}
} else {
val = (const xmlChar *)
xmlHashLookup2(style->stripSpaces, node->name, NULL);
}
if (val != NULL) {
if (xmlStrEqual(val, (xmlChar *) "strip"))
return(1);
if (xmlStrEqual(val, (xmlChar *) "preserve"))
return(0);
}
if (style->stripAll == 1)
return(1);
if (style->stripAll == -1)
return(0);
style = xsltNextImport(style);
}
return(0);
}
/**
* xsltFindTemplate:
* @ctxt: an XSLT transformation context
* @name: the template name
* @nameURI: the template name URI
*
* Finds the named template, apply import precedence rule.
* REVISIT TODO: We'll change the nameURI fields of
* templates to be in the string dict, so if the
* specified @nameURI is in the same dict, then use pointer
* comparison. Check if this can be done in a sane way.
* Maybe this function is not needed internally at
* transformation-time if we hard-wire the called templates
* to the caller.
*
* Returns the xsltTemplatePtr or NULL if not found
*/
xsltTemplatePtr
xsltFindTemplate(xsltTransformContextPtr ctxt, const xmlChar *name,
const xmlChar *nameURI) {
xsltTemplatePtr cur;
xsltStylesheetPtr style;
if ((ctxt == NULL) || (name == NULL))
return(NULL);
style = ctxt->style;
while (style != NULL) {
if (style->namedTemplates != NULL) {
cur = (xsltTemplatePtr)
xmlHashLookup2(style->namedTemplates, name, nameURI);
if (cur != NULL)
return(cur);
}
style = xsltNextImport(style);
}
return(NULL);
}

View File

@ -0,0 +1,75 @@
/*
* Summary: interface for the XSLT import support
* Description: macros and fuctions needed to implement and
* access the import tree
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_IMPORTS_H__
#define __XML_XSLT_IMPORTS_H__
#include <libxml/tree.h>
#include "xsltexports.h"
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* XSLT_GET_IMPORT_PTR:
*
* A macro to import pointers from the stylesheet cascading order.
*/
#define XSLT_GET_IMPORT_PTR(res, style, name) { \
xsltStylesheetPtr st = style; \
res = NULL; \
while (st != NULL) { \
if (st->name != NULL) { res = st->name; break; } \
st = xsltNextImport(st); \
}}
/**
* XSLT_GET_IMPORT_INT:
*
* A macro to import intergers from the stylesheet cascading order.
*/
#define XSLT_GET_IMPORT_INT(res, style, name) { \
xsltStylesheetPtr st = style; \
res = -1; \
while (st != NULL) { \
if (st->name != -1) { res = st->name; break; } \
st = xsltNextImport(st); \
}}
/*
* Module interfaces
*/
XSLTPUBFUN int XSLTCALL
xsltParseStylesheetImport(xsltStylesheetPtr style,
xmlNodePtr cur);
XSLTPUBFUN int XSLTCALL
xsltParseStylesheetInclude
(xsltStylesheetPtr style,
xmlNodePtr cur);
XSLTPUBFUN xsltStylesheetPtr XSLTCALL
xsltNextImport (xsltStylesheetPtr style);
XSLTPUBFUN int XSLTCALL
xsltNeedElemSpaceHandling(xsltTransformContextPtr ctxt);
XSLTPUBFUN int XSLTCALL
xsltFindElemSpaceHandling(xsltTransformContextPtr ctxt,
xmlNodePtr node);
XSLTPUBFUN xsltTemplatePtr XSLTCALL
xsltFindTemplate (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *nameURI);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_IMPORTS_H__ */

947
libs/xslt/libxslt/keys.c Normal file
View File

@ -0,0 +1,947 @@
/*
* keys.c: Implemetation of the keys support
*
* Reference:
* http://www.w3.org/TR/1999/REC-xslt-19991116
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#define IN_LIBXSLT
#include "libxslt.h"
#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/valid.h>
#include <libxml/hash.h>
#include <libxml/xmlerror.h>
#include <libxml/parserInternals.h>
#include <libxml/xpathInternals.h>
#include <libxml/xpath.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "imports.h"
#include "templates.h"
#include "keys.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_KEYS
#endif
static int
xsltInitDocKeyTable(xsltTransformContextPtr ctxt, const xmlChar *name,
const xmlChar *nameURI);
/************************************************************************
* *
* Type functions *
* *
************************************************************************/
/**
* xsltNewKeyDef:
* @name: the key name or NULL
* @nameURI: the name URI or NULL
*
* Create a new XSLT KeyDef
*
* Returns the newly allocated xsltKeyDefPtr or NULL in case of error
*/
static xsltKeyDefPtr
xsltNewKeyDef(const xmlChar *name, const xmlChar *nameURI) {
xsltKeyDefPtr cur;
cur = (xsltKeyDefPtr) xmlMalloc(sizeof(xsltKeyDef));
if (cur == NULL) {
xsltTransformError(NULL, NULL, NULL,
"xsltNewKeyDef : malloc failed\n");
return(NULL);
}
memset(cur, 0, sizeof(xsltKeyDef));
if (name != NULL)
cur->name = xmlStrdup(name);
if (nameURI != NULL)
cur->nameURI = xmlStrdup(nameURI);
cur->nsList = NULL;
return(cur);
}
/**
* xsltFreeKeyDef:
* @keyd: an XSLT key definition
*
* Free up the memory allocated by @keyd
*/
static void
xsltFreeKeyDef(xsltKeyDefPtr keyd) {
if (keyd == NULL)
return;
if (keyd->comp != NULL)
xmlXPathFreeCompExpr(keyd->comp);
if (keyd->usecomp != NULL)
xmlXPathFreeCompExpr(keyd->usecomp);
if (keyd->name != NULL)
xmlFree(keyd->name);
if (keyd->nameURI != NULL)
xmlFree(keyd->nameURI);
if (keyd->match != NULL)
xmlFree(keyd->match);
if (keyd->use != NULL)
xmlFree(keyd->use);
if (keyd->nsList != NULL)
xmlFree(keyd->nsList);
memset(keyd, -1, sizeof(xsltKeyDef));
xmlFree(keyd);
}
/**
* xsltFreeKeyDefList:
* @keyd: an XSLT key definition list
*
* Free up the memory allocated by all the elements of @keyd
*/
static void
xsltFreeKeyDefList(xsltKeyDefPtr keyd) {
xsltKeyDefPtr cur;
while (keyd != NULL) {
cur = keyd;
keyd = keyd->next;
xsltFreeKeyDef(cur);
}
}
/**
* xsltNewKeyTable:
* @name: the key name or NULL
* @nameURI: the name URI or NULL
*
* Create a new XSLT KeyTable
*
* Returns the newly allocated xsltKeyTablePtr or NULL in case of error
*/
static xsltKeyTablePtr
xsltNewKeyTable(const xmlChar *name, const xmlChar *nameURI) {
xsltKeyTablePtr cur;
cur = (xsltKeyTablePtr) xmlMalloc(sizeof(xsltKeyTable));
if (cur == NULL) {
xsltTransformError(NULL, NULL, NULL,
"xsltNewKeyTable : malloc failed\n");
return(NULL);
}
memset(cur, 0, sizeof(xsltKeyTable));
if (name != NULL)
cur->name = xmlStrdup(name);
if (nameURI != NULL)
cur->nameURI = xmlStrdup(nameURI);
cur->keys = xmlHashCreate(0);
return(cur);
}
static void
xsltFreeNodeSetEntry(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
xmlXPathFreeNodeSet((xmlNodeSetPtr) payload);
}
/**
* xsltFreeKeyTable:
* @keyt: an XSLT key table
*
* Free up the memory allocated by @keyt
*/
static void
xsltFreeKeyTable(xsltKeyTablePtr keyt) {
if (keyt == NULL)
return;
if (keyt->name != NULL)
xmlFree(keyt->name);
if (keyt->nameURI != NULL)
xmlFree(keyt->nameURI);
if (keyt->keys != NULL)
xmlHashFree(keyt->keys, xsltFreeNodeSetEntry);
memset(keyt, -1, sizeof(xsltKeyTable));
xmlFree(keyt);
}
/**
* xsltFreeKeyTableList:
* @keyt: an XSLT key table list
*
* Free up the memory allocated by all the elements of @keyt
*/
static void
xsltFreeKeyTableList(xsltKeyTablePtr keyt) {
xsltKeyTablePtr cur;
while (keyt != NULL) {
cur = keyt;
keyt = keyt->next;
xsltFreeKeyTable(cur);
}
}
/************************************************************************
* *
* The interpreter for the precompiled patterns *
* *
************************************************************************/
/**
* xsltFreeKeys:
* @style: an XSLT stylesheet
*
* Free up the memory used by XSLT keys in a stylesheet
*/
void
xsltFreeKeys(xsltStylesheetPtr style) {
if (style->keys)
xsltFreeKeyDefList((xsltKeyDefPtr) style->keys);
}
/**
* skipString:
* @cur: the current pointer
* @end: the current offset
*
* skip a string delimited by " or '
*
* Returns the byte after the string or -1 in case of error
*/
static int
skipString(const xmlChar *cur, int end) {
xmlChar limit;
if ((cur == NULL) || (end < 0)) return(-1);
if ((cur[end] == '\'') || (cur[end] == '"')) limit = cur[end];
else return(end);
end++;
while (cur[end] != 0) {
if (cur[end] == limit)
return(end + 1);
end++;
}
return(-1);
}
/**
* skipPredicate:
* @cur: the current pointer
* @end: the current offset
*
* skip a predicate
*
* Returns the byte after the predicate or -1 in case of error
*/
static int
skipPredicate(const xmlChar *cur, int end) {
int level = 0;
if ((cur == NULL) || (end < 0)) return(-1);
if (cur[end] != '[') return(end);
end++;
while (cur[end] != 0) {
if ((cur[end] == '\'') || (cur[end] == '"')) {
end = skipString(cur, end);
if (end <= 0)
return(-1);
continue;
} else if (cur[end] == '[') {
level += 1;
} else if (cur[end] == ']') {
if (level == 0)
return(end + 1);
level -= 1;
}
end++;
}
return(-1);
}
/**
* xsltAddKey:
* @style: an XSLT stylesheet
* @name: the key name or NULL
* @nameURI: the name URI or NULL
* @match: the match value
* @use: the use value
* @inst: the key instruction
*
* add a key definition to a stylesheet
*
* Returns 0 in case of success, and -1 in case of failure.
*/
int
xsltAddKey(xsltStylesheetPtr style, const xmlChar *name,
const xmlChar *nameURI, const xmlChar *match,
const xmlChar *use, xmlNodePtr inst) {
xsltKeyDefPtr key;
xmlChar *pattern = NULL;
int current, end, start, i = 0;
if ((style == NULL) || (name == NULL) || (match == NULL) || (use == NULL))
return(-1);
#ifdef WITH_XSLT_DEBUG_KEYS
xsltGenericDebug(xsltGenericDebugContext,
"Add key %s, match %s, use %s\n", name, match, use);
#endif
key = xsltNewKeyDef(name, nameURI);
key->match = xmlStrdup(match);
key->use = xmlStrdup(use);
key->inst = inst;
key->nsList = xmlGetNsList(inst->doc, inst);
if (key->nsList != NULL) {
while (key->nsList[i] != NULL)
i++;
}
key->nsNr = i;
/*
* Split the | and register it as as many keys
*/
current = end = 0;
while (match[current] != 0) {
start = current;
while (IS_BLANK_CH(match[current]))
current++;
end = current;
while ((match[end] != 0) && (match[end] != '|')) {
if (match[end] == '[') {
end = skipPredicate(match, end);
if (end <= 0) {
xsltTransformError(NULL, style, inst,
"xsl:key : 'match' pattern is malformed: %s",
key->match);
if (style != NULL) style->errors++;
goto error;
}
} else
end++;
}
if (current == end) {
xsltTransformError(NULL, style, inst,
"xsl:key : 'match' pattern is empty\n");
if (style != NULL) style->errors++;
goto error;
}
if (match[start] != '/') {
pattern = xmlStrcat(pattern, (xmlChar *)"//");
if (pattern == NULL) {
if (style != NULL) style->errors++;
goto error;
}
}
pattern = xmlStrncat(pattern, &match[start], end - start);
if (pattern == NULL) {
if (style != NULL) style->errors++;
goto error;
}
if (match[end] == '|') {
pattern = xmlStrcat(pattern, (xmlChar *)"|");
end++;
}
current = end;
}
if (pattern == NULL) {
xsltTransformError(NULL, style, inst,
"xsl:key : 'match' pattern is empty\n");
if (style != NULL) style->errors++;
goto error;
}
#ifdef WITH_XSLT_DEBUG_KEYS
xsltGenericDebug(xsltGenericDebugContext,
" resulting pattern %s\n", pattern);
#endif
/*
* XSLT-1: "It is an error for the value of either the use
* attribute or the match attribute to contain a
* VariableReference."
* TODO: We should report a variable-reference at compile-time.
* Maybe a search for "$", if it occurs outside of quotation
* marks, could be sufficient.
*/
#ifdef XML_XPATH_NOVAR
key->comp = xsltXPathCompileFlags(style, pattern, XML_XPATH_NOVAR);
#else
key->comp = xsltXPathCompile(style, pattern);
#endif
if (key->comp == NULL) {
xsltTransformError(NULL, style, inst,
"xsl:key : 'match' pattern compilation failed '%s'\n",
pattern);
if (style != NULL) style->errors++;
}
#ifdef XML_XPATH_NOVAR
key->usecomp = xsltXPathCompileFlags(style, use, XML_XPATH_NOVAR);
#else
key->usecomp = xsltXPathCompile(style, use);
#endif
if (key->usecomp == NULL) {
xsltTransformError(NULL, style, inst,
"xsl:key : 'use' expression compilation failed '%s'\n",
use);
if (style != NULL) style->errors++;
}
/*
* Sometimes the stylesheet writer use the order to ease the
* resolution of keys when they are dependant, keep the provided
* order so add the new one at the end.
*/
if (style->keys == NULL) {
style->keys = key;
} else {
xsltKeyDefPtr prev = style->keys;
while (prev->next != NULL)
prev = prev->next;
prev->next = key;
}
key->next = NULL;
key = NULL;
error:
if (pattern != NULL)
xmlFree(pattern);
if (key != NULL)
xsltFreeKeyDef(key);
return(0);
}
/**
* xsltGetKey:
* @ctxt: an XSLT transformation context
* @name: the key name or NULL
* @nameURI: the name URI or NULL
* @value: the key value to look for
*
* Looks up a key of the in current source doc (the document info
* on @ctxt->document). Computes the key if not already done
* for the current source doc.
*
* Returns the nodeset resulting from the query or NULL
*/
xmlNodeSetPtr
xsltGetKey(xsltTransformContextPtr ctxt, const xmlChar *name,
const xmlChar *nameURI, const xmlChar *value) {
xmlNodeSetPtr ret;
xsltKeyTablePtr table;
int init_table = 0;
if ((ctxt == NULL) || (name == NULL) || (value == NULL) ||
(ctxt->document == NULL))
return(NULL);
#ifdef WITH_XSLT_DEBUG_KEYS
xsltGenericDebug(xsltGenericDebugContext,
"Get key %s, value %s\n", name, value);
#endif
/*
* keys are computed only on-demand on first key access for a document
*/
if ((ctxt->document->nbKeysComputed < ctxt->nbKeys) &&
(ctxt->keyInitLevel == 0)) {
/*
* If non-recursive behaviour, just try to initialize all keys
*/
if (xsltInitAllDocKeys(ctxt))
return(NULL);
}
retry:
table = (xsltKeyTablePtr) ctxt->document->keys;
while (table != NULL) {
if (((nameURI != NULL) == (table->nameURI != NULL)) &&
xmlStrEqual(table->name, name) &&
xmlStrEqual(table->nameURI, nameURI))
{
ret = (xmlNodeSetPtr)xmlHashLookup(table->keys, value);
return(ret);
}
table = table->next;
}
if ((ctxt->keyInitLevel != 0) && (init_table == 0)) {
/*
* Apparently one key is recursive and this one is needed,
* initialize just it, that time and retry
*/
xsltInitDocKeyTable(ctxt, name, nameURI);
init_table = 1;
goto retry;
}
return(NULL);
}
/**
* xsltInitDocKeyTable:
*
* INTERNAL ROUTINE ONLY
*
* Check if any keys on the current document need to be computed
*/
static int
xsltInitDocKeyTable(xsltTransformContextPtr ctxt, const xmlChar *name,
const xmlChar *nameURI)
{
xsltStylesheetPtr style;
xsltKeyDefPtr keyd = NULL;
int found = 0;
#ifdef KEY_INIT_DEBUG
fprintf(stderr, "xsltInitDocKeyTable %s\n", name);
#endif
style = ctxt->style;
while (style != NULL) {
keyd = (xsltKeyDefPtr) style->keys;
while (keyd != NULL) {
if (((keyd->nameURI != NULL) ==
(nameURI != NULL)) &&
xmlStrEqual(keyd->name, name) &&
xmlStrEqual(keyd->nameURI, nameURI))
{
xsltInitCtxtKey(ctxt, ctxt->document, keyd);
if (ctxt->document->nbKeysComputed == ctxt->nbKeys)
return(0);
found = 1;
}
keyd = keyd->next;
}
style = xsltNextImport(style);
}
if (found == 0) {
#ifdef WITH_XSLT_DEBUG_KEYS
XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,xsltGenericDebug(xsltGenericDebugContext,
"xsltInitDocKeyTable: did not found %s\n", name));
#endif
xsltTransformError(ctxt, NULL, keyd? keyd->inst : NULL,
"Failed to find key definition for %s\n", name);
ctxt->state = XSLT_STATE_STOPPED;
return(-1);
}
#ifdef KEY_INIT_DEBUG
fprintf(stderr, "xsltInitDocKeyTable %s done\n", name);
#endif
return(0);
}
/**
* xsltInitAllDocKeys:
* @ctxt: transformation context
*
* INTERNAL ROUTINE ONLY
*
* Check if any keys on the current document need to be computed
*
* Returns 0 in case of success, -1 in case of failure
*/
int
xsltInitAllDocKeys(xsltTransformContextPtr ctxt)
{
xsltStylesheetPtr style;
xsltKeyDefPtr keyd;
xsltKeyTablePtr table;
if (ctxt == NULL)
return(-1);
#ifdef KEY_INIT_DEBUG
fprintf(stderr, "xsltInitAllDocKeys %d %d\n",
ctxt->document->nbKeysComputed, ctxt->nbKeys);
#endif
if (ctxt->document->nbKeysComputed == ctxt->nbKeys)
return(0);
/*
* TODO: This could be further optimized
*/
style = ctxt->style;
while (style) {
keyd = (xsltKeyDefPtr) style->keys;
while (keyd != NULL) {
#ifdef KEY_INIT_DEBUG
fprintf(stderr, "Init key %s\n", keyd->name);
#endif
/*
* Check if keys with this QName have been already
* computed.
*/
table = (xsltKeyTablePtr) ctxt->document->keys;
while (table) {
if (((keyd->nameURI != NULL) == (table->nameURI != NULL)) &&
xmlStrEqual(keyd->name, table->name) &&
xmlStrEqual(keyd->nameURI, table->nameURI))
{
break;
}
table = table->next;
}
if (table == NULL) {
/*
* Keys with this QName have not been yet computed.
*/
xsltInitDocKeyTable(ctxt, keyd->name, keyd->nameURI);
}
keyd = keyd->next;
}
style = xsltNextImport(style);
}
#ifdef KEY_INIT_DEBUG
fprintf(stderr, "xsltInitAllDocKeys: done\n");
#endif
return(0);
}
/**
* xsltInitCtxtKey:
* @ctxt: an XSLT transformation context
* @idoc: the document information (holds key values)
* @keyDef: the key definition
*
* Computes the key tables this key and for the current input document.
*
* Returns: 0 on success, -1 on error
*/
int
xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr idoc,
xsltKeyDefPtr keyDef)
{
int i, len, k;
xmlNodeSetPtr matchList = NULL, keylist;
xmlXPathObjectPtr matchRes = NULL, useRes = NULL;
xmlChar *str = NULL;
xsltKeyTablePtr table;
xmlNodePtr oldInst, cur;
xmlNodePtr oldContextNode;
xsltDocumentPtr oldDocInfo;
int oldXPPos, oldXPSize;
xmlNodePtr oldXPNode;
xmlDocPtr oldXPDoc;
int oldXPNsNr;
xmlNsPtr *oldXPNamespaces;
xmlXPathContextPtr xpctxt;
#ifdef KEY_INIT_DEBUG
fprintf(stderr, "xsltInitCtxtKey %s : %d\n", keyDef->name, ctxt->keyInitLevel);
#endif
if ((keyDef->comp == NULL) || (keyDef->usecomp == NULL))
return(-1);
/*
* Detect recursive keys
*/
if (ctxt->keyInitLevel > ctxt->nbKeys) {
#ifdef WITH_XSLT_DEBUG_KEYS
XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,
xsltGenericDebug(xsltGenericDebugContext,
"xsltInitCtxtKey: key definition of %s is recursive\n",
keyDef->name));
#endif
xsltTransformError(ctxt, NULL, keyDef->inst,
"Key definition for %s is recursive\n", keyDef->name);
ctxt->state = XSLT_STATE_STOPPED;
return(-1);
}
ctxt->keyInitLevel++;
xpctxt = ctxt->xpathCtxt;
idoc->nbKeysComputed++;
/*
* Save context state.
*/
oldInst = ctxt->inst;
oldDocInfo = ctxt->document;
oldContextNode = ctxt->node;
oldXPNode = xpctxt->node;
oldXPDoc = xpctxt->doc;
oldXPPos = xpctxt->proximityPosition;
oldXPSize = xpctxt->contextSize;
oldXPNsNr = xpctxt->nsNr;
oldXPNamespaces = xpctxt->namespaces;
/*
* Set up contexts.
*/
ctxt->document = idoc;
ctxt->node = (xmlNodePtr) idoc->doc;
ctxt->inst = keyDef->inst;
xpctxt->doc = idoc->doc;
xpctxt->node = (xmlNodePtr) idoc->doc;
/* TODO : clarify the use of namespaces in keys evaluation */
xpctxt->namespaces = keyDef->nsList;
xpctxt->nsNr = keyDef->nsNr;
/*
* Evaluate the 'match' expression of the xsl:key.
* TODO: The 'match' is a *pattern*.
*/
matchRes = xmlXPathCompiledEval(keyDef->comp, xpctxt);
if (matchRes == NULL) {
#ifdef WITH_XSLT_DEBUG_KEYS
XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,xsltGenericDebug(xsltGenericDebugContext,
"xsltInitCtxtKey: %s evaluation failed\n", keyDef->match));
#endif
xsltTransformError(ctxt, NULL, keyDef->inst,
"Failed to evaluate the 'match' expression.\n");
ctxt->state = XSLT_STATE_STOPPED;
goto error;
} else {
if (matchRes->type == XPATH_NODESET) {
matchList = matchRes->nodesetval;
#ifdef WITH_XSLT_DEBUG_KEYS
if (matchList != NULL)
XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,xsltGenericDebug(xsltGenericDebugContext,
"xsltInitCtxtKey: %s evaluates to %d nodes\n",
keyDef->match, matchList->nodeNr));
#endif
} else {
/*
* Is not a node set, but must be.
*/
#ifdef WITH_XSLT_DEBUG_KEYS
XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,xsltGenericDebug(xsltGenericDebugContext,
"xsltInitCtxtKey: %s is not a node set\n", keyDef->match));
#endif
xsltTransformError(ctxt, NULL, keyDef->inst,
"The 'match' expression did not evaluate to a node set.\n");
ctxt->state = XSLT_STATE_STOPPED;
goto error;
}
}
if ((matchList == NULL) || (matchList->nodeNr <= 0))
goto exit;
/**
* Multiple key definitions for the same name are allowed, so
* we must check if the key is already present for this doc
*/
table = (xsltKeyTablePtr) idoc->keys;
while (table != NULL) {
if (xmlStrEqual(table->name, keyDef->name) &&
(((keyDef->nameURI == NULL) && (table->nameURI == NULL)) ||
((keyDef->nameURI != NULL) && (table->nameURI != NULL) &&
(xmlStrEqual(table->nameURI, keyDef->nameURI)))))
break;
table = table->next;
}
/**
* If the key was not previously defined, create it now and
* chain it to the list of keys for the doc
*/
if (table == NULL) {
table = xsltNewKeyTable(keyDef->name, keyDef->nameURI);
if (table == NULL)
goto error;
table->next = idoc->keys;
idoc->keys = table;
}
/*
* SPEC XSLT 1.0 (XSLT 2.0 does not clarify the context size!)
* "...the use attribute of the xsl:key element is evaluated with x as
" the current node and with a node list containing just x as the
* current node list"
*/
xpctxt->contextSize = 1;
xpctxt->proximityPosition = 1;
for (i = 0; i < matchList->nodeNr; i++) {
cur = matchList->nodeTab[i];
if (! IS_XSLT_REAL_NODE(cur))
continue;
ctxt->node = cur;
xpctxt->node = cur;
/*
* Process the 'use' of the xsl:key.
* SPEC XSLT 1.0:
* "The use attribute is an expression specifying the values of
* the key; the expression is evaluated once for each node that
* matches the pattern."
*/
if (useRes != NULL)
xmlXPathFreeObject(useRes);
useRes = xmlXPathCompiledEval(keyDef->usecomp, xpctxt);
if (useRes == NULL) {
xsltTransformError(ctxt, NULL, keyDef->inst,
"Failed to evaluate the 'use' expression.\n");
ctxt->state = XSLT_STATE_STOPPED;
break;
}
if (useRes->type == XPATH_NODESET) {
if ((useRes->nodesetval != NULL) &&
(useRes->nodesetval->nodeNr != 0))
{
len = useRes->nodesetval->nodeNr;
str = xmlXPathCastNodeToString(useRes->nodesetval->nodeTab[0]);
} else {
continue;
}
} else {
len = 1;
if (useRes->type == XPATH_STRING) {
/*
* Consume the string value.
*/
str = useRes->stringval;
useRes->stringval = NULL;
} else {
str = xmlXPathCastToString(useRes);
}
}
/*
* Process all strings.
*/
k = 0;
while (1) {
if (str == NULL)
goto next_string;
#ifdef WITH_XSLT_DEBUG_KEYS
XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,xsltGenericDebug(xsltGenericDebugContext,
"xsl:key : node associated to ('%s', '%s')\n", keyDef->name, str));
#endif
keylist = xmlHashLookup(table->keys, str);
if (keylist == NULL) {
keylist = xmlXPathNodeSetCreate(cur);
if (keylist == NULL)
goto error;
xmlHashAddEntry(table->keys, str, keylist);
} else {
/*
* TODO: How do we know if this function failed?
*/
xmlXPathNodeSetAdd(keylist, cur);
}
switch (cur->type) {
case XML_ELEMENT_NODE:
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
cur->psvi = keyDef;
break;
case XML_ATTRIBUTE_NODE:
((xmlAttrPtr) cur)->psvi = keyDef;
break;
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
((xmlDocPtr) cur)->psvi = keyDef;
break;
default:
break;
}
xmlFree(str);
str = NULL;
next_string:
k++;
if (k >= len)
break;
str = xmlXPathCastNodeToString(useRes->nodesetval->nodeTab[k]);
}
}
exit:
error:
ctxt->keyInitLevel--;
/*
* Restore context state.
*/
xpctxt->node = oldXPNode;
xpctxt->doc = oldXPDoc;
xpctxt->nsNr = oldXPNsNr;
xpctxt->namespaces = oldXPNamespaces;
xpctxt->proximityPosition = oldXPPos;
xpctxt->contextSize = oldXPSize;
ctxt->node = oldContextNode;
ctxt->document = oldDocInfo;
ctxt->inst = oldInst;
if (str)
xmlFree(str);
if (useRes != NULL)
xmlXPathFreeObject(useRes);
if (matchRes != NULL)
xmlXPathFreeObject(matchRes);
return(0);
}
/**
* xsltInitCtxtKeys:
* @ctxt: an XSLT transformation context
* @idoc: a document info
*
* Computes all the keys tables for the current input document.
* Should be done before global varibales are initialized.
* NOTE: Not used anymore in the refactored code.
*/
void
xsltInitCtxtKeys(xsltTransformContextPtr ctxt, xsltDocumentPtr idoc) {
xsltStylesheetPtr style;
xsltKeyDefPtr keyDef;
if ((ctxt == NULL) || (idoc == NULL))
return;
#ifdef KEY_INIT_DEBUG
fprintf(stderr, "xsltInitCtxtKeys on document\n");
#endif
#ifdef WITH_XSLT_DEBUG_KEYS
if ((idoc->doc != NULL) && (idoc->doc->URL != NULL))
XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,xsltGenericDebug(xsltGenericDebugContext, "Initializing keys on %s\n",
idoc->doc->URL));
#endif
style = ctxt->style;
while (style != NULL) {
keyDef = (xsltKeyDefPtr) style->keys;
while (keyDef != NULL) {
xsltInitCtxtKey(ctxt, idoc, keyDef);
keyDef = keyDef->next;
}
style = xsltNextImport(style);
}
#ifdef KEY_INIT_DEBUG
fprintf(stderr, "xsltInitCtxtKeys on document: done\n");
#endif
}
/**
* xsltFreeDocumentKeys:
* @idoc: a XSLT document
*
* Free the keys associated to a document
*/
void
xsltFreeDocumentKeys(xsltDocumentPtr idoc) {
if (idoc != NULL)
xsltFreeKeyTableList(idoc->keys);
}

53
libs/xslt/libxslt/keys.h Normal file
View File

@ -0,0 +1,53 @@
/*
* Summary: interface for the key matching used in key() and template matches.
* Description: implementation of the key mechanims.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_KEY_H__
#define __XML_XSLT_KEY_H__
#include <libxml/xpath.h>
#include "xsltexports.h"
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* NODE_IS_KEYED:
*
* check for bit 15 set
*/
#define NODE_IS_KEYED (1 >> 15)
XSLTPUBFUN int XSLTCALL
xsltAddKey (xsltStylesheetPtr style,
const xmlChar *name,
const xmlChar *nameURI,
const xmlChar *match,
const xmlChar *use,
xmlNodePtr inst);
XSLTPUBFUN xmlNodeSetPtr XSLTCALL
xsltGetKey (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *nameURI,
const xmlChar *value);
XSLTPUBFUN void XSLTCALL
xsltInitCtxtKeys (xsltTransformContextPtr ctxt,
xsltDocumentPtr doc);
XSLTPUBFUN void XSLTCALL
xsltFreeKeys (xsltStylesheetPtr style);
XSLTPUBFUN void XSLTCALL
xsltFreeDocumentKeys (xsltDocumentPtr doc);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_H__ */

View File

@ -0,0 +1,36 @@
/*
* Summary: internal header only used during the compilation of libxslt
* Description: internal header only used during the compilation of libxslt
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XSLT_LIBXSLT_H__
#define __XSLT_LIBXSLT_H__
#ifdef _WIN32
#include <win32config.h>
#else
#include "config.h"
#endif
#include <libxslt/xsltconfig.h>
#include <libxml/xmlversion.h>
#if !defined LIBXSLT_PUBLIC
#if (defined (__CYGWIN__) || defined _MSC_VER) && !defined IN_LIBXSLT && !defined LIBXSLT_STATIC
#define LIBXSLT_PUBLIC __declspec(dllimport)
#else
#define LIBXSLT_PUBLIC
#endif
#endif
#ifdef _WIN32
#include <io.h>
#include <direct.h>
#define mkdir(p,m) _mkdir(p)
#endif
#endif /* ! __XSLT_LIBXSLT_H__ */

View File

@ -0,0 +1,853 @@
/*
* namespaces.c: Implementation of the XSLT namespaces handling
*
* Reference:
* http://www.w3.org/TR/1999/REC-xslt-19991116
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#define IN_LIBXSLT
#include "libxslt.h"
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_MATH_H
#include <math.h>
#endif
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
#ifdef HAVE_NAN_H
#include <nan.h>
#endif
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#ifndef XSLT_NEED_TRIO
#include <stdio.h>
#else
#include <trio.h>
#endif
#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/hash.h>
#include <libxml/xmlerror.h>
#include <libxml/uri.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "namespaces.h"
#include "imports.h"
/************************************************************************
* *
* Module interfaces *
* *
************************************************************************/
#ifdef XSLT_REFACTORED
static xsltNsAliasPtr
xsltNewNsAlias(xsltCompilerCtxtPtr cctxt)
{
xsltNsAliasPtr ret;
if (cctxt == NULL)
return(NULL);
ret = (xsltNsAliasPtr) xmlMalloc(sizeof(xsltNsAlias));
if (ret == NULL) {
xsltTransformError(NULL, cctxt->style, NULL,
"Internal error in xsltNewNsAlias(): Memory allocation failed.\n");
cctxt->style->errors++;
return(NULL);
}
memset(ret, 0, sizeof(xsltNsAlias));
/*
* TODO: Store the item at current stylesheet-level.
*/
ret->next = cctxt->nsAliases;
cctxt->nsAliases = ret;
return(ret);
}
#endif /* XSLT_REFACTORED */
/**
* xsltNamespaceAlias:
* @style: the XSLT stylesheet
* @node: the xsl:namespace-alias node
*
* Read the stylesheet-prefix and result-prefix attributes, register
* them as well as the corresponding namespace.
*/
void
xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node)
{
xmlChar *resultPrefix = NULL;
xmlChar *stylePrefix = NULL;
xmlNsPtr literalNs = NULL;
xmlNsPtr targetNs = NULL;
#ifdef XSLT_REFACTORED
xsltNsAliasPtr alias;
if ((style == NULL) || (node == NULL))
return;
/*
* SPEC XSLT 1.0:
* "If a namespace URI is declared to be an alias for multiple
* different namespace URIs, then the declaration with the highest
* import precedence is used. It is an error if there is more than
* one such declaration. An XSLT processor may signal the error;
* if it does not signal the error, it must recover by choosing,
* from amongst the declarations with the highest import precedence,
* the one that occurs last in the stylesheet."
*
* SPEC TODO: Check for the errors mentioned above.
*/
/*
* NOTE that the XSLT 2.0 also *does* use the NULL namespace if
* "#default" is used and there's no default namespace is scope.
* I.e., this is *not* an error.
* Most XSLT 1.0 implementations work this way.
* The XSLT 1.0 spec has nothing to say on the subject.
*/
/*
* Attribute "stylesheet-prefix".
*/
stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL);
if (stylePrefix == NULL) {
xsltTransformError(NULL, style, node,
"The attribute 'stylesheet-prefix' is missing.\n");
return;
}
if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default"))
literalNs = xmlSearchNs(node->doc, node, NULL);
else {
literalNs = xmlSearchNs(node->doc, node, stylePrefix);
if (literalNs == NULL) {
xsltTransformError(NULL, style, node,
"Attribute 'stylesheet-prefix': There's no namespace "
"declaration in scope for the prefix '%s'.\n",
stylePrefix);
goto error;
}
}
/*
* Attribute "result-prefix".
*/
resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL);
if (resultPrefix == NULL) {
xsltTransformError(NULL, style, node,
"The attribute 'result-prefix' is missing.\n");
goto error;
}
if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default"))
targetNs = xmlSearchNs(node->doc, node, NULL);
else {
targetNs = xmlSearchNs(node->doc, node, resultPrefix);
if (targetNs == NULL) {
xsltTransformError(NULL, style, node,
"Attribute 'result-prefix': There's no namespace "
"declaration in scope for the prefix '%s'.\n",
stylePrefix);
goto error;
}
}
/*
*
* Same alias for multiple different target namespace URIs:
* TODO: The one with the highest import precedence is used.
* Example:
* <xsl:namespace-alias stylesheet-prefix="foo"
* result-prefix="bar"/>
*
* <xsl:namespace-alias stylesheet-prefix="foo"
* result-prefix="zar"/>
*
* Same target namespace URI for multiple different aliases:
* All alias-definitions will be used.
* Example:
* <xsl:namespace-alias stylesheet-prefix="bar"
* result-prefix="foo"/>
*
* <xsl:namespace-alias stylesheet-prefix="zar"
* result-prefix="foo"/>
* Cases using #default:
* <xsl:namespace-alias stylesheet-prefix="#default"
* result-prefix="#default"/>
* TODO: Has this an effect at all?
*
* <xsl:namespace-alias stylesheet-prefix="foo"
* result-prefix="#default"/>
* From namespace to no namespace.
*
* <xsl:namespace-alias stylesheet-prefix="#default"
* result-prefix="foo"/>
* From no namespace to namespace.
*/
/*
* Store the ns-node in the alias-object.
*/
alias = xsltNewNsAlias(XSLT_CCTXT(style));
if (alias == NULL)
return;
alias->literalNs = literalNs;
alias->targetNs = targetNs;
XSLT_CCTXT(style)->hasNsAliases = 1;
#else /* XSLT_REFACTORED */
const xmlChar *literalNsName;
const xmlChar *targetNsName;
if ((style == NULL) || (node == NULL))
return;
stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL);
if (stylePrefix == NULL) {
xsltTransformError(NULL, style, node,
"namespace-alias: stylesheet-prefix attribute missing\n");
return;
}
resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL);
if (resultPrefix == NULL) {
xsltTransformError(NULL, style, node,
"namespace-alias: result-prefix attribute missing\n");
goto error;
}
if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default")) {
literalNs = xmlSearchNs(node->doc, node, NULL);
if (literalNs == NULL) {
literalNsName = NULL;
} else
literalNsName = literalNs->href; /* Yes - set for nsAlias table */
} else {
literalNs = xmlSearchNs(node->doc, node, stylePrefix);
if ((literalNs == NULL) || (literalNs->href == NULL)) {
xsltTransformError(NULL, style, node,
"namespace-alias: prefix %s not bound to any namespace\n",
stylePrefix);
goto error;
} else
literalNsName = literalNs->href;
}
/*
* When "#default" is used for result, if a default namespace has not
* been explicitly declared the special value UNDEFINED_DEFAULT_NS is
* put into the nsAliases table
*/
if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default")) {
targetNs = xmlSearchNs(node->doc, node, NULL);
if (targetNs == NULL) {
targetNsName = UNDEFINED_DEFAULT_NS;
} else
targetNsName = targetNs->href;
} else {
targetNs = xmlSearchNs(node->doc, node, resultPrefix);
if ((targetNs == NULL) || (targetNs->href == NULL)) {
xsltTransformError(NULL, style, node,
"namespace-alias: prefix %s not bound to any namespace\n",
resultPrefix);
goto error;
} else
targetNsName = targetNs->href;
}
/*
* Special case: if #default is used for
* the stylesheet-prefix (literal namespace) and there's no default
* namespace in scope, we'll use style->defaultAlias for this.
*/
if (literalNsName == NULL) {
if (targetNs != NULL) {
/*
* BUG TODO: Is it not sufficient to have only 1 field for
* this, since subsequently alias declarations will
* overwrite this.
* Example:
* <xsl:namespace-alias result-prefix="foo"
* stylesheet-prefix="#default"/>
* <xsl:namespace-alias result-prefix="bar"
* stylesheet-prefix="#default"/>
* The mapping for "foo" won't be visible anymore.
*/
style->defaultAlias = targetNs->href;
}
} else {
if (style->nsAliases == NULL)
style->nsAliases = xmlHashCreate(10);
if (style->nsAliases == NULL) {
xsltTransformError(NULL, style, node,
"namespace-alias: cannot create hash table\n");
goto error;
}
xmlHashAddEntry((xmlHashTablePtr) style->nsAliases,
literalNsName, (void *) targetNsName);
}
#endif /* else of XSLT_REFACTORED */
error:
if (stylePrefix != NULL)
xmlFree(stylePrefix);
if (resultPrefix != NULL)
xmlFree(resultPrefix);
}
/**
* xsltGetSpecialNamespace:
* @ctxt: the transformation context
* @invocNode: the invoking node; e.g. a literal result element/attr;
* only used for error reports
* @nsName: the namespace name (or NULL)
* @nsPrefix: the suggested namespace prefix (or NULL)
* @target: the result element on which to anchor a namespace
*
* Find a matching (prefix and ns-name) ns-declaration
* for the requested @nsName and @nsPrefix in the result tree.
* If none is found then a new ns-declaration will be
* added to @resultElem. If, in this case, the given prefix is
* already in use, then a ns-declaration with a modified ns-prefix
* be we created. Note that this function's priority is to
* preserve ns-prefixes; it will only change a prefix if there's
* a namespace clash.
* If both @nsName and @nsPrefix are NULL, then this will try to
* "undeclare" a default namespace by declaring an xmlns="".
*
* Returns a namespace declaration or NULL.
*/
xmlNsPtr
xsltGetSpecialNamespace(xsltTransformContextPtr ctxt, xmlNodePtr invocNode,
const xmlChar *nsName, const xmlChar *nsPrefix,
xmlNodePtr target)
{
xmlNsPtr ns;
int prefixOccupied = 0;
if ((ctxt == NULL) || (target == NULL) ||
(target->type != XML_ELEMENT_NODE))
return(NULL);
/*
* NOTE: Namespace exclusion and ns-aliasing is performed at
* compilation-time in the refactored code; so this need not be done
* here (it was in the old code).
* NOTE: @invocNode was named @cur in the old code and was documented to
* be an input node; since it was only used to anchor an error report
* somewhere, we can safely change this to @invocNode, which now
* will be the XSLT instruction (also a literal result element/attribute),
* which was responsible for this call.
*/
/*
* OPTIMIZE TODO: This all could be optimized by keeping track of
* the ns-decls currently in-scope via a specialized context.
*/
if ((nsPrefix == NULL) && ((nsName == NULL) || (nsName[0] == 0))) {
/*
* NOTE: the "undeclaration" of the default namespace was
* part of the logic of the old xsltGetSpecialNamespace() code,
* so we'll keep that mechanism.
* Related to the old code: bug #302020:
*/
/*
* OPTIMIZE TODO: This all could be optimized by keeping track of
* the ns-decls currently in-scope via a specialized context.
*/
/*
* Search on the result element itself.
*/
if (target->nsDef != NULL) {
ns = target->nsDef;
do {
if (ns->prefix == NULL) {
if ((ns->href != NULL) && (ns->href[0] != 0)) {
/*
* Raise a namespace normalization error.
*/
xsltTransformError(ctxt, NULL, invocNode,
"Namespace normalization error: Cannot undeclare "
"the default namespace, since the default namespace "
"'%s' is already declared on the result element "
"'%s'.\n", ns->href, target->name);
return(NULL);
} else {
/*
* The default namespace was undeclared on the
* result element.
*/
return(NULL);
}
break;
}
ns = ns->next;
} while (ns != NULL);
}
if ((target->parent != NULL) &&
(target->parent->type == XML_ELEMENT_NODE))
{
/*
* The parent element is in no namespace, so assume
* that there is no default namespace in scope.
*/
if (target->parent->ns == NULL)
return(NULL);
ns = xmlSearchNs(target->doc, target->parent,
NULL);
/*
* Fine if there's no default ns is scope, or if the
* default ns was undeclared.
*/
if ((ns == NULL) || (ns->href == NULL) || (ns->href[0] == 0))
return(NULL);
/*
* Undeclare the default namespace.
*/
xmlNewNs(target, BAD_CAST "", NULL);
/* TODO: Check result */
return(NULL);
}
return(NULL);
}
/*
* Handle the XML namespace.
* QUESTION: Is this faster than using xmlStrEqual() anyway?
*/
if ((nsPrefix != NULL) &&
(nsPrefix[0] == 'x') && (nsPrefix[1] == 'm') &&
(nsPrefix[2] == 'l') && (nsPrefix[3] == 0))
{
return(xmlSearchNs(target->doc, target, nsPrefix));
}
/*
* First: search on the result element itself.
*/
if (target->nsDef != NULL) {
ns = target->nsDef;
do {
if ((ns->prefix == NULL) == (nsPrefix == NULL)) {
if (ns->prefix == nsPrefix) {
if (xmlStrEqual(ns->href, nsName))
return(ns);
prefixOccupied = 1;
break;
} else if (xmlStrEqual(ns->prefix, nsPrefix)) {
if (xmlStrEqual(ns->href, nsName))
return(ns);
prefixOccupied = 1;
break;
}
}
ns = ns->next;
} while (ns != NULL);
}
if (prefixOccupied) {
/*
* If the ns-prefix is occupied by an other ns-decl on the
* result element, then this means:
* 1) The desired prefix is shadowed
* 2) There's no way around changing the prefix
*
* Try a desperate search for an in-scope ns-decl
* with a matching ns-name before we use the last option,
* which is to recreate the ns-decl with a modified prefix.
*/
ns = xmlSearchNsByHref(target->doc, target, nsName);
if (ns != NULL)
return(ns);
/*
* Fallback to changing the prefix.
*/
} else if ((target->parent != NULL) &&
(target->parent->type == XML_ELEMENT_NODE))
{
/*
* Try to find a matching ns-decl in the ancestor-axis.
*
* Check the common case: The parent element of the current
* result element is in the same namespace (with an equal ns-prefix).
*/
if ((target->parent->ns != NULL) &&
((target->parent->ns->prefix != NULL) == (nsPrefix != NULL)))
{
ns = target->parent->ns;
if (nsPrefix == NULL) {
if (xmlStrEqual(ns->href, nsName))
return(ns);
} else if (xmlStrEqual(ns->prefix, nsPrefix) &&
xmlStrEqual(ns->href, nsName))
{
return(ns);
}
}
/*
* Lookup the remaining in-scope namespaces.
*/
ns = xmlSearchNs(target->doc, target->parent, nsPrefix);
if (ns != NULL) {
if (xmlStrEqual(ns->href, nsName))
return(ns);
/*
* Now check for a nasty case: We need to ensure that the new
* ns-decl won't shadow a prefix in-use by an existing attribute.
* <foo xmlns:a="urn:test:a">
* <bar a:a="val-a">
* <xsl:attribute xmlns:a="urn:test:b" name="a:b">
* val-b</xsl:attribute>
* </bar>
* </foo>
*/
if (target->properties) {
xmlAttrPtr attr = target->properties;
do {
if ((attr->ns) &&
xmlStrEqual(attr->ns->prefix, nsPrefix))
{
/*
* Bad, this prefix is already in use.
* Since we'll change the prefix anyway, try
* a search for a matching ns-decl based on the
* namespace name.
*/
ns = xmlSearchNsByHref(target->doc, target, nsName);
if (ns != NULL)
return(ns);
goto declare_new_prefix;
}
attr = attr->next;
} while (attr != NULL);
}
} else {
/*
* Either no matching ns-prefix was found or the namespace is
* shadowed.
* Create a new ns-decl on the current result element.
*
* Hmm, we could also try to reuse an in-scope
* namespace with a matching ns-name but a different
* ns-prefix.
* What has higher priority?
* 1) If keeping the prefix: create a new ns-decl.
* 2) If reusal: first lookup ns-names; then fallback
* to creation of a new ns-decl.
* REVISIT: this currently uses case 1) although
* the old way was use xmlSearchNsByHref() and to let change
* the prefix.
*/
#if 0
ns = xmlSearchNsByHref(target->doc, target, nsName);
if (ns != NULL)
return(ns);
#endif
}
/*
* Create the ns-decl on the current result element.
*/
ns = xmlNewNs(target, nsName, nsPrefix);
/* TODO: check errors */
return(ns);
} else {
/*
* This is either the root of the tree or something weird is going on.
*/
ns = xmlNewNs(target, nsName, nsPrefix);
/* TODO: Check result */
return(ns);
}
declare_new_prefix:
/*
* Fallback: we need to generate a new prefix and declare the namespace
* on the result element.
*/
{
xmlChar pref[30];
int counter = 1;
if (nsPrefix == NULL) {
nsPrefix = BAD_CAST "ns";
}
do {
snprintf((char *) pref, 30, "%s_%d", nsPrefix, counter++);
ns = xmlSearchNs(target->doc, target, BAD_CAST pref);
if (counter > 1000) {
xsltTransformError(ctxt, NULL, invocNode,
"Internal error in xsltAcquireResultInScopeNs(): "
"Failed to compute a unique ns-prefix for the "
"generated element");
return(NULL);
}
} while (ns != NULL);
ns = xmlNewNs(target, nsName, BAD_CAST pref);
/* TODO: Check result */
return(ns);
}
return(NULL);
}
/**
* xsltGetNamespace:
* @ctxt: a transformation context
* @cur: the input node
* @ns: the namespace
* @out: the output node (or its parent)
*
* Find a matching (prefix and ns-name) ns-declaration
* for the requested @ns->prefix and @ns->href in the result tree.
* If none is found then a new ns-declaration will be
* added to @resultElem. If, in this case, the given prefix is
* already in use, then a ns-declaration with a modified ns-prefix
* be we created.
*
* Called by:
* - xsltCopyPropList() (*not* anymore)
* - xsltShallowCopyElement()
* - xsltCopyTreeInternal() (*not* anymore)
* - xsltApplySequenceConstructor() (*not* in the refactored code),
* - xsltElement() (*not* anymore)
*
* Returns a namespace declaration or NULL in case of
* namespace fixup failures or API or internal errors.
*/
xmlNsPtr
xsltGetNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns,
xmlNodePtr out)
{
if (ns == NULL)
return(NULL);
#ifdef XSLT_REFACTORED
/*
* Namespace exclusion and ns-aliasing is performed at
* compilation-time in the refactored code.
* Additionally, aliasing is not intended for non Literal
* Result Elements.
*/
return(xsltGetSpecialNamespace(ctxt, cur, ns->href, ns->prefix, out));
#else
{
xsltStylesheetPtr style;
const xmlChar *URI = NULL; /* the replacement URI */
if ((ctxt == NULL) || (cur == NULL) || (out == NULL))
return(NULL);
style = ctxt->style;
while (style != NULL) {
if (style->nsAliases != NULL)
URI = (const xmlChar *)
xmlHashLookup(style->nsAliases, ns->href);
if (URI != NULL)
break;
style = xsltNextImport(style);
}
if (URI == UNDEFINED_DEFAULT_NS) {
return(xsltGetSpecialNamespace(ctxt, cur, NULL, NULL, out));
#if 0
/*
* TODO: Removed, since wrong. If there was no default
* namespace in the stylesheet then this must resolve to
* the NULL namespace.
*/
xmlNsPtr dflt;
dflt = xmlSearchNs(cur->doc, cur, NULL);
if (dflt != NULL)
URI = dflt->href;
else
return NULL;
#endif
} else if (URI == NULL)
URI = ns->href;
return(xsltGetSpecialNamespace(ctxt, cur, URI, ns->prefix, out));
}
#endif
}
/**
* xsltGetPlainNamespace:
* @ctxt: a transformation context
* @cur: the input node
* @ns: the namespace
* @out: the result element
*
* Obsolete.
* *Not* called by any Libxslt/Libexslt function.
* Exaclty the same as xsltGetNamespace().
*
* Returns a namespace declaration or NULL in case of
* namespace fixup failures or API or internal errors.
*/
xmlNsPtr
xsltGetPlainNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur,
xmlNsPtr ns, xmlNodePtr out)
{
return(xsltGetNamespace(ctxt, cur, ns, out));
}
/**
* xsltCopyNamespaceList:
* @ctxt: a transformation context
* @node: the target node
* @cur: the first namespace
*
* Do a copy of an namespace list. If @node is non-NULL the
* new namespaces are added automatically. This handles namespaces
* aliases.
* This function is intended only for *internal* use at
* transformation-time for copying ns-declarations of Literal
* Result Elements.
*
* Called by:
* xsltCopyTreeInternal() (transform.c)
* xsltShallowCopyElem() (transform.c)
*
* REVISIT: This function won't be used in the refactored code.
*
* Returns: a new xmlNsPtr, or NULL in case of error.
*/
xmlNsPtr
xsltCopyNamespaceList(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNsPtr cur) {
xmlNsPtr ret = NULL, tmp;
xmlNsPtr p = NULL,q;
if (cur == NULL)
return(NULL);
if (cur->type != XML_NAMESPACE_DECL)
return(NULL);
/*
* One can add namespaces only on element nodes
*/
if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
node = NULL;
while (cur != NULL) {
if (cur->type != XML_NAMESPACE_DECL)
break;
/*
* Avoid duplicating namespace declarations in the tree if
* a matching declaration is in scope.
*/
if (node != NULL) {
if ((node->ns != NULL) &&
(xmlStrEqual(node->ns->prefix, cur->prefix)) &&
(xmlStrEqual(node->ns->href, cur->href))) {
cur = cur->next;
continue;
}
tmp = xmlSearchNs(node->doc, node, cur->prefix);
if ((tmp != NULL) && (xmlStrEqual(tmp->href, cur->href))) {
cur = cur->next;
continue;
}
}
#ifdef XSLT_REFACTORED
/*
* Namespace exclusion and ns-aliasing is performed at
* compilation-time in the refactored code.
*/
q = xmlNewNs(node, cur->href, cur->prefix);
if (p == NULL) {
ret = p = q;
} else {
p->next = q;
p = q;
}
#else
/*
* TODO: Remove this if the refactored code gets enabled.
*/
if (!xmlStrEqual(cur->href, XSLT_NAMESPACE)) {
const xmlChar *URI;
/* TODO apply cascading */
URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases,
cur->href);
if (URI == UNDEFINED_DEFAULT_NS) {
cur = cur->next;
continue;
}
if (URI != NULL) {
q = xmlNewNs(node, URI, cur->prefix);
} else {
q = xmlNewNs(node, cur->href, cur->prefix);
}
if (p == NULL) {
ret = p = q;
} else {
p->next = q;
p = q;
}
}
#endif
cur = cur->next;
}
return(ret);
}
/**
* xsltCopyNamespace:
* @ctxt: a transformation context
* @elem: the target element node
* @ns: the namespace node
*
* Copies a namespace node (declaration). If @elem is not NULL,
* then the new namespace will be declared on @elem.
*
* Returns: a new xmlNsPtr, or NULL in case of an error.
*/
xmlNsPtr
xsltCopyNamespace(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
xmlNodePtr elem, xmlNsPtr ns)
{
if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
return(NULL);
/*
* One can add namespaces only on element nodes
*/
if ((elem != NULL) && (elem->type != XML_ELEMENT_NODE))
return(xmlNewNs(NULL, ns->href, ns->prefix));
else
return(xmlNewNs(elem, ns->href, ns->prefix));
}
/**
* xsltFreeNamespaceAliasHashes:
* @style: an XSLT stylesheet
*
* Free up the memory used by namespaces aliases
*/
void
xsltFreeNamespaceAliasHashes(xsltStylesheetPtr style) {
if (style->nsAliases != NULL)
xmlHashFree((xmlHashTablePtr) style->nsAliases, NULL);
style->nsAliases = NULL;
}

View File

@ -0,0 +1,68 @@
/*
* Summary: interface for the XSLT namespace handling
* Description: set of function easing the processing and generation
* of namespace nodes in XSLT.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_NAMESPACES_H__
#define __XML_XSLT_NAMESPACES_H__
#include <libxml/tree.h>
#include "xsltexports.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Used within nsAliases hashtable when the default namespace is required
* but it's not been explicitly defined
*/
/**
* UNDEFINED_DEFAULT_NS:
*
* Special value for undefined namespace, internal
*/
#define UNDEFINED_DEFAULT_NS (const xmlChar *) -1L
XSLTPUBFUN void XSLTCALL
xsltNamespaceAlias (xsltStylesheetPtr style,
xmlNodePtr node);
XSLTPUBFUN xmlNsPtr XSLTCALL
xsltGetNamespace (xsltTransformContextPtr ctxt,
xmlNodePtr cur,
xmlNsPtr ns,
xmlNodePtr out);
XSLTPUBFUN xmlNsPtr XSLTCALL
xsltGetPlainNamespace (xsltTransformContextPtr ctxt,
xmlNodePtr cur,
xmlNsPtr ns,
xmlNodePtr out);
XSLTPUBFUN xmlNsPtr XSLTCALL
xsltGetSpecialNamespace (xsltTransformContextPtr ctxt,
xmlNodePtr cur,
const xmlChar *URI,
const xmlChar *prefix,
xmlNodePtr out);
XSLTPUBFUN xmlNsPtr XSLTCALL
xsltCopyNamespace (xsltTransformContextPtr ctxt,
xmlNodePtr elem,
xmlNsPtr ns);
XSLTPUBFUN xmlNsPtr XSLTCALL
xsltCopyNamespaceList (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNsPtr cur);
XSLTPUBFUN void XSLTCALL
xsltFreeNamespaceAliasHashes
(xsltStylesheetPtr style);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_NAMESPACES_H__ */

1363
libs/xslt/libxslt/numbers.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
/*
* Summary: Implementation of the XSLT number functions
* Description: Implementation of the XSLT number functions
*
* Copy: See Copyright for the status of this software.
*
* Author: Bjorn Reese <breese@users.sourceforge.net> and Daniel Veillard
*/
#ifndef __XML_XSLT_NUMBERSINTERNALS_H__
#define __XML_XSLT_NUMBERSINTERNALS_H__
#include <libxml/tree.h>
#include "xsltexports.h"
#ifdef __cplusplus
extern "C" {
#endif
struct _xsltCompMatch;
/**
* xsltNumberData:
*
* This data structure is just a wrapper to pass xsl:number data in.
*/
typedef struct _xsltNumberData xsltNumberData;
typedef xsltNumberData *xsltNumberDataPtr;
struct _xsltNumberData {
const xmlChar *level;
const xmlChar *count;
const xmlChar *from;
const xmlChar *value;
const xmlChar *format;
int has_format;
int digitsPerGroup;
int groupingCharacter;
int groupingCharacterLen;
xmlDocPtr doc;
xmlNodePtr node;
struct _xsltCompMatch *countPat;
struct _xsltCompMatch *fromPat;
/*
* accelerators
*/
};
/**
* xsltFormatNumberInfo,:
*
* This data structure lists the various parameters needed to format numbers.
*/
typedef struct _xsltFormatNumberInfo xsltFormatNumberInfo;
typedef xsltFormatNumberInfo *xsltFormatNumberInfoPtr;
struct _xsltFormatNumberInfo {
int integer_hash; /* Number of '#' in integer part */
int integer_digits; /* Number of '0' in integer part */
int frac_digits; /* Number of '0' in fractional part */
int frac_hash; /* Number of '#' in fractional part */
int group; /* Number of chars per display 'group' */
int multiplier; /* Scaling for percent or permille */
char add_decimal; /* Flag for whether decimal point appears in pattern */
char is_multiplier_set; /* Flag to catch multiple occurences of percent/permille */
char is_negative_pattern;/* Flag for processing -ve prefix/suffix */
};
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_NUMBERSINTERNALS_H__ */

2642
libs/xslt/libxslt/pattern.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,84 @@
/*
* Summary: interface for the pattern matching used in template matches.
* Description: the implementation of the lookup of the right template
* for a given node must be really fast in order to keep
* decent performances.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_PATTERN_H__
#define __XML_XSLT_PATTERN_H__
#include "xsltInternals.h"
#include "xsltexports.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* xsltCompMatch:
*
* Data structure used for the implementation of patterns.
* It is kept private (in pattern.c).
*/
typedef struct _xsltCompMatch xsltCompMatch;
typedef xsltCompMatch *xsltCompMatchPtr;
/*
* Pattern related interfaces.
*/
XSLTPUBFUN xsltCompMatchPtr XSLTCALL
xsltCompilePattern (const xmlChar *pattern,
xmlDocPtr doc,
xmlNodePtr node,
xsltStylesheetPtr style,
xsltTransformContextPtr runtime);
XSLTPUBFUN void XSLTCALL
xsltFreeCompMatchList (xsltCompMatchPtr comp);
XSLTPUBFUN int XSLTCALL
xsltTestCompMatchList (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xsltCompMatchPtr comp);
XSLTPUBFUN void XSLTCALL
xsltCompMatchClearCache (xsltTransformContextPtr ctxt,
xsltCompMatchPtr comp);
XSLTPUBFUN void XSLTCALL
xsltNormalizeCompSteps (void *payload,
void *data,
const xmlChar *name);
/*
* Template related interfaces.
*/
XSLTPUBFUN int XSLTCALL
xsltAddTemplate (xsltStylesheetPtr style,
xsltTemplatePtr cur,
const xmlChar *mode,
const xmlChar *modeURI);
XSLTPUBFUN xsltTemplatePtr XSLTCALL
xsltGetTemplate (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xsltStylesheetPtr style);
XSLTPUBFUN void XSLTCALL
xsltFreeTemplateHashes (xsltStylesheetPtr style);
XSLTPUBFUN void XSLTCALL
xsltCleanupTemplates (xsltStylesheetPtr style);
#if 0
int xsltMatchPattern (xsltTransformContextPtr ctxt,
xmlNodePtr node,
const xmlChar *pattern,
xmlDocPtr ctxtdoc,
xmlNodePtr ctxtnode);
#endif
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_PATTERN_H__ */

2376
libs/xslt/libxslt/preproc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
/*
* Summary: precomputing stylesheets
* Description: this is the compilation phase, where most of the
* stylesheet is "compiled" into faster to use data.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_PRECOMP_H__
#define __XML_XSLT_PRECOMP_H__
#include <libxml/tree.h>
#include "xsltexports.h"
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Interfaces
*/
extern const xmlChar *xsltExtMarker;
XSLTPUBFUN xsltElemPreCompPtr XSLTCALL
xsltDocumentComp (xsltStylesheetPtr style,
xmlNodePtr inst,
xsltTransformFunction function);
XSLTPUBFUN void XSLTCALL
xsltStylePreCompute (xsltStylesheetPtr style,
xmlNodePtr inst);
XSLTPUBFUN void XSLTCALL
xsltFreeStylePreComps (xsltStylesheetPtr style);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_PRECOMP_H__ */

View File

@ -0,0 +1,482 @@
/*
* security.c: Implementation of the XSLT security framework
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#define IN_LIBXSLT
#include "libxslt.h"
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_MATH_H
#include <math.h>
#endif
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
#ifdef HAVE_NAN_H
#include <nan.h>
#endif
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
#endif
#ifndef HAVE_STAT
# ifdef HAVE__STAT
/* MS C library seems to define stat and _stat. The definition
* is identical. Still, mapping them to each other causes a warning. */
# ifndef _MSC_VER
# define stat(x,y) _stat(x,y)
# endif
# define HAVE_STAT
# endif
#endif
#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/uri.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "extensions.h"
#include "security.h"
struct _xsltSecurityPrefs {
xsltSecurityCheck readFile;
xsltSecurityCheck createFile;
xsltSecurityCheck createDir;
xsltSecurityCheck readNet;
xsltSecurityCheck writeNet;
};
static xsltSecurityPrefsPtr xsltDefaultSecurityPrefs = NULL;
/************************************************************************
* *
* Module interfaces *
* *
************************************************************************/
/**
* xsltNewSecurityPrefs:
*
* Create a new security preference block
*
* Returns a pointer to the new block or NULL in case of error
*/
xsltSecurityPrefsPtr
xsltNewSecurityPrefs(void) {
xsltSecurityPrefsPtr ret;
xsltInitGlobals();
ret = (xsltSecurityPrefsPtr) xmlMalloc(sizeof(xsltSecurityPrefs));
if (ret == NULL) {
xsltTransformError(NULL, NULL, NULL,
"xsltNewSecurityPrefs : malloc failed\n");
return(NULL);
}
memset(ret, 0, sizeof(xsltSecurityPrefs));
return(ret);
}
/**
* xsltFreeSecurityPrefs:
* @sec: the security block to free
*
* Free up a security preference block
*/
void
xsltFreeSecurityPrefs(xsltSecurityPrefsPtr sec) {
if (sec == NULL)
return;
xmlFree(sec);
}
/**
* xsltSetSecurityPrefs:
* @sec: the security block to update
* @option: the option to update
* @func: the user callback to use for this option
*
* Update the security option to use the new callback checking function
*
* Returns -1 in case of error, 0 otherwise
*/
int
xsltSetSecurityPrefs(xsltSecurityPrefsPtr sec, xsltSecurityOption option,
xsltSecurityCheck func) {
xsltInitGlobals();
if (sec == NULL)
return(-1);
switch (option) {
case XSLT_SECPREF_READ_FILE:
sec->readFile = func; return(0);
case XSLT_SECPREF_WRITE_FILE:
sec->createFile = func; return(0);
case XSLT_SECPREF_CREATE_DIRECTORY:
sec->createDir = func; return(0);
case XSLT_SECPREF_READ_NETWORK:
sec->readNet = func; return(0);
case XSLT_SECPREF_WRITE_NETWORK:
sec->writeNet = func; return(0);
}
return(-1);
}
/**
* xsltGetSecurityPrefs:
* @sec: the security block to update
* @option: the option to lookup
*
* Lookup the security option to get the callback checking function
*
* Returns NULL if not found, the function otherwise
*/
xsltSecurityCheck
xsltGetSecurityPrefs(xsltSecurityPrefsPtr sec, xsltSecurityOption option) {
if (sec == NULL)
return(NULL);
switch (option) {
case XSLT_SECPREF_READ_FILE:
return(sec->readFile);
case XSLT_SECPREF_WRITE_FILE:
return(sec->createFile);
case XSLT_SECPREF_CREATE_DIRECTORY:
return(sec->createDir);
case XSLT_SECPREF_READ_NETWORK:
return(sec->readNet);
case XSLT_SECPREF_WRITE_NETWORK:
return(sec->writeNet);
}
return(NULL);
}
/**
* xsltSetDefaultSecurityPrefs:
* @sec: the security block to use
*
* Set the default security preference application-wide
*/
void
xsltSetDefaultSecurityPrefs(xsltSecurityPrefsPtr sec) {
xsltDefaultSecurityPrefs = sec;
}
/**
* xsltGetDefaultSecurityPrefs:
*
* Get the default security preference application-wide
*
* Returns the current xsltSecurityPrefsPtr in use or NULL if none
*/
xsltSecurityPrefsPtr
xsltGetDefaultSecurityPrefs(void) {
return(xsltDefaultSecurityPrefs);
}
/**
* xsltSetCtxtSecurityPrefs:
* @sec: the security block to use
* @ctxt: an XSLT transformation context
*
* Set the security preference for a specific transformation
*
* Returns -1 in case of error, 0 otherwise
*/
int
xsltSetCtxtSecurityPrefs(xsltSecurityPrefsPtr sec,
xsltTransformContextPtr ctxt) {
if (ctxt == NULL)
return(-1);
ctxt->sec = (void *) sec;
return(0);
}
/**
* xsltSecurityAllow:
* @sec: the security block to use
* @ctxt: an XSLT transformation context
* @value: unused
*
* Function used to always allow an operation
*
* Returns 1 always
*/
int
xsltSecurityAllow(xsltSecurityPrefsPtr sec ATTRIBUTE_UNUSED,
xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
const char *value ATTRIBUTE_UNUSED) {
return(1);
}
/**
* xsltSecurityForbid:
* @sec: the security block to use
* @ctxt: an XSLT transformation context
* @value: unused
*
* Function used to always forbid an operation
*
* Returns 0 always
*/
int
xsltSecurityForbid(xsltSecurityPrefsPtr sec ATTRIBUTE_UNUSED,
xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
const char *value ATTRIBUTE_UNUSED) {
return(0);
}
/************************************************************************
* *
* Internal interfaces *
* *
************************************************************************/
/**
* xsltCheckFilename
* @path: the path to check
*
* function checks to see if @path is a valid source
* (file, socket...) for XML.
*
* TODO: remove at some point !!!
* Local copy of xmlCheckFilename to avoid a hard dependency on
* a new version of libxml2
*
* if stat is not available on the target machine,
* returns 1. if stat fails, returns 0 (if calling
* stat on the filename fails, it can't be right).
* if stat succeeds and the file is a directory,
* returns 2. otherwise returns 1.
*/
static int
xsltCheckFilename (const char *path)
{
#ifdef HAVE_STAT
struct stat stat_buffer;
#if defined(_WIN32) && !defined(__CYGWIN__)
DWORD dwAttrs;
dwAttrs = GetFileAttributes(path);
if (dwAttrs != INVALID_FILE_ATTRIBUTES) {
if (dwAttrs & FILE_ATTRIBUTE_DIRECTORY) {
return 2;
}
}
#endif
if (stat(path, &stat_buffer) == -1)
return 0;
#ifdef S_ISDIR
if (S_ISDIR(stat_buffer.st_mode)) {
return 2;
}
#endif
#endif
return 1;
}
static int
xsltCheckWritePath(xsltSecurityPrefsPtr sec,
xsltTransformContextPtr ctxt,
const char *path)
{
int ret;
xsltSecurityCheck check;
char *directory;
check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_WRITE_FILE);
if (check != NULL) {
ret = check(sec, ctxt, path);
if (ret == 0) {
xsltTransformError(ctxt, NULL, NULL,
"File write for %s refused\n", path);
return(0);
}
}
directory = xmlParserGetDirectory (path);
if (directory != NULL) {
ret = xsltCheckFilename(directory);
if (ret == 0) {
/*
* The directory doesn't exist check for creation
*/
check = xsltGetSecurityPrefs(sec,
XSLT_SECPREF_CREATE_DIRECTORY);
if (check != NULL) {
ret = check(sec, ctxt, directory);
if (ret == 0) {
xsltTransformError(ctxt, NULL, NULL,
"Directory creation for %s refused\n",
path);
xmlFree(directory);
return(0);
}
}
ret = xsltCheckWritePath(sec, ctxt, directory);
if (ret == 1)
ret = mkdir(directory, 0755);
}
xmlFree(directory);
if (ret < 0)
return(ret);
}
return(1);
}
/**
* xsltCheckWrite:
* @sec: the security options
* @ctxt: an XSLT transformation context
* @URL: the resource to be written
*
* Check if the resource is allowed to be written, if necessary makes
* some preliminary work like creating directories
*
* Return 1 if write is allowed, 0 if not and -1 in case or error.
*/
int
xsltCheckWrite(xsltSecurityPrefsPtr sec,
xsltTransformContextPtr ctxt, const xmlChar *URL) {
int ret;
xmlURIPtr uri;
xsltSecurityCheck check;
uri = xmlParseURI((const char *)URL);
if (uri == NULL) {
uri = xmlCreateURI();
if (uri == NULL) {
xsltTransformError(ctxt, NULL, NULL,
"xsltCheckWrite: out of memory for %s\n", URL);
return(-1);
}
uri->path = (char *)xmlStrdup(URL);
}
if ((uri->scheme == NULL) ||
(xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {
#if defined(_WIN32) && !defined(__CYGWIN__)
if ((uri->path)&&(uri->path[0]=='/')&&
(uri->path[1]!='\0')&&(uri->path[2]==':'))
ret = xsltCheckWritePath(sec, ctxt, uri->path+1);
else
#endif
{
/*
* Check if we are allowed to write this file
*/
ret = xsltCheckWritePath(sec, ctxt, uri->path);
}
if (ret <= 0) {
xmlFreeURI(uri);
return(ret);
}
} else {
/*
* Check if we are allowed to write this network resource
*/
check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_WRITE_NETWORK);
if (check != NULL) {
ret = check(sec, ctxt, (const char *)URL);
if (ret == 0) {
xsltTransformError(ctxt, NULL, NULL,
"File write for %s refused\n", URL);
xmlFreeURI(uri);
return(0);
}
}
}
xmlFreeURI(uri);
return(1);
}
/**
* xsltCheckRead:
* @sec: the security options
* @ctxt: an XSLT transformation context
* @URL: the resource to be read
*
* Check if the resource is allowed to be read
*
* Return 1 if read is allowed, 0 if not and -1 in case or error.
*/
int
xsltCheckRead(xsltSecurityPrefsPtr sec,
xsltTransformContextPtr ctxt, const xmlChar *URL) {
int ret;
xmlURIPtr uri;
xsltSecurityCheck check;
uri = xmlParseURI((const char *)URL);
if (uri == NULL) {
xsltTransformError(ctxt, NULL, NULL,
"xsltCheckRead: URL parsing failed for %s\n",
URL);
return(-1);
}
if ((uri->scheme == NULL) ||
(xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {
/*
* Check if we are allowed to read this file
*/
check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_READ_FILE);
if (check != NULL) {
ret = check(sec, ctxt, uri->path);
if (ret == 0) {
xsltTransformError(ctxt, NULL, NULL,
"Local file read for %s refused\n", URL);
xmlFreeURI(uri);
return(0);
}
}
} else {
/*
* Check if we are allowed to write this network resource
*/
check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_READ_NETWORK);
if (check != NULL) {
ret = check(sec, ctxt, (const char *)URL);
if (ret == 0) {
xsltTransformError(ctxt, NULL, NULL,
"Network file read for %s refused\n", URL);
xmlFreeURI(uri);
return(0);
}
}
}
xmlFreeURI(uri);
return(1);
}

View File

@ -0,0 +1,104 @@
/*
* Summary: interface for the libxslt security framework
* Description: the libxslt security framework allow to restrict
* the access to new resources (file or URL) from
* the stylesheet at runtime.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_SECURITY_H__
#define __XML_XSLT_SECURITY_H__
#include <libxml/tree.h>
#include "xsltexports.h"
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* xsltSecurityPref:
*
* structure to indicate the preferences for security in the XSLT
* transformation.
*/
typedef struct _xsltSecurityPrefs xsltSecurityPrefs;
typedef xsltSecurityPrefs *xsltSecurityPrefsPtr;
/**
* xsltSecurityOption:
*
* the set of option that can be configured
*/
typedef enum {
XSLT_SECPREF_READ_FILE = 1,
XSLT_SECPREF_WRITE_FILE,
XSLT_SECPREF_CREATE_DIRECTORY,
XSLT_SECPREF_READ_NETWORK,
XSLT_SECPREF_WRITE_NETWORK
} xsltSecurityOption;
/**
* xsltSecurityCheck:
*
* User provided function to check the value of a string like a file
* path or an URL ...
*/
typedef int (*xsltSecurityCheck) (xsltSecurityPrefsPtr sec,
xsltTransformContextPtr ctxt,
const char *value);
/*
* Module interfaces
*/
XSLTPUBFUN xsltSecurityPrefsPtr XSLTCALL
xsltNewSecurityPrefs (void);
XSLTPUBFUN void XSLTCALL
xsltFreeSecurityPrefs (xsltSecurityPrefsPtr sec);
XSLTPUBFUN int XSLTCALL
xsltSetSecurityPrefs (xsltSecurityPrefsPtr sec,
xsltSecurityOption option,
xsltSecurityCheck func);
XSLTPUBFUN xsltSecurityCheck XSLTCALL
xsltGetSecurityPrefs (xsltSecurityPrefsPtr sec,
xsltSecurityOption option);
XSLTPUBFUN void XSLTCALL
xsltSetDefaultSecurityPrefs (xsltSecurityPrefsPtr sec);
XSLTPUBFUN xsltSecurityPrefsPtr XSLTCALL
xsltGetDefaultSecurityPrefs (void);
XSLTPUBFUN int XSLTCALL
xsltSetCtxtSecurityPrefs (xsltSecurityPrefsPtr sec,
xsltTransformContextPtr ctxt);
XSLTPUBFUN int XSLTCALL
xsltSecurityAllow (xsltSecurityPrefsPtr sec,
xsltTransformContextPtr ctxt,
const char *value);
XSLTPUBFUN int XSLTCALL
xsltSecurityForbid (xsltSecurityPrefsPtr sec,
xsltTransformContextPtr ctxt,
const char *value);
/*
* internal interfaces
*/
XSLTPUBFUN int XSLTCALL
xsltCheckWrite (xsltSecurityPrefsPtr sec,
xsltTransformContextPtr ctxt,
const xmlChar *URL);
XSLTPUBFUN int XSLTCALL
xsltCheckRead (xsltSecurityPrefsPtr sec,
xsltTransformContextPtr ctxt,
const xmlChar *URL);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_SECURITY_H__ */

View File

@ -0,0 +1,864 @@
/*
* templates.c: Implementation of the template processing
*
* Reference:
* http://www.w3.org/TR/1999/REC-xslt-19991116
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#define IN_LIBXSLT
#include "libxslt.h"
#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/globals.h>
#include <libxml/xmlerror.h>
#include <libxml/tree.h>
#include <libxml/dict.h>
#include <libxml/xpathInternals.h>
#include <libxml/parserInternals.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "variables.h"
#include "functions.h"
#include "templates.h"
#include "transform.h"
#include "namespaces.h"
#include "attributes.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_TEMPLATES
#endif
/************************************************************************
* *
* Module interfaces *
* *
************************************************************************/
/**
* xsltEvalXPathPredicate:
* @ctxt: the XSLT transformation context
* @comp: the XPath compiled expression
* @nsList: the namespaces in scope
* @nsNr: the number of namespaces in scope
*
* Process the expression using XPath and evaluate the result as
* an XPath predicate
*
* Returns 1 is the predicate was true, 0 otherwise
*/
int
xsltEvalXPathPredicate(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
xmlNsPtr *nsList, int nsNr) {
int ret;
xmlXPathObjectPtr res;
int oldNsNr;
xmlNsPtr *oldNamespaces;
xmlNodePtr oldInst;
int oldProximityPosition, oldContextSize;
if ((ctxt == NULL) || (ctxt->inst == NULL)) {
xsltTransformError(ctxt, NULL, NULL,
"xsltEvalXPathPredicate: No context or instruction\n");
return(0);
}
oldContextSize = ctxt->xpathCtxt->contextSize;
oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
oldNsNr = ctxt->xpathCtxt->nsNr;
oldNamespaces = ctxt->xpathCtxt->namespaces;
oldInst = ctxt->inst;
ctxt->xpathCtxt->node = ctxt->node;
ctxt->xpathCtxt->namespaces = nsList;
ctxt->xpathCtxt->nsNr = nsNr;
res = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
if (res != NULL) {
ret = xmlXPathEvalPredicate(ctxt->xpathCtxt, res);
xmlXPathFreeObject(res);
#ifdef WITH_XSLT_DEBUG_TEMPLATES
XSLT_TRACE(ctxt,XSLT_TRACE_TEMPLATES,xsltGenericDebug(xsltGenericDebugContext,
"xsltEvalXPathPredicate: returns %d\n", ret));
#endif
} else {
#ifdef WITH_XSLT_DEBUG_TEMPLATES
XSLT_TRACE(ctxt,XSLT_TRACE_TEMPLATES,xsltGenericDebug(xsltGenericDebugContext,
"xsltEvalXPathPredicate: failed\n"));
#endif
ctxt->state = XSLT_STATE_STOPPED;
ret = 0;
}
ctxt->xpathCtxt->nsNr = oldNsNr;
ctxt->xpathCtxt->namespaces = oldNamespaces;
ctxt->inst = oldInst;
ctxt->xpathCtxt->contextSize = oldContextSize;
ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
return(ret);
}
/**
* xsltEvalXPathStringNs:
* @ctxt: the XSLT transformation context
* @comp: the compiled XPath expression
* @nsNr: the number of namespaces in the list
* @nsList: the list of in-scope namespaces to use
*
* Process the expression using XPath, allowing to pass a namespace mapping
* context and get a string
*
* Returns the computed string value or NULL, must be deallocated by the
* caller.
*/
xmlChar *
xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
int nsNr, xmlNsPtr *nsList) {
xmlChar *ret = NULL;
xmlXPathObjectPtr res;
xmlNodePtr oldInst;
xmlNodePtr oldNode;
int oldPos, oldSize;
int oldNsNr;
xmlNsPtr *oldNamespaces;
if ((ctxt == NULL) || (ctxt->inst == NULL)) {
xsltTransformError(ctxt, NULL, NULL,
"xsltEvalXPathStringNs: No context or instruction\n");
return(0);
}
oldInst = ctxt->inst;
oldNode = ctxt->node;
oldPos = ctxt->xpathCtxt->proximityPosition;
oldSize = ctxt->xpathCtxt->contextSize;
oldNsNr = ctxt->xpathCtxt->nsNr;
oldNamespaces = ctxt->xpathCtxt->namespaces;
ctxt->xpathCtxt->node = ctxt->node;
/* TODO: do we need to propagate the namespaces here ? */
ctxt->xpathCtxt->namespaces = nsList;
ctxt->xpathCtxt->nsNr = nsNr;
res = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
if (res != NULL) {
if (res->type != XPATH_STRING)
res = xmlXPathConvertString(res);
if (res->type == XPATH_STRING) {
ret = res->stringval;
res->stringval = NULL;
} else {
xsltTransformError(ctxt, NULL, NULL,
"xpath : string() function didn't return a String\n");
}
xmlXPathFreeObject(res);
} else {
ctxt->state = XSLT_STATE_STOPPED;
}
#ifdef WITH_XSLT_DEBUG_TEMPLATES
XSLT_TRACE(ctxt,XSLT_TRACE_TEMPLATES,xsltGenericDebug(xsltGenericDebugContext,
"xsltEvalXPathString: returns %s\n", ret));
#endif
ctxt->inst = oldInst;
ctxt->node = oldNode;
ctxt->xpathCtxt->contextSize = oldSize;
ctxt->xpathCtxt->proximityPosition = oldPos;
ctxt->xpathCtxt->nsNr = oldNsNr;
ctxt->xpathCtxt->namespaces = oldNamespaces;
return(ret);
}
/**
* xsltEvalXPathString:
* @ctxt: the XSLT transformation context
* @comp: the compiled XPath expression
*
* Process the expression using XPath and get a string
*
* Returns the computed string value or NULL, must be deallocated by the
* caller.
*/
xmlChar *
xsltEvalXPathString(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp) {
return(xsltEvalXPathStringNs(ctxt, comp, 0, NULL));
}
/**
* xsltEvalTemplateString:
* @ctxt: the XSLT transformation context
* @contextNode: the current node in the source tree
* @inst: the XSLT instruction (xsl:comment, xsl:processing-instruction)
*
* Processes the sequence constructor of the given instruction on
* @contextNode and converts the resulting tree to a string.
* This is needed by e.g. xsl:comment and xsl:processing-instruction.
*
* Returns the computed string value or NULL; it's up to the caller to
* free the result.
*/
xmlChar *
xsltEvalTemplateString(xsltTransformContextPtr ctxt,
xmlNodePtr contextNode,
xmlNodePtr inst)
{
xmlNodePtr oldInsert, insert = NULL;
xmlChar *ret;
if ((ctxt == NULL) || (contextNode == NULL) || (inst == NULL) ||
(inst->type != XML_ELEMENT_NODE))
return(NULL);
if (inst->children == NULL)
return(NULL);
/*
* This creates a temporary element-node to add the resulting
* text content to.
* OPTIMIZE TODO: Keep such an element-node in the transformation
* context to avoid creating it every time.
*/
insert = xmlNewDocNode(ctxt->output, NULL,
(const xmlChar *)"fake", NULL);
if (insert == NULL) {
xsltTransformError(ctxt, NULL, contextNode,
"Failed to create temporary node\n");
return(NULL);
}
oldInsert = ctxt->insert;
ctxt->insert = insert;
/*
* OPTIMIZE TODO: if inst->children consists only of text-nodes.
*/
xsltApplyOneTemplate(ctxt, contextNode, inst->children, NULL, NULL);
ctxt->insert = oldInsert;
ret = xmlNodeGetContent(insert);
if (insert != NULL)
xmlFreeNode(insert);
return(ret);
}
/**
* xsltAttrTemplateValueProcessNode:
* @ctxt: the XSLT transformation context
* @str: the attribute template node value
* @inst: the instruction (or LRE) in the stylesheet holding the
* attribute with an AVT
*
* Process the given string, allowing to pass a namespace mapping
* context and return the new string value.
*
* Called by:
* - xsltAttrTemplateValueProcess() (templates.c)
* - xsltEvalAttrValueTemplate() (templates.c)
*
* QUESTION: Why is this function public? It is not used outside
* of templates.c.
*
* Returns the computed string value or NULL, must be deallocated by the
* caller.
*/
xmlChar *
xsltAttrTemplateValueProcessNode(xsltTransformContextPtr ctxt,
const xmlChar *str, xmlNodePtr inst)
{
xmlChar *ret = NULL;
const xmlChar *cur;
xmlChar *expr, *val;
xmlNsPtr *nsList = NULL;
int nsNr = 0;
if (str == NULL) return(NULL);
if (*str == 0)
return(xmlStrndup((xmlChar *)"", 0));
cur = str;
while (*cur != 0) {
if (*cur == '{') {
if (*(cur+1) == '{') { /* escaped '{' */
cur++;
ret = xmlStrncat(ret, str, cur - str);
cur++;
str = cur;
continue;
}
ret = xmlStrncat(ret, str, cur - str);
str = cur;
cur++;
while ((*cur != 0) && (*cur != '}')) {
/* Need to check for literal (bug539741) */
if ((*cur == '\'') || (*cur == '"')) {
char delim = *(cur++);
while ((*cur != 0) && (*cur != delim))
cur++;
if (*cur != 0)
cur++; /* skip the ending delimiter */
} else
cur++;
}
if (*cur == 0) {
xsltTransformError(ctxt, NULL, inst,
"xsltAttrTemplateValueProcessNode: unmatched '{'\n");
ret = xmlStrncat(ret, str, cur - str);
goto exit;
}
str++;
expr = xmlStrndup(str, cur - str);
if (expr == NULL)
goto exit;
else if (*expr == '{') {
ret = xmlStrcat(ret, expr);
xmlFree(expr);
} else {
xmlXPathCompExprPtr comp;
/*
* TODO: keep precompiled form around
*/
if ((nsList == NULL) && (inst != NULL)) {
int i = 0;
nsList = xmlGetNsList(inst->doc, inst);
if (nsList != NULL) {
while (nsList[i] != NULL)
i++;
nsNr = i;
}
}
comp = xmlXPathCtxtCompile(ctxt->xpathCtxt, expr);
val = xsltEvalXPathStringNs(ctxt, comp, nsNr, nsList);
xmlXPathFreeCompExpr(comp);
xmlFree(expr);
if (val != NULL) {
ret = xmlStrcat(ret, val);
xmlFree(val);
}
}
cur++;
str = cur;
} else if (*cur == '}') {
cur++;
if (*cur == '}') { /* escaped '}' */
ret = xmlStrncat(ret, str, cur - str);
cur++;
str = cur;
continue;
} else {
xsltTransformError(ctxt, NULL, inst,
"xsltAttrTemplateValueProcessNode: unmatched '}'\n");
}
} else
cur++;
}
if (cur != str) {
ret = xmlStrncat(ret, str, cur - str);
}
exit:
if (nsList != NULL)
xmlFree(nsList);
return(ret);
}
/**
* xsltAttrTemplateValueProcess:
* @ctxt: the XSLT transformation context
* @str: the attribute template node value
*
* Process the given node and return the new string value.
*
* Returns the computed string value or NULL, must be deallocated by the
* caller.
*/
xmlChar *
xsltAttrTemplateValueProcess(xsltTransformContextPtr ctxt, const xmlChar *str) {
return(xsltAttrTemplateValueProcessNode(ctxt, str, NULL));
}
/**
* xsltEvalAttrValueTemplate:
* @ctxt: the XSLT transformation context
* @inst: the instruction (or LRE) in the stylesheet holding the
* attribute with an AVT
* @name: the attribute QName
* @ns: the attribute namespace URI
*
* Evaluate a attribute value template, i.e. the attribute value can
* contain expressions contained in curly braces ({}) and those are
* substituted by they computed value.
*
* Returns the computed string value or NULL, must be deallocated by the
* caller.
*/
xmlChar *
xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr inst,
const xmlChar *name, const xmlChar *ns)
{
xmlChar *ret;
xmlChar *expr;
if ((ctxt == NULL) || (inst == NULL) || (name == NULL) ||
(inst->type != XML_ELEMENT_NODE))
return(NULL);
expr = xsltGetNsProp(inst, name, ns);
if (expr == NULL)
return(NULL);
/*
* TODO: though now {} is detected ahead, it would still be good to
* optimize both functions to keep the splitted value if the
* attribute content and the XPath precompiled expressions around
*/
ret = xsltAttrTemplateValueProcessNode(ctxt, expr, inst);
#ifdef WITH_XSLT_DEBUG_TEMPLATES
XSLT_TRACE(ctxt,XSLT_TRACE_TEMPLATES,xsltGenericDebug(xsltGenericDebugContext,
"xsltEvalAttrValueTemplate: %s returns %s\n", expr, ret));
#endif
if (expr != NULL)
xmlFree(expr);
return(ret);
}
/**
* xsltEvalStaticAttrValueTemplate:
* @style: the XSLT stylesheet
* @inst: the instruction (or LRE) in the stylesheet holding the
* attribute with an AVT
* @name: the attribute Name
* @ns: the attribute namespace URI
* @found: indicator whether the attribute is present
*
* Check if an attribute value template has a static value, i.e. the
* attribute value does not contain expressions contained in curly braces ({})
*
* Returns the static string value or NULL, must be deallocated by the
* caller.
*/
const xmlChar *
xsltEvalStaticAttrValueTemplate(xsltStylesheetPtr style, xmlNodePtr inst,
const xmlChar *name, const xmlChar *ns, int *found) {
const xmlChar *ret;
xmlChar *expr;
if ((style == NULL) || (inst == NULL) || (name == NULL) ||
(inst->type != XML_ELEMENT_NODE))
return(NULL);
expr = xsltGetNsProp(inst, name, ns);
if (expr == NULL) {
*found = 0;
return(NULL);
}
*found = 1;
ret = xmlStrchr(expr, '{');
if (ret != NULL) {
xmlFree(expr);
return(NULL);
}
ret = xmlDictLookup(style->dict, expr, -1);
xmlFree(expr);
return(ret);
}
/**
* xsltAttrTemplateProcess:
* @ctxt: the XSLT transformation context
* @target: the element where the attribute will be grafted
* @attr: the attribute node of a literal result element
*
* Process one attribute of a Literal Result Element (in the stylesheet).
* Evaluates Attribute Value Templates and copies the attribute over to
* the result element.
* This does *not* process attribute sets (xsl:use-attribute-set).
*
*
* Returns the generated attribute node.
*/
xmlAttrPtr
xsltAttrTemplateProcess(xsltTransformContextPtr ctxt, xmlNodePtr target,
xmlAttrPtr attr)
{
const xmlChar *value;
xmlAttrPtr ret;
if ((ctxt == NULL) || (attr == NULL) || (target == NULL) ||
(target->type != XML_ELEMENT_NODE))
return(NULL);
if (attr->type != XML_ATTRIBUTE_NODE)
return(NULL);
/*
* Skip all XSLT attributes.
*/
#ifdef XSLT_REFACTORED
if (attr->psvi == xsltXSLTAttrMarker)
return(NULL);
#else
if ((attr->ns != NULL) && xmlStrEqual(attr->ns->href, XSLT_NAMESPACE))
return(NULL);
#endif
/*
* Get the value.
*/
if (attr->children != NULL) {
if ((attr->children->type != XML_TEXT_NODE) ||
(attr->children->next != NULL))
{
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: The children of an attribute node of a "
"literal result element are not in the expected form.\n");
return(NULL);
}
value = attr->children->content;
if (value == NULL)
value = xmlDictLookup(ctxt->dict, BAD_CAST "", 0);
} else
value = xmlDictLookup(ctxt->dict, BAD_CAST "", 0);
/*
* Overwrite duplicates.
*/
ret = target->properties;
while (ret != NULL) {
if (((attr->ns != NULL) == (ret->ns != NULL)) &&
xmlStrEqual(ret->name, attr->name) &&
((attr->ns == NULL) || xmlStrEqual(ret->ns->href, attr->ns->href)))
{
break;
}
ret = ret->next;
}
if (ret != NULL) {
/* free the existing value */
xmlFreeNodeList(ret->children);
ret->children = ret->last = NULL;
/*
* Adjust ns-prefix if needed.
*/
if ((ret->ns != NULL) &&
(! xmlStrEqual(ret->ns->prefix, attr->ns->prefix)))
{
ret->ns = xsltGetNamespace(ctxt, attr->parent, attr->ns, target);
}
} else {
/* create a new attribute */
if (attr->ns != NULL)
ret = xmlNewNsProp(target,
xsltGetNamespace(ctxt, attr->parent, attr->ns, target),
attr->name, NULL);
else
ret = xmlNewNsProp(target, NULL, attr->name, NULL);
}
/*
* Set the value.
*/
if (ret != NULL) {
xmlNodePtr text;
text = xmlNewText(NULL);
if (text != NULL) {
ret->last = ret->children = text;
text->parent = (xmlNodePtr) ret;
text->doc = ret->doc;
if (attr->psvi != NULL) {
/*
* Evaluate the Attribute Value Template.
*/
xmlChar *val;
val = xsltEvalAVT(ctxt, attr->psvi, attr->parent);
if (val == NULL) {
/*
* TODO: Damn, we need an easy mechanism to report
* qualified names!
*/
if (attr->ns) {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to evaluate the AVT "
"of attribute '{%s}%s'.\n",
attr->ns->href, attr->name);
} else {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to evaluate the AVT "
"of attribute '%s'.\n",
attr->name);
}
text->content = xmlStrdup(BAD_CAST "");
} else {
text->content = val;
}
} else if ((ctxt->internalized) && (target != NULL) &&
(target->doc != NULL) &&
(target->doc->dict == ctxt->dict) &&
xmlDictOwns(ctxt->dict, value)) {
text->content = (xmlChar *) value;
} else {
text->content = xmlStrdup(value);
}
}
} else {
if (attr->ns) {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to create attribute '{%s}%s'.\n",
attr->ns->href, attr->name);
} else {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to create attribute '%s'.\n",
attr->name);
}
}
return(ret);
}
/**
* xsltAttrListTemplateProcess:
* @ctxt: the XSLT transformation context
* @target: the element where the attributes will be grafted
* @attrs: the first attribute
*
* Processes all attributes of a Literal Result Element.
* Attribute references are applied via xsl:use-attribute-set
* attributes.
* Copies all non XSLT-attributes over to the @target element
* and evaluates Attribute Value Templates.
*
* Called by xsltApplySequenceConstructor() (transform.c).
*
* Returns a new list of attribute nodes, or NULL in case of error.
* (Don't assign the result to @target->properties; if
* the result is NULL, you'll get memory leaks, since the
* attributes will be disattached.)
*/
xmlAttrPtr
xsltAttrListTemplateProcess(xsltTransformContextPtr ctxt,
xmlNodePtr target, xmlAttrPtr attrs)
{
xmlAttrPtr attr, copy, last = NULL;
xmlNodePtr oldInsert, text;
xmlNsPtr origNs = NULL, copyNs = NULL;
const xmlChar *value;
xmlChar *valueAVT;
int hasAttr = 0;
if ((ctxt == NULL) || (target == NULL) || (attrs == NULL) ||
(target->type != XML_ELEMENT_NODE))
return(NULL);
oldInsert = ctxt->insert;
ctxt->insert = target;
/*
* Apply attribute-sets.
*/
attr = attrs;
do {
#ifdef XSLT_REFACTORED
if ((attr->psvi == xsltXSLTAttrMarker) &&
xmlStrEqual(attr->name, (const xmlChar *)"use-attribute-sets"))
{
xsltApplyAttributeSet(ctxt, ctxt->node, (xmlNodePtr) attr, NULL);
}
#else
if ((attr->ns != NULL) &&
xmlStrEqual(attr->name, (const xmlChar *)"use-attribute-sets") &&
xmlStrEqual(attr->ns->href, XSLT_NAMESPACE))
{
xsltApplyAttributeSet(ctxt, ctxt->node, (xmlNodePtr) attr, NULL);
}
#endif
attr = attr->next;
} while (attr != NULL);
if (target->properties != NULL) {
hasAttr = 1;
}
/*
* Instantiate LRE-attributes.
*/
attr = attrs;
do {
/*
* Skip XSLT attributes.
*/
#ifdef XSLT_REFACTORED
if (attr->psvi == xsltXSLTAttrMarker) {
goto next_attribute;
}
#else
if ((attr->ns != NULL) &&
xmlStrEqual(attr->ns->href, XSLT_NAMESPACE))
{
goto next_attribute;
}
#endif
/*
* Get the value.
*/
if (attr->children != NULL) {
if ((attr->children->type != XML_TEXT_NODE) ||
(attr->children->next != NULL))
{
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: The children of an attribute node of a "
"literal result element are not in the expected form.\n");
goto error;
}
value = attr->children->content;
if (value == NULL)
value = xmlDictLookup(ctxt->dict, BAD_CAST "", 0);
} else
value = xmlDictLookup(ctxt->dict, BAD_CAST "", 0);
/*
* Get the namespace. Avoid lookups of same namespaces.
*/
if (attr->ns != origNs) {
origNs = attr->ns;
if (attr->ns != NULL) {
#ifdef XSLT_REFACTORED
copyNs = xsltGetSpecialNamespace(ctxt, attr->parent,
attr->ns->href, attr->ns->prefix, target);
#else
copyNs = xsltGetNamespace(ctxt, attr->parent,
attr->ns, target);
#endif
if (copyNs == NULL)
goto error;
} else
copyNs = NULL;
}
/*
* Create a new attribute.
*/
if (hasAttr) {
copy = xmlSetNsProp(target, copyNs, attr->name, NULL);
} else {
/*
* Avoid checking for duplicate attributes if there aren't
* any attribute sets.
*/
copy = xmlNewDocProp(target->doc, attr->name, NULL);
if (copy != NULL) {
copy->ns = copyNs;
/*
* Attach it to the target element.
*/
copy->parent = target;
if (last == NULL) {
target->properties = copy;
last = copy;
} else {
last->next = copy;
copy->prev = last;
last = copy;
}
}
}
if (copy == NULL) {
if (attr->ns) {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to create attribute '{%s}%s'.\n",
attr->ns->href, attr->name);
} else {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to create attribute '%s'.\n",
attr->name);
}
goto error;
}
/*
* Set the value.
*/
text = xmlNewText(NULL);
if (text != NULL) {
copy->last = copy->children = text;
text->parent = (xmlNodePtr) copy;
text->doc = copy->doc;
if (attr->psvi != NULL) {
/*
* Evaluate the Attribute Value Template.
*/
valueAVT = xsltEvalAVT(ctxt, attr->psvi, attr->parent);
if (valueAVT == NULL) {
/*
* TODO: Damn, we need an easy mechanism to report
* qualified names!
*/
if (attr->ns) {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to evaluate the AVT "
"of attribute '{%s}%s'.\n",
attr->ns->href, attr->name);
} else {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to evaluate the AVT "
"of attribute '%s'.\n",
attr->name);
}
text->content = xmlStrdup(BAD_CAST "");
goto error;
} else {
text->content = valueAVT;
}
} else if ((ctxt->internalized) &&
(target->doc != NULL) &&
(target->doc->dict == ctxt->dict) &&
xmlDictOwns(ctxt->dict, value))
{
text->content = (xmlChar *) value;
} else {
text->content = xmlStrdup(value);
}
if ((copy != NULL) && (text != NULL) &&
(xmlIsID(copy->doc, copy->parent, copy)))
xmlAddID(NULL, copy->doc, text->content, copy);
}
next_attribute:
attr = attr->next;
} while (attr != NULL);
ctxt->insert = oldInsert;
return(target->properties);
error:
ctxt->insert = oldInsert;
return(NULL);
}
/**
* xsltTemplateProcess:
* @ctxt: the XSLT transformation context
* @node: the attribute template node
*
* Obsolete. Don't use it.
*
* Returns NULL.
*/
xmlNodePtr *
xsltTemplateProcess(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED, xmlNodePtr node) {
if (node == NULL)
return(NULL);
return(0);
}

View File

@ -0,0 +1,77 @@
/*
* Summary: interface for the template processing
* Description: This set of routine encapsulates XPath calls
* and Attribute Value Templates evaluation.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_TEMPLATES_H__
#define __XML_XSLT_TEMPLATES_H__
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include "xsltexports.h"
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
XSLTPUBFUN int XSLTCALL
xsltEvalXPathPredicate (xsltTransformContextPtr ctxt,
xmlXPathCompExprPtr comp,
xmlNsPtr *nsList,
int nsNr);
XSLTPUBFUN xmlChar * XSLTCALL
xsltEvalTemplateString (xsltTransformContextPtr ctxt,
xmlNodePtr contextNode,
xmlNodePtr inst);
XSLTPUBFUN xmlChar * XSLTCALL
xsltEvalAttrValueTemplate (xsltTransformContextPtr ctxt,
xmlNodePtr node,
const xmlChar *name,
const xmlChar *ns);
XSLTPUBFUN const xmlChar * XSLTCALL
xsltEvalStaticAttrValueTemplate (xsltStylesheetPtr style,
xmlNodePtr node,
const xmlChar *name,
const xmlChar *ns,
int *found);
/* TODO: this is obviously broken ... the namespaces should be passed too ! */
XSLTPUBFUN xmlChar * XSLTCALL
xsltEvalXPathString (xsltTransformContextPtr ctxt,
xmlXPathCompExprPtr comp);
XSLTPUBFUN xmlChar * XSLTCALL
xsltEvalXPathStringNs (xsltTransformContextPtr ctxt,
xmlXPathCompExprPtr comp,
int nsNr,
xmlNsPtr *nsList);
XSLTPUBFUN xmlNodePtr * XSLTCALL
xsltTemplateProcess (xsltTransformContextPtr ctxt,
xmlNodePtr node);
XSLTPUBFUN xmlAttrPtr XSLTCALL
xsltAttrListTemplateProcess (xsltTransformContextPtr ctxt,
xmlNodePtr target,
xmlAttrPtr cur);
XSLTPUBFUN xmlAttrPtr XSLTCALL
xsltAttrTemplateProcess (xsltTransformContextPtr ctxt,
xmlNodePtr target,
xmlAttrPtr attr);
XSLTPUBFUN xmlChar * XSLTCALL
xsltAttrTemplateValueProcess (xsltTransformContextPtr ctxt,
const xmlChar* attr);
XSLTPUBFUN xmlChar * XSLTCALL
xsltAttrTemplateValueProcessNode(xsltTransformContextPtr ctxt,
const xmlChar* str,
xmlNodePtr node);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_TEMPLATES_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,207 @@
/*
* Summary: the XSLT engine transformation part.
* Description: This module implements the bulk of the actual
* transformation processing. Most of the xsl: element
* constructs are implemented in this module.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_TRANSFORM_H__
#define __XML_XSLT_TRANSFORM_H__
#include <libxml/parser.h>
#include <libxml/xmlIO.h>
#include "xsltexports.h"
#include <libxslt/xsltInternals.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* XInclude default processing.
*/
XSLTPUBFUN void XSLTCALL
xsltSetXIncludeDefault (int xinclude);
XSLTPUBFUN int XSLTCALL
xsltGetXIncludeDefault (void);
/**
* Export context to users.
*/
XSLTPUBFUN xsltTransformContextPtr XSLTCALL
xsltNewTransformContext (xsltStylesheetPtr style,
xmlDocPtr doc);
XSLTPUBFUN void XSLTCALL
xsltFreeTransformContext(xsltTransformContextPtr ctxt);
XSLTPUBFUN xmlDocPtr XSLTCALL
xsltApplyStylesheetUser (xsltStylesheetPtr style,
xmlDocPtr doc,
const char **params,
const char *output,
FILE * profile,
xsltTransformContextPtr userCtxt);
XSLTPUBFUN void XSLTCALL
xsltProcessOneNode (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xsltStackElemPtr params);
/**
* Private Interfaces.
*/
XSLTPUBFUN void XSLTCALL
xsltApplyStripSpaces (xsltTransformContextPtr ctxt,
xmlNodePtr node);
XSLTPUBFUN xmlDocPtr XSLTCALL
xsltApplyStylesheet (xsltStylesheetPtr style,
xmlDocPtr doc,
const char **params);
XSLTPUBFUN xmlDocPtr XSLTCALL
xsltProfileStylesheet (xsltStylesheetPtr style,
xmlDocPtr doc,
const char **params,
FILE * output);
XSLTPUBFUN int XSLTCALL
xsltRunStylesheet (xsltStylesheetPtr style,
xmlDocPtr doc,
const char **params,
const char *output,
xmlSAXHandlerPtr SAX,
xmlOutputBufferPtr IObuf);
XSLTPUBFUN int XSLTCALL
xsltRunStylesheetUser (xsltStylesheetPtr style,
xmlDocPtr doc,
const char **params,
const char *output,
xmlSAXHandlerPtr SAX,
xmlOutputBufferPtr IObuf,
FILE * profile,
xsltTransformContextPtr userCtxt);
XSLTPUBFUN void XSLTCALL
xsltApplyOneTemplate (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr list,
xsltTemplatePtr templ,
xsltStackElemPtr params);
XSLTPUBFUN void XSLTCALL
xsltDocumentElem (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltSort (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltCopy (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltText (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltElement (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltComment (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltAttribute (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltProcessingInstruction(xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltCopyOf (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltValueOf (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltNumber (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltApplyImports (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltCallTemplate (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltApplyTemplates (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltChoose (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltIf (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltForEach (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
xsltElemPreCompPtr comp);
XSLTPUBFUN void XSLTCALL
xsltRegisterAllElement (xsltTransformContextPtr ctxt);
XSLTPUBFUN xmlNodePtr XSLTCALL
xsltCopyTextString (xsltTransformContextPtr ctxt,
xmlNodePtr target,
const xmlChar *string,
int noescape);
/* Following 2 functions needed for libexslt/functions.c */
XSLTPUBFUN void XSLTCALL
xsltLocalVariablePop (xsltTransformContextPtr ctxt,
int limitNr,
int level);
XSLTPUBFUN int XSLTCALL
xsltLocalVariablePush (xsltTransformContextPtr ctxt,
xsltStackElemPtr variable,
int level);
/*
* Hook for the debugger if activated.
*/
XSLTPUBFUN void XSLTCALL
xslHandleDebugger (xmlNodePtr cur,
xmlNodePtr node,
xsltTemplatePtr templ,
xsltTransformContextPtr ctxt);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_TRANSFORM_H__ */

216
libs/xslt/libxslt/trio.h Normal file
View File

@ -0,0 +1,216 @@
/*************************************************************************
*
* $Id$
*
* Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
* CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
*
*************************************************************************
*
* http://ctrio.sourceforge.net/
*
************************************************************************/
#ifndef TRIO_TRIO_H
#define TRIO_TRIO_H
#if !defined(WITHOUT_TRIO)
/*
* Use autoconf defines if present. Packages using trio must define
* HAVE_CONFIG_H as a compiler option themselves.
*/
#if defined(HAVE_CONFIG_H)
# include <config.h>
#endif
#include "triodef.h"
#include <stdio.h>
#include <stdlib.h>
#if defined(TRIO_COMPILER_ANCIENT)
# include <varargs.h>
#else
# include <stdarg.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Error codes.
*
* Remember to add a textual description to trio_strerror.
*/
enum {
TRIO_EOF = 1,
TRIO_EINVAL = 2,
TRIO_ETOOMANY = 3,
TRIO_EDBLREF = 4,
TRIO_EGAP = 5,
TRIO_ENOMEM = 6,
TRIO_ERANGE = 7,
TRIO_ERRNO = 8,
TRIO_ECUSTOM = 9
};
/* Error macros */
#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF)
#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8)
#define TRIO_ERROR_NAME(x) trio_strerror(x)
typedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int));
typedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t));
TRIO_CONST char *trio_strerror TRIO_PROTO((int));
/*************************************************************************
* Print Functions
*/
int trio_printf TRIO_PROTO((TRIO_CONST char *format, ...));
int trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
int trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args));
int trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
int trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
int trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
int trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
int trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
int trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
int trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
TRIO_CONST char *format, ...));
int trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
TRIO_CONST char *format, va_list args));
int trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
TRIO_CONST char *format, void **args));
int trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...));
int trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args));
int trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args));
int trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
int trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
va_list args));
int trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
void **args));
int trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
int trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
va_list args));
char *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...));
char *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
int trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...));
int trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args));
/*************************************************************************
* Scan Functions
*/
int trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...));
int trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args));
int trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args));
int trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
int trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
int trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
int trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
int trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
int trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
int trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
TRIO_CONST char *format, ...));
int trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
TRIO_CONST char *format, va_list args));
int trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
TRIO_CONST char *format, void **args));
int trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...));
int trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args));
int trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args));
/*************************************************************************
* Locale Functions
*/
void trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint));
void trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator));
void trio_locale_set_grouping TRIO_PROTO((char *grouping));
/*************************************************************************
* Renaming
*/
#ifdef TRIO_REPLACE_STDIO
/* Replace the <stdio.h> functions */
#ifndef HAVE_PRINTF
# define printf trio_printf
#endif
#ifndef HAVE_VPRINTF
# define vprintf trio_vprintf
#endif
#ifndef HAVE_FPRINTF
# define fprintf trio_fprintf
#endif
#ifndef HAVE_VFPRINTF
# define vfprintf trio_vfprintf
#endif
#ifndef HAVE_SPRINTF
# define sprintf trio_sprintf
#endif
#ifndef HAVE_VSPRINTF
# define vsprintf trio_vsprintf
#endif
#ifndef HAVE_SNPRINTF
# define snprintf trio_snprintf
#endif
#ifndef HAVE_VSNPRINTF
# define vsnprintf trio_vsnprintf
#endif
#ifndef HAVE_SCANF
# define scanf trio_scanf
#endif
#ifndef HAVE_VSCANF
# define vscanf trio_vscanf
#endif
#ifndef HAVE_FSCANF
# define fscanf trio_fscanf
#endif
#ifndef HAVE_VFSCANF
# define vfscanf trio_vfscanf
#endif
#ifndef HAVE_SSCANF
# define sscanf trio_sscanf
#endif
#ifndef HAVE_VSSCANF
# define vsscanf trio_vsscanf
#endif
/* These aren't stdio functions, but we make them look similar */
#define dprintf trio_dprintf
#define vdprintf trio_vdprintf
#define aprintf trio_aprintf
#define vaprintf trio_vaprintf
#define asprintf trio_asprintf
#define vasprintf trio_vasprintf
#define dscanf trio_dscanf
#define vdscanf trio_vdscanf
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* WITHOUT_TRIO */
#endif /* TRIO_TRIO_H */

220
libs/xslt/libxslt/triodef.h Normal file
View File

@ -0,0 +1,220 @@
/*************************************************************************
*
* $Id$
*
* Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
* CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
*
************************************************************************/
#ifndef TRIO_TRIODEF_H
#define TRIO_TRIODEF_H
/*************************************************************************
* Platform and compiler support detection
*/
#if defined(__GNUC__)
# define TRIO_COMPILER_GCC
#elif defined(__SUNPRO_C)
# define TRIO_COMPILER_SUNPRO
#elif defined(__SUNPRO_CC)
# define TRIO_COMPILER_SUNPRO
# define __SUNPRO_C __SUNPRO_CC
#elif defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__)
# define TRIO_COMPILER_XLC
#elif defined(_AIX) && !defined(__GNUC__)
# define TRIO_COMPILER_XLC /* Workaround for old xlc */
#elif defined(__DECC) || defined(__DECCXX)
# define TRIO_COMPILER_DECC
#elif defined(__osf__) && defined(__LANGUAGE_C__)
# define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */
#elif defined(_MSC_VER)
# define TRIO_COMPILER_MSVC
#elif defined(__BORLANDC__)
# define TRIO_COMPILER_BCB
#endif
#if defined(VMS) || defined(__VMS)
/*
* VMS is placed first to avoid identifying the platform as Unix
* based on the DECC compiler later on.
*/
# define TRIO_PLATFORM_VMS
#elif defined(unix) || defined(__unix) || defined(__unix__)
# define TRIO_PLATFORM_UNIX
#elif defined(TRIO_COMPILER_XLC) || defined(_AIX)
# define TRIO_PLATFORM_UNIX
#elif defined(TRIO_COMPILER_DECC) || defined(__osf___)
# define TRIO_PLATFORM_UNIX
#elif defined(__NetBSD__)
# define TRIO_PLATFORM_UNIX
#elif defined(__QNX__)
# define TRIO_PLATFORM_UNIX
# define TRIO_PLATFORM_QNX
#elif defined(__CYGWIN__)
# define TRIO_PLATFORM_UNIX
#elif defined(AMIGA) && defined(TRIO_COMPILER_GCC)
# define TRIO_PLATFORM_UNIX
#elif defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32)
# define TRIO_PLATFORM_WIN32
#elif defined(mpeix) || defined(__mpexl)
# define TRIO_PLATFORM_MPEIX
#endif
#if defined(_AIX)
# define TRIO_PLATFORM_AIX
#elif defined(__hpux)
# define TRIO_PLATFORM_HPUX
#elif defined(sun) || defined(__sun__)
# if defined(__SVR4) || defined(__svr4__)
# define TRIO_PLATFORM_SOLARIS
# else
# define TRIO_PLATFORM_SUNOS
# endif
#endif
#if defined(__STDC__) || defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
# define TRIO_COMPILER_SUPPORTS_C89
# if defined(__STDC_VERSION__)
# define TRIO_COMPILER_SUPPORTS_C90
# if (__STDC_VERSION__ >= 199409L)
# define TRIO_COMPILER_SUPPORTS_C94
# endif
# if (__STDC_VERSION__ >= 199901L)
# define TRIO_COMPILER_SUPPORTS_C99
# endif
# elif defined(TRIO_COMPILER_SUNPRO)
# if (__SUNPRO_C >= 0x420)
# define TRIO_COMPILER_SUPPORTS_C94
# endif
# endif
#endif
#if defined(_XOPEN_SOURCE)
# if defined(_XOPEN_SOURCE_EXTENDED)
# define TRIO_COMPILER_SUPPORTS_UNIX95
# endif
# if (_XOPEN_VERSION >= 500)
# define TRIO_COMPILER_SUPPORTS_UNIX98
# endif
# if (_XOPEN_VERSION >= 600)
# define TRIO_COMPILER_SUPPORTS_UNIX01
# endif
#endif
/*************************************************************************
* Generic defines
*/
#if !defined(TRIO_PUBLIC)
# define TRIO_PUBLIC
#endif
#if !defined(TRIO_PRIVATE)
# define TRIO_PRIVATE static
#endif
#if !(defined(TRIO_COMPILER_SUPPORTS_C89) || defined(__cplusplus))
# define TRIO_COMPILER_ANCIENT
#endif
#if defined(TRIO_COMPILER_ANCIENT)
# define TRIO_CONST
# define TRIO_VOLATILE
# define TRIO_SIGNED
typedef double trio_long_double_t;
typedef char * trio_pointer_t;
# define TRIO_SUFFIX_LONG(x) x
# define TRIO_PROTO(x) ()
# define TRIO_NOARGS
# define TRIO_ARGS1(list,a1) list a1;
# define TRIO_ARGS2(list,a1,a2) list a1; a2;
# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3;
# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4;
# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5;
# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6;
# define TRIO_VARGS2(list,a1,a2) list a1; a2
# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3
# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4
# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5
# define TRIO_VA_DECL va_dcl
# define TRIO_VA_START(x,y) va_start(x)
# define TRIO_VA_END(x) va_end(x)
#else /* ANSI C */
# define TRIO_CONST const
# define TRIO_VOLATILE volatile
# define TRIO_SIGNED signed
typedef long double trio_long_double_t;
typedef void * trio_pointer_t;
# define TRIO_SUFFIX_LONG(x) x ## L
# define TRIO_PROTO(x) x
# define TRIO_NOARGS void
# define TRIO_ARGS1(list,a1) (a1)
# define TRIO_ARGS2(list,a1,a2) (a1,a2)
# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3)
# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4)
# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5)
# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6)
# define TRIO_VARGS2 TRIO_ARGS2
# define TRIO_VARGS3 TRIO_ARGS3
# define TRIO_VARGS4 TRIO_ARGS4
# define TRIO_VARGS5 TRIO_ARGS5
# define TRIO_VA_DECL ...
# define TRIO_VA_START(x,y) va_start(x,y)
# define TRIO_VA_END(x) va_end(x)
#endif
#if defined(TRIO_COMPILER_SUPPORTS_C99) || defined(__cplusplus)
# define TRIO_INLINE inline
#elif defined(TRIO_COMPILER_GCC)
# define TRIO_INLINE __inline__
#elif defined(TRIO_COMPILER_MSVC)
# define TRIO_INLINE _inline
#elif defined(TRIO_COMPILER_BCB)
# define TRIO_INLINE __inline
#else
# define TRIO_INLINE
#endif
/*************************************************************************
* Workarounds
*/
#if defined(TRIO_PLATFORM_VMS)
/*
* Computations done with constants at compile time can trigger these
* even when compiling with IEEE enabled.
*/
# pragma message disable (UNDERFLOW, FLOATOVERFL)
# if (__CRTL_VER < 80000000)
/*
* Although the compiler supports C99 language constructs, the C
* run-time library does not contain all C99 functions.
*
* This was the case for 70300022. Update the 80000000 value when
* it has been accurately determined what version of the library
* supports C99.
*/
# if defined(TRIO_COMPILER_SUPPORTS_C99)
# undef TRIO_COMPILER_SUPPORTS_C99
# endif
# endif
#endif
/*
* Not all preprocessors supports the LL token.
*/
#if defined(TRIO_COMPILER_BCB)
#else
# define TRIO_COMPILER_SUPPORTS_LL
#endif
#endif /* TRIO_TRIODEF_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,118 @@
/*
* Summary: interface for the variable matching and lookup.
* Description: interface for the variable matching and lookup.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_VARIABLES_H__
#define __XML_XSLT_VARIABLES_H__
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include "xsltexports.h"
#include "xsltInternals.h"
#include "functions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* XSLT_REGISTER_VARIABLE_LOOKUP:
*
* Registering macro, not general purpose at all but used in different modules.
*/
#define XSLT_REGISTER_VARIABLE_LOOKUP(ctxt) \
xmlXPathRegisterVariableLookup((ctxt)->xpathCtxt, \
xsltXPathVariableLookup, (void *)(ctxt)); \
xsltRegisterAllFunctions((ctxt)->xpathCtxt); \
xsltRegisterAllElement(ctxt); \
(ctxt)->xpathCtxt->extra = ctxt
/*
* Flags for memory management of RVTs
*/
/**
* XSLT_RVT_LOCAL:
*
* RVT is destroyed after the current instructions ends.
*/
#define XSLT_RVT_LOCAL ((void *)1)
/**
* XSLT_RVT_FUNC_RESULT:
*
* RVT is part of results returned with func:result. The RVT won't be
* destroyed after exiting a template and will be reset to XSLT_RVT_LOCAL or
* XSLT_RVT_VARIABLE in the template that receives the return value.
*/
#define XSLT_RVT_FUNC_RESULT ((void *)2)
/**
* XSLT_RVT_GLOBAL:
*
* RVT is part of a global variable.
*/
#define XSLT_RVT_GLOBAL ((void *)3)
/*
* Interfaces for the variable module.
*/
XSLTPUBFUN int XSLTCALL
xsltEvalGlobalVariables (xsltTransformContextPtr ctxt);
XSLTPUBFUN int XSLTCALL
xsltEvalUserParams (xsltTransformContextPtr ctxt,
const char **params);
XSLTPUBFUN int XSLTCALL
xsltQuoteUserParams (xsltTransformContextPtr ctxt,
const char **params);
XSLTPUBFUN int XSLTCALL
xsltEvalOneUserParam (xsltTransformContextPtr ctxt,
const xmlChar * name,
const xmlChar * value);
XSLTPUBFUN int XSLTCALL
xsltQuoteOneUserParam (xsltTransformContextPtr ctxt,
const xmlChar * name,
const xmlChar * value);
XSLTPUBFUN void XSLTCALL
xsltParseGlobalVariable (xsltStylesheetPtr style,
xmlNodePtr cur);
XSLTPUBFUN void XSLTCALL
xsltParseGlobalParam (xsltStylesheetPtr style,
xmlNodePtr cur);
XSLTPUBFUN void XSLTCALL
xsltParseStylesheetVariable (xsltTransformContextPtr ctxt,
xmlNodePtr cur);
XSLTPUBFUN void XSLTCALL
xsltParseStylesheetParam (xsltTransformContextPtr ctxt,
xmlNodePtr cur);
XSLTPUBFUN xsltStackElemPtr XSLTCALL
xsltParseStylesheetCallerParam (xsltTransformContextPtr ctxt,
xmlNodePtr cur);
XSLTPUBFUN int XSLTCALL
xsltAddStackElemList (xsltTransformContextPtr ctxt,
xsltStackElemPtr elems);
XSLTPUBFUN void XSLTCALL
xsltFreeGlobalVariables (xsltTransformContextPtr ctxt);
XSLTPUBFUN xmlXPathObjectPtr XSLTCALL
xsltVariableLookup (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *ns_uri);
XSLTPUBFUN xmlXPathObjectPtr XSLTCALL
xsltXPathVariableLookup (void *ctxt,
const xmlChar *name,
const xmlChar *ns_uri);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_VARIABLES_H__ */

View File

@ -0,0 +1,129 @@
/*
* Summary: Windows configuration header
* Description: Windows configuration header
*
* Copy: See Copyright for the status of this software.
*
* Author: Igor Zlatkovic
*/
#ifndef __LIBXSLT_WIN32_CONFIG__
#define __LIBXSLT_WIN32_CONFIG__
#define HAVE_CTYPE_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STDARG_H 1
#define HAVE_MALLOC_H 1
#define HAVE_TIME_H 1
#define HAVE_LOCALTIME 1
#define HAVE_GMTIME 1
#define HAVE_TIME 1
#define HAVE_MATH_H 1
#define HAVE_FCNTL_H 1
#include <io.h>
#define HAVE_ISINF
#define HAVE_ISNAN
#include <math.h>
#ifdef _WIN32
/* MS C-runtime has functions which can be used in order to determine if
a given floating-point variable contains NaN, (+-)INF. These are
preferred, because floating-point technology is considered propriatary
by MS and we can assume that their functions know more about their
oddities than we do. */
#include <float.h>
/* Bjorn Reese figured a quite nice construct for isinf() using the
_fpclass() function. */
#ifndef isinf
#define isinf(d) ((_fpclass(d) == _FPCLASS_PINF) ? 1 \
: ((_fpclass(d) == _FPCLASS_NINF) ? -1 : 0))
#endif
/* _isnan(x) returns nonzero if (x == NaN) and zero otherwise. */
#ifndef isnan
#define isnan(d) (_isnan(d))
#endif
#else /* _MSC_VER */
static int isinf (double d) {
int expon = 0;
double val = frexp (d, &expon);
if (expon == 1025) {
if (val == 0.5) {
return 1;
} else if (val == -0.5) {
return -1;
} else {
return 0;
}
} else {
return 0;
}
}
static int isnan (double d) {
int expon = 0;
double val = frexp (d, &expon);
if (expon == 1025) {
if (val == 0.5) {
return 0;
} else if (val == -0.5) {
return 0;
} else {
return 1;
}
} else {
return 0;
}
}
#endif /* _MSC_VER */
#include <direct.h>
/* snprintf emulation taken from http://stackoverflow.com/a/8712996/1956010 */
#if defined(_MSC_VER) && _MSC_VER < 1900
#include <stdarg.h>
#include <stdio.h>
#define snprintf c99_snprintf
#define vsnprintf c99_vsnprintf
__inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
{
int count = -1;
if (size != 0)
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
if (count == -1)
count = _vscprintf(format, ap);
return count;
}
__inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
{
int count;
va_list ap;
va_start(ap, format);
count = c99_vsnprintf(outBuf, size, format, ap);
va_end(ap);
return count;
}
#endif /* defined(_MSC_VER) && _MSC_VER < 1900 */
#define HAVE_SYS_STAT_H
#define HAVE_STAT
#define HAVE_STRING_H
#include <libxml/xmlversion.h>
#ifndef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED
#endif
#define _WINSOCKAPI_
#endif /* __LIBXSLT_WIN32_CONFIG__ */

7047
libs/xslt/libxslt/xslt.c Normal file

File diff suppressed because it is too large Load Diff

110
libs/xslt/libxslt/xslt.h Normal file
View File

@ -0,0 +1,110 @@
/*
* Summary: Interfaces, constants and types related to the XSLT engine
* Description: Interfaces, constants and types related to the XSLT engine
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLT_H__
#define __XML_XSLT_H__
#include <libxml/tree.h>
#include "xsltexports.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* XSLT_DEFAULT_VERSION:
*
* The default version of XSLT supported.
*/
#define XSLT_DEFAULT_VERSION "1.0"
/**
* XSLT_DEFAULT_VENDOR:
*
* The XSLT "vendor" string for this processor.
*/
#define XSLT_DEFAULT_VENDOR "libxslt"
/**
* XSLT_DEFAULT_URL:
*
* The XSLT "vendor" URL for this processor.
*/
#define XSLT_DEFAULT_URL "http://xmlsoft.org/XSLT/"
/**
* XSLT_NAMESPACE:
*
* The XSLT specification namespace.
*/
#define XSLT_NAMESPACE ((const xmlChar *)"http://www.w3.org/1999/XSL/Transform")
/**
* XSLT_PARSE_OPTIONS:
*
* The set of options to pass to an xmlReadxxx when loading files for
* XSLT consumption.
*/
#define XSLT_PARSE_OPTIONS \
XML_PARSE_NOENT | XML_PARSE_DTDLOAD | XML_PARSE_DTDATTR | XML_PARSE_NOCDATA
/**
* xsltMaxDepth:
*
* This value is used to detect templates loops.
*/
XSLTPUBVAR int xsltMaxDepth;
/**
* * xsltMaxVars:
* *
* * This value is used to detect templates loops.
* */
XSLTPUBVAR int xsltMaxVars;
/**
* xsltEngineVersion:
*
* The version string for libxslt.
*/
XSLTPUBVAR const char *xsltEngineVersion;
/**
* xsltLibxsltVersion:
*
* The version of libxslt compiled.
*/
XSLTPUBVAR const int xsltLibxsltVersion;
/**
* xsltLibxmlVersion:
*
* The version of libxml libxslt was compiled against.
*/
XSLTPUBVAR const int xsltLibxmlVersion;
/*
* Global initialization function.
*/
XSLTPUBFUN void XSLTCALL
xsltInit (void);
/*
* Global cleanup function.
*/
XSLTPUBFUN void XSLTCALL
xsltCleanupGlobals (void);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,180 @@
/*
* Summary: compile-time version information for the XSLT engine
* Description: compile-time version information for the XSLT engine
* this module is autogenerated.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLTCONFIG_H__
#define __XML_XSLTCONFIG_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* LIBXSLT_DOTTED_VERSION:
*
* the version string like "1.2.3"
*/
#define LIBXSLT_DOTTED_VERSION "1.1.34"
/**
* LIBXSLT_VERSION:
*
* the version number: 1.2.3 value is 10203
*/
#define LIBXSLT_VERSION 10134
/**
* LIBXSLT_VERSION_STRING:
*
* the version number string, 1.2.3 value is "10203"
*/
#define LIBXSLT_VERSION_STRING "10134"
/**
* LIBXSLT_VERSION_EXTRA:
*
* extra version information, used to show a CVS compilation
*/
#define LIBXSLT_VERSION_EXTRA ""
/**
* WITH_XSLT_DEBUG:
*
* Activate the compilation of the debug reporting. Speed penalty
* is insignifiant and being able to run xsltpoc -v is useful. On
* by default unless --without-debug is passed to configure
*/
#if 0
#define WITH_XSLT_DEBUG
#endif
#if 0
/**
* DEBUG_MEMORY:
*
* should be activated only when debugging libxslt. It replaces the
* allocator with a collect and debug shell to the libc allocator.
* Use configure --with-mem-debug to activate it on both library
*/
#define DEBUG_MEMORY
/**
* DEBUG_MEMORY_LOCATION:
*
* should be activated only when debugging libxslt.
* DEBUG_MEMORY_LOCATION should be activated only when libxml has
* been configured with --with-debug-mem too
*/
#define DEBUG_MEMORY_LOCATION
#endif
/**
* XSLT_NEED_TRIO:
*
* should be activated if the existing libc library lacks some of the
* string formatting function, in that case reuse the Trio ones already
* compiled in the libxml2 library.
*/
#if 0
#define XSLT_NEED_TRIO
#endif
#ifdef __VMS
#define HAVE_MATH_H 1
#define HAVE_SYS_STAT_H 1
#ifndef XSLT_NEED_TRIO
#define XSLT_NEED_TRIO
#endif
#endif
#ifdef XSLT_NEED_TRIO
#define TRIO_REPLACE_STDIO
#endif
/**
* WITH_XSLT_DEBUGGER:
*
* Activate the compilation of the debugger support. Speed penalty
* is insignifiant.
* On by default unless --without-debugger is passed to configure
*/
#if 0
#ifndef WITH_DEBUGGER
#define WITH_DEBUGGER
#endif
#endif
/**
* WITH_PROFILER:
*
* Activate the compilation of the profiler. Speed penalty
* is insignifiant.
* On by default unless --without-profiler is passed to configure
*/
#if 0
#ifndef WITH_PROFILER
#define WITH_PROFILER
#endif
#endif
/**
* WITH_MODULES:
*
* Whether module support is configured into libxslt
* Note: no default module path for win32 platforms
*/
#if 0
#ifndef WITH_MODULES
#define WITH_MODULES
#endif
#define LIBXSLT_DEFAULT_PLUGINS_PATH() "/usr/local/lib/libxslt-plugins"
#endif
/**
* ATTRIBUTE_UNUSED:
*
* This macro is used to flag unused function parameters to GCC
*/
#ifdef __GNUC__
#ifndef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED __attribute__((unused))
#endif
#else
#define ATTRIBUTE_UNUSED
#endif
/**
* LIBXSLT_ATTR_FORMAT:
*
* This macro is used to indicate to GCC the parameters are printf-like
*/
#ifdef __GNUC__
#define LIBXSLT_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
#else
#define LIBXSLT_ATTR_FORMAT(fmt,args)
#endif
/**
* LIBXSLT_PUBLIC:
*
* This macro is used to declare PUBLIC variables for Cygwin and for MSC on Windows
*/
#if !defined LIBXSLT_PUBLIC
#if (defined(__CYGWIN__) || defined _MSC_VER) && !defined IN_LIBXSLT && !defined LIBXSLT_STATIC
#define LIBXSLT_PUBLIC __declspec(dllimport)
#else
#define LIBXSLT_PUBLIC
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLTCONFIG_H__ */

View File

@ -0,0 +1,142 @@
/*
* Summary: macros for marking symbols as exportable/importable.
* Description: macros for marking symbols as exportable/importable.
*
* Copy: See Copyright for the status of this software.
*
* Author: Igor Zlatkovic <igor@zlatkovic.com>
*/
#ifndef __XSLT_EXPORTS_H__
#define __XSLT_EXPORTS_H__
/**
* XSLTPUBFUN:
* XSLTPUBFUN, XSLTPUBVAR, XSLTCALL
*
* Macros which declare an exportable function, an exportable variable and
* the calling convention used for functions.
*
* Please use an extra block for every platform/compiler combination when
* modifying this, rather than overlong #ifdef lines. This helps
* readability as well as the fact that different compilers on the same
* platform might need different definitions.
*/
/**
* XSLTPUBFUN:
*
* Macros which declare an exportable function
*/
#define XSLTPUBFUN
/**
* XSLTPUBVAR:
*
* Macros which declare an exportable variable
*/
#define XSLTPUBVAR extern
/**
* XSLTCALL:
*
* Macros which declare the called convention for exported functions
*/
#define XSLTCALL
/** DOC_DISABLE */
/* Windows platform with MS compiler */
#if defined(_WIN32) && defined(_MSC_VER)
#undef XSLTPUBFUN
#undef XSLTPUBVAR
#undef XSLTCALL
#if defined(IN_LIBXSLT) && !defined(LIBXSLT_STATIC)
#define XSLTPUBFUN __declspec(dllexport)
#define XSLTPUBVAR __declspec(dllexport)
#else
#define XSLTPUBFUN
#if !defined(LIBXSLT_STATIC)
#define XSLTPUBVAR __declspec(dllimport) extern
#else
#define XSLTPUBVAR extern
#endif
#endif
#define XSLTCALL __cdecl
#if !defined _REENTRANT
#define _REENTRANT
#endif
#endif
/* Windows platform with Borland compiler */
#if defined(_WIN32) && defined(__BORLANDC__)
#undef XSLTPUBFUN
#undef XSLTPUBVAR
#undef XSLTCALL
#if defined(IN_LIBXSLT) && !defined(LIBXSLT_STATIC)
#define XSLTPUBFUN __declspec(dllexport)
#define XSLTPUBVAR __declspec(dllexport) extern
#else
#define XSLTPUBFUN
#if !defined(LIBXSLT_STATIC)
#define XSLTPUBVAR __declspec(dllimport) extern
#else
#define XSLTPUBVAR extern
#endif
#endif
#define XSLTCALL __cdecl
#if !defined _REENTRANT
#define _REENTRANT
#endif
#endif
/* Windows platform with GNU compiler (Mingw) */
#if defined(_WIN32) && defined(__MINGW32__)
#undef XSLTPUBFUN
#undef XSLTPUBVAR
#undef XSLTCALL
/*
#if defined(IN_LIBXSLT) && !defined(LIBXSLT_STATIC)
*/
#if !defined(LIBXSLT_STATIC)
#define XSLTPUBFUN __declspec(dllexport)
#define XSLTPUBVAR __declspec(dllexport) extern
#else
#define XSLTPUBFUN
#if !defined(LIBXSLT_STATIC)
#define XSLTPUBVAR __declspec(dllimport) extern
#else
#define XSLTPUBVAR extern
#endif
#endif
#define XSLTCALL __cdecl
#if !defined _REENTRANT
#define _REENTRANT
#endif
#endif
/* Cygwin platform (does not define _WIN32), GNU compiler */
#if defined(__CYGWIN__)
#undef XSLTPUBFUN
#undef XSLTPUBVAR
#undef XSLTCALL
#if defined(IN_LIBXSLT) && !defined(LIBXSLT_STATIC)
#define XSLTPUBFUN __declspec(dllexport)
#define XSLTPUBVAR __declspec(dllexport)
#else
#define XSLTPUBFUN
#if !defined(LIBXSLT_STATIC)
#define XSLTPUBVAR __declspec(dllimport) extern
#else
#define XSLTPUBVAR extern
#endif
#endif
#define XSLTCALL __cdecl
#endif
/* Compatibility */
#if !defined(LIBXSLT_PUBLIC)
#define LIBXSLT_PUBLIC XSLTPUBVAR
#endif
#endif /* __XSLT_EXPORTS_H__ */

View File

@ -0,0 +1,520 @@
/*
* xsltlocale.c: locale handling
*
* Reference:
* RFC 3066: Tags for the Identification of Languages
* http://www.ietf.org/rfc/rfc3066.txt
* ISO 639-1, ISO 3166-1
*
* Author: Nick Wellnhofer
* winapi port: Roumen Petrov
*/
#define IN_LIBXSLT
#include "libxslt.h"
#include <string.h>
#include <libxml/xmlmemory.h>
#include "xsltlocale.h"
#include "xsltutils.h"
#define TOUPPER(c) (c & ~0x20)
#define TOLOWER(c) (c | 0x20)
#define ISALPHA(c) ((unsigned)(TOUPPER(c) - 'A') < 26)
/*without terminating null character*/
#define XSLTMAX_ISO639LANGLEN 8
#define XSLTMAX_ISO3166CNTRYLEN 8
/* <lang>-<cntry> */
#define XSLTMAX_LANGTAGLEN (XSLTMAX_ISO639LANGLEN+1+XSLTMAX_ISO3166CNTRYLEN)
static const xmlChar* xsltDefaultRegion(const xmlChar *localeName);
#ifdef XSLT_LOCALE_WINAPI
xmlRMutexPtr xsltLocaleMutex = NULL;
struct xsltRFC1766Info_s {
/*note typedef unsigned char xmlChar !*/
xmlChar tag[XSLTMAX_LANGTAGLEN+1];
/*note typedef LCID xsltLocale !*/
xsltLocale lcid;
};
typedef struct xsltRFC1766Info_s xsltRFC1766Info;
static int xsltLocaleListSize = 0;
static xsltRFC1766Info *xsltLocaleList = NULL;
static xsltLocale
xslt_locale_WINAPI(const xmlChar *languageTag) {
int k;
xsltRFC1766Info *p = xsltLocaleList;
for (k=0; k<xsltLocaleListSize; k++, p++)
if (xmlStrcmp(p->tag, languageTag) == 0) return p->lcid;
return((xsltLocale)0);
}
static void xsltEnumSupportedLocales(void);
#endif
/**
* xsltFreeLocales:
*
* Cleanup function for the locale support on shutdown
*/
void
xsltFreeLocales(void) {
#ifdef XSLT_LOCALE_WINAPI
xmlRMutexLock(xsltLocaleMutex);
xmlFree(xsltLocaleList);
xsltLocaleList = NULL;
xmlRMutexUnlock(xsltLocaleMutex);
#endif
}
/**
* xsltNewLocale:
* @languageTag: RFC 3066 language tag
*
* Creates a new locale of an opaque system dependent type based on the
* language tag.
*
* Returns the locale or NULL on error or if no matching locale was found
*/
xsltLocale
xsltNewLocale(const xmlChar *languageTag) {
#ifdef XSLT_LOCALE_POSIX
xsltLocale locale;
char localeName[XSLTMAX_LANGTAGLEN+6]; /* 6 chars for ".utf8\0" */
const xmlChar *p = languageTag;
const char *region = NULL;
char *q = localeName;
int i, llen;
/* Convert something like "pt-br" to "pt_BR.utf8" */
if (languageTag == NULL)
return(NULL);
for (i=0; i<XSLTMAX_ISO639LANGLEN && ISALPHA(*p); ++i)
*q++ = TOLOWER(*p++);
if (i == 0)
return(NULL);
llen = i;
if (*p) {
if (*p++ != '-')
return(NULL);
*q++ = '_';
for (i=0; i<XSLTMAX_ISO3166CNTRYLEN && ISALPHA(*p); ++i)
*q++ = TOUPPER(*p++);
if (i == 0 || *p)
return(NULL);
memcpy(q, ".utf8", 6);
locale = newlocale(LC_COLLATE_MASK, localeName, NULL);
if (locale != NULL)
return(locale);
/* Continue without using country code */
q = localeName + llen;
}
/* Try locale without territory, e.g. for Esperanto (eo) */
memcpy(q, ".utf8", 6);
locale = newlocale(LC_COLLATE_MASK, localeName, NULL);
if (locale != NULL)
return(locale);
/* Try to find most common country for language */
if (llen != 2)
return(NULL);
region = (char *)xsltDefaultRegion((xmlChar *)localeName);
if (region == NULL)
return(NULL);
q = localeName + llen;
*q++ = '_';
*q++ = region[0];
*q++ = region[1];
memcpy(q, ".utf8", 6);
locale = newlocale(LC_COLLATE_MASK, localeName, NULL);
return(locale);
#endif
#ifdef XSLT_LOCALE_WINAPI
{
xsltLocale locale = (xsltLocale)0;
xmlChar localeName[XSLTMAX_LANGTAGLEN+1];
xmlChar *q = localeName;
const xmlChar *p = languageTag;
int i, llen;
const xmlChar *region = NULL;
if (languageTag == NULL) goto end;
xsltEnumSupportedLocales();
for (i=0; i<XSLTMAX_ISO639LANGLEN && ISALPHA(*p); ++i)
*q++ = TOLOWER(*p++);
if (i == 0) goto end;
llen = i;
*q++ = '-';
if (*p) { /*if country tag is given*/
if (*p++ != '-') goto end;
for (i=0; i<XSLTMAX_ISO3166CNTRYLEN && ISALPHA(*p); ++i)
*q++ = TOUPPER(*p++);
if (i == 0 || *p) goto end;
*q = '\0';
locale = xslt_locale_WINAPI(localeName);
if (locale != (xsltLocale)0) goto end;
}
/* Try to find most common country for language */
region = xsltDefaultRegion(localeName);
if (region == NULL) goto end;
strcpy((char *) localeName + llen + 1, (char *) region);
locale = xslt_locale_WINAPI(localeName);
end:
return(locale);
}
#endif
#ifdef XSLT_LOCALE_NONE
return(NULL);
#endif
}
static const xmlChar*
xsltDefaultRegion(const xmlChar *localeName) {
xmlChar c;
/* region should be xmlChar, but gcc warns on all string assignments */
const char *region = NULL;
c = localeName[1];
/* This is based on the locales from glibc 2.3.3 */
switch (localeName[0]) {
case 'a':
if (c == 'a' || c == 'm') region = "ET";
else if (c == 'f') region = "ZA";
else if (c == 'n') region = "ES";
else if (c == 'r') region = "AE";
else if (c == 'z') region = "AZ";
break;
case 'b':
if (c == 'e') region = "BY";
else if (c == 'g') region = "BG";
else if (c == 'n') region = "BD";
else if (c == 'r') region = "FR";
else if (c == 's') region = "BA";
break;
case 'c':
if (c == 'a') region = "ES";
else if (c == 's') region = "CZ";
else if (c == 'y') region = "GB";
break;
case 'd':
if (c == 'a') region = "DK";
else if (c == 'e') region = "DE";
break;
case 'e':
if (c == 'l') region = "GR";
else if (c == 'n' || c == 'o') region = "US";
else if (c == 's' || c == 'u') region = "ES";
else if (c == 't') region = "EE";
break;
case 'f':
if (c == 'a') region = "IR";
else if (c == 'i') region = "FI";
else if (c == 'o') region = "FO";
else if (c == 'r') region = "FR";
break;
case 'g':
if (c == 'a') region = "IE";
else if (c == 'l') region = "ES";
else if (c == 'v') region = "GB";
break;
case 'h':
if (c == 'e') region = "IL";
else if (c == 'i') region = "IN";
else if (c == 'r') region = "HT";
else if (c == 'u') region = "HU";
break;
case 'i':
if (c == 'd') region = "ID";
else if (c == 's') region = "IS";
else if (c == 't') region = "IT";
else if (c == 'w') region = "IL";
break;
case 'j':
if (c == 'a') region = "JP";
break;
case 'k':
if (c == 'l') region = "GL";
else if (c == 'o') region = "KR";
else if (c == 'w') region = "GB";
break;
case 'l':
if (c == 't') region = "LT";
else if (c == 'v') region = "LV";
break;
case 'm':
if (c == 'k') region = "MK";
else if (c == 'l' || c == 'r') region = "IN";
else if (c == 'n') region = "MN";
else if (c == 's') region = "MY";
else if (c == 't') region = "MT";
break;
case 'n':
if (c == 'b' || c == 'n' || c == 'o') region = "NO";
else if (c == 'e') region = "NP";
else if (c == 'l') region = "NL";
break;
case 'o':
if (c == 'm') region = "ET";
break;
case 'p':
if (c == 'a') region = "IN";
else if (c == 'l') region = "PL";
else if (c == 't') region = "PT";
break;
case 'r':
if (c == 'o') region = "RO";
else if (c == 'u') region = "RU";
break;
case 's':
switch (c) {
case 'e': region = "NO"; break;
case 'h': region = "YU"; break;
case 'k': region = "SK"; break;
case 'l': region = "SI"; break;
case 'o': region = "ET"; break;
case 'q': region = "AL"; break;
case 't': region = "ZA"; break;
case 'v': region = "SE"; break;
}
break;
case 't':
if (c == 'a' || c == 'e') region = "IN";
else if (c == 'h') region = "TH";
else if (c == 'i') region = "ER";
else if (c == 'r') region = "TR";
else if (c == 't') region = "RU";
break;
case 'u':
if (c == 'k') region = "UA";
else if (c == 'r') region = "PK";
break;
case 'v':
if (c == 'i') region = "VN";
break;
case 'w':
if (c == 'a') region = "BE";
break;
case 'x':
if (c == 'h') region = "ZA";
break;
case 'z':
if (c == 'h') region = "CN";
else if (c == 'u') region = "ZA";
break;
}
return((xmlChar *)region);
}
/**
* xsltFreeLocale:
* @locale: the locale to free
*
* Frees a locale created with xsltNewLocale
*/
void
xsltFreeLocale(xsltLocale locale) {
#ifdef XSLT_LOCALE_POSIX
freelocale(locale);
#endif
}
/**
* xsltStrxfrm:
* @locale: locale created with xsltNewLocale
* @string: UTF-8 string to transform
*
* Transforms a string according to locale. The transformed string must then be
* compared with xsltLocaleStrcmp and freed with xmlFree.
*
* Returns the transformed string or NULL on error
*/
xsltLocaleChar *
xsltStrxfrm(xsltLocale locale, const xmlChar *string)
{
#ifdef XSLT_LOCALE_NONE
return(NULL);
#else
size_t xstrlen, r;
xsltLocaleChar *xstr;
#ifdef XSLT_LOCALE_POSIX
xstrlen = strxfrm_l(NULL, (const char *)string, 0, locale) + 1;
xstr = (xsltLocaleChar *) xmlMalloc(xstrlen);
if (xstr == NULL) {
xsltTransformError(NULL, NULL, NULL,
"xsltStrxfrm : out of memory error\n");
return(NULL);
}
r = strxfrm_l((char *)xstr, (const char *)string, xstrlen, locale);
#endif
#ifdef XSLT_LOCALE_WINAPI
xstrlen = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, NULL, 0);
if (xstrlen == 0) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar check failed\n");
return(NULL);
}
xstr = (xsltLocaleChar*) xmlMalloc(xstrlen * sizeof(xsltLocaleChar));
if (xstr == NULL) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory\n");
return(NULL);
}
r = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, xstr, xstrlen);
if (r == 0) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar failed\n");
xmlFree(xstr);
return(NULL);
}
return(xstr);
#endif /* XSLT_LOCALE_WINAPI */
if (r >= xstrlen) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : strxfrm failed\n");
xmlFree(xstr);
return(NULL);
}
return(xstr);
#endif /* XSLT_LOCALE_NONE */
}
/**
* xsltLocaleStrcmp:
* @locale: a locale identifier
* @str1: a string transformed with xsltStrxfrm
* @str2: a string transformed with xsltStrxfrm
*
* Compares two strings transformed with xsltStrxfrm
*
* Returns a value < 0 if str1 sorts before str2,
* a value > 0 if str1 sorts after str2,
* 0 if str1 and str2 are equal wrt sorting
*/
int
xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocaleChar *str2) {
(void)locale;
#ifdef XSLT_LOCALE_WINAPI
{
int ret;
if (str1 == str2) return(0);
if (str1 == NULL) return(-1);
if (str2 == NULL) return(1);
ret = CompareStringW(locale, 0, str1, -1, str2, -1);
if (ret == 0) {
xsltTransformError(NULL, NULL, NULL, "xsltLocaleStrcmp : CompareStringW fail\n");
return(0);
}
return(ret - 2);
}
#else
return(xmlStrcmp(str1, str2));
#endif
}
#ifdef XSLT_LOCALE_WINAPI
/**
* xsltCountSupportedLocales:
* @lcid: not used
*
* callback used to count locales
*
* Returns TRUE
*/
BOOL CALLBACK
xsltCountSupportedLocales(LPSTR lcid) {
(void) lcid;
++xsltLocaleListSize;
return(TRUE);
}
/**
* xsltIterateSupportedLocales:
* @lcid: not used
*
* callback used to track locales
*
* Returns TRUE if not at the end of the array
*/
BOOL CALLBACK
xsltIterateSupportedLocales(LPSTR lcid) {
static int count = 0;
xmlChar iso639lang [XSLTMAX_ISO639LANGLEN +1];
xmlChar iso3136ctry[XSLTMAX_ISO3166CNTRYLEN+1];
int k, l;
xsltRFC1766Info *p = xsltLocaleList + count;
k = sscanf(lcid, "%lx", (long*)&p->lcid);
if (k < 1) goto end;
/*don't count terminating null character*/
k = GetLocaleInfoA(p->lcid, LOCALE_SISO639LANGNAME,
(char *) iso639lang, sizeof(iso639lang));
if (--k < 1) goto end;
l = GetLocaleInfoA(p->lcid, LOCALE_SISO3166CTRYNAME,
(char *) iso3136ctry, sizeof(iso3136ctry));
if (--l < 1) goto end;
{ /*fill results*/
xmlChar *q = p->tag;
memcpy(q, iso639lang, k);
q += k;
*q++ = '-';
memcpy(q, iso3136ctry, l);
q += l;
*q = '\0';
}
++count;
end:
return((count < xsltLocaleListSize) ? TRUE : FALSE);
}
static void
xsltEnumSupportedLocales(void) {
xmlRMutexLock(xsltLocaleMutex);
if (xsltLocaleListSize <= 0) {
size_t len;
EnumSystemLocalesA(xsltCountSupportedLocales, LCID_SUPPORTED);
len = xsltLocaleListSize * sizeof(xsltRFC1766Info);
xsltLocaleList = xmlMalloc(len);
memset(xsltLocaleList, 0, len);
EnumSystemLocalesA(xsltIterateSupportedLocales, LCID_SUPPORTED);
}
xmlRMutexUnlock(xsltLocaleMutex);
}
#endif /*def XSLT_LOCALE_WINAPI*/

View File

@ -0,0 +1,76 @@
/*
* Summary: Locale handling
* Description: Interfaces for locale handling. Needed for language dependent
* sorting.
*
* Copy: See Copyright for the status of this software.
*
* Author: Nick Wellnhofer
*/
#ifndef __XML_XSLTLOCALE_H__
#define __XML_XSLTLOCALE_H__
#include <libxml/xmlstring.h>
#include "xsltexports.h"
#ifdef HAVE_STRXFRM_L
/*
* XSLT_LOCALE_POSIX:
* Macro indicating to use POSIX locale extensions
*/
#define XSLT_LOCALE_POSIX
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
#endif
typedef locale_t xsltLocale;
typedef xmlChar xsltLocaleChar;
#elif defined(_WIN32) && !defined(__CYGWIN__)
/*
* XSLT_LOCALE_WINAPI:
* Macro indicating to use WinAPI for extended locale support
*/
#define XSLT_LOCALE_WINAPI
#include <windows.h>
#include <winnls.h>
typedef LCID xsltLocale;
typedef wchar_t xsltLocaleChar;
#else
/*
* XSLT_LOCALE_NONE:
* Macro indicating that there's no extended locale support
*/
#define XSLT_LOCALE_NONE
typedef void *xsltLocale;
typedef xmlChar xsltLocaleChar;
#endif
XSLTPUBFUN xsltLocale XSLTCALL
xsltNewLocale (const xmlChar *langName);
XSLTPUBFUN void XSLTCALL
xsltFreeLocale (xsltLocale locale);
XSLTPUBFUN xsltLocaleChar * XSLTCALL
xsltStrxfrm (xsltLocale locale,
const xmlChar *string);
XSLTPUBFUN int XSLTCALL
xsltLocaleStrcmp (xsltLocale locale,
const xsltLocaleChar *str1,
const xsltLocaleChar *str2);
XSLTPUBFUN void XSLTCALL
xsltFreeLocales (void);
#endif /* __XML_XSLTLOCALE_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,313 @@
/*
* Summary: set of utilities for the XSLT engine
* Description: interfaces for the utilities module of the XSLT engine.
* things like message handling, profiling, and other
* generally useful routines.
*
* Copy: See Copyright for the status of this software.
*
* Author: Daniel Veillard
*/
#ifndef __XML_XSLTUTILS_H__
#define __XML_XSLTUTILS_H__
#include <libxslt/xsltconfig.h>
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
#include <libxml/xpath.h>
#include <libxml/dict.h>
#include <libxml/xmlerror.h>
#include "xsltexports.h"
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* XSLT_TODO:
*
* Macro to flag unimplemented blocks.
*/
#define XSLT_TODO \
xsltGenericError(xsltGenericErrorContext, \
"Unimplemented block at %s:%d\n", \
__FILE__, __LINE__);
/**
* XSLT_STRANGE:
*
* Macro to flag that a problem was detected internally.
*/
#define XSLT_STRANGE \
xsltGenericError(xsltGenericErrorContext, \
"Internal error at %s:%d\n", \
__FILE__, __LINE__);
/**
* IS_XSLT_ELEM:
*
* Checks that the element pertains to XSLT namespace.
*/
#define IS_XSLT_ELEM(n) \
(((n) != NULL) && ((n)->type == XML_ELEMENT_NODE) && \
((n)->ns != NULL) && (xmlStrEqual((n)->ns->href, XSLT_NAMESPACE)))
/**
* IS_XSLT_NAME:
*
* Checks the value of an element in XSLT namespace.
*/
#define IS_XSLT_NAME(n, val) \
(xmlStrEqual((n)->name, (const xmlChar *) (val)))
/**
* IS_XSLT_REAL_NODE:
*
* Check that a node is a 'real' one: document, element, text or attribute.
*/
#define IS_XSLT_REAL_NODE(n) \
(((n) != NULL) && \
(((n)->type == XML_ELEMENT_NODE) || \
((n)->type == XML_TEXT_NODE) || \
((n)->type == XML_CDATA_SECTION_NODE) || \
((n)->type == XML_ATTRIBUTE_NODE) || \
((n)->type == XML_DOCUMENT_NODE) || \
((n)->type == XML_HTML_DOCUMENT_NODE) || \
((n)->type == XML_COMMENT_NODE) || \
((n)->type == XML_PI_NODE)))
/*
* Our own version of namespaced attributes lookup.
*/
XSLTPUBFUN xmlChar * XSLTCALL
xsltGetNsProp (xmlNodePtr node,
const xmlChar *name,
const xmlChar *nameSpace);
XSLTPUBFUN const xmlChar * XSLTCALL
xsltGetCNsProp (xsltStylesheetPtr style,
xmlNodePtr node,
const xmlChar *name,
const xmlChar *nameSpace);
XSLTPUBFUN int XSLTCALL
xsltGetUTF8Char (const unsigned char *utf,
int *len);
/*
* XSLT Debug Tracing Tracing Types
*/
typedef enum {
XSLT_TRACE_ALL = -1,
XSLT_TRACE_NONE = 0,
XSLT_TRACE_COPY_TEXT = 1<<0,
XSLT_TRACE_PROCESS_NODE = 1<<1,
XSLT_TRACE_APPLY_TEMPLATE = 1<<2,
XSLT_TRACE_COPY = 1<<3,
XSLT_TRACE_COMMENT = 1<<4,
XSLT_TRACE_PI = 1<<5,
XSLT_TRACE_COPY_OF = 1<<6,
XSLT_TRACE_VALUE_OF = 1<<7,
XSLT_TRACE_CALL_TEMPLATE = 1<<8,
XSLT_TRACE_APPLY_TEMPLATES = 1<<9,
XSLT_TRACE_CHOOSE = 1<<10,
XSLT_TRACE_IF = 1<<11,
XSLT_TRACE_FOR_EACH = 1<<12,
XSLT_TRACE_STRIP_SPACES = 1<<13,
XSLT_TRACE_TEMPLATES = 1<<14,
XSLT_TRACE_KEYS = 1<<15,
XSLT_TRACE_VARIABLES = 1<<16
} xsltDebugTraceCodes;
/**
* XSLT_TRACE:
*
* Control the type of xsl debugtrace messages emitted.
*/
#define XSLT_TRACE(ctxt,code,call) \
if (ctxt->traceCode && (*(ctxt->traceCode) & code)) \
call
XSLTPUBFUN void XSLTCALL
xsltDebugSetDefaultTrace(xsltDebugTraceCodes val);
XSLTPUBFUN xsltDebugTraceCodes XSLTCALL
xsltDebugGetDefaultTrace(void);
/*
* XSLT specific error and debug reporting functions.
*/
XSLTPUBVAR xmlGenericErrorFunc xsltGenericError;
XSLTPUBVAR void *xsltGenericErrorContext;
XSLTPUBVAR xmlGenericErrorFunc xsltGenericDebug;
XSLTPUBVAR void *xsltGenericDebugContext;
XSLTPUBFUN void XSLTCALL
xsltPrintErrorContext (xsltTransformContextPtr ctxt,
xsltStylesheetPtr style,
xmlNodePtr node);
XSLTPUBFUN void XSLTCALL
xsltMessage (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst);
XSLTPUBFUN void XSLTCALL
xsltSetGenericErrorFunc (void *ctx,
xmlGenericErrorFunc handler);
XSLTPUBFUN void XSLTCALL
xsltSetGenericDebugFunc (void *ctx,
xmlGenericErrorFunc handler);
XSLTPUBFUN void XSLTCALL
xsltSetTransformErrorFunc (xsltTransformContextPtr ctxt,
void *ctx,
xmlGenericErrorFunc handler);
XSLTPUBFUN void WINAPIV
xsltTransformError (xsltTransformContextPtr ctxt,
xsltStylesheetPtr style,
xmlNodePtr node,
const char *msg,
...) LIBXSLT_ATTR_FORMAT(4,5);
XSLTPUBFUN int XSLTCALL
xsltSetCtxtParseOptions (xsltTransformContextPtr ctxt,
int options);
/*
* Sorting.
*/
XSLTPUBFUN void XSLTCALL
xsltDocumentSortFunction (xmlNodeSetPtr list);
XSLTPUBFUN void XSLTCALL
xsltSetSortFunc (xsltSortFunc handler);
XSLTPUBFUN void XSLTCALL
xsltSetCtxtSortFunc (xsltTransformContextPtr ctxt,
xsltSortFunc handler);
XSLTPUBFUN void XSLTCALL
xsltDefaultSortFunction (xsltTransformContextPtr ctxt,
xmlNodePtr *sorts,
int nbsorts);
XSLTPUBFUN void XSLTCALL
xsltDoSortFunction (xsltTransformContextPtr ctxt,
xmlNodePtr * sorts,
int nbsorts);
XSLTPUBFUN xmlXPathObjectPtr * XSLTCALL
xsltComputeSortResult (xsltTransformContextPtr ctxt,
xmlNodePtr sort);
/*
* QNames handling.
*/
XSLTPUBFUN const xmlChar * XSLTCALL
xsltSplitQName (xmlDictPtr dict,
const xmlChar *name,
const xmlChar **prefix);
XSLTPUBFUN const xmlChar * XSLTCALL
xsltGetQNameURI (xmlNodePtr node,
xmlChar **name);
XSLTPUBFUN const xmlChar * XSLTCALL
xsltGetQNameURI2 (xsltStylesheetPtr style,
xmlNodePtr node,
const xmlChar **name);
/*
* Output, reuse libxml I/O buffers.
*/
XSLTPUBFUN int XSLTCALL
xsltSaveResultTo (xmlOutputBufferPtr buf,
xmlDocPtr result,
xsltStylesheetPtr style);
XSLTPUBFUN int XSLTCALL
xsltSaveResultToFilename (const char *URI,
xmlDocPtr result,
xsltStylesheetPtr style,
int compression);
XSLTPUBFUN int XSLTCALL
xsltSaveResultToFile (FILE *file,
xmlDocPtr result,
xsltStylesheetPtr style);
XSLTPUBFUN int XSLTCALL
xsltSaveResultToFd (int fd,
xmlDocPtr result,
xsltStylesheetPtr style);
XSLTPUBFUN int XSLTCALL
xsltSaveResultToString (xmlChar **doc_txt_ptr,
int * doc_txt_len,
xmlDocPtr result,
xsltStylesheetPtr style);
/*
* XPath interface
*/
XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL
xsltXPathCompile (xsltStylesheetPtr style,
const xmlChar *str);
XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL
xsltXPathCompileFlags (xsltStylesheetPtr style,
const xmlChar *str,
int flags);
/*
* Profiling.
*/
XSLTPUBFUN void XSLTCALL
xsltSaveProfiling (xsltTransformContextPtr ctxt,
FILE *output);
XSLTPUBFUN xmlDocPtr XSLTCALL
xsltGetProfileInformation (xsltTransformContextPtr ctxt);
XSLTPUBFUN long XSLTCALL
xsltTimestamp (void);
XSLTPUBFUN void XSLTCALL
xsltCalibrateAdjust (long delta);
/**
* XSLT_TIMESTAMP_TICS_PER_SEC:
*
* Sampling precision for profiling
*/
#define XSLT_TIMESTAMP_TICS_PER_SEC 100000l
/*
* Hooks for the debugger.
*/
typedef enum {
XSLT_DEBUG_NONE = 0, /* no debugging allowed */
XSLT_DEBUG_INIT,
XSLT_DEBUG_STEP,
XSLT_DEBUG_STEPOUT,
XSLT_DEBUG_NEXT,
XSLT_DEBUG_STOP,
XSLT_DEBUG_CONT,
XSLT_DEBUG_RUN,
XSLT_DEBUG_RUN_RESTART,
XSLT_DEBUG_QUIT
} xsltDebugStatusCodes;
XSLTPUBVAR int xslDebugStatus;
typedef void (*xsltHandleDebuggerCallback) (xmlNodePtr cur, xmlNodePtr node,
xsltTemplatePtr templ, xsltTransformContextPtr ctxt);
typedef int (*xsltAddCallCallback) (xsltTemplatePtr templ, xmlNodePtr source);
typedef void (*xsltDropCallCallback) (void);
XSLTPUBFUN void XSLTCALL
xsltSetDebuggerStatus (int value);
XSLTPUBFUN int XSLTCALL
xsltGetDebuggerStatus (void);
XSLTPUBFUN int XSLTCALL
xsltSetDebuggerCallbacks (int no, void *block);
XSLTPUBFUN int XSLTCALL
xslAddCall (xsltTemplatePtr templ,
xmlNodePtr source);
XSLTPUBFUN void XSLTCALL
xslDropCall (void);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLTUTILS_H__ */