You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
6.8 KiB
236 lines
6.8 KiB
|
|
/***************************************************************************
|
|
debug.c - main functions for debugger use
|
|
-------------------
|
|
begin : Fri Nov 2 2001
|
|
copyright : (C) 2001 by Keith Isdale
|
|
email : k_isdale@tpg.com.au
|
|
***************************************************************************/
|
|
|
|
#include "xsldbg.h"
|
|
#include "debug.h"
|
|
#include "debugXSL.h" /* needed for debugXSLBreak function */
|
|
#include "breakpoint.h"
|
|
#include "callstack.h"
|
|
#include "files.h"
|
|
#include "options.h"
|
|
|
|
#include <libxslt/xsltutils.h> /* need for breakpoint callback support */
|
|
|
|
/* setup debugger callbacks */
|
|
struct DebuggerCallbacks {
|
|
xsltHandleDebuggerCallback debuggercallback;
|
|
xsltAddCallCallback addcallback;
|
|
xsltDropCallCallback dropcallback;
|
|
} debuggerDriver;
|
|
|
|
|
|
/* -----------------------------------------
|
|
Private functions
|
|
-------------------------------------------*/
|
|
|
|
/**
|
|
* debugHandleDebugger:
|
|
* @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 debugXSLBreak function
|
|
*/
|
|
void debugHandleDebugger(xmlNodePtr cur, xmlNodePtr node,
|
|
xsltTemplatePtr templ,
|
|
xsltTransformContextPtr ctxt);
|
|
|
|
/* -------------------------------------
|
|
End private functions
|
|
---------------------------------------*/
|
|
|
|
|
|
/*-----------------------------------------------------------
|
|
Main debugger functions
|
|
-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
/**
|
|
* debugInit :
|
|
*
|
|
* Initialize debugger
|
|
* Returns 1 on success,
|
|
* 0 otherwise
|
|
*/
|
|
int
|
|
debugInit(void)
|
|
{
|
|
int result;
|
|
|
|
xslDebugStatus = DEBUG_NONE;
|
|
result = breakPointInit();
|
|
result = result && callStackInit();
|
|
|
|
/* setup debugger callbacks */
|
|
debuggerDriver.debuggercallback = debugHandleDebugger;
|
|
debuggerDriver.addcallback = callStackAdd;
|
|
debuggerDriver.dropcallback = callStackDrop;
|
|
xsltSetDebuggerCallbacks(3, &debuggerDriver);
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* debugFree :
|
|
*
|
|
* Free up any memory taken by debugging
|
|
*/
|
|
void
|
|
debugFree(void)
|
|
{
|
|
breakPointFree();
|
|
callStackFree();
|
|
}
|
|
|
|
|
|
/**
|
|
* debugGotControl:
|
|
* @reached: 1 if debugger has received control, -1 to read its value,
|
|
0 to clear the flag
|
|
*
|
|
* Set flag that debugger has received control to value of @reached
|
|
*
|
|
* Returns 1 if any break point was reached previously,
|
|
* 0 otherwise
|
|
*/
|
|
int
|
|
debugGotControl(int reached)
|
|
{
|
|
static int hasReached;
|
|
int result = hasReached;
|
|
|
|
if (reached != -1)
|
|
hasReached = reached;
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* debugHandleDebugger:
|
|
* @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 debugXSLBreak function
|
|
*/
|
|
void
|
|
debugHandleDebugger(xmlNodePtr cur, xmlNodePtr node,
|
|
xsltTemplatePtr templ, xsltTransformContextPtr ctxt)
|
|
{
|
|
|
|
if (!cur && !node) {
|
|
xsldbgGenericErrorFunc(i18n("Error: XSLT source and XML data are empty. Cannot enter the debugger.\n"));
|
|
} else {
|
|
if (optionsGetIntOption(OPTIONS_GDB)){
|
|
int doValidation = 0;
|
|
switch(xsldbgValidateBreakpoints){
|
|
case BREAKPOINTS_ARE_VALID:
|
|
if (!filesGetStylesheet() || !filesGetMainDoc()) {
|
|
xsldbgValidateBreakpoints = BREAKPOINTS_NEED_VALIDATION;
|
|
doValidation = 1;
|
|
}
|
|
|
|
break;
|
|
|
|
case BREAKPOINTS_NEED_VALIDATION:
|
|
if (filesGetStylesheet() && filesGetMainDoc() && templ){
|
|
xsldbgValidateBreakpoints = BREAKPOINTS_BEING_VALIDATED;
|
|
doValidation = 1;
|
|
}
|
|
break;
|
|
|
|
case BREAKPOINTS_BEING_VALIDATED:
|
|
/*should never be in the state for any length of time */
|
|
#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
|
|
xsltGenericError(xsltGenericErrorContext,
|
|
"Error: Unexpected breakpoint validation state %d", xsldbgValidateBreakpoints);
|
|
#endif
|
|
break;
|
|
}
|
|
if (doValidation){
|
|
/* breakpoints will either be marked as orphaned or not as needed */
|
|
xsldbgValidateBreakpoints = BREAKPOINTS_BEING_VALIDATED;
|
|
walkBreakPoints((xmlHashScanner)
|
|
xslDbgShellValidateBreakPoint, ctxt);
|
|
if (filesGetStylesheet() && filesGetMainDoc() && templ){
|
|
xsldbgValidateBreakpoints = BREAKPOINTS_ARE_VALID;
|
|
}else{
|
|
xsldbgValidateBreakpoints = BREAKPOINTS_NEED_VALIDATION;
|
|
}
|
|
}
|
|
}
|
|
switch (xslDebugStatus) {
|
|
|
|
/* A temparary stopping point */
|
|
case DEBUG_WALK:
|
|
case DEBUG_TRACE:
|
|
/* only allow breakpoints at xml elements */
|
|
if (xmlGetLineNo(cur) != -1)
|
|
debugXSLBreak(cur, node, templ, ctxt);
|
|
break;
|
|
|
|
case DEBUG_STOP:
|
|
xslDebugStatus = DEBUG_CONT;
|
|
/* only allow breakpoints at xml elements */
|
|
if (xmlGetLineNo(cur) != -1)
|
|
debugXSLBreak(cur, node, templ, ctxt);
|
|
break;
|
|
|
|
case DEBUG_STEP:
|
|
/* only allow breakpoints at xml elements */
|
|
if (xmlGetLineNo(cur) != -1)
|
|
debugXSLBreak(cur, node, templ, ctxt);
|
|
break;
|
|
|
|
case DEBUG_CONT:
|
|
{
|
|
breakPointPtr breakPtr = NULL;
|
|
xmlChar *baseUri = NULL;
|
|
|
|
if (cur) {
|
|
breakPtr =
|
|
breakPointGet(cur->doc->URL,
|
|
xmlGetLineNo(cur));
|
|
|
|
if (breakPtr && (breakPtr->flags & BREAKPOINT_ENABLED) ){
|
|
debugXSLBreak(cur, node, templ, ctxt);
|
|
return;
|
|
}
|
|
}
|
|
if (node) {
|
|
baseUri = filesGetBaseUri(node);
|
|
if (baseUri != NULL) {
|
|
breakPtr =
|
|
breakPointGet(baseUri, xmlGetLineNo(node));
|
|
} else {
|
|
breakPtr =
|
|
breakPointGet(node->doc->URL,
|
|
xmlGetLineNo(node));
|
|
}
|
|
if (breakPtr) {
|
|
if (breakPtr->flags & BREAKPOINT_ENABLED) {
|
|
debugXSLBreak(cur, node, templ, ctxt);
|
|
}
|
|
}
|
|
if (baseUri)
|
|
xmlFree(baseUri);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|