1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-08-05 23:35:48 +03:00

revamped the mechanism to hook a debuger to use a callback setup function,

* libxslt/attributes.c libxslt/transform.c libxslt/xsltutils.c
  libxslt/xsltutils.h: revamped the mechanism to hook a debuger
  to use a callback setup function, deprecating libxsltbreakpoint
* xsltproc/Makefile.am configure.in breakpoint/Makefile.am: removing
  dependancies on libxsltbreakpoint
Daniel
This commit is contained in:
Daniel Veillard
2001-11-30 12:01:25 +00:00
parent b95c91c67b
commit 3efba7ccbf
8 changed files with 412 additions and 287 deletions

View File

@@ -1,3 +1,11 @@
Fri Nov 30 12:59:05 CET 2001 Daniel Veillard <daniel@veillard.com>
* libxslt/attributes.c libxslt/transform.c libxslt/xsltutils.c
libxslt/xsltutils.h: revamped the mechanism to hook a debuger
to use a callback setup function, deprecating libxsltbreakpoint
* xsltproc/Makefile.am configure.in breakpoint/Makefile.am: removing
dependancies on libxsltbreakpoint
Thu Nov 29 09:52:38 CET 2001 Daniel Veillard <daniel@veillard.com> Thu Nov 29 09:52:38 CET 2001 Daniel Veillard <daniel@veillard.com>
Build patch from Peter Williams <peterw@ximian.com> Build patch from Peter Williams <peterw@ximian.com>

View File

@@ -15,7 +15,7 @@ libxsltbreakpoint_la_SOURCES = \
libxsltbreakpoint_la_LIBADD = @LIBXML_LIBS@ libxsltbreakpoint_la_LIBADD = @LIBXML_LIBS@
libxsltbreakpoint_la_LDFLAGS = -version-info @LIBXSLT_VERSION_INFO@ libxsltbreakpoint_la_LDFLAGS = -version-info @LIBXSLTBREAK_VERSION_INFO@
man_MANS = #breakpoint.4 man_MANS = #breakpoint.4

View File

@@ -42,6 +42,30 @@ AC_SUBST(LIBEXSLT_VERSION)
AC_SUBST(LIBEXSLT_VERSION_INFO) AC_SUBST(LIBEXSLT_VERSION_INFO)
AC_SUBST(LIBEXSLT_VERSION_NUMBER) AC_SUBST(LIBEXSLT_VERSION_NUMBER)
dnl
dnl libxsltbreakpoint is a compatibility obsoleted library
dnl it's blocked at 1.0.8 and should be removed in default build in the
dnl future
dnl
LIBXSLTBREAK_MAJOR_VERSION=1
LIBXSLTBREAK_MINOR_VERSION=0
LIBXSLTBREAK_MICRO_VERSION=8
LIBXSLTBREAK_VERSION=$LIBXSLTBREAK_MAJOR_VERSION.$LIBXSLTBREAK_MINOR_VERSION.$LIBXSLTBREAK_MICRO_VERSION
LIBXSLTBREAK_VERSION_INFO=`expr $LIBXSLTBREAK_MAJOR_VERSION + $LIBXSLTBREAK_MINOR_VERSION`:$LIBXSLTBREAK_MICRO_VERSION:$LIBXSLTBREAK_MINOR_VERSION
LIBXSLTBREAK_VERSION_NUMBER=`expr $LIBXSLTBREAK_MAJOR_VERSION \* 10000 + $LIBXSLTBREAK_MINOR_VERSION \* 100 + $LIBXSLTBREAK_MICRO_VERSION`
AC_SUBST(LIBXSLTBREAK_MAJOR_VERSION)
AC_SUBST(LIBXSLTBREAK_MINOR_VERSION)
AC_SUBST(LIBXSLTBREAK_MICRO_VERSION)
AC_SUBST(LIBXSLTBREAK_VERSION)
AC_SUBST(LIBXSLTBREAK_VERSION_INFO)
AC_SUBST(LIBXSLTBREAK_VERSION_NUMBER)
VERSION=${LIBXSLT_VERSION} VERSION=${LIBXSLT_VERSION}
@@ -136,7 +160,7 @@ AC_SUBST(WITH_MEM_DEBUG)
dnl dnl
dnl Is debugger support requested dnl Is debugger support requested
dnl dnl
AC_ARG_WITH(with_debugger, [ --with-debugger Add the debugging module (off)]) AC_ARG_WITH(with_debugger, [ --with-debugger Add the debugging support (on)])
if test "$with_debugger" = "no" ; then if test "$with_debugger" = "no" ; then
echo Disabling debugger echo Disabling debugger
WITH_DEBUGGER=0 WITH_DEBUGGER=0
@@ -260,13 +284,8 @@ case ${host} in
esac esac
XSLT_INCLUDEDIR='-I${includedir}' XSLT_INCLUDEDIR='-I${includedir}'
if test "${WITH_DEBUGGER}" = "1" ; then XSLT_LIBS="-lxslt $LIBXML_LIBS $M_LIBS"
XSLT_LIBS="-lxslt -lxsltbreakpoint $LIBXML_LIBS $M_LIBS" EXTRA_LIBS="$LIBXML_LIBS $M_LIBS"
EXTRA_LIBS='$(top_builddir)/breakpoint/libxsltbreakpoint.la'" $LIBXML_LIBS $M_LIBS"
else
XSLT_LIBS="-lxslt $LIBXML_LIBS $M_LIBS"
EXTRA_LIBS="$LIBXML_LIBS $M_LIBS"
fi
AC_SUBST(XSLT_LIBDIR) AC_SUBST(XSLT_LIBDIR)
AC_SUBST(XSLT_INCLUDEDIR) AC_SUBST(XSLT_INCLUDEDIR)

View File

@@ -46,9 +46,6 @@
#include "imports.h" #include "imports.h"
#include "transform.h" #include "transform.h"
#ifdef WITH_DEBUGGER
#include "../breakpoint/breakpoint.h"
#endif
#ifdef WITH_XSLT_DEBUG #ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_ATTRIBUTES #define WITH_XSLT_DEBUG_ATTRIBUTES
#endif #endif
@@ -383,7 +380,9 @@ error:
*/ */
static void static void
xsltAttributeInternal(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltAttributeInternal(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp, int fromset) { xmlNodePtr inst, xsltStylePreCompPtr comp,
int fromset)
{
xmlChar *prop = NULL; xmlChar *prop = NULL;
xmlChar *ncname = NULL, *name, *namespace; xmlChar *ncname = NULL, *name, *namespace;
xmlChar *prefix = NULL; xmlChar *prefix = NULL;
@@ -394,105 +393,108 @@ xsltAttributeInternal(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (ctxt->insert == NULL) if (ctxt->insert == NULL)
return; return;
if (comp == NULL) { if (comp == NULL) {
xsltPrintErrorContext(ctxt, NULL, inst); xsltPrintErrorContext(ctxt, NULL, inst);
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsl:attribute : compilation failed\n"); "xsl:attribute : compilation failed\n");
return; return;
} }
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL)) if ((ctxt == NULL) || (node == NULL) || (inst == NULL)
return; || (comp == NULL))
return;
if (!comp->has_name) { if (!comp->has_name) {
return; return;
} }
if (ctxt->insert->children != NULL) { if (ctxt->insert->children != NULL) {
xsltPrintErrorContext(ctxt, NULL, inst); xsltPrintErrorContext(ctxt, NULL, inst);
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsl:attribute : node already has children\n"); "xsl:attribute : node already has children\n");
return; return;
} }
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
/* --- break point code --- */ if (xslDebugStatus != XSLT_DEBUG_NONE) {
if (xslDebugStatus != DEBUG_NONE) { xslHandleDebugger(inst, node, NULL, ctxt);
xslHandleDebugger(inst, node, NULL, ctxt); }
}
#endif #endif
if (comp->name == NULL) { if (comp->name == NULL) {
prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"name", prop =
XSLT_NAMESPACE); xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *) "name",
if (prop == NULL) { XSLT_NAMESPACE);
xsltPrintErrorContext(ctxt, NULL, inst); if (prop == NULL) {
xsltGenericError(xsltGenericErrorContext, xsltPrintErrorContext(ctxt, NULL, inst);
"xsl:attribute : name is missing\n"); xsltGenericError(xsltGenericErrorContext,
goto error; "xsl:attribute : name is missing\n");
} goto error;
name = prop; }
name = prop;
} else { } else {
name = comp->name; name = comp->name;
} }
ncname = xmlSplitQName2(name, &prefix); ncname = xmlSplitQName2(name, &prefix);
if (ncname == NULL) { if (ncname == NULL) {
prefix = NULL; prefix = NULL;
} else { } else {
name = ncname; name = ncname;
} }
if (!xmlStrncasecmp(prefix, (xmlChar *)"xml", 3)) { if (!xmlStrncasecmp(prefix, (xmlChar *) "xml", 3)) {
#ifdef WITH_XSLT_DEBUG_PARSING #ifdef WITH_XSLT_DEBUG_PARSING
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"xsltAttribute: xml prefix forbidden\n"); "xsltAttribute: xml prefix forbidden\n");
#endif #endif
goto error; goto error;
} }
if ((comp->ns == NULL) && (comp->has_ns)) { if ((comp->ns == NULL) && (comp->has_ns)) {
namespace = xsltEvalAttrValueTemplate(ctxt, inst, namespace = xsltEvalAttrValueTemplate(ctxt, inst,
(const xmlChar *)"namespace", XSLT_NAMESPACE); (const xmlChar *)
if (namespace != NULL) { "namespace", XSLT_NAMESPACE);
ns = xsltGetSpecialNamespace(ctxt, inst, namespace, prefix, if (namespace != NULL) {
ctxt->insert); ns = xsltGetSpecialNamespace(ctxt, inst, namespace, prefix,
xmlFree(namespace); ctxt->insert);
} else { xmlFree(namespace);
if (prefix != NULL) { } else {
ns = xmlSearchNs(inst->doc, inst, prefix); if (prefix != NULL) {
if (ns == NULL) { ns = xmlSearchNs(inst->doc, inst, prefix);
xsltPrintErrorContext(ctxt, NULL, inst); if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext, xsltPrintErrorContext(ctxt, NULL, inst);
"xsl:attribute : no namespace bound to prefix %s\n", prefix); xsltGenericError(xsltGenericErrorContext,
} else { "xsl:attribute : no namespace bound to prefix %s\n",
ns = xsltGetNamespace(ctxt, inst, ns, ctxt->insert); prefix);
} } else {
} ns = xsltGetNamespace(ctxt, inst, ns, ctxt->insert);
} }
}
}
} else if (comp->ns != NULL) { } else if (comp->ns != NULL) {
ns = xsltGetSpecialNamespace(ctxt, inst, comp->ns, prefix, ns = xsltGetSpecialNamespace(ctxt, inst, comp->ns, prefix,
ctxt->insert); ctxt->insert);
} }
if ((fromset) && (ns != NULL)) if ((fromset) && (ns != NULL))
URL = ns->href; URL = ns->href;
if ((fromset == 0) || (!xmlHasNsProp(ctxt->insert, name, URL))) { if ((fromset == 0) || (!xmlHasNsProp(ctxt->insert, name, URL))) {
value = xsltEvalTemplateString(ctxt, node, inst); value = xsltEvalTemplateString(ctxt, node, inst);
if (value == NULL) { if (value == NULL) {
if (ns) { if (ns) {
attr = xmlSetNsProp(ctxt->insert, ns, name, attr = xmlSetNsProp(ctxt->insert, ns, name,
(const xmlChar *)""); (const xmlChar *) "");
} else { } else {
attr = xmlSetProp(ctxt->insert, name, (const xmlChar *)""); attr =
} xmlSetProp(ctxt->insert, name, (const xmlChar *) "");
} else { }
if (ns) { } else {
attr = xmlSetNsProp(ctxt->insert, ns, name, value); if (ns) {
} else { attr = xmlSetNsProp(ctxt->insert, ns, name, value);
attr = xmlSetProp(ctxt->insert, name, value); } else {
} attr = xmlSetProp(ctxt->insert, name, value);
} }
}
} }
error: error:
if (prop != NULL) if (prop != NULL)
xmlFree(prop); xmlFree(prop);
if (ncname != NULL) if (ncname != NULL)
@@ -530,7 +532,9 @@ xsltAttribute(xsltTransformContextPtr ctxt, xmlNodePtr node,
void void
xsltApplyAttributeSet(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltApplyAttributeSet(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst ATTRIBUTE_UNUSED, xmlChar *attributes) { xmlNodePtr inst ATTRIBUTE_UNUSED,
xmlChar * attributes)
{
xmlChar *ncname = NULL; xmlChar *ncname = NULL;
xmlChar *prefix = NULL; xmlChar *prefix = NULL;
xmlChar *attrib, *endattr; xmlChar *attrib, *endattr;
@@ -538,57 +542,61 @@ xsltApplyAttributeSet(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltStylesheetPtr style; xsltStylesheetPtr style;
if (attributes == NULL) { if (attributes == NULL) {
return; return;
} }
attrib = attributes; attrib = attributes;
while (*attrib != 0) { while (*attrib != 0) {
while (IS_BLANK(*attrib)) attrib++; while (IS_BLANK(*attrib))
if (*attrib == 0) attrib++;
break; if (*attrib == 0)
break;
endattr = attrib; endattr = attrib;
while ((*endattr != 0) && (!IS_BLANK(*endattr))) endattr++; while ((*endattr != 0) && (!IS_BLANK(*endattr)))
attrib = xmlStrndup(attrib, endattr - attrib); endattr++;
if (attrib) { attrib = xmlStrndup(attrib, endattr - attrib);
if (attrib) {
#ifdef WITH_XSLT_DEBUG_ATTRIBUTES #ifdef WITH_XSLT_DEBUG_ATTRIBUTES
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"apply attribute set %s\n", attrib); "apply attribute set %s\n", attrib);
#endif #endif
ncname = xmlSplitQName2(attrib, &prefix); ncname = xmlSplitQName2(attrib, &prefix);
if (ncname == NULL) { if (ncname == NULL) {
ncname = attrib; ncname = attrib;
attrib = NULL; attrib = NULL;
prefix = NULL; prefix = NULL;
} }
style = ctxt->style; style = ctxt->style;
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
/* --- break point code --- */ if (style && (xslDebugStatus != XSLT_DEBUG_NONE)) {
if (style && (xslDebugStatus != DEBUG_NONE)) { values =
values = xmlHashLookup2(style->attributeSets, ncname, prefix); xmlHashLookup2(style->attributeSets, ncname, prefix);
if (values) if (values)
xslHandleDebugger(values->attr->parent, node, NULL, ctxt); xslHandleDebugger(values->attr->parent, node, NULL,
} ctxt);
}
#endif #endif
while (style != NULL) { while (style != NULL) {
values = xmlHashLookup2(style->attributeSets, ncname, prefix); values =
while (values != NULL) { xmlHashLookup2(style->attributeSets, ncname, prefix);
if (values->attr != NULL) { while (values != NULL) {
xsltAttributeInternal(ctxt, node, values->attr, if (values->attr != NULL) {
values->attr->_private, 1); xsltAttributeInternal(ctxt, node, values->attr,
} values->attr->_private, 1);
values = values->next; }
} values = values->next;
style = xsltNextImport(style); }
} style = xsltNextImport(style);
if (attrib != NULL) }
xmlFree(attrib); if (attrib != NULL)
if (ncname != NULL) xmlFree(attrib);
xmlFree(ncname); if (ncname != NULL)
if (prefix != NULL) xmlFree(ncname);
xmlFree(prefix); if (prefix != NULL)
} xmlFree(prefix);
attrib = endattr; }
attrib = endattr;
} }
} }

View File

@@ -61,11 +61,6 @@ static int xsltGetHTMLIDs(const xmlChar *version, const xmlChar **publicID,
const xmlChar **systemID); const xmlChar **systemID);
#endif #endif
#ifdef WITH_DEBUGGER
#include "../breakpoint/breakpoint.h"
int xslDebugStatus;
#endif
int xsltMaxDepth = 5000; int xsltMaxDepth = 5000;
/* /*
@@ -1016,24 +1011,6 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
} }
/**
* 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 ATTRIBUTE_UNUSED, xmlNodePtr node ATTRIBUTE_UNUSED,
xsltTemplatePtr templ ATTRIBUTE_UNUSED, xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED)
{
}
/** /**
* xsltApplyOneTemplate: * xsltApplyOneTemplate:
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
@@ -1049,7 +1026,7 @@ xslHandleDebugger(xmlNodePtr cur ATTRIBUTE_UNUSED, xmlNodePtr node ATTRIBUTE_UNU
void void
xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr list, xsltTemplatePtr templ, xmlNodePtr list, xsltTemplatePtr templ,
xsltStackElemPtr params) xsltStackElemPtr params)
{ {
xmlNodePtr cur = NULL, insert, copy = NULL; xmlNodePtr cur = NULL, insert, copy = NULL;
xmlNodePtr oldInsert; xmlNodePtr oldInsert;
@@ -1064,8 +1041,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
long start = 0; long start = 0;
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
/* --- break point code --- */ if (xslDebugStatus != XSLT_DEBUG_NONE) {
if (xslDebugStatus != DEBUG_NONE) {
if (templ) { if (templ) {
addCallResult = xslAddCall(templ, templ->elem); addCallResult = xslAddCall(templ, templ->elem);
} else { } else {
@@ -1074,8 +1050,8 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
switch (xslDebugStatus) { switch (xslDebugStatus) {
case DEBUG_RUN_RESTART: case XSLT_DEBUG_RUN_RESTART:
case DEBUG_QUIT: case XSLT_DEBUG_QUIT:
if (addCallResult) if (addCallResult)
xslDropCall(); xslDropCall();
return; return;
@@ -1084,11 +1060,10 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (templ) if (templ)
xslHandleDebugger(templ->elem, node, templ, ctxt); xslHandleDebugger(templ->elem, node, templ, ctxt);
else if (list) else if (list)
xslHandleDebugger(list, node, templ, ctxt); xslHandleDebugger(list, node, templ, ctxt);
else if (ctxt->inst) else if (ctxt->inst)
xslHandleDebugger(ctxt->inst, node, templ, ctxt); xslHandleDebugger(ctxt->inst, node, templ, ctxt);
} }
/* -- end --- */
#endif #endif
if ((ctxt == NULL) || (list == NULL)) if ((ctxt == NULL) || (list == NULL))
@@ -1096,7 +1071,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
CHECK_STOPPED; CHECK_STOPPED;
if (ctxt->templNr >= xsltMaxDepth) { if (ctxt->templNr >= xsltMaxDepth) {
xsltPrintErrorContext(ctxt, NULL, list); xsltPrintErrorContext(ctxt, NULL, list);
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltApplyOneTemplate: loop found ???\n"); "xsltApplyOneTemplate: loop found ???\n");
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
@@ -1112,21 +1087,20 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
oldInst = ctxt->inst; oldInst = ctxt->inst;
oldCurrent = ctxt->node; oldCurrent = ctxt->node;
varsPush(ctxt, params); varsPush(ctxt, params);
oldBase = ctxt->varsBase; /* only needed if templ != NULL */ oldBase = ctxt->varsBase; /* only needed if templ != NULL */
if (templ != NULL) { if (templ != NULL) {
ctxt->varsBase = ctxt->varsNr - 1; ctxt->varsBase = ctxt->varsNr - 1;
ctxt->node = node; ctxt->node = node;
if (ctxt->profile) { if (ctxt->profile) {
templ->nbCalls++; templ->nbCalls++;
start = xsltTimestamp(); start = xsltTimestamp();
profPush(ctxt, 0); profPush(ctxt, 0);
} }
templPush(ctxt, templ); templPush(ctxt, templ);
#ifdef WITH_XSLT_DEBUG_PROCESS #ifdef WITH_XSLT_DEBUG_PROCESS
if (templ->name != NULL) if (templ->name != NULL)
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"applying template '%s'\n", "applying template '%s'\n", templ->name);
templ->name);
#endif #endif
} }
@@ -1137,14 +1111,12 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
while (cur != NULL) { while (cur != NULL) {
ctxt->inst = cur; ctxt->inst = cur;
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
/* --- break point code --- */
switch (xslDebugStatus) { switch (xslDebugStatus) {
case DEBUG_RUN_RESTART: case XSLT_DEBUG_RUN_RESTART:
case DEBUG_QUIT: case XSLT_DEBUG_QUIT:
break; break;
} }
/* --- end --- */
#endif #endif
/* /*
* test, we must have a valid insertion point * test, we must have a valid insertion point
@@ -1154,10 +1126,10 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"xsltApplyOneTemplate: insert == NULL !\n"); "xsltApplyOneTemplate: insert == NULL !\n");
#endif #endif
goto error; goto error;
} }
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
if (xslDebugStatus != DEBUG_NONE) if (xslDebugStatus != XSLT_DEBUG_NONE)
xslHandleDebugger(cur, node, templ, ctxt); xslHandleDebugger(cur, node, templ, ctxt);
#endif #endif
@@ -1171,16 +1143,16 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (IS_XSLT_NAME(cur, "message")) { if (IS_XSLT_NAME(cur, "message")) {
xsltMessage(ctxt, node, cur); xsltMessage(ctxt, node, cur);
} else { } else {
/* /*
* That's an error try to apply one of the fallback cases * That's an error try to apply one of the fallback cases
*/ */
ctxt->insert = insert; ctxt->insert = insert;
if (!xsltApplyFallbacks(ctxt, node, cur)) { if (!xsltApplyFallbacks(ctxt, node, cur)) {
xsltGenericError(xsltGenericDebugContext, xsltGenericError(xsltGenericDebugContext,
"xsltApplyOneTemplate: %s was not compiled\n", "xsltApplyOneTemplate: %s was not compiled\n",
cur->name); cur->name);
} }
ctxt->insert = oldInsert; ctxt->insert = oldInsert;
} }
goto skip_children; goto skip_children;
} }
@@ -1219,14 +1191,14 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
cur->content); cur->content);
else if (cur->name == xmlStringTextNoenc) else if (cur->name == xmlStringTextNoenc)
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"xsltApplyOneTemplate: copy unescaped text %s\n", "xsltApplyOneTemplate: copy unescaped text %s\n",
cur->content); cur->content);
else else
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"xsltApplyOneTemplate: copy text %s\n", "xsltApplyOneTemplate: copy text %s\n",
cur->content); cur->content);
#endif #endif
xsltCopyText(ctxt, insert, cur); xsltCopyText(ctxt, insert, cur);
} else if ((cur->type == XML_ELEMENT_NODE) && } else if ((cur->type == XML_ELEMENT_NODE) &&
(cur->ns != NULL) && (cur->_private != NULL)) { (cur->ns != NULL) && (cur->_private != NULL)) {
xsltTransformFunction function; xsltTransformFunction function;
@@ -1234,11 +1206,11 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
/* /*
* Flagged as an extension element * Flagged as an extension element
*/ */
if (cur->_private == xsltExtMarker) if (cur->_private == xsltExtMarker)
function = (xsltTransformFunction) function = (xsltTransformFunction)
xsltExtElementLookup(ctxt, cur->name, cur->ns->href); xsltExtElementLookup(ctxt, cur->name, cur->ns->href);
else else
function = ((xsltElemPreCompPtr)cur->_private)->func; function = ((xsltElemPreCompPtr) cur->_private)->func;
if (function == NULL) { if (function == NULL) {
xmlNodePtr child; xmlNodePtr child;
@@ -1246,7 +1218,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
#ifdef WITH_XSLT_DEBUG_PROCESS #ifdef WITH_XSLT_DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"xsltApplyOneTemplate: unknown extension %s\n", "xsltApplyOneTemplate: unknown extension %s\n",
cur->name); cur->name);
#endif #endif
/* /*
@@ -1258,21 +1230,21 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
(IS_XSLT_NAME(child, "fallback"))) { (IS_XSLT_NAME(child, "fallback"))) {
found = 1; found = 1;
xsltApplyOneTemplate(ctxt, node, child->children, xsltApplyOneTemplate(ctxt, node, child->children,
NULL, NULL); NULL, NULL);
} }
child = child->next; child = child->next;
} }
if (!found) { if (!found) {
xsltPrintErrorContext(ctxt, NULL, cur); xsltPrintErrorContext(ctxt, NULL, cur);
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltApplyOneTemplate: failed to find extension %s\n", "xsltApplyOneTemplate: failed to find extension %s\n",
cur->name); cur->name);
} }
} else { } else {
#ifdef WITH_XSLT_DEBUG_PROCESS #ifdef WITH_XSLT_DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"xsltApplyOneTemplate: extension construct %s\n", "xsltApplyOneTemplate: extension construct %s\n",
cur->name); cur->name);
#endif #endif
@@ -1295,41 +1267,42 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
attrs = xsltAttrListTemplateProcess(ctxt, copy, attrs = xsltAttrListTemplateProcess(ctxt, copy,
cur->properties); cur->properties);
} }
/* /*
* Add extra namespaces inherited from the current template * Add extra namespaces inherited from the current template
* if we are in the first level children * if we are in the first level children
*/ */
if ((oldInsert == insert) && (ctxt->templ != NULL) && if ((oldInsert == insert) && (ctxt->templ != NULL) &&
(ctxt->templ->inheritedNs != NULL)) { (ctxt->templ->inheritedNs != NULL)) {
int i; int i;
xmlNsPtr ns, ret; xmlNsPtr ns, ret;
for (i = 0;i < ctxt->templ->inheritedNsNr;i++) { for (i = 0; i < ctxt->templ->inheritedNsNr; i++) {
ns = ctxt->templ->inheritedNs[i]; ns = ctxt->templ->inheritedNs[i];
if (ctxt->style->nsAliases != NULL) { if (ctxt->style->nsAliases != NULL) {
const xmlChar *URI; const xmlChar *URI;
URI = (const xmlChar *)
xmlHashLookup(ctxt->style->nsAliases, URI = (const xmlChar *)
ns->href); xmlHashLookup(ctxt->style->nsAliases,
if (URI == NULL) { ns->href);
ret = xmlSearchNs(copy->doc, copy, ns->prefix); if (URI == NULL) {
if ((ret == NULL) || ret = xmlSearchNs(copy->doc, copy, ns->prefix);
(!xmlStrEqual(ret->href, ns->href))) if ((ret == NULL) ||
xmlNewNs(copy, ns->href, ns->prefix); (!xmlStrEqual(ret->href, ns->href)))
} else if (!xmlStrEqual(URI, XSLT_NAMESPACE)) { xmlNewNs(copy, ns->href, ns->prefix);
ret = xmlSearchNs(copy->doc, copy, ns->prefix); } else if (!xmlStrEqual(URI, XSLT_NAMESPACE)) {
if ((ret == NULL) || ret = xmlSearchNs(copy->doc, copy, ns->prefix);
(!xmlStrEqual(ret->href, URI))) if ((ret == NULL) ||
xmlNewNs(copy, URI, ns->prefix); (!xmlStrEqual(ret->href, URI)))
} xmlNewNs(copy, URI, ns->prefix);
} else { }
ret = xmlSearchNs(copy->doc, copy, ns->prefix); } else {
if ((ret == NULL) || ret = xmlSearchNs(copy->doc, copy, ns->prefix);
(!xmlStrEqual(ret->href, ns->href))) if ((ret == NULL) ||
xmlNewNs(copy, ns->href, ns->prefix); (!xmlStrEqual(ret->href, ns->href)))
} xmlNewNs(copy, ns->href, ns->prefix);
} }
} }
}
} }
/* /*
@@ -1364,58 +1337,58 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
} }
} while (cur != NULL); } while (cur != NULL);
} }
error: error:
ctxt->node = oldCurrent; ctxt->node = oldCurrent;
ctxt->inst = oldInst; ctxt->inst = oldInst;
ctxt->insert = oldInsert; ctxt->insert = oldInsert;
if (params == NULL) if (params == NULL)
xsltFreeStackElemList(varsPop(ctxt)); xsltFreeStackElemList(varsPop(ctxt));
else { else {
xsltStackElemPtr p, tmp = varsPop(ctxt); xsltStackElemPtr p, tmp = varsPop(ctxt);
if (tmp != params) {
p = tmp; if (tmp != params) {
while ((p != NULL) && (p->next != params)) p = tmp;
p = p->next; while ((p != NULL) && (p->next != params))
if (p == NULL) { p = p->next;
xsltFreeStackElemList(tmp); if (p == NULL) {
} else { xsltFreeStackElemList(tmp);
p->next = NULL; } else {
xsltFreeStackElemList(tmp); p->next = NULL;
} xsltFreeStackElemList(tmp);
} }
}
} }
if (templ != NULL) { if (templ != NULL) {
ctxt->varsBase = oldBase; ctxt->varsBase = oldBase;
templPop(ctxt); templPop(ctxt);
if (ctxt->profile) { if (ctxt->profile) {
long spent, child, total, end; long spent, child, total, end;
end = xsltTimestamp();
child = profPop(ctxt);
total = end - start;
spent = total - child;
if (spent <= 0) {
/*
* Not possible unless the original calibration failed
* we can try to corret it on the fly.
*/
xsltCalibrateAdjust(spent);
spent = 0;
}
templ->time += spent; end = xsltTimestamp();
if (ctxt->profNr > 0) child = profPop(ctxt);
ctxt->profTab[ctxt->profNr - 1] += total; total = end - start;
} spent = total - child;
if (spent <= 0) {
/*
* Not possible unless the original calibration failed
* we can try to corret it on the fly.
*/
xsltCalibrateAdjust(spent);
spent = 0;
}
templ->time += spent;
if (ctxt->profNr > 0)
ctxt->profTab[ctxt->profNr - 1] += total;
}
} }
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
if (xslDebugStatus != DEBUG_NONE && addCallResult) { if ((xslDebugStatus != XSLT_DEBUG_NONE) && (addCallResult)) {
xslDropCall(); xslDropCall();
} }
#endif #endif
} }
/************************************************************************ /************************************************************************
* * * *
* XSLT-1.1 extensions * * XSLT-1.1 extensions *
@@ -2522,7 +2495,7 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
cur = inst->children; cur = inst->children;
while (cur != NULL) { while (cur != NULL) {
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
if (xslDebugStatus != DEBUG_NONE) if (xslDebugStatus != XSLT_DEBUG_NONE)
xslHandleDebugger(cur, node, comp->templ, ctxt); xslHandleDebugger(cur, node, comp->templ, ctxt);
#endif #endif
if (ctxt->state == XSLT_STATE_STOPPED) break; if (ctxt->state == XSLT_STATE_STOPPED) break;
@@ -2722,7 +2695,7 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
cur = inst->children; cur = inst->children;
while (cur!=NULL) { while (cur!=NULL) {
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
if (xslDebugStatus != DEBUG_NONE) if (xslDebugStatus != XSLT_DEBUG_NONE)
xslHandleDebugger(cur, node, comp->templ, ctxt); xslHandleDebugger(cur, node, comp->templ, ctxt);
#endif #endif
if (ctxt->state == XSLT_STATE_STOPPED) break; if (ctxt->state == XSLT_STATE_STOPPED) break;
@@ -2856,7 +2829,7 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
if (xslDebugStatus != DEBUG_NONE) if (xslDebugStatus != XSLT_DEBUG_NONE)
xslHandleDebugger(when, node, comp->templ, ctxt); xslHandleDebugger(when, node, comp->templ, ctxt);
#endif #endif
@@ -2912,7 +2885,7 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
} }
if (IS_XSLT_ELEM(replacement) && (IS_XSLT_NAME(replacement, "otherwise"))) { if (IS_XSLT_ELEM(replacement) && (IS_XSLT_NAME(replacement, "otherwise"))) {
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
if (xslDebugStatus != DEBUG_NONE) if (xslDebugStatus != XSLT_DEBUG_NONE)
xslHandleDebugger(replacement, node, comp->templ, ctxt); xslHandleDebugger(replacement, node, comp->templ, ctxt);
#endif #endif
@@ -3101,7 +3074,7 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node,
sorts[nbsorts++] = replacement; sorts[nbsorts++] = replacement;
} }
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
if (xslDebugStatus != DEBUG_NONE) if (xslDebugStatus != XSLT_DEBUG_NONE)
xslHandleDebugger(replacement, node, NULL, ctxt); xslHandleDebugger(replacement, node, NULL, ctxt);
#endif #endif
replacement = replacement->next; replacement = replacement->next;

View File

@@ -32,6 +32,7 @@
#include "templates.h" #include "templates.h"
#include "xsltInternals.h" #include "xsltInternals.h"
#include "imports.h" #include "imports.h"
#include "transform.h"
/* gettimeofday on Windows ??? */ /* gettimeofday on Windows ??? */
#ifdef WIN32 #ifdef WIN32
@@ -1246,3 +1247,103 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
xmlFree(templates); xmlFree(templates);
} }
/************************************************************************
* *
* Hooks for the debugger *
* *
************************************************************************/
/*
* There is currently only 3 debugging callback defined
* Debugger callbacks are disabled by default
*/
#define XSLT_CALLBACK_NUMBER 3
typedef struct _xsltDebuggerCallbacks xsltDebuggerCallbacks;
typedef xsltDebuggerCallbacks *xsltDebuggerCallbacksPtr;
struct _xsltDebuggerCallbacks {
xsltHandleDebuggerCallback handler;
xsltAddCallCallback add;
xsltDropCallCallback drop;
};
static xsltDebuggerCallbacks xsltDebuggerCurrentCallbacks = {
NULL, /* handler */
NULL, /* add */
NULL /* drop */
};
int xslDebugStatus;
/**
* xslSetDebuggerCallbacks:
* @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 != 1))
return(-1);
callbacks = (xsltDebuggerCallbacksPtr) block;
xsltDebuggerCurrentCallbacks.handler = callbacks->handler;
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();
}

View File

@@ -154,6 +154,35 @@ void xsltCalibrateAdjust (long delta);
#define XSLT_TIMESTAMP_TICS_PER_SEC 100000l #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;
LIBXSLT_PUBLIC extern int xslDebugStatus;
typedef void (*xsltHandleDebuggerCallback) (xmlNodePtr cur, xmlNodePtr node,
xsltTemplatePtr templ, xsltTransformContextPtr ctxt);
typedef int (*xsltAddCallCallback) (xsltTemplatePtr templ, xmlNodePtr source);
typedef void (*xsltDropCallCallback) (void);
int xsltSetDebuggerCallbacks (int no, void *block);
int xslAddCall (xsltTemplatePtr templ,
xmlNodePtr source);
void xslDropCall (void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -11,22 +11,9 @@ xsltproc_LDFLAGS =
xsltproc_DEPENDENCIES = $(DEPS) xsltproc_DEPENDENCIES = $(DEPS)
xsltproc_LDADD = $(LDADDS) xsltproc_LDADD = $(LDADDS)
if WITH_DEBUGGER
DEPS = $(top_builddir)/libxslt/libxslt.la \
$(top_builddir)/breakpoint/libxsltbreakpoint.la \
$(top_builddir)/libexslt/libexslt.la
else
DEPS = $(top_builddir)/libxslt/libxslt.la \ DEPS = $(top_builddir)/libxslt/libxslt.la \
$(top_builddir)/libexslt/libexslt.la $(top_builddir)/libexslt/libexslt.la
endif
if WITH_DEBUGGER
LDADDS = $(top_builddir)/libxslt/libxslt.la \
$(top_builddir)/libexslt/libexslt.la \
$(top_builddir)/breakpoint/libxsltbreakpoint.la \
@LIBXML_LIBS@ $(EXTRA_LIBS)
else
LDADDS = $(top_builddir)/libxslt/libxslt.la \ LDADDS = $(top_builddir)/libxslt/libxslt.la \
$(top_builddir)/libexslt/libexslt.la \ $(top_builddir)/libexslt/libexslt.la \
@LIBXML_LIBS@ $(EXTRA_LIBS) @LIBXML_LIBS@ $(EXTRA_LIBS)
endif