chromium/third_party/libxslt/src/libxslt/preproc.c

/*
 * preproc.c: Preprocessing of style operations
 *
 * References:
 *   http://www.w3.org/TR/1999/REC-xslt-19991116
 *
 *   Michael Kay "XSLT Programmer's Reference" pp 637-643
 *   Writing Multiple Output Files
 *
 *   XSLT-1.1 Working Draft
 *   http://www.w3.org/TR/xslt11#multiple-output
 *
 * See Copyright for the status of this software.
 *
 * [email protected]
 */

#define IN_LIBXSLT
#include "libxslt.h"

#include <string.h>

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/valid.h>
#include <libxml/hash.h>
#include <libxml/uri.h>
#include <libxml/encoding.h>
#include <libxml/xmlerror.h>
#include "xslt.h"
#include "xsltutils.h"
#include "xsltInternals.h"
#include "transform.h"
#include "templates.h"
#include "variables.h"
#include "numbersInternals.h"
#include "preproc.h"
#include "extra.h"
#include "imports.h"
#include "extensions.h"
#include "pattern.h"

#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_PREPROC
#endif

const xmlChar *xsltExtMarker =;

/************************************************************************
 *									*
 *			Grammar checks					*
 *									*
 ************************************************************************/

#ifdef XSLT_REFACTORED
    /*
    * Grammar checks are now performed in xslt.c.
    */
#else
/**
 * xsltCheckTopLevelElement:
 * @style: the XSLT stylesheet
 * @inst: the XSLT instruction
 * @err: raise an error or not
 *
 * Check that the instruction is instanciated as a top level element.
 *
 * Returns -1 in case of error, 0 if failed and 1 in case of success
 */
static int
xsltCheckTopLevelElement(xsltStylesheetPtr style, xmlNodePtr inst, int err) {}

/**
 * xsltCheckInstructionElement:
 * @style: the XSLT stylesheet
 * @inst: the XSLT instruction
 *
 * Check that the instruction is instanciated as an instruction element.
 */
static void
xsltCheckInstructionElement(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltCheckParentElement:
 * @style: the XSLT stylesheet
 * @inst: the XSLT instruction
 * @allow1: allowed parent1
 * @allow2: allowed parent2
 *
 * Check that the instruction is instanciated as the childre of one of the
 * possible parents.
 */
static void
xsltCheckParentElement(xsltStylesheetPtr style, xmlNodePtr inst,
                       const xmlChar *allow1, const xmlChar *allow2) {}
#endif

/************************************************************************
 *									*
 *			handling of precomputed data			*
 *									*
 ************************************************************************/

/**
 * xsltNewStylePreComp:
 * @style:  the XSLT stylesheet
 * @type:  the construct type
 *
 * Create a new XSLT Style precomputed block
 *
 * Returns the newly allocated specialized structure
 *         or NULL in case of error
 */
static xsltStylePreCompPtr
xsltNewStylePreComp(xsltStylesheetPtr style, xsltStyleType type) {}

/**
 * xsltFreeStylePreComp:
 * @comp:  an XSLT Style precomputed block
 *
 * Free up the memory allocated by @comp
 */
static void
xsltFreeStylePreComp(xsltStylePreCompPtr comp) {}


/************************************************************************
 *									*
 *		    XSLT-1.1 extensions					*
 *									*
 ************************************************************************/

/**
 * xsltDocumentComp:
 * @style:  the XSLT stylesheet
 * @inst:  the instruction in the stylesheet
 * @function:  unused
 *
 * Pre process an XSLT-1.1 document element
 *
 * Returns a precompiled data structure for the element
 */
xsltElemPreCompPtr
xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst,
		 xsltTransformFunction function ATTRIBUTE_UNUSED) {}

/************************************************************************
 *									*
 *		Most of the XSLT-1.0 transformations			*
 *									*
 ************************************************************************/

/**
 * xsltSortComp:
 * @style:  the XSLT stylesheet
 * @inst:  the xslt sort node
 *
 * Process the xslt sort node on the source node
 */
static void
xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltCopyComp:
 * @style:  the XSLT stylesheet
 * @inst:  the xslt copy node
 *
 * Process the xslt copy node on the source node
 */
static void
xsltCopyComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

#ifdef XSLT_REFACTORED
    /* Enable if ever needed for xsl:text. */
#else
/**
 * xsltTextComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt text node
 *
 * TODO: This function is obsolete, since xsl:text won't
 *  be compiled, but removed from the tree.
 *
 * Process the xslt text node on the source node
 */
static void
xsltTextComp(xsltStylesheetPtr style, xmlNodePtr inst) {}
#endif /* else of XSLT_REFACTORED */

/**
 * xsltElementComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt element node
 *
 * Process the xslt element node on the source node
 */
static void
xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltAttributeComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt attribute node
 *
 * Process the xslt attribute node on the source node
 */
static void
xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltCommentComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt comment node
 *
 * Process the xslt comment node on the source node
 */
static void
xsltCommentComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltProcessingInstructionComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt processing-instruction node
 *
 * Process the xslt processing-instruction node on the source node
 */
static void
xsltProcessingInstructionComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltCopyOfComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt copy-of node
 *
 * Process the xslt copy-of node on the source node
 */
static void
xsltCopyOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltValueOfComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt value-of node
 *
 * Process the xslt value-of node on the source node
 */
static void
xsltValueOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

static void
xsltGetQNameProperty(xsltStylesheetPtr style, xmlNodePtr inst,
		     const xmlChar *propName,
		     int mandatory,
		     int *hasProp, const xmlChar **nsName,
		     const xmlChar** localName)
{}

/**
 * xsltWithParamComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt with-param node
 *
 * Process the xslt with-param node on the source node
 * Allowed parents: xsl:call-template, xsl:apply-templates.
 * <xsl:with-param
 *  name = qname
 *  select = expression>
 *  <!-- Content: template -->
 * </xsl:with-param>
 */
static void
xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltNumberComp:
 * @style: an XSLT compiled stylesheet
 * @cur:   the xslt number node
 *
 * Process the xslt number node on the source node
 */
static void
xsltNumberComp(xsltStylesheetPtr style, xmlNodePtr cur) {}

/**
 * xsltApplyImportsComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt apply-imports node
 *
 * Process the xslt apply-imports node on the source node
 */
static void
xsltApplyImportsComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltCallTemplateComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt call-template node
 *
 * Process the xslt call-template node on the source node
 */
static void
xsltCallTemplateComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltApplyTemplatesComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the apply-templates node
 *
 * Process the apply-templates node on the source node
 */
static void
xsltApplyTemplatesComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltChooseComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt choose node
 *
 * Process the xslt choose node on the source node
 */
static void
xsltChooseComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltIfComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt if node
 *
 * Process the xslt if node on the source node
 */
static void
xsltIfComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltWhenComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt if node
 *
 * Process the xslt if node on the source node
 */
static void
xsltWhenComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltForEachComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt for-each node
 *
 * Process the xslt for-each node on the source node
 */
static void
xsltForEachComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltVariableComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt variable node
 *
 * Process the xslt variable node on the source node
 */
static void
xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/**
 * xsltParamComp:
 * @style: an XSLT compiled stylesheet
 * @inst:  the xslt param node
 *
 * Process the xslt param node on the source node
 */
static void
xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {}

/************************************************************************
 *									*
 *		    Generic interface					*
 *									*
 ************************************************************************/

/**
 * xsltFreeStylePreComps:
 * @style:  an XSLT transformation context
 *
 * Free up the memory allocated by all precomputed blocks
 */
void
xsltFreeStylePreComps(xsltStylesheetPtr style) {}

#ifdef XSLT_REFACTORED

/**
 * xsltStylePreCompute:
 * @style:  the XSLT stylesheet
 * @node:  the element in the XSLT namespace
 *
 * Precompute an XSLT element.
 * This expects the type of the element to be already
 * set in style->compCtxt->inode->type;
 */
void
xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr node) {
    /*
    * The xsltXSLTElemMarker marker was set beforehand by
    *  the parsing mechanism for all elements in the XSLT namespace.
    */
    if (style == NULL) {
	if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
	    node->psvi = NULL;
	return;
    }
    if (node == NULL)
	return;
    if (! IS_XSLT_ELEM_FAST(node))
	return;

    node->psvi = NULL;
    if (XSLT_CCTXT(style)->inode->type != 0) {
	switch (XSLT_CCTXT(style)->inode->type) {
	    case XSLT_FUNC_APPLYTEMPLATES:
		xsltApplyTemplatesComp(style, node);
		break;
	    case XSLT_FUNC_WITHPARAM:
		xsltWithParamComp(style, node);
		break;
	    case XSLT_FUNC_VALUEOF:
		xsltValueOfComp(style, node);
		break;
	    case XSLT_FUNC_COPY:
		xsltCopyComp(style, node);
		break;
	    case XSLT_FUNC_COPYOF:
		xsltCopyOfComp(style, node);
		break;
	    case XSLT_FUNC_IF:
		xsltIfComp(style, node);
		break;
	    case XSLT_FUNC_CHOOSE:
		xsltChooseComp(style, node);
		break;
	    case XSLT_FUNC_WHEN:
		xsltWhenComp(style, node);
		break;
	    case XSLT_FUNC_OTHERWISE:
		/* NOP yet */
		return;
	    case XSLT_FUNC_FOREACH:
		xsltForEachComp(style, node);
		break;
	    case XSLT_FUNC_APPLYIMPORTS:
		xsltApplyImportsComp(style, node);
		break;
	    case XSLT_FUNC_ATTRIBUTE:
		xsltAttributeComp(style, node);
		break;
	    case XSLT_FUNC_ELEMENT:
		xsltElementComp(style, node);
		break;
	    case XSLT_FUNC_SORT:
		xsltSortComp(style, node);
		break;
	    case XSLT_FUNC_COMMENT:
		xsltCommentComp(style, node);
		break;
	    case XSLT_FUNC_NUMBER:
		xsltNumberComp(style, node);
		break;
	    case XSLT_FUNC_PI:
		xsltProcessingInstructionComp(style, node);
		break;
	    case XSLT_FUNC_CALLTEMPLATE:
		xsltCallTemplateComp(style, node);
		break;
	    case XSLT_FUNC_PARAM:
		xsltParamComp(style, node);
		break;
	    case XSLT_FUNC_VARIABLE:
		xsltVariableComp(style, node);
		break;
	    case XSLT_FUNC_FALLBACK:
		/* NOP yet */
		return;
	    case XSLT_FUNC_DOCUMENT:
		/* The extra one */
		node->psvi = (void *) xsltDocumentComp(style, node,
		    xsltDocumentElem);
		break;
	    case XSLT_FUNC_MESSAGE:
		/* NOP yet */
		return;
	    default:
		/*
		* NOTE that xsl:text, xsl:template, xsl:stylesheet,
		*  xsl:transform, xsl:import, xsl:include are not expected
		*  to be handed over to this function.
		*/
		xsltTransformError(NULL, style, node,
		    "Internal error: (xsltStylePreCompute) cannot handle "
		    "the XSLT element '%s'.\n", node->name);
		style->errors++;
		return;
	}
    } else {
	/*
	* Fallback to string comparison.
	*/
	if (IS_XSLT_NAME(node, "apply-templates")) {
	    xsltApplyTemplatesComp(style, node);
	} else if (IS_XSLT_NAME(node, "with-param")) {
	    xsltWithParamComp(style, node);
	} else if (IS_XSLT_NAME(node, "value-of")) {
	    xsltValueOfComp(style, node);
	} else if (IS_XSLT_NAME(node, "copy")) {
	    xsltCopyComp(style, node);
	} else if (IS_XSLT_NAME(node, "copy-of")) {
	    xsltCopyOfComp(style, node);
	} else if (IS_XSLT_NAME(node, "if")) {
	    xsltIfComp(style, node);
	} else if (IS_XSLT_NAME(node, "choose")) {
	    xsltChooseComp(style, node);
	} else if (IS_XSLT_NAME(node, "when")) {
	    xsltWhenComp(style, node);
	} else if (IS_XSLT_NAME(node, "otherwise")) {
	    /* NOP yet */
	    return;
	} else if (IS_XSLT_NAME(node, "for-each")) {
	    xsltForEachComp(style, node);
	} else if (IS_XSLT_NAME(node, "apply-imports")) {
	    xsltApplyImportsComp(style, node);
	} else if (IS_XSLT_NAME(node, "attribute")) {
	    xsltAttributeComp(style, node);
	} else if (IS_XSLT_NAME(node, "element")) {
	    xsltElementComp(style, node);
	} else if (IS_XSLT_NAME(node, "sort")) {
	    xsltSortComp(style, node);
	} else if (IS_XSLT_NAME(node, "comment")) {
	    xsltCommentComp(style, node);
	} else if (IS_XSLT_NAME(node, "number")) {
	    xsltNumberComp(style, node);
	} else if (IS_XSLT_NAME(node, "processing-instruction")) {
	    xsltProcessingInstructionComp(style, node);
	} else if (IS_XSLT_NAME(node, "call-template")) {
	    xsltCallTemplateComp(style, node);
	} else if (IS_XSLT_NAME(node, "param")) {
	    xsltParamComp(style, node);
	} else if (IS_XSLT_NAME(node, "variable")) {
	    xsltVariableComp(style, node);
	} else if (IS_XSLT_NAME(node, "fallback")) {
	    /* NOP yet */
	    return;
	} else if (IS_XSLT_NAME(node, "document")) {
	    /* The extra one */
	    node->psvi = (void *) xsltDocumentComp(style, node,
		xsltDocumentElem);
	} else if (IS_XSLT_NAME(node, "output")) {
	    /* Top-level */
	    return;
	} else if (IS_XSLT_NAME(node, "preserve-space")) {
	    /* Top-level */
	    return;
	} else if (IS_XSLT_NAME(node, "strip-space")) {
	    /* Top-level */
	    return;
	} else if (IS_XSLT_NAME(node, "key")) {
	    /* Top-level */
	    return;
	} else if (IS_XSLT_NAME(node, "message")) {
	    return;
	} else if (IS_XSLT_NAME(node, "attribute-set")) {
	    /* Top-level */
	    return;
	} else if (IS_XSLT_NAME(node, "namespace-alias")) {
	    /* Top-level */
	    return;
	} else if (IS_XSLT_NAME(node, "decimal-format")) {
	    /* Top-level */
	    return;
	} else if (IS_XSLT_NAME(node, "include")) {
	    /* Top-level */
	} else {
	    /*
	    * NOTE that xsl:text, xsl:template, xsl:stylesheet,
	    *  xsl:transform, xsl:import, xsl:include are not expected
	    *  to be handed over to this function.
	    */
	    xsltTransformError(NULL, style, node,
		"Internal error: (xsltStylePreCompute) cannot handle "
		"the XSLT element '%s'.\n", node->name);
		style->errors++;
	    return;
	}
    }
    /*
    * Assign the current list of in-scope namespaces to the
    * item. This is needed for XPath expressions.
    */
    if (node->psvi != NULL) {
	((xsltStylePreCompPtr) node->psvi)->inScopeNs =
	    XSLT_CCTXT(style)->inode->inScopeNs;
    }
}

#else

/**
 * xsltStylePreCompute:
 * @style:  the XSLT stylesheet
 * @inst:  the instruction in the stylesheet
 *
 * Precompute an XSLT stylesheet element
 */
void
xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {}
#endif /* XSLT_REFACTORED */