diff --git a/ChangeLog b/ChangeLog index 78d2e30f..553e61cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Mon Nov 5 14:29:26 CET 2001 Daniel Veillard + + * Makefile.am acconfig.h config.h.in configure.in + xsltproc/Makefile.am breakpoint/* libxslt/transform.[ch] + libxslt/xsltconfig.h.in: Applied Keith Isdale patch for + the debugger support, make it the default, added the + WITH_XSLT_DEBUGGER define to xsltconfig.h.in, small cleanups + Fri Nov 2 11:19:49 CET 2001 Daniel Veillard * libxslt/libxslt.h: make sure LIBXSLT_PUBLIC is defined diff --git a/Makefile.am b/Makefile.am index 4e331e1c..f98d750e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,6 @@ SUBDIRS = \ libxslt \ + breakpoint \ libexslt \ xsltproc \ tests \ diff --git a/acconfig.h b/acconfig.h index f00b312e..3900a67c 100644 --- a/acconfig.h +++ b/acconfig.h @@ -3,3 +3,4 @@ #undef HAVE_POW #undef HAVE_FLOOR #undef HAVE_FABS +#undef WITH_DEBUGGER diff --git a/breakpoint/Makefile.am b/breakpoint/Makefile.am new file mode 100644 index 00000000..3b3ee615 --- /dev/null +++ b/breakpoint/Makefile.am @@ -0,0 +1,30 @@ +INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/libxslt $(LIBXML_CFLAGS) + +lib_LTLIBRARIES = libxsltbreakpoint.la + +xsltbreakpointincdir = $(includedir)/breakpoint + +xsltbreakpointinc_HEADERS = \ + breakpoint.h + +libxsltbreakpoint_la_SOURCES = \ + dbgbreakpoint.c \ + dbgcallstack.c \ + dbgsearch.c \ + dbgmain.c + + +libxsltbreakpoint_la_LIBADD = $(EXTRA_LIBS) +libxsltbreakpoint_la_LDFLAGS = -version-info @LIBXSLT_VERSION_INFO@ + +man_MANS = #breakpoint.4 + +EXTRA_DIST = $(man_MANS) + +clean: + rm -f *.lo + rm -f *.o + rm -rf .libs + rm -f *.la + + diff --git a/breakpoint/breakpoint.h b/breakpoint/breakpoint.h new file mode 100644 index 00000000..4c6f1703 --- /dev/null +++ b/breakpoint/breakpoint.h @@ -0,0 +1,397 @@ + +/*************************************************************************** + breakpoint.h - description + ------------------- + begin : Sun Sep 16 2001 + copyright : (C) 2001 by Keith Isdale + email : k_isdale@tpg.com.au + ***************************************************************************/ + +#include "config.h" + +#ifdef WITH_DEBUGGER +#ifndef BREAKPOINT_H +#define BREAKPOINT_H + +#ifdef WITH_XSLT_DEBUG +#define WITH_XSLT_DEBUG_BREAKPOINTS +#endif + +#include + +#include +#include +#include + +/* Define the types of status whilst debugging*/ +typedef enum { + DEBUG_NONE, /* no debugging allowed */ + DEBUG_INIT, + DEBUG_STEP, + DEBUG_STEPUP, + DEBUG_STEPDOWN, + DEBUG_NEXT, + DEBUG_STOP, + DEBUG_CONT, + DEBUG_RUN, + DEBUG_RUN_RESTART, + DEBUG_QUIT +} DebugStatus; + +typedef enum { + DEBUG_BREAK_SOURCE = 1, + DEBUG_BREAK_DATA +} BreakPointType; + +#define XSL_TOGGLE_BREAKPOINT -1 +extern int xslDebugStatus; + +typedef struct _xslBreakPoint xslBreakPoint; +typedef xslBreakPoint *xslBreakPointPtr; +struct _xslBreakPoint { + xmlChar *url; + long lineNo; + xmlChar *templateName; /* only used when printing break point */ + int enabled; + int type; + int id; +}; + + +/* +----------------------------------------------------------- + Break point related functions +---------------------------------------------------------- +* + +/** + * xslFindTemplateNode: + * @style : valid stylesheet collection to look into + * @name : template name to look for + * + * Returns : template node found if successfull, + * NULL otherwise + */ +xmlNodePtr xslFindTemplateNode(const xsltStylesheetPtr style, + const xmlChar * name); + + +/** + * xslActiveBreakPoint: + * + * Return the break point number that we stoped at +*/ +int xslActiveBreakPoint(); + + +/** + * xslSetActiveBreakPoint: + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * + * Sets the active break point number + * Returns 1 on success, + * 0 otherwise + */ +int xslSetActiveBreakPoint(int breakPointNumber); + + +/** + * xslAddBreakPoint: + * @url : a valid url that has been loaded by debugger + * @lineNumber : number >= 0 and is available in url specified and points to + * an xml element + * @temlateName : the template name of breakpoint or NULL if not adding + * a template break point + * @type : DEBUG_BREAK_SOURCE if are we stopping at a xsl source line + * DEBUG_BREAK_DATA otherwise + * + * Add break point at file and line number specified + * Returns break point number if successfull, + * 0 otherwise +*/ +int xslAddBreakPoint(const xmlChar * url, long lineNumber, + const xmlChar * templateName, int type); + + +/** + * xslDeleteBreakPoint: + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * + * Delete the break point with breakPointNumber specified + * Returns 1 if successfull, + * 0 otherwise +*/ +int xslDeleteBreakPoint(int breakPointNumber); + + +/** + * xslFindBreakPointById: + * @id : The break point id to look for + * + * Find the break point number for given break point id + * Returns break point number can be found for given the break point id + * 0 otherwise + */ +int xslFindBreakPointById(int id); + + +/** + * xslFindBreakPointByLineNo: + * @url : a valid url that has been loaded by debugger + * @lineNumber : lineNumber >= 0 and is available in url specified + * + * Find the break point number for a given url and line number + * Returns breakpoint number number if successfull, + * 0 otherwise +*/ +int xslFindBreakPointByLineNo(const xmlChar * url, long lineNumber); + + +/** + * xslFindBreakPointByName: + * @templateName : template name to look for + * + * Find the breakpoint at template with "match" or "name" equal + * to templateName + * Returns the break point number given the template name is found + * 0 otherwise +*/ +int xslFindBreakPointByName(const xmlChar * templateName); + + +/** + * xslEnableBreakPoint: + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * @enable : enable break point if 1, disable if 0, toggle if -1 + * + * Enable or disable a break point + * Returns 1 if successfull, + * 0 otherwise +*/ +int xslEnableBreakPoint(int breakPointNumber, int enable); + + +/** + * xslIsBreakPointEnabled: + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * + * Is the breakpoint at breakPointNumber specified enabled + * Returns -1 if breakPointNumber is invalid + * 0 if break point is disabled + * 1 if break point is enabled +*/ +int xslIsBreakPointEnabled(int breakPointNumber); + + +/** + * xslBreakPointCount: + * + * Returns the number of break points present + */ +int xslBreakPointCount(); + + +/** + * xslGetBreakPoint: + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * + * Lookup the value of break point at breakPointNumber specified + * Returns break point if breakPointNumber is valid, + * NULL otherwise +*/ +xslBreakPointPtr xslGetBreakPoint(int breakPointNumber); + + +/** + * xslPrintBreakPoint: + * @file : file != NULL + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * + * Print the details of break point to file specified + * + * Returns 1 if successfull, + * 0 otherwise + */ +int xslPrintBreakPoint(FILE * file, int breakPointNumber); + + +/** + * xslIsBreakPoint: + * @url : url non-null, non-empty file name that has been loaded by + * debugger + * @lineNumber : number >= 0 and is available in url specified + * + * Determine if there is a break point at file and line number specifiec + * Returns 1 if successfull, + * 0 otherwise +*/ +int xslIsBreakPoint(const xmlChar * url, long lineNumber); + + +/** + * xslIsBreakPointNode: + * @node : node != NULL + * + * Determine if a node is a break point + * Returns : 1 on sucess, 0 otherwise + */ +int xslIsBreakPointNode(xmlNodePtr node); + +/* +----------------------------------------------------------- + Main debugger functions +----------------------------------------------------------- +*/ + +/** + * xslDebugBreak: + * @templ : The source node being executed + * @node : The data node being processed + * @root : The template being applide to "node" + * @ctxt : stylesheet being processed + * + * A break point has been found so pass control to user + */ +void xslDebugBreak(xmlNodePtr templ, xmlNodePtr node, xsltTemplatePtr root, + xsltTransformContextPtr ctxt); + + +/** + * xslDebugInit : + * + * Initialize debugger allocating any memory needed by debugger + */ +void xslDebugInit(); + + +/** + * xslDebugFree : + * + * Free up any memory taken by debugger + */ +void xslDebugFree(); + + +/** + * xslDebugGotControl : + * @reached : true if debugger has received control + * + * Set flag that debuger has received control to value of @reached + * Returns true if any breakpoint was reached previously + */ +int xslDebugGotControl(int reached); + + + +/* +------------------------------------------------------ + Xsl call stack related +----------------------------------------------------- +*/ + +typedef struct _xslCallPointInfo xslCallPointInfo; +typedef xslCallPointInfo *xslCallPointInfoPtr; + +struct _xslCallPointInfo { + const xmlChar *templateName; /* will be unique */ + const xmlChar *url; + xslCallPointInfoPtr next; +}; + + +/** + * xslAddCallInfo: + * @templateName : template name to add + * @url : url for the template + * + * Returns a reference to the added info if sucessfull, + * NULL otherwise + */ +xslCallPointInfoPtr xslAddCallInfo(const xmlChar * templateName, + const xmlChar * url); + +typedef struct _xslCallPoint xslCallPoint; +typedef xslCallPoint *xslCallPointPtr; + +struct _xslCallPoint { + xslCallPointInfoPtr info; + long lineNo; + xslCallPointPtr next; +}; + + +/** + * xslAddCall: + * @templ : current template being applied + * @source : the source node being processed + * + * Add template "call" to call stack + * Returns 1 on sucess, + * 0 otherwise + */ +int xslAddCall(xsltTemplatePtr templ, xmlNodePtr source); + + +/** + * xslDropCall : + * + * Drop the topmost item off the call stack + */ +void xslDropCall(); + + +/** + * xslStepupToDepth : + * @depth :the frame depth to step up to + * + * Set the frame depth to step up to + * Returns 1 on sucess, + * 0 otherwise + */ +int xslStepupToDepth(int depth); + + +/** + * xslStepdownToDepth : + * @depth : the frame depth to step down to + * + * Set the frame depth to step down to + * Returns 1 on sucess, + * 0 otherwise + */ +int xslStepdownToDepth(int depth); + + +/** + * xslGetCall : + * @depth : 0 < depth <= xslCallDepth() + * + * Retrieve the call point at specified call depth + + * Return non-null a if depth is valid, + * NULL otherwise + */ +xslCallPointPtr xslGetCall(int depth); + + +/** + * xslGetCallStackTop : + * + * Returns the top of the call stack + */ +xslCallPointPtr xslGetCallStackTop(); + + +/** + * xslCallDepth : + * + * Returns the depth of call stack + */ +int xslCallDepth(); + + + + +#endif + +#endif diff --git a/breakpoint/dbgbreakpoint.c b/breakpoint/dbgbreakpoint.c new file mode 100644 index 00000000..c2bc2336 --- /dev/null +++ b/breakpoint/dbgbreakpoint.c @@ -0,0 +1,224 @@ + +/*************************************************************************** + breakpoint.c - description + ------------------- + begin : Fri Nov 2 2001 + copyright : (C) 2001 by Keith Isdale + email : k_isdale@tpg.com.au + ***************************************************************************/ + +#include "config.h" + +#ifdef WITH_DEBUGGER + +/* +----------------------------------------------------------- + Breakpoint debugger functions +----------------------------------------------------------- +*/ + + +#include "xsltutils.h" +#include "breakpoint.h" + + +/** + * xslActiveBreakPoint(); + * Return the break point number that we stoped at + */ +int +xslActiveBreakPoint() +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslDebugInit' not overloaded\n"); + + return 0; +} + +/** + * xslSetActiveBreakPoint: + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * + * Return 1 on success, + * 0 otherwise + */ +int +xslSetActiveBreakPoint(int breakPointNumber) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslSetActiveBreakPoint' not overloaded\n"); + return 0; +} + + +/** + * xslAddBreakPoint: + * @url : url non-null, non-empty file name that has been loaded by + * debugger + * @lineNumber : number >= 0 and is available in url specified and points to + * an xml element + * @temlateName : the template name of breakpoint or NULL + * @type : DEBUG_BREAK_SOURCE if are we stopping at a xsl source line + * DEBUG_BREAK_DATA otherwise + * + * Add break point at file and line number specifiec + * Returns break point number if successfull, + * 0 otherwise +*/ +int +xslAddBreakPoint(const xmlChar * url, long lineNumber, + const xmlChar * templateName, int type) +{ + + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslAddBreakPoint' not overloaded\n"); + return 0; +} + + +/** + * xslDeleteBreakPoint: + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * + * Delete the break point specified + * Returns 1 if successfull, + * 0 otherwise +*/ +int +xslDeleteBreakPoint(int breakPointNumber) +{ + + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslDeleteBreakPoint' not overloaded\n"); + + return 0; +} + + + + +/** + * xslEnableBreakPoint: + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * @enable : enable break point if 1, disable if 0, toggle if -1 + * + * Enable or disable a break point + * Returns 1 if successfull, + * 0 otherwise +*/ +int +xslEnableBreakPoint(int breakPointNumber, int enable) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslEnableBreakPoint' not overloaded\n"); + + return 0; +} + + +/** + * xslIsBreakPointEnabled: + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * + * Is the breakpoint at breakPointNumber specified enabled + * Returns -1 if breakPointNumber is invalid + * 0 if break point is disabled + * 1 if break point is enabled +*/ +int +xslIsBreakPointEnabled(int breakPointNumber) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslIsBreakPointEnabled' not overloaded\n"); + return -1; +} + + +/** + * xslBreakPointCount: + * + * Return the number of breakpoints present + */ +int +xslBreakPointCount() +{ + return 0; +} + + +/** + * xslGetBreakPoint: + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * + * Lookup the value of break point at breakPointNumber specified + * Returns break point if breakPointNumber is valid, + * NULL otherwise +*/ +xslBreakPointPtr +xslGetBreakPoint(int breakPointNumber) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslGetBreakPoint' not overloaded\n"); + return NULL; +} + + +/** + * xslPrintBreakPoint: + * @file : file != NULL + * @breakPointNumber : 0 < breakPointNumber <= xslBreakPointCount() + * + * Print the details of break point to file specified + * + * Returns 1 if successfull, + * 0 otherwise + */ +int +xslPrintBreakPoint(FILE * file, int breakPointNumber) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslPrintBreakPoint' not overloaded\n"); + + return 0; +} + + +/** + * xslIsBreakPoint: + * @url : url non-null, non-empty file name that has been loaded by + * debugger + * @lineNumber : number >= 0 and is available in url specified + * + * Determine if there is a break point at file and line number specified + * Returns 1 if successfull, + * 0 otherwise +*/ +int +xslIsBreakPoint(const xmlChar * url, long lineNumber) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslIsBreakPoint' not overloaded\n"); + + return 0; +} + + +/** + * xslIsBreakPointNode: + * @node : node != NULL + * + * Determine if a node is a break point + * Returns : 1 on sucess, + * 0 otherwise + */ +int +xslIsBreakPointNode(xmlNodePtr node) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslIsBreakPointNode' not overloaded\n"); + + + return 0; +} + +#endif diff --git a/breakpoint/dbgcallstack.c b/breakpoint/dbgcallstack.c new file mode 100644 index 00000000..778a14e3 --- /dev/null +++ b/breakpoint/dbgcallstack.c @@ -0,0 +1,153 @@ + +/*************************************************************************** + dbgcallstack.c - description + ------------------- + begin : Fri Nov 2 2001 + copyright : (C) 2001 by Keith Isdale + email : k_isdale@tpg.com.au + ***************************************************************************/ + +#include "config.h" + +#ifdef WITH_DEBUGGER + +/* +------------------------------------------------------ + Xsl call stack related +----------------------------------------------------- +*/ + +#include "xsltutils.h" +#include "breakpoint.h" + + +/** + * xslAddCallInfo: + * @templateName : template name to add + * @url : url for templateName + * + * Returns a reference to the added info if sucessfull, otherwise NULL + */ +xslCallPointInfoPtr +xslAddCallInfo(const xmlChar * templateName, const xmlChar * url) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslAddCallInfo' not overloaded\n"); + + return NULL; +} + + +/** + * xslAddCall: + * @templ : current template being applied + * @source : the source node being processed + * + * Add template "call" to call stack + * Returns : 1 on sucess, 0 otherwise + */ +int +xslAddCall(xsltTemplatePtr templ, xmlNodePtr source) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslAddCall' not overloaded\n"); + + return 0; +} + + +/** + * xslDropCall : + * + * Drop the topmost item off the call stack + */ +void +xslDropCall() +{ + + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslDropCall' not overloaded\n"); + +} + + +/** + * xslStepupToDepth : + * @depth :the frame depth to step up to + * + * Set the frame depth to step up to + * Returns 1 on sucess , 0 otherwise + */ +int +xslStepupToDepth(int depth) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslStepupToDepth' not overloaded\n"); + return 0; +} + + +/** + * xslStepdownToDepth : + * @depth : the frame depth to step down to + * + * Set the frame depth to step down to + * Returns 1 on sucess , 0 otherwise + */ +int +xslStepdownToDepth(int depth) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslStepdownToDepth' not overloaded\n"); + return 0; +} + + +/** + * xslGetCall : + * @depth : 0 < depth <= xslCallDepth() + * + * Retrieve the call point at specified call depth + + * Return non-null a if depth is valid + * NULL otherwise + */ +xslCallPointPtr +xslGetCall(int depth) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslGetCall' not overloaded\n"); + + return 0; +} + + +/** + * xslGetCallStackTop : + * + * Returns the top of the call stack + */ +xslCallPointPtr +xslGetCallStackTop() +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslGetCallStackTop' not overloaded\n"); + + return NULL; +} + + +/** + * xslCallDepth : + * + * Return the depth of call stack + */ +int +xslCallDepth() +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslCallDepth' not overloaded\n"); + return 0; +} + +#endif diff --git a/breakpoint/dbgmain.c b/breakpoint/dbgmain.c new file mode 100644 index 00000000..e1efda75 --- /dev/null +++ b/breakpoint/dbgmain.c @@ -0,0 +1,88 @@ + +/*************************************************************************** + dbgmain.c - description + ------------------- + begin : Fri Nov 2 2001 + copyright : (C) 2001 by Keith Isdale + email : k_isdale@tpg.com.au + ***************************************************************************/ + + +#include "config.h" + +#ifdef WITH_DEBUGGER + +/* +----------------------------------------------------------- + Main debugger functions +----------------------------------------------------------- +*/ + +#include "xsltutils.h" +#include "breakpoint.h" + +int xslDebugStatus = DEBUG_NONE; + +/** + * xslDebugInit : + * + * Initialize debugger + */ +void +xslDebugInit() +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslDebugInit' not overloaded\n"); +} + + +/** + * xslDebugFree : + * + * Free up any memory taken by debugging + */ +void +xslDebugFree() +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslDebugFree' not overloaded\n"); + +} + + +extern char *xslShellReadline(char *prompt); + +/** + * @templ : The source node being executed + * @node : The data node being processed + * @root : The template being applide to "node" + * @ctxt : stylesheet being processed + * + * A break point has been found so pass control to user + */ +void +xslDebugBreak(xmlNodePtr templ, xmlNodePtr node, xsltTemplatePtr root, + xsltTransformContextPtr ctxt) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslDebugBreak' not overloaded\n"); + +} + +/** + * xslDebugGotControl : + * @reached : true if debugger has received control + * + * Set flag that debuger has received control to value of @reached + * Returns true if any breakpoint was reached previously + */ +int +xslDebugGotControl(int reached) +{ + static int got_control = 0; + int result = got_control; + got_control = reached; + return result; +} + +#endif diff --git a/breakpoint/dbgsearch.c b/breakpoint/dbgsearch.c new file mode 100644 index 00000000..3d911499 --- /dev/null +++ b/breakpoint/dbgsearch.c @@ -0,0 +1,119 @@ + +/*************************************************************************** + dbgsearch.c - description + ------------------- + begin : Fri Nov 2 2001 + copyright : (C) 2001 by Keith Isdale + email : k_isdale@tpg.com.au + ***************************************************************************/ + + +#include "config.h" + +#ifdef WITH_DEBUGGER + +/* +----------------------------------------------------------- + Search/Find debugger functions +----------------------------------------------------------- +*/ + +#include "xsltutils.h" +#include "breakpoint.h" + +/** + * xslFindTemplateNode: + * @style : valid stylesheet collection context to look into + * @name : template name to look for + * + * Returns : template node found if successfull + * NULL otherwise + */ +xmlNodePtr +xslFindTemplateNode(xsltStylesheetPtr style, const xmlChar * name) +{ + + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslFindTemplateNode' not overloaded\n"); + return NULL; +} + + +/** + * xslFindBreakPointByLineNo: + * @ctxt : valid ctxt to look into + * @url : url non-null, non-empty file name that has been loaded by + * debugger + * @lineNumber : number >= 0 and is available in url specified + * + * Find the closest line number in file specified that can be a point + * Returns line number number if successfull, + * 0 otherwise +*/ +xmlNodePtr +xslFindNodeByLineNo(xsltTransformContextPtr ctxt, + const xmlChar * url, long lineNumber) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslFindNodeByLineNo' not overloaded\n"); + + return NULL; +} + + +/** + * xslFindBreakPointById: + * @id : The break point id to look for + * + * Find the break point number for given break point id + * Returns break point number can be found for given the break point id + * 0 otherwise + */ +int +xslFindBreakPointById(int id) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslFindBreakPointById' not overloaded\n"); + + return 0; +} + + +/** + * xslFindBreakPointByLineNo: + * @url : a valid url that has been loaded by debugger + * @lineNumber : lineNumber >= 0 and is available in url specified + * + * Find the break point number for a given url and line number + * Returns break point number number if successfull, + * 0 otherwise +*/ +int +xslFindBreakPointByLineNo(const xmlChar * url, long lineNumber) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslFindBreakPointByLineNo' not overloaded\n"); + + return 0; +} + + +/** + * xslFindBreakPointByName: + * @templateName : template name to look for + * + * Find the breakpoint at template with "match" or "name" or equal to + * templateName + * Returns break point number given the template name is found + * 0 otherwise +*/ +int +xslFindBreakPointByName(const xmlChar * templateName) +{ + xsltGenericError(xsltGenericErrorContext, + "Error!: Debugger function 'xslFindBreakPointByName' not overloaded\n"); + + return 0; +} + +#endif diff --git a/config.h.in b/config.h.in index 948754c0..08af5633 100644 --- a/config.h.in +++ b/config.h.in @@ -8,6 +8,7 @@ #undef HAVE_POW #undef HAVE_FLOOR #undef HAVE_FABS +#undef WITH_DEBUGGER /* Define if you have the _stat function. */ #undef HAVE__STAT diff --git a/configure.in b/configure.in index 5614bbee..7dddf069 100644 --- a/configure.in +++ b/configure.in @@ -133,6 +133,21 @@ else fi AC_SUBST(WITH_MEM_DEBUG) +dnl +dnl Is debugger support requested +dnl +AC_ARG_WITH(with_debugger, [ --with-debugger Add the debugging module (off)]) +if test "$with_debugger" = "no" ; then + echo Disabling debugger + WITH_DEBUGGER=0 +else + echo Enabling debugger + WITH_DEBUGGER=1 + AC_DEFINE(WITH_DEBUGGER) +fi +AM_CONDITIONAL(WITH_DEBUGGER, test "${WITH_DEBUGGER}" = "1") +AC_SUBST(WITH_DEBUGGER) + dnl dnl The following new parameters were added to offer dnl the ability to specify the location of the libxml @@ -250,18 +265,25 @@ esac XSLT_INCLUDEDIR='-I${includedir}' EXTRA_LIBS="$M_LIBS" -XSLT_LIBS="-lxslt $LIBXML_LIBS $M_LIBS" +if test "${WITH_DEBUGGER}" = "1" ; then + XSLT_LIBS="-lxslt -lxsltbreakpoint $LIBXML_LIBS $M_LIBS" +else + XSLT_LIBS="-lxslt $LIBXML_LIBS $M_LIBS" +fi + AC_SUBST(XSLT_LIBDIR) AC_SUBST(XSLT_INCLUDEDIR) AC_SUBST(EXTRA_LIBS) AC_SUBST(XSLT_LIBS) + AC_OUTPUT([ Makefile libxslt/Makefile libxslt/xsltconfig.h libxslt/xsltwin32config.h +breakpoint/Makefile libexslt/Makefile libexslt/exsltconfig.h xsltproc/Makefile diff --git a/libxslt/transform.c b/libxslt/transform.c index 3339a488..0d2fbd27 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -60,6 +60,18 @@ static int xsltGetHTMLIDs(const xmlChar *version, const xmlChar **publicID, const xmlChar **systemID); #endif +#ifdef WITH_DEBUGGER + +/* -- breakpoint code --- */ +#include "../breakpoint/breakpoint.h" + +int xslDebugStatus; + +/* -------- end ---------- */ +#endif + + + int xsltMaxDepth = 500; @@ -1008,6 +1020,68 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node, } } +#ifdef WITH_DEBUGGER + +/* make it eaier to reuse the code for handling checking of debug + status and breaking to debugger if needed */ + +/** + * 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) +{ + + xslSetActiveBreakPoint(0); + + switch (xslDebugStatus) { + + /* A temparary stopping point */ + case DEBUG_STOP: + xslDebugStatus = DEBUG_CONT; + /* only allow breakpoints at xml elements */ + if (xmlGetLineNo(cur) != -1) + xslDebugBreak(cur, node, templ, ctxt); + break; + + case DEBUG_STEP: + /* only allow breakpoints at xml elements */ + if (xmlGetLineNo(cur) != -1) + xslDebugBreak(cur, node, templ, ctxt); + break; + + case DEBUG_CONT: + { + int breakPoint = xslIsBreakPointNode(cur); + + if (breakPoint) { + if (xslIsBreakPointEnabled(breakPoint) == 1) { + xslSetActiveBreakPoint(breakPoint); + xslDebugBreak(cur, node, templ, ctxt); + } + } else { + breakPoint = xslIsBreakPointNode(node); + if (xslIsBreakPointEnabled(breakPoint) == 1) { + xslSetActiveBreakPoint(breakPoint); + xslDebugBreak(cur, node, templ, ctxt); + } + } + } + break; + } +} +#endif + + /** * xsltApplyOneTemplate: * @ctxt: a XSLT process context @@ -1031,8 +1105,39 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr oldInst = NULL; xmlAttrPtr attrs; int oldBase; + +#ifdef WITH_DEBUGGER + int addCallResult = 0; +#endif long start = 0; +#ifdef WITH_DEBUGGER + /* --- break point code --- */ + if (xslDebugStatus != DEBUG_NONE) { + if (templ) { + addCallResult = xslAddCall(templ, templ->elem); + } else { + addCallResult = xslAddCall(NULL, list); + } + + switch (xslDebugStatus) { + + case DEBUG_RUN_RESTART: + case DEBUG_QUIT: + if (addCallResult) + xslDropCall(); + return; + } + + if (templ) + xslHandleDebugger(templ->elem, node, templ, ctxt); + else + xslHandleDebugger(list, node, templ, ctxt); + + } + /* -- end --- */ +#endif + if ((ctxt == NULL) || (list == NULL)) return; CHECK_STOPPED; @@ -1078,6 +1183,16 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, cur = list; while (cur != NULL) { ctxt->inst = cur; +#ifdef WITH_DEBUGGER + /* --- break point code --- */ + switch (xslDebugStatus) { + case DEBUG_RUN_RESTART: + case DEBUG_QUIT: + break; + + } + /* --- end --- */ +#endif /* * test, we must have a valid insertion point */ @@ -1088,6 +1203,10 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, #endif goto error; } +#ifdef WITH_DEBUGGER + if (xslDebugStatus != DEBUG_NONE) + xslHandleDebugger(cur, node, templ, ctxt); +#endif if (IS_XSLT_ELEM(cur)) { /* @@ -1336,6 +1455,11 @@ error: ctxt->profTab[ctxt->profNr - 1] += total; } } +#ifdef WITH_DEBUGGER + if (xslDebugStatus != DEBUG_NONE && addCallResult) { + xslDropCall(); + } +#endif } @@ -2388,6 +2512,10 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, cur = inst->children; while (cur != NULL) { +#ifdef WITH_DEBUGGER + if (xslDebugStatus != DEBUG_NONE) + xslHandleDebugger(cur, node, comp->templ, ctxt); +#endif if (ctxt->state == XSLT_STATE_STOPPED) break; if (IS_XSLT_ELEM(cur)) { if (IS_XSLT_NAME(cur, "with-param")) { @@ -2584,6 +2712,10 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node, */ cur = inst->children; while (cur!=NULL) { +#ifdef WITH_DEBUGGER + if (xslDebugStatus != DEBUG_NONE) + xslHandleDebugger(cur, node, comp->templ, ctxt); +#endif if (ctxt->state == XSLT_STATE_STOPPED) break; if (IS_XSLT_ELEM(cur)) { if (IS_XSLT_NAME(cur, "with-param")) { @@ -2712,6 +2844,13 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node, goto error; } when = replacement; + + +#ifdef WITH_DEBUGGER + if (xslDebugStatus != DEBUG_NONE) + xslHandleDebugger(when, node, comp->templ, ctxt); +#endif + #ifdef WITH_XSLT_DEBUG_PROCESS xsltGenericDebug(xsltGenericDebugContext, "xsltChoose: test %s\n", wcomp->test); @@ -2763,6 +2902,11 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node, replacement = replacement->next; } if (IS_XSLT_ELEM(replacement) && (IS_XSLT_NAME(replacement, "otherwise"))) { +#ifdef WITH_DEBUGGER + if (xslDebugStatus != DEBUG_NONE) + xslHandleDebugger(replacement, node, comp->templ, ctxt); +#endif + #ifdef WITH_XSLT_DEBUG_PROCESS xsltGenericDebug(xsltGenericDebugContext, "evaluating xsl:otherwise\n"); @@ -2947,6 +3091,10 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node, } else { sorts[nbsorts++] = replacement; } +#ifdef WITH_DEBUGGER + if (xslDebugStatus != DEBUG_NONE) + xslHandleDebugger(replacement, node, NULL, ctxt); +#endif replacement = replacement->next; } diff --git a/libxslt/transform.h b/libxslt/transform.h index 9840622f..9aa7386a 100644 --- a/libxslt/transform.h +++ b/libxslt/transform.h @@ -134,6 +134,15 @@ void xsltForEach (xsltTransformContextPtr ctxt, xmlNodePtr inst, xsltStylePreCompPtr comp); void xsltRegisterAllElement (xsltTransformContextPtr ctxt); + +/* + * Hook for the debugger if activated. + */ +void xslHandleDebugger (xmlNodePtr cur, + xmlNodePtr node, + xsltTemplatePtr templ, + xsltTransformContextPtr ctxt); + #ifdef __cplusplus } #endif diff --git a/libxslt/xsltconfig.h.in b/libxslt/xsltconfig.h.in index 7270f862..3ac02b58 100644 --- a/libxslt/xsltconfig.h.in +++ b/libxslt/xsltconfig.h.in @@ -65,6 +65,17 @@ extern "C" { #define DEBUG_MEMORY_LOCATION #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 @WITH_DEBUGGER@ +#define WITH_XSLT_DEBUGGER +#endif + /** * ATTRIBUTE_UNUSED: * diff --git a/xsltproc/Makefile.am b/xsltproc/Makefile.am index e855f9ca..919bf8bc 100644 --- a/xsltproc/Makefile.am +++ b/xsltproc/Makefile.am @@ -8,8 +8,13 @@ if DV_STATIC_LINK # all: xsltproc +if WITH_DEBUGGER +xsltproc: xsltproc.o ../libxslt/.libs/libxslt.a ../libexslt/.libs/libexslt.a ../breakpoint/.libs/libxsltbreakpoint.a ../../XML/.libs/libxml2.a + gcc -g -O -o xsltproc xsltproc.o ../libxslt/.libs/libxslt.a ../breakpoint/.libs/libxsltbreakpoint.a ../libexslt/.libs/libexslt.a ../../XML/.libs/libxml2.a -lz -lm +else xsltproc: xsltproc.o ../libxslt/.libs/libxslt.a ../libexslt/.libs/libexslt.a ../../XML/.libs/libxml2.a gcc -g -O -o xsltproc xsltproc.o ../libxslt/.libs/libxslt.a ../libexslt/.libs/libexslt.a ../../XML/.libs/libxml2.a -lz -lm +endif programs= else @@ -23,6 +28,22 @@ xsltproc_LDFLAGS = xsltproc_DEPENDENCIES = $(DEPS) xsltproc_LDADD = $(LDADDS) -DEPS = $(top_builddir)/libxslt/libxslt.la $(top_builddir)/libexslt/libexslt.la +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 \ + $(top_builddir)/libexslt/libexslt.la +endif + +if WITH_DEBUGGER LDADDS = $(top_builddir)/libxslt/libxslt.la \ - $(top_builddir)/libexslt/libexslt.la @LIBXML_LIBS@ $(EXTRA_LIBS) + $(top_builddir)/libexslt/libexslt.la \ + $(top_builddir)/breakpoint/libxsltbreakpoint.la \ + @LIBXML_LIBS@ $(EXTRA_LIBS) +else +LDADDS = $(top_builddir)/libxslt/libxslt.la \ + $(top_builddir)/libexslt/libexslt.la \ + @LIBXML_LIBS@ $(EXTRA_LIBS) +endif