libs: Import code from upstream libxslt 1.1.34.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9d9d4fcc37
commit
c638618cbc
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
|
@ -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.
|
||||
----------------------------------------------------------------------
|
|
@ -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
|
@ -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__ */
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
@ -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__ */
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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
|
@ -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__ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
|
@ -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__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -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__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -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__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -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__ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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
|
@ -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__ */
|
||||
|
|
@ -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 */
|
|
@ -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
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
@ -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__ */
|
|
@ -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__ */
|
||||
|
||||
|
|
@ -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*/
|
|
@ -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
|
@ -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__ */
|
||||
|
||||
|
Loading…
Reference in New Issue