chromium/third_party/libxslt/src/libxslt/xsltutils.c

/*
 * xsltutils.c: Utilities for the XSL Transformation 1.0 engine
 *
 * Reference:
 *   http://www.w3.org/TR/1999/REC-xslt-19991116
 *
 * See Copyright for the status of this software.
 *
 * [email protected]
 */

#define IN_LIBXSLT
#include "libxslt.h"

#ifndef	XSLT_NEED_TRIO
#include <stdio.h>
#else
#include <trio.h>
#endif

#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>

#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/HTMLtree.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlIO.h>
#include "xsltutils.h"
#include "templates.h"
#include "xsltInternals.h"
#include "imports.h"
#include "transform.h"

#if defined(_WIN32)
#include <windows.h>
#define XSLT_WIN32_PERFORMANCE_COUNTER
#endif

/************************************************************************
 *									*
 *			Convenience function				*
 *									*
 ************************************************************************/

/**
 * xsltGetCNsProp:
 * @style: the stylesheet
 * @node:  the node
 * @name:  the attribute name
 * @nameSpace:  the URI of the namespace
 *
 * Similar to xmlGetNsProp() but with a slightly different semantic
 *
 * Search and get the value of an attribute associated to a node
 * This attribute has to be anchored in the namespace specified,
 * or has no namespace and the element is in that namespace.
 *
 * This does the entity substitution.
 * This function looks in DTD attribute declaration for #FIXED or
 * default declaration values unless DTD use has been turned off.
 *
 * Returns the attribute value or NULL if not found. The string is allocated
 *         in the stylesheet dictionary.
 */
const xmlChar *
xsltGetCNsProp(xsltStylesheetPtr style, xmlNodePtr node,
              const xmlChar *name, const xmlChar *nameSpace) {}
/**
 * xsltGetNsProp:
 * @node:  the node
 * @name:  the attribute name
 * @nameSpace:  the URI of the namespace
 *
 * Similar to xmlGetNsProp() but with a slightly different semantic
 *
 * Search and get the value of an attribute associated to a node
 * This attribute has to be anchored in the namespace specified,
 * or has no namespace and the element is in that namespace.
 *
 * This does the entity substitution.
 * This function looks in DTD attribute declaration for #FIXED or
 * default declaration values unless DTD use has been turned off.
 *
 * Returns the attribute value or NULL if not found.
 *     It's up to the caller to free the memory.
 */
xmlChar *
xsltGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {}

/**
 * xsltGetUTF8Char:
 * @utf:  a sequence of UTF-8 encoded bytes
 * @len:  a pointer to @bytes len
 *
 * Read one UTF8 Char from @utf
 * Function copied from libxml2 xmlGetUTF8Char() ... to discard ultimately
 * and use the original API
 *
 * Returns the char value or -1 in case of error and update @len with the
 *        number of bytes used
 */
int
xsltGetUTF8Char(const unsigned char *utf, int *len) {}

/**
 * xsltGetUTF8CharZ:
 * @utf:  a sequence of UTF-8 encoded bytes
 * @len:  a pointer to @bytes len
 *
 * Read one UTF8 Char from a null-terminated string.
 *
 * Returns the char value or -1 in case of error and update @len with the
 *        number of bytes used
 */
int
xsltGetUTF8CharZ(const unsigned char *utf, int *len) {}

#ifdef XSLT_REFACTORED

/**
 * xsltPointerListAddSize:
 * @list: the pointer list structure
 * @item: the item to be stored
 * @initialSize: the initial size of the list
 *
 * Adds an item to the list.
 *
 * Returns the position of the added item in the list or
 *         -1 in case of an error.
 */
int
xsltPointerListAddSize(xsltPointerListPtr list,
		       void *item,
		       int initialSize)
{
    if (list->items == NULL) {
	if (initialSize <= 0)
	    initialSize = 1;
	list->items = (void **) xmlMalloc(
	    initialSize * sizeof(void *));
	if (list->items == NULL) {
	    xsltGenericError(xsltGenericErrorContext,
	     "xsltPointerListAddSize: memory allocation failure.\n");
	    return(-1);
	}
	list->number = 0;
	list->size = initialSize;
    } else if (list->size <= list->number) {
	list->size *= 2;
	list->items = (void **) xmlRealloc(list->items,
	    list->size * sizeof(void *));
	if (list->items == NULL) {
	    xsltGenericError(xsltGenericErrorContext,
	     "xsltPointerListAddSize: memory re-allocation failure.\n");
	    list->size = 0;
	    return(-1);
	}
    }
    list->items[list->number++] = item;
    return(0);
}

/**
 * xsltPointerListCreate:
 * @initialSize: the initial size for the list
 *
 * Creates an xsltPointerList structure.
 *
 * Returns a xsltPointerList structure or NULL in case of an error.
 */
xsltPointerListPtr
xsltPointerListCreate(int initialSize)
{
    xsltPointerListPtr ret;

    ret = xmlMalloc(sizeof(xsltPointerList));
    if (ret == NULL) {
	xsltGenericError(xsltGenericErrorContext,
	     "xsltPointerListCreate: memory allocation failure.\n");
	return (NULL);
    }
    memset(ret, 0, sizeof(xsltPointerList));
    if (initialSize > 0) {
	xsltPointerListAddSize(ret, NULL, initialSize);
	ret->number = 0;
    }
    return (ret);
}

/**
 * xsltPointerListFree:
 * @list: pointer to the list to be freed
 *
 * Frees the xsltPointerList structure. This does not free
 * the content of the list.
 */
void
xsltPointerListFree(xsltPointerListPtr list)
{
    if (list == NULL)
	return;
    if (list->items != NULL)
	xmlFree(list->items);
    xmlFree(list);
}

/**
 * xsltPointerListClear:
 * @list: pointer to the list to be cleared
 *
 * Resets the list, but does not free the allocated array
 * and does not free the content of the list.
 */
void
xsltPointerListClear(xsltPointerListPtr list)
{
    if (list->items != NULL) {
	xmlFree(list->items);
	list->items = NULL;
    }
    list->number = 0;
    list->size = 0;
}

#endif /* XSLT_REFACTORED */

/************************************************************************
 *									*
 *		Handling of XSLT stylesheets messages			*
 *									*
 ************************************************************************/

/**
 * xsltMessage:
 * @ctxt:  an XSLT processing context
 * @node:  The current node
 * @inst:  The node containing the message instruction
 *
 * Process and xsl:message construct
 */
void
xsltMessage(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst) {}

/************************************************************************
 *									*
 *		Handling of out of context errors			*
 *									*
 ************************************************************************/

#define XSLT_GET_VAR_STR(msg, str)
/**
 * xsltGenericErrorDefaultFunc:
 * @ctx:  an error context
 * @msg:  the message to display/transmit
 * @...:  extra parameters for the message display
 *
 * Default handler for out of context error messages.
 */
static void LIBXSLT_ATTR_FORMAT(2,3)
xsltGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {}

xmlGenericErrorFunc xsltGenericError =;
void *xsltGenericErrorContext =;


/**
 * xsltSetGenericErrorFunc:
 * @ctx:  the new error handling context
 * @handler:  the new handler function
 *
 * Function to reset the handler and the error context for out of
 * context error messages.
 * This simply means that @handler will be called for subsequent
 * error messages while not parsing nor validating. And @ctx will
 * be passed as first argument to @handler
 * One can simply force messages to be emitted to another FILE * than
 * stderr by setting @ctx to this file handle and @handler to NULL.
 */
void
xsltSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {}

/**
 * xsltGenericDebugDefaultFunc:
 * @ctx:  an error context
 * @msg:  the message to display/transmit
 * @...:  extra parameters for the message display
 *
 * Default handler for out of context error messages.
 */
static void LIBXSLT_ATTR_FORMAT(2,3)
xsltGenericDebugDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {}

xmlGenericErrorFunc xsltGenericDebug =;
void *xsltGenericDebugContext =;


/**
 * xsltSetGenericDebugFunc:
 * @ctx:  the new error handling context
 * @handler:  the new handler function
 *
 * Function to reset the handler and the error context for out of
 * context error messages.
 * This simply means that @handler will be called for subsequent
 * error messages while not parsing or validating. And @ctx will
 * be passed as first argument to @handler
 * One can simply force messages to be emitted to another FILE * than
 * stderr by setting @ctx to this file handle and @handler to NULL.
 */
void
xsltSetGenericDebugFunc(void *ctx, xmlGenericErrorFunc handler) {}

/**
 * xsltPrintErrorContext:
 * @ctxt:  the transformation context
 * @style:  the stylesheet
 * @node:  the current node being processed
 *
 * Display the context of an error.
 */
void
xsltPrintErrorContext(xsltTransformContextPtr ctxt,
	              xsltStylesheetPtr style, xmlNodePtr node) {}

/**
 * xsltSetTransformErrorFunc:
 * @ctxt:  the XSLT transformation context
 * @ctx:  the new error handling context
 * @handler:  the new handler function
 *
 * Function to reset the handler and the error context for out of
 * context error messages specific to a given XSLT transromation.
 *
 * This simply means that @handler will be called for subsequent
 * error messages while running the transformation.
 */
void
xsltSetTransformErrorFunc(xsltTransformContextPtr ctxt,
                          void *ctx, xmlGenericErrorFunc handler)
{}

/**
 * xsltTransformError:
 * @ctxt:  an XSLT transformation context
 * @style:  the XSLT stylesheet used
 * @node:  the current node in the stylesheet
 * @msg:  the message to display/transmit
 * @...:  extra parameters for the message display
 *
 * Display and format an error messages, gives file, line, position and
 * extra parameters, will use the specific transformation context if available
 */
void
xsltTransformError(xsltTransformContextPtr ctxt,
		   xsltStylesheetPtr style,
		   xmlNodePtr node,
		   const char *msg, ...) {}

/************************************************************************
 *									*
 *				QNames					*
 *									*
 ************************************************************************/

/**
 * xsltSplitQName:
 * @dict: a dictionary
 * @name:  the full QName
 * @prefix: the return value
 *
 * Split QNames into prefix and local names, both allocated from a dictionary.
 *
 * Returns: the localname or NULL in case of error.
 */
const xmlChar *
xsltSplitQName(xmlDictPtr dict, const xmlChar *name, const xmlChar **prefix) {}

/**
 * xsltGetQNameURI:
 * @node:  the node holding the QName
 * @name:  pointer to the initial QName value
 *
 * This function analyzes @name, if the name contains a prefix,
 * the function seaches the associated namespace in scope for it.
 * It will also replace @name value with the NCName, the old value being
 * freed.
 * Errors in the prefix lookup are signalled by setting @name to NULL.
 *
 * NOTE: the namespace returned is a pointer to the place where it is
 *       defined and hence has the same lifespan as the document holding it.
 *
 * Returns the namespace URI if there is a prefix, or NULL if @name is
 *         not prefixed.
 */
const xmlChar *
xsltGetQNameURI(xmlNodePtr node, xmlChar ** name)
{}

/**
 * xsltGetQNameURI2:
 * @style:  stylesheet pointer
 * @node:   the node holding the QName
 * @name:   pointer to the initial QName value
 *
 * This function is similar to xsltGetQNameURI, but is used when
 * @name is a dictionary entry.
 *
 * Returns the namespace URI if there is a prefix, or NULL if @name is
 * not prefixed.
 */
const xmlChar *
xsltGetQNameURI2(xsltStylesheetPtr style, xmlNodePtr node,
		 const xmlChar **name) {}

/************************************************************************
 *									*
 *				Sorting					*
 *									*
 ************************************************************************/

/**
 * xsltDocumentSortFunction:
 * @list:  the node set
 *
 * reorder the current node list @list accordingly to the document order
 * This function is slow, obsolete and should not be used anymore.
 */
void
xsltDocumentSortFunction(xmlNodeSetPtr list) {}

/**
 * xsltComputeSortResultInternal:
 * @ctxt:  a XSLT process context
 * @sort:  xsl:sort node
 * @number:  data-type is number
 * @locale:  transform strings according to locale
 *
 * reorder the current node list accordingly to the set of sorting
 * requirement provided by the array of nodes.
 *
 * Returns a ordered XPath nodeset or NULL in case of error.
 */
static xmlXPathObjectPtr *
xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort,
                              int number, void *locale) {}

/**
 * xsltComputeSortResult:
 * @ctxt:  a XSLT process context
 * @sort:  node list
 *
 * reorder the current node list accordingly to the set of sorting
 * requirement provided by the array of nodes.
 *
 * Returns a ordered XPath nodeset or NULL in case of error.
 */
xmlXPathObjectPtr *
xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) {}

/**
 * xsltDefaultSortFunction:
 * @ctxt:  a XSLT process context
 * @sorts:  array of sort nodes
 * @nbsorts:  the number of sorts in the array
 *
 * reorder the current node list accordingly to the set of sorting
 * requirement provided by the arry of nodes.
 */
void
xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
	           int nbsorts) {}


static xsltSortFunc xsltSortFunction =;

/**
 * xsltDoSortFunction:
 * @ctxt:  a XSLT process context
 * @sorts:  array of sort nodes
 * @nbsorts:  the number of sorts in the array
 *
 * reorder the current node list accordingly to the set of sorting
 * requirement provided by the arry of nodes.
 * This is a wrapper function, the actual function used is specified
 * using xsltSetCtxtSortFunc() to set the context specific sort function,
 * or xsltSetSortFunc() to set the global sort function.
 * If a sort function is set on the context, this will get called.
 * Otherwise the global sort function is called.
 */
void
xsltDoSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr * sorts,
                   int nbsorts)
{}

/**
 * xsltSetSortFunc:
 * @handler:  the new handler function
 *
 * DEPRECATED: Use xsltSetCtxtLocaleHandlers.
 *
 * Function to reset the global handler for XSLT sorting.
 * If the handler is NULL, the default sort function will be used.
 */
void
xsltSetSortFunc(xsltSortFunc handler) {}

/**
 * xsltSetCtxtSortFunc:
 * @ctxt:  a XSLT process context
 * @handler:  the new handler function
 *
 * DEPRECATED: Use xsltSetCtxtLocaleHandlers.
 *
 * Function to set the handler for XSLT sorting
 * for the specified context.
 * If the handler is NULL, then the global
 * sort function will be called
 */
void
xsltSetCtxtSortFunc(xsltTransformContextPtr ctxt, xsltSortFunc handler) {}

/**
 * xsltSetCtxtLocaleHandlers:
 * @ctxt:  an XSLT transform context
 * @newLocale:  locale constructor
 * @freeLocale:  locale destructor
 * @genSortKey:  sort key generator
 *
 * Set the locale handlers.
 */
void
xsltSetCtxtLocaleHandlers(xsltTransformContextPtr ctxt,
                          xsltNewLocaleFunc newLocale,
                          xsltFreeLocaleFunc freeLocale,
                          xsltGenSortKeyFunc genSortKey) {}

/************************************************************************
 *									*
 *				Parsing options				*
 *									*
 ************************************************************************/

/**
 * xsltSetCtxtParseOptions:
 * @ctxt:  a XSLT process context
 * @options:  a combination of libxml2 xmlParserOption
 *
 * Change the default parser option passed by the XSLT engine to the
 * parser when using document() loading.
 *
 * Returns the previous options or -1 in case of error
 */
int
xsltSetCtxtParseOptions(xsltTransformContextPtr ctxt, int options)
{}

/************************************************************************
 *									*
 *				Output					*
 *									*
 ************************************************************************/

/**
 * xsltSaveResultTo:
 * @buf:  an output buffer
 * @result:  the result xmlDocPtr
 * @style:  the stylesheet
 *
 * Save the result @result obtained by applying the @style stylesheet
 * to an I/O output channel @buf
 *
 * Returns the number of byte written or -1 in case of failure.
 */
int
xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result,
	       xsltStylesheetPtr style) {}

/**
 * xsltSaveResultToFilename:
 * @URL:  a filename or URL
 * @result:  the result xmlDocPtr
 * @style:  the stylesheet
 * @compression:  the compression factor (0 - 9 included)
 *
 * Save the result @result obtained by applying the @style stylesheet
 * to a file or @URL
 *
 * Returns the number of byte written or -1 in case of failure.
 */
int
xsltSaveResultToFilename(const char *URL, xmlDocPtr result,
			 xsltStylesheetPtr style, int compression) {}

/**
 * xsltSaveResultToFile:
 * @file:  a FILE * I/O
 * @result:  the result xmlDocPtr
 * @style:  the stylesheet
 *
 * Save the result @result obtained by applying the @style stylesheet
 * to an open FILE * I/O.
 * This does not close the FILE @file
 *
 * Returns the number of bytes written or -1 in case of failure.
 */
int
xsltSaveResultToFile(FILE *file, xmlDocPtr result, xsltStylesheetPtr style) {}

/**
 * xsltSaveResultToFd:
 * @fd:  a file descriptor
 * @result:  the result xmlDocPtr
 * @style:  the stylesheet
 *
 * Save the result @result obtained by applying the @style stylesheet
 * to an open file descriptor
 * This does not close the descriptor.
 *
 * Returns the number of bytes written or -1 in case of failure.
 */
int
xsltSaveResultToFd(int fd, xmlDocPtr result, xsltStylesheetPtr style) {}

/**
 * xsltSaveResultToString:
 * @doc_txt_ptr:  Memory pointer for allocated XML text
 * @doc_txt_len:  Length of the generated XML text
 * @result:  the result xmlDocPtr
 * @style:  the stylesheet
 *
 * Save the result @result obtained by applying the @style stylesheet
 * to a new allocated string.
 *
 * Returns 0 in case of success and -1 in case of error
 */
int
xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len,
		       xmlDocPtr result, xsltStylesheetPtr style) {}

/**
 * xsltGetSourceNodeFlags:
 * @node:  Node from source document
 *
 * Returns the flags for a source node.
 */
int
xsltGetSourceNodeFlags(xmlNodePtr node) {}

/**
 * xsltSetSourceNodeFlags:
 * @node:  Node from source document
 * @flags:  Flags
 *
 * Sets the specified flags to 1.
 *
 * Returns 0 on success, -1 on error.
 */
int
xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node,
                       int flags) {}

/**
 * xsltClearSourceNodeFlags:
 * @node:  Node from source document
 * @flags:  Flags
 *
 * Sets the specified flags to 0.
 *
 * Returns 0 on success, -1 on error.
 */
int
xsltClearSourceNodeFlags(xmlNodePtr node, int flags) {}

/**
 * xsltGetPSVIPtr:
 * @cur:  Node
 *
 * Returns a pointer to the psvi member of a node or NULL on error.
 */
void **
xsltGetPSVIPtr(xmlNodePtr cur) {}

#ifdef WITH_PROFILER

/************************************************************************
 *									*
 *		Generating profiling information			*
 *									*
 ************************************************************************/

static long calibration =;

/**
 * xsltCalibrateTimestamps:
 *
 * Used for to calibrate the xsltTimestamp() function
 * Should work if launched at startup and we don't loose our quantum :-)
 *
 * Returns the number of milliseconds used by xsltTimestamp()
 */
#if !defined(XSLT_WIN32_PERFORMANCE_COUNTER) && \
    (defined(HAVE_CLOCK_GETTIME) || defined(HAVE_GETTIMEOFDAY))
static long
xsltCalibrateTimestamps(void) {}
#endif

/**
 * xsltCalibrateAdjust:
 * @delta:  a negative dealy value found
 *
 * Used for to correct the calibration for xsltTimestamp()
 */
void
xsltCalibrateAdjust(long delta) {}

/**
 * xsltTimestamp:
 *
 * Used for gathering profiling data
 *
 * Returns the number of tenth of milliseconds since the beginning of the
 * profiling
 */
long
xsltTimestamp(void)
{}

static char *
pretty_templ_match(xsltTemplatePtr templ) {}

#define MAX_TEMPLATES

/**
 * xsltSaveProfiling:
 * @ctxt:  an XSLT context
 * @output:  a FILE * for saving the information
 *
 * Save the profiling information on @output
 */
void
xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {}

/************************************************************************
 *									*
 *		Fetching profiling information				*
 *									*
 ************************************************************************/

/**
 * xsltGetProfileInformation:
 * @ctxt:  a transformation context
 *
 * This function should be called after the transformation completed
 * to extract template processing profiling information if available.
 * The information is returned as an XML document tree like
 * <?xml version="1.0"?>
 * <profile>
 * <template rank="1" match="*" name=""
 *         mode="" calls="6" time="48" average="8"/>
 * <template rank="2" match="item2|item3" name=""
 *         mode="" calls="10" time="30" average="3"/>
 * <template rank="3" match="item1" name=""
 *         mode="" calls="5" time="17" average="3"/>
 * </profile>
 * The caller will need to free up the returned tree with xmlFreeDoc()
 *
 * Returns the xmlDocPtr corresponding to the result or NULL if not available.
 */

xmlDocPtr
xsltGetProfileInformation(xsltTransformContextPtr ctxt)
{}

#endif /* WITH_PROFILER */

/************************************************************************
 *									*
 *		Hooks for libxml2 XPath					*
 *									*
 ************************************************************************/

/**
 * xsltXPathCompileFlags:
 * @style: the stylesheet
 * @str:  the XPath expression
 * @flags: extra compilation flags to pass down to libxml2 XPath
 *
 * Compile an XPath expression
 *
 * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL.
 *         the caller has to free the object.
 */
xmlXPathCompExprPtr
xsltXPathCompileFlags(xsltStylesheetPtr style, const xmlChar *str, int flags) {}

/**
 * xsltXPathCompile:
 * @style: the stylesheet
 * @str:  the XPath expression
 *
 * Compile an XPath expression
 *
 * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL.
 *         the caller has to free the object.
 */
xmlXPathCompExprPtr
xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str) {}

/************************************************************************
 *									*
 *		Hooks for the debugger					*
 *									*
 ************************************************************************/

int xslDebugStatus;

/**
 * xsltGetDebuggerStatus:
 *
 * Get xslDebugStatus.
 *
 * Returns the value of xslDebugStatus.
 */
int
xsltGetDebuggerStatus(void)
{}

#ifdef WITH_DEBUGGER

/*
 * There is currently only 3 debugging callback defined
 * Debugger callbacks are disabled by default
 */
#define XSLT_CALLBACK_NUMBER

typedef struct _xsltDebuggerCallbacks xsltDebuggerCallbacks;
typedef xsltDebuggerCallbacks *xsltDebuggerCallbacksPtr;
struct _xsltDebuggerCallbacks {
    xsltHandleDebuggerCallback handler;
    xsltAddCallCallback add;
    xsltDropCallCallback drop;
};

static xsltDebuggerCallbacks xsltDebuggerCurrentCallbacks = {
    NULL, /* handler */
    NULL, /* add */
    NULL  /* drop */
};

/**
 * xsltSetDebuggerStatus:
 * @value : the value to be set
 *
 * This function sets the value of xslDebugStatus.
 */
void
xsltSetDebuggerStatus(int value)
{
    xslDebugStatus = value;
}

/**
 * xsltSetDebuggerCallbacks:
 * @no : number of callbacks
 * @block : the block of callbacks
 *
 * This function allow to plug a debugger into the XSLT library
 * @block points to a block of memory containing the address of @no
 * callback routines.
 *
 * Returns 0 in case of success and -1 in case of error
 */
int
xsltSetDebuggerCallbacks(int no, void *block)
{
    xsltDebuggerCallbacksPtr callbacks;

    if ((block == NULL) || (no != XSLT_CALLBACK_NUMBER))
	return(-1);

    callbacks = (xsltDebuggerCallbacksPtr) block;
    xsltDebuggerCurrentCallbacks.handler = callbacks->handler;
    xsltDebuggerCurrentCallbacks.add  = callbacks->add;
    xsltDebuggerCurrentCallbacks.drop  = callbacks->drop;
    return(0);
}

/**
 * xslHandleDebugger:
 * @cur : source node being executed
 * @node : data node being processed
 * @templ : temlate that applies to node
 * @ctxt : the xslt transform context
 *
 * If either cur or node are a breakpoint, or xslDebugStatus in state
 *   where debugging must occcur at this time then transfer control
 *   to the xslDebugBreak function
 */
void
xslHandleDebugger(xmlNodePtr cur, xmlNodePtr node, xsltTemplatePtr templ,
	          xsltTransformContextPtr ctxt)
{
    if (xsltDebuggerCurrentCallbacks.handler != NULL)
	xsltDebuggerCurrentCallbacks.handler(cur, node, templ, ctxt);
}

/**
 * xslAddCall:
 * @templ : current template being applied
 * @source : the source node being processed
 *
 * Add template "call" to call stack
 * Returns : 1 on sucess 0 otherwise an error may be printed if
 *            WITH_XSLT_DEBUG_BREAKPOINTS is defined
 */
int
xslAddCall(xsltTemplatePtr templ, xmlNodePtr source)
{
    if (xsltDebuggerCurrentCallbacks.add != NULL)
	return(xsltDebuggerCurrentCallbacks.add(templ, source));
    return(0);
}

/**
 * xslDropCall:
 *
 * Drop the topmost item off the call stack
 */
void
xslDropCall(void)
{
    if (xsltDebuggerCurrentCallbacks.drop != NULL)
	xsltDebuggerCurrentCallbacks.drop();
}

#endif /* WITH_DEBUGGER */