/***************************************************************************
breakpoint_cmds . c - breakpoint commands for xsldbg
- - - - - - - - - - - - - - - - - - -
begin : Wed Nov 21 2001
copyright : ( C ) 2001 by Keith Isdale
email : k_isdale @ tpg . com . au
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***************************************************************************
* *
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "xsldbg.h"
# include "debugXSL.h"
# include "files.h"
# include "utils.h"
# include <libxml/valid.h> /* needed for xmlSplitQName2 */
# include <libxml/xpathInternals.h> /* needed for xmlNSLookup */
# include <libxml/uri.h> /* needed for xmlURIEscapeStr */
# include "xsldbgthread.h" /* for getThreadStatus() */
# include "xsldbgmsg.h"
# include "options.h"
/* temp buffer needed occationaly */
static xmlChar buff [ DEBUG_BUFFER_SIZE ] ;
/* needed by breakpoint validation */
extern int breakPointCounter ;
/* we need to have a fake URL and line number for orphaned template breakpoints */
int orphanedTemplateLineNo = 1 ;
const xmlChar * orphanedTemplateURL = ( xmlChar * ) " http://xsldbg.sourceforge.net/default.xsl " ;
/* ---------------------------------------------------
Private function declarations for breakpoint_cmds . c
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* validateSource :
* @ url : is valid name of a xsl source file
* @ lineNo : lineNo > = 0
*
* Returns 1 if a breakpoint could be set at specified file url and line number
* 0 otherwise
*/
int validateSource ( xmlChar * * url , long * lineNo ) ;
/**
* validateData :
* @ url : is valid name of a xml data file
* @ lineNo : lineNo > = 0
*
* Returns 1 if a breakpoint could be set at specified file url and line number
* 0 otherwise
*/
int validateData ( xmlChar * * url , long * lineNo ) ;
/* -------------------------------------
End private functions
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* -----------------------------------------
BreakPoint related commands
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* xslDbgShellFrameBreak :
* @ arg : Is valid number of frames to change location by
* @ stepup : If ! = 1 then we step up , otherwise step down
*
* Set a " frame " break point either up or down from here
*
* Returns 1 on success ,
* 0 otherwise
*/
int
xslDbgShellFrameBreak ( xmlChar * arg , int stepup )
{
int result = 0 ;
/* how many frames to go up/down */
int noOfFrames ;
static const char * errorPrompt = I18N_NOOP ( " Failed to add breakpoint. " ) ;
if ( ! filesGetStylesheet ( ) | | ! filesGetMainDoc ( ) ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Debugger has no files loaded. Try reloading files. \n " ) ) ;
xsldbgGenericErrorFunc ( TQString ( " Error: %1. \n " ) . tqarg ( i18n ( errorPrompt ) ) ) ;
return result ;
}
if ( ! arg ) {
# ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
xsltGenericError ( xsltGenericErrorContext ,
" Error: NULL argument provided \n " ) ;
# endif
xsldbgGenericErrorFunc ( TQString ( " Error: %1 \n " ) . tqarg ( i18n ( errorPrompt ) ) ) ;
return result ;
}
if ( xmlStrLen ( arg ) > 0 ) {
if ( ! sscanf ( ( char * ) arg , " %d " , & noOfFrames ) ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Unable to parse %1 as a number of frames. \n " ) . tqarg ( ( char * ) arg ) ) ;
noOfFrames = - 1 ;
}
} else {
noOfFrames = 0 ;
}
if ( noOfFrames > 0 ) {
if ( stepup ) {
result = callStackStepup ( callStackGetDepth ( ) - noOfFrames ) ;
} else {
result = callStackStepdown ( callStackGetDepth ( ) + noOfFrames ) ;
}
}
if ( ! result )
xsldbgGenericErrorFunc ( TQString ( " Error: %1 \n " ) . tqarg ( i18n ( errorPrompt ) ) ) ;
return result ;
}
/**
* validateSource :
* @ url : is valid name of a xsl source file
* @ lineNo : lineNo > = 0
*
* Returns 1 if a breakpoint could be set at specified file url and line number
* 0 otherwise
*/
int
validateSource ( xmlChar * * url , long * lineNo )
{
int result = 0 , type ;
searchInfoPtr searchInf ;
nodeSearchDataPtr searchData = NULL ;
if ( ! filesGetStylesheet ( ) ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Stylesheet is not valid or file is not loaded. \n " ) ) ;
return result ;
}
if ( ! url ) {
# ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
xsltGenericError ( xsltGenericErrorContext ,
" Error: NULL argument provided \n " ) ;
# endif
return result ;
}
searchInf = searchNewInfo ( SEARCH_NODE ) ;
if ( searchInf & & searchInf - > data ) {
type = DEBUG_BREAK_SOURCE ;
searchData = ( nodeSearchDataPtr ) searchInf - > data ;
if ( lineNo ! = NULL )
searchData - > lineNo = * lineNo ;
searchData - > nameInput = ( xmlChar * ) xmlMemStrdup ( ( char * ) * url ) ;
guessStylesheetName ( searchInf ) ;
/* try to verify that the line number is valid */
if ( searchInf - > found ) {
/* ok it looks like we've got a valid url */
/* searchData->url will be freed by searchFreeInfo */
if ( searchData - > absoluteNameMatch )
searchData - > url = ( xmlChar * )
xmlMemStrdup ( ( char * ) searchData - > absoluteNameMatch ) ;
else
searchData - > url = ( xmlChar * )
xmlMemStrdup ( ( char * ) searchData - > guessedNameMatch ) ;
if ( lineNo ! = NULL ) {
/* now to check the line number */
if ( searchData - > node ) {
searchInf - > found = 0 ;
/* searchData->node is set to the topmost node in stylesheet */
walkChildNodes ( ( xmlHashScanner ) scanForNode , searchInf ,
searchData - > node ) ;
if ( ! searchInf - > found ) {
xsldbgGenericErrorFunc ( i18n ( " Warning: Breakpoint for file \" %1 \" at line %2 does not seem to be valid. \n " ) . tqarg ( xsldbgUrl ( * url ) ) . tqarg ( * lineNo ) ) ;
}
* lineNo = searchData - > lineNo ;
xmlFree ( * url ) ;
* url = xmlStrdup ( searchData - > url ) ;
result = 1 ;
}
} else {
/* we've been asked just to check the file name */
if ( * url )
xmlFree ( * url ) ;
if ( searchData - > absoluteNameMatch )
* url = ( xmlChar * )
xmlMemStrdup ( ( char * ) searchData - > absoluteNameMatch ) ;
else
* url = ( xmlChar * )
xmlMemStrdup ( ( char * ) searchData - > guessedNameMatch ) ;
result = 1 ;
}
} else {
xsldbgGenericErrorFunc ( i18n ( " Error: Unable to find a stylesheet file whose name contains %1. \n " ) . tqarg ( xsldbgUrl ( * url ) ) ) ;
if ( lineNo ) {
xsldbgGenericErrorFunc ( i18n ( " Warning: Breakpoint for file \" %1 \" at line %2 does not seem to be valid. \n " ) . tqarg ( xsldbgUrl ( * url ) ) . tqarg ( * lineNo ) ) ;
}
}
}
if ( searchInf )
searchFreeInfo ( searchInf ) ;
else
xsldbgGenericErrorFunc ( i18n ( " Error: Out of memory. \n " ) ) ;
return result ;
}
/**
* validateData :
* @ url : is valid name of a xml data file
* @ lineNo : lineNo > = 0
*
* Returns 1 if a breakpoint could be set at specified file url and line number
* 0 otherwise
*/
int
validateData ( xmlChar * * url , long * lineNo )
{
int result = 0 ;
searchInfoPtr searchInf ;
nodeSearchDataPtr searchData = NULL ;
char * lastSlash ;
if ( ! filesGetMainDoc ( ) ) {
if ( ! optionsGetIntOption ( OPTIONS_GDB ) ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Data file is invalid. Try the run command first. \n " ) ) ;
}
return result ;
}
if ( ! url ) {
# ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
xsltGenericError ( xsltGenericErrorContext ,
" Error: NULL argument provided \n " ) ;
# endif
return result ;
}
searchInf = searchNewInfo ( SEARCH_NODE ) ;
if ( searchInf & & searchInf - > data & & filesGetMainDoc ( ) ) {
/* Try to verify that the line number is valid.
First try an absolute name match */
searchData = ( nodeSearchDataPtr ) searchInf - > data ;
if ( lineNo ! = NULL )
searchData - > lineNo = * lineNo ;
else
searchData - > lineNo = - 1 ;
searchData - > url = ( xmlChar * ) xmlMemStrdup ( ( char * ) * url ) ;
walkChildNodes ( ( xmlHashScanner ) scanForNode , searchInf ,
( xmlNodePtr ) filesGetMainDoc ( ) ) ;
/* Next try to guess file name by adding the prefix of main document
if no luck so far */
if ( ! searchInf - > found ) {
/* Find the last separator of the documents URL */
lastSlash = xmlStrrChr ( filesGetMainDoc ( ) - > URL , URISEPARATORCHAR ) ;
if ( ! lastSlash )
lastSlash = xmlStrrChr ( filesGetMainDoc ( ) - > URL , PATHCHAR ) ;
if ( lastSlash ) {
lastSlash + + ;
xmlStrnCpy ( buff , filesGetMainDoc ( ) - > URL ,
lastSlash - ( char * ) filesGetMainDoc ( ) - > URL ) ;
buff [ lastSlash - ( char * ) filesGetMainDoc ( ) - > URL ] = ' \0 ' ;
xmlStrCat ( buff , * url ) ;
} else
xmlStrCpy ( buff , " " ) ;
if ( xmlStrLen ( buff ) > 0 ) {
if ( searchData - > url )
xmlFree ( searchData - > url ) ;
searchData - > url = ( xmlChar * ) xmlMemStrdup ( ( char * ) buff ) ;
walkChildNodes ( ( xmlHashScanner ) scanForNode , searchInf ,
( xmlNodePtr ) filesGetMainDoc ( ) ) ;
}
}
if ( ! searchInf - > found ) {
if ( lineNo ) {
xsldbgGenericErrorFunc ( i18n ( " Warning: Breakpoint for file \" %1 \" at line %2 does not seem to be valid. \n " ) . tqarg ( xsldbgUrl ( * url ) ) . tqarg ( * lineNo ) ) ;
} else {
xsldbgGenericErrorFunc ( i18n ( " Error: Unable to find a data file whose name contains %1. \n " ) . tqarg ( xsldbgUrl ( * url ) ) ) ;
}
result = 1 ;
} else {
if ( * url )
xmlFree ( * url ) ;
* url = xmlStrdup ( searchData - > url ) ;
result = 1 ;
}
}
if ( searchInf )
searchFreeInfo ( searchInf ) ;
else
xsldbgGenericErrorFunc ( i18n ( " Error: Out of memory. \n " ) ) ;
return result ;
}
/**
* xslDbgShellBreak :
* @ arg : Is valid and in UTF - 8
* @ style : Is valid
* @ ctxt : Is valid
*
* Add break point specified by arg
*
* Returns 1 on success ,
* 0 otherwise
*/
int
xslDbgShellBreak ( xmlChar * arg , xsltStylesheetPtr style ,
xsltTransformContextPtr ctxt )
{
int result = 0 ;
long lineNo = - 1 ;
xmlChar * url = NULL ;
int orphanedBreakPoint = 0 ;
breakPointPtr breakPtr ;
static const char * errorPrompt = I18N_NOOP ( " Failed to add breakpoint. " ) ;
if ( style = = NULL ) {
style = filesGetStylesheet ( ) ;
}
if ( ! style | | ! filesGetMainDoc ( ) ) {
if ( ! optionsGetIntOption ( OPTIONS_GDB ) ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Debugger has no files loaded. Try reloading files. \n " ) ) ;
xsldbgGenericErrorFunc ( TQString ( " Error: %1 \n " ) . tqarg ( i18n ( errorPrompt ) ) ) ;
return result ;
} else {
orphanedBreakPoint = 1 ;
}
}
if ( ! arg ) {
# ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
xsltGenericError ( xsltGenericErrorContext ,
" Error: NULL argument provided \n " ) ;
# endif
return result ;
}
if ( arg [ 0 ] = = ' - ' ) {
xmlChar * opts [ 2 ] ;
if ( ( xmlStrLen ( arg ) > 1 ) & & ( arg [ 1 ] = = ' l ' ) ) {
if ( splitString ( & arg [ 2 ] , 2 , opts ) = = 2 ) {
if ( ( xmlStrlen ( opts [ 1 ] ) = = 0 ) | |
! sscanf ( ( char * ) opts [ 1 ] , " %ld " , & lineNo ) ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Unable to parse %1 as a line number. \n " ) . tqarg ( ( char * ) opts [ 1 ] ) ) ;
xsldbgGenericErrorFunc ( TQString ( " Error: %1 \n " ) . tqarg ( i18n ( errorPrompt ) ) ) ;
return result ;
} else {
/* try to guess whether we are looking for source or data
* break point
*/
xmlChar * escapedURI ;
trimString ( opts [ 0 ] ) ;
url = filesExpandName ( opts [ 0 ] ) ;
if ( url ) {
escapedURI = xmlURIEscapeStr ( url , ( const xmlChar * ) " / " ) ;
if ( escapedURI ) {
xmlFree ( url ) ;
url = escapedURI ;
}
}
if ( url ) {
if ( ! orphanedBreakPoint ) {
if ( filesIsSourceFile ( url ) ) {
if ( validateSource ( & url , & lineNo ) )
result =
breakPointAdd ( url , lineNo , NULL , NULL ,
DEBUG_BREAK_SOURCE ) ;
} else {
if ( validateData ( & url , & lineNo ) )
result =
breakPointAdd ( url , lineNo , NULL , NULL ,
DEBUG_BREAK_DATA ) ;
}
} else {
if ( filesIsSourceFile ( url ) ) {
result =
breakPointAdd ( url , lineNo , NULL , NULL ,
DEBUG_BREAK_SOURCE ) ;
} else {
result =
breakPointAdd ( url , lineNo , NULL , NULL ,
DEBUG_BREAK_DATA ) ;
}
breakPtr = breakPointGet ( url , lineNo ) ;
if ( breakPtr ) {
breakPtr - > flags | = BREAKPOINT_ORPHANED ;
} else {
xsldbgGenericErrorFunc ( i18n ( " Error: Unable to find the added breakpoint. " ) ) ;
}
}
}
}
} else
xsldbgGenericErrorFunc ( i18n ( " Error: Invalid arguments to command %1. \n " ) . tqarg ( " break " ) ) ;
}
} else {
/* add breakpoint at specified template names */
xmlChar * opts [ 2 ] ;
xmlChar * name = NULL , * nameURI = NULL , * mode = NULL , * modeURI = NULL ;
xmlChar * templateName = NULL , * modeName = NULL ;
xmlChar * tempUrl = NULL ; /* we must use a non-const xmlChar *
and we are not making a copy
of orginal value so this must not be
freed */
xmlChar * defaultUrl = ( xmlChar * ) " <n/a> " ;
int newBreakPoints = 0 , validatedBreakPoints = 0 ;
int allTemplates = 0 ;
int ignoreTemplateNames = 0 ;
int argCount ;
int found ;
xsltTemplatePtr templ ;
if ( orphanedBreakPoint | | ! ctxt ) {
/* Add an orphaned template breakpoint we will need to call this function later to
activate the breakpoint */
result =
breakPointAdd ( orphanedTemplateURL , orphanedTemplateLineNo , arg , NULL ,
DEBUG_BREAK_SOURCE ) ;
breakPtr = breakPointGet ( orphanedTemplateURL , orphanedTemplateLineNo + + ) ;
if ( breakPtr ) {
breakPtr - > flags | = BREAKPOINT_ORPHANED ;
} else {
# ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
xsltGenericError ( xsltGenericErrorContext ,
" Error: Unable to find added breakpoint " ) ;
# endif
}
return result ;
}
argCount = splitString ( arg , 2 , opts ) ;
if ( ( argCount = = 2 ) & & ( xmlStrLen ( opts [ 1 ] ) = = 0 ) )
argCount = 1 ;
switch ( argCount ) {
case 0 :
allTemplates = 1 ;
break ;
case 1 :
if ( xmlStrEqual ( opts [ 0 ] , ( xmlChar * ) " * " ) ) {
allTemplates = 1 ;
} else {
if ( xmlStrEqual ( opts [ 0 ] , ( xmlChar * ) " \\ * " ) ) {
opts [ 0 ] [ 0 ] = ' * ' ;
opts [ 0 ] [ 1 ] = ' \0 ' ;
}
name = xmlSplitQName2 ( opts [ 0 ] , & nameURI ) ;
if ( name = = NULL ) {
name = xmlStrdup ( opts [ 0 ] ) ;
} else {
if ( nameURI ) {
/* get the real URI for this namespace */
const xmlChar * temp = xmlXPathNsLookup ( ctxt - > xpathCtxt , nameURI ) ;
if ( temp )
xmlFree ( nameURI ) ;
nameURI = xmlStrdup ( temp ) ;
}
}
}
break ;
case 2 :
if ( xmlStrLen ( opts [ 0 ] ) = = 0 ) {
/* we don't care about the template name ie we are trying to match
templates with a given mode */
ignoreTemplateNames = 1 ;
} else {
name = xmlSplitQName2 ( opts [ 0 ] , & nameURI ) ;
if ( name = = NULL )
name = xmlStrdup ( opts [ 0 ] ) ;
if ( nameURI ) {
/* get the real URI for this namespace */
const xmlChar * temp = xmlXPathNsLookup ( ctxt - > xpathCtxt ,
nameURI ) ;
if ( temp )
xmlFree ( nameURI ) ;
nameURI = xmlStrdup ( temp ) ;
}
}
mode = xmlSplitQName2 ( opts [ 1 ] , & modeURI ) ;
if ( mode = = NULL )
mode = xmlStrdup ( opts [ 1 ] ) ;
if ( modeURI ) {
/* get the real URI for this namespace */
const xmlChar * temp = xmlXPathNsLookup ( ctxt - > xpathCtxt , modeURI ) ;
if ( temp )
xmlFree ( modeURI ) ;
modeURI = xmlStrdup ( temp ) ;
}
break ;
default :
xsldbgGenericErrorFunc ( i18n ( " Error: Invalid arguments for command %1. \n " ) . tqarg ( " break " ) ) ;
return 0 ;
}
while ( style ) {
templ = style - > templates ;
while ( templ ) {
found = 0 ;
if ( templ - > elem & & templ - > elem - > doc
& & templ - > elem - > doc - > URL ) {
tempUrl = ( xmlChar * ) templ - > elem - > doc - > URL ;
} else {
tempUrl = defaultUrl ;
}
if ( templ - > match )
templateName = xmlStrdup ( templ - > match ) ;
else
templateName = fullTQName ( templ - > nameURI , templ - > name ) ;
if ( allTemplates )
found = 1 ;
else {
if ( ignoreTemplateNames ) {
if ( ! mode | | ( xmlStrEqual ( templ - > mode , mode ) & &
( ! modeURI | | xmlStrEqual ( templ - > modeURI ,
modeURI ) ) ) )
found = 1 ;
} else if ( templ - > match ) {
if ( ( xmlStrEqual ( templ - > match , name ) & &
( ! modeURI | | xmlStrEqual ( templ - > modeURI ,
modeURI ) ) & &
( ! mode | | xmlStrEqual ( templ - > mode ,
mode ) ) ) )
found = 1 ;
} else {
if ( xmlStrEqual ( templ - > name , name ) & &
( ! nameURI | | xmlStrEqual ( templ - > nameURI , nameURI ) ) )
found = 1 ;
}
}
if ( found ) {
int templateLineNo = xmlGetLineNo ( templ - > elem ) ;
breakPointPtr searchPtr = breakPointGet ( tempUrl , templateLineNo ) ;
if ( templ - > mode )
modeName =
fullTQName ( templ - > modeURI , templ - > mode ) ;
if ( ! searchPtr ) {
if ( breakPointAdd ( tempUrl , templateLineNo ,
templateName , modeName ,
DEBUG_BREAK_SOURCE ) ) {
newBreakPoints + + ;
}
} else {
if ( ( templateLineNo ! = searchPtr - > lineNo ) | | ! xmlStrEqual ( tempUrl , searchPtr - > url ) ) {
int lastId = searchPtr - > id ;
int lastCounter = breakPointCounter ;
/* we have a new location for breakpoint */
if ( breakPointDelete ( searchPtr ) ) {
if ( breakPointAdd ( tempUrl , templateLineNo , templateName , modeName , DEBUG_BREAK_SOURCE ) ) {
searchPtr = breakPointGet ( tempUrl , templateLineNo ) ;
if ( searchPtr ) {
searchPtr - > id = lastId ;
result = 1 ;
breakPointCounter = lastCounter ;
xsldbgGenericErrorFunc ( i18n ( " Information: Breakpoint validation has caused breakpoint %1 to be re-created. \n " ) . tqarg ( searchPtr - > id ) ) ;
validatedBreakPoints + + ;
}
}
}
} else {
if ( xsldbgValidateBreakpoints ! = BREAKPOINTS_BEING_VALIDATED ) {
xsldbgGenericErrorFunc ( i18n ( " Warning: Breakpoint exits for file \" %1 \" at line %2. \n " ) . tqarg ( xsldbgUrl ( tempUrl ) ) . tqarg ( templateLineNo ) ) ;
}
validatedBreakPoints + + ;
}
}
}
if ( templateName ) {
xmlFree ( templateName ) ;
templateName = NULL ;
}
if ( modeName ) {
xmlFree ( modeName ) ;
modeName = NULL ;
}
templ = templ - > next ;
}
if ( style - > next )
style = style - > next ;
else
style = style - > imports ;
}
if ( ( newBreakPoints = = 0 ) & & ( validatedBreakPoints = = 0 ) ) {
xsldbgGenericErrorFunc ( i18n ( " Error: No templates found or unable to add breakpoint. \n " ) ) ;
url = NULL ; /* flag that we've printed partial error message about the problem url */
} else {
result = 1 ;
if ( newBreakPoints ) {
xsldbgGenericErrorFunc ( i18n ( " Information: Added %n new breakpoint. " , " Information: Added %n new breakpoints. " , newBreakPoints ) + TQString ( " \n " ) ) ;
}
}
if ( name )
xmlFree ( name ) ;
if ( nameURI )
xmlFree ( nameURI ) ;
if ( mode )
xmlFree ( mode ) ;
if ( modeURI )
xmlFree ( modeURI ) ;
if ( defaultUrl & & ! xmlStrEqual ( ( xmlChar * ) " <n/a> " , defaultUrl ) )
xmlFree ( defaultUrl ) ;
if ( tempUrl )
url = xmlStrdup ( tempUrl ) ;
} /* end add template breakpoints */
if ( ! result ) {
if ( url )
xsldbgGenericErrorFunc ( i18n ( " Error: Failed to add breakpoint for file \" %1 \" at line %2. \n " ) . tqarg ( xsldbgUrl ( url ) ) . tqarg ( lineNo ) ) ;
else
xsldbgGenericErrorFunc ( i18n ( " Error: Failed to add breakpoint. \n " ) ) ;
}
if ( url )
xmlFree ( url ) ;
return result ;
}
/**
* xslDbgShellDelete :
* @ arg : Is valid and in UTF - 8
*
* Delete break point specified by arg
*
* Returns 1 on success ,
* 0 otherwise
*/
int
xslDbgShellDelete ( xmlChar * arg )
{
int result = 0 , breakPointId ;
long lineNo ;
breakPointPtr breakPtr = NULL ;
static const char * errorPrompt = I18N_NOOP ( " Failed to delete breakpoint. " ) ;
if ( ! arg ) {
# ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
xsltGenericError ( xsltGenericErrorContext ,
" Error: NULL argument provided \n " ) ;
# endif
xsldbgGenericErrorFunc ( TQString ( " Error: %1 \n " ) . tqarg ( i18n ( errorPrompt ) ) ) ;
return result ;
}
if ( arg [ 0 ] = = ' - ' ) {
xmlChar * opts [ 2 ] , * url = NULL ;
if ( ( xmlStrLen ( arg ) > 1 ) & & ( arg [ 1 ] = = ' l ' ) ) {
if ( splitString ( & arg [ 2 ] , 2 , opts ) = = 2 ) {
if ( ( xmlStrlen ( opts [ 1 ] ) = = 0 ) | |
! sscanf ( ( char * ) opts [ 1 ] , " %ld " , & lineNo ) ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Unable to parse %1 as a line number. \n " ) . tqarg ( ( char * ) opts [ 1 ] ) ) ;
} else {
xmlChar * escapedURI ;
trimString ( opts [ 0 ] ) ;
url = filesExpandName ( opts [ 0 ] ) ;
if ( url ) {
escapedURI = xmlURIEscapeStr ( url , ( const xmlChar * ) " / " ) ;
if ( escapedURI ) {
xmlFree ( url ) ;
url = escapedURI ;
}
}
if ( url ) {
if ( filesIsSourceFile ( url ) ) {
if ( validateSource ( & url , & lineNo ) )
breakPtr = breakPointGet ( url , lineNo ) ;
} else if ( validateData ( & url , & lineNo ) )
breakPtr = breakPointGet ( url , lineNo ) ;
if ( ! breakPtr | | ! breakPointDelete ( breakPtr ) ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Breakpoint does not exist for file \" %1 \" at line %2. \n " ) . tqarg ( xsldbgUrl ( url ) ) . tqarg ( lineNo ) ) ;
} else {
result = 1 ;
}
xmlFree ( url ) ;
}
}
} else {
xsldbgGenericErrorFunc ( i18n ( " Error: Invalid arguments for command %1. \n " ) . tqarg ( " delete " ) ) ;
}
}
} else if ( xmlStrEqual ( ( xmlChar * ) " * " , arg ) ) {
result = 1 ;
/*remove all from breakpoints */
breakPointEmpty ( ) ;
} else if ( sscanf ( ( char * ) arg , " %d " , & breakPointId ) ) {
breakPtr = findBreakPointById ( breakPointId ) ;
if ( breakPtr ) {
result = breakPointDelete ( breakPtr ) ;
if ( ! result ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Unable to delete breakpoint %1. \n " ) . tqarg ( breakPointId ) ) ;
}
} else {
xsldbgGenericErrorFunc ( i18n ( " Error: Breakpoint %1 does not exist. \n " ) . tqarg ( breakPointId ) ) ;
}
} else {
breakPtr = findBreakPointByName ( arg ) ;
if ( breakPtr ) {
result = breakPointDelete ( breakPtr ) ;
if ( ! result ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Unable to delete breakpoint at template %1. \n " ) . tqarg ( xsldbgText ( arg ) ) ) ;
}
} else {
xsldbgGenericErrorFunc ( i18n ( " Error: Breakpoint at template \" %1 \" does not exist. \n " ) . tqarg ( xsldbgText ( arg ) ) ) ;
}
}
if ( ! result )
xsldbgGenericErrorFunc ( TQString ( " Error: %1 \n " ) . tqarg ( i18n ( errorPrompt ) ) ) ;
return result ;
}
/**
* xslDbgShellEnableBreakPoint :
* @ payload : A valid breakPointPtr
* @ data : Enable type , a pointer to an integer
* for a value of
* 1 enable break point
* 0 disable break point
* - 1 toggle enabling of break point
* @ name : Not used
*
* Enable / disable break points via use of scan of break points
*/
void
xslDbgShellEnableBreakPoint ( void * payload , void * data ,
xmlChar * name )
{
Q_UNUSED ( name ) ;
if ( payload & & data ) {
breakPointEnable ( ( breakPointPtr ) payload , * ( int * ) data ) ;
}
}
/**
* xslDbgShellEnable :
* @ arg : is valid and in UTF - 8
* @ enableType : enable break point if 1 , disable if 0 , toggle if - 1
*
* Enable / disable break point specified by arg using enable
* type of @ enableType
* Returns 1 if successful ,
* 0 otherwise
*/
int
xslDbgShellEnable ( xmlChar * arg , int enableType )
{
int result = 0 , breakPointId ;
long lineNo ;
breakPointPtr breakPtr = NULL ;
static const char * errorPrompt = I18N_NOOP ( " Failed to enable/disable breakpoint. " ) ;
if ( ! filesGetStylesheet ( ) | | ! filesGetMainDoc ( ) ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Debugger has no files loaded. Try reloading files. \n " ) ) ;
xsldbgGenericErrorFunc ( TQString ( " Error: %1 \n " ) . tqarg ( i18n ( errorPrompt ) ) ) ;
return result ;
}
if ( ! arg ) {
# ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
xsltGenericError ( xsltGenericErrorContext ,
" Error: NULL argument provided \n " ) ;
# endif
xsldbgGenericErrorFunc ( TQString ( " Error: %1 \n " ) . tqarg ( i18n ( errorPrompt ) ) ) ;
return result ;
}
if ( arg [ 0 ] = = ' - ' ) {
xmlChar * opts [ 2 ] , * url = NULL ;
if ( ( xmlStrLen ( arg ) > 1 ) & & ( arg [ 1 ] = = ' l ' ) ) {
if ( splitString ( & arg [ 2 ] , 2 , opts ) = = 2 ) {
if ( ( xmlStrlen ( opts [ 1 ] ) = = 0 ) | |
! sscanf ( ( char * ) opts [ 1 ] , " %ld " , & lineNo ) ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Unable to parse %1 as a line number. \n " ) . tqarg ( ( char * ) opts [ 1 ] ) ) ;
} else {
xmlChar * escapedURI ;
trimString ( opts [ 0 ] ) ;
url = filesExpandName ( opts [ 0 ] ) ;
if ( url ) {
escapedURI = xmlURIEscapeStr ( url , ( const xmlChar * ) " / " ) ;
if ( escapedURI ) {
xmlFree ( url ) ;
url = escapedURI ;
}
}
if ( url ) {
if ( strstr ( ( char * ) url , " .xsl " ) ) {
if ( validateSource ( & url , NULL ) )
breakPtr = breakPointGet ( url , lineNo ) ;
} else if ( validateData ( & url , NULL ) )
breakPtr = breakPointGet ( url , lineNo ) ;
if ( breakPtr ) {
result = breakPointEnable ( breakPtr , enableType ) ;
} else {
xsldbgGenericErrorFunc ( i18n ( " Error: Breakpoint does not exist for file \" %1 \" at line %2. \n " ) . tqarg ( xsldbgUrl ( url ) ) . tqarg ( lineNo ) ) ;
}
xmlFree ( url ) ;
}
}
} else
xsldbgGenericErrorFunc ( i18n ( " Error: Invalid arguments for command %1. \n " ) . tqarg ( " enable " ) ) ;
}
} else if ( xmlStrEqual ( ( xmlChar * ) " * " , arg ) ) {
result = 1 ;
/*enable/disable all from breakpoints */
walkBreakPoints ( ( xmlHashScanner ) xslDbgShellEnableBreakPoint ,
& enableType ) ;
} else if ( sscanf ( ( char * ) arg , " %d " , & breakPointId ) ) {
breakPtr = findBreakPointById ( breakPointId ) ;
if ( breakPtr ) {
result = breakPointEnable ( breakPtr , enableType ) ;
if ( ! result ) {
xsldbgGenericErrorFunc ( i18n ( " Error: Unable to enable/disable breakpoint %1. \n " ) . tqarg ( breakPointId ) ) ;
}
} else {
xsldbgGenericErrorFunc ( i18n ( " Error: Breakpoint %1 does not exist. \n " ) . tqarg ( breakPointId ) ) ;
}
} else {
breakPtr = findBreakPointByName ( arg ) ;
if ( breakPtr ) {
result = breakPointEnable ( breakPtr , enableType ) ;
} else
xsldbgGenericErrorFunc ( i18n ( " Error: Breakpoint at template \" %1 \" does not exist. \n " ) . tqarg ( xsldbgText ( arg ) ) ) ;
}
if ( ! result )
xsldbgGenericErrorFunc ( TQString ( " Error: %1 \n " ) . tqarg ( i18n ( errorPrompt ) ) ) ;
return result ;
}
/**
* xslDbgShellPrintBreakPoint :
* @ payload : A valid breakPointPtr
* @ data : Not used
* @ name : Not used
*
* Print data given by scan of break points
*/
void
xslDbgShellPrintBreakPoint ( void * payload , void * data ,
xmlChar * name )
{
Q_UNUSED ( data ) ;
Q_UNUSED ( name ) ;
if ( payload ) {
if ( getThreadStatus ( ) = = XSLDBG_MSG_THREAD_RUN ) {
notifyListQueue ( payload ) ;
} else {
printCount + + ;
xsldbgGenericErrorFunc ( " " ) ;
breakPointPrint ( ( breakPointPtr ) payload ) ;
xsldbgGenericErrorFunc ( " \n " ) ;
}
}
}
/* Validiate a breakpoint at a given URL and line number
breakPtr and copy must be valid
*/
static int validateBreakPoint ( breakPointPtr breakPtr , breakPointPtr copy )
{
int result = 0 ;
if ( ! breakPtr | | ! copy ) {
# ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
xsltGenericError ( xsltGenericErrorContext ,
" Warning: NULL arguments passed to validateBreakPoint \n " ) ;
# endif
return result ;
}
if ( filesIsSourceFile ( breakPtr - > url ) ) {
result = validateSource ( & copy - > url , & copy - > lineNo ) ;
} else {
result = validateData ( & copy - > url , & copy - > lineNo ) ;
}
if ( result )
breakPtr - > flags & = BREAKPOINT_ALLFLAGS ^ BREAKPOINT_ORPHANED ;
else
breakPtr - > flags | = BREAKPOINT_ORPHANED ;
if ( breakPtr - > flags & BREAKPOINT_ORPHANED ) {
xsldbgGenericErrorFunc ( TQString ( " Warning: Breakpoint %1 is orphaned. Result: %2. Old flags: %3. New flags: %4. \n " ) . tqarg ( breakPtr - > id ) . tqarg ( result ) . tqarg ( copy - > flags ) . tqarg ( breakPtr - > flags ) ) ;
}
if ( ! ( breakPtr - > flags & BREAKPOINT_ORPHANED ) & & ( ( copy - > lineNo ! = breakPtr - > lineNo ) | |
( xmlStrlen ( copy - > url ) ! = xmlStrlen ( breakPtr - > url ) ) | | xmlStrCmp ( copy - > url , breakPtr - > url ) ) ) {
/* we have a new location for breakpoint */
int lastCounter = breakPointCounter ;
copy - > templateName = xmlStrdup ( breakPtr - > templateName ) ;
copy - > modeName = xmlStrdup ( breakPtr - > modeName ) ;
if ( breakPointDelete ( breakPtr ) & & ! breakPointGet ( copy - > url , copy - > lineNo ) ) {
if ( breakPointAdd ( copy - > url , copy - > lineNo , NULL , NULL , copy - > type ) ) {
breakPtr = breakPointGet ( copy - > url , copy - > lineNo ) ;
if ( breakPtr ) {
breakPtr - > id = copy - > id ;
breakPtr - > flags = copy - > flags ;
breakPointCounter = lastCounter ; /* compensate for breakPointAdd which always
increments the breakPoint counter */
result = 1 ;
xsldbgGenericErrorFunc ( i18n ( " Information: Breakpoint validation has caused breakpoint %1 to be re-created. \n " ) . tqarg ( breakPtr - > id ) ) ;
}
}
if ( ! result ) {
xsldbgGenericErrorFunc ( i18n ( " Warning: Validation of breakpoint %1 failed. \n " ) . tqarg ( copy - > id ) ) ;
}
}
}
return result ;
}
/* Validiate a breakpoint at a given URL and line number
breakPtr , copy and ctx must be valid
*/
static int validateTemplateBreakPoint ( breakPointPtr breakPtr , breakPointPtr copy , xsltTransformContextPtr ctxt )
{
int result = 0 ;
if ( ! breakPtr | | ! copy | | ! ctxt ) {
# ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
xsltGenericError ( xsltGenericErrorContext ,
" Warning: NULL arguments passed to validateTemplateBreakPoint \n " ) ;
# endif
return result ;
}
copy - > templateName = xmlStrdup ( breakPtr - > templateName ) ;
if ( ( xmlStrlen ( copy - > templateName ) = = 0 ) | | xmlStrEqual ( copy - > templateName , ( xmlChar * ) " * " ) ) {
if ( xmlStrEqual ( breakPtr - > url , orphanedTemplateURL ) )
breakPointDelete ( breakPtr ) ;
if ( xslDbgShellBreak ( copy - > templateName , NULL , ctxt ) ) {
result = 1 ;
xsldbgGenericErrorFunc ( i18n ( " Information: Breakpoint validation has caused one or more breakpoints to be re-created. \n " ) ) ;
}
} else {
if ( xmlStrEqual ( breakPtr - > url , orphanedTemplateURL ) )
breakPointDelete ( breakPtr ) ;
if ( xslDbgShellBreak ( copy - > templateName , NULL , ctxt ) ) {
result = 1 ;
}
}
xmlFree ( copy - > templateName ) ;
if ( ! result ) {
xsldbgGenericErrorFunc ( i18n ( " Warning: Validation of breakpoint %1 failed. \n " ) . tqarg ( copy - > id ) ) ;
}
return result ;
}
/**
* xslDbgShellValidateBreakPoint :
* @ payload : A valid breakPointPtr
* @ data : Not used
* @ name : Not used
*
* Print an warning if a breakpoint is invalid
*/
void xslDbgShellValidateBreakPoint ( void * payload , void * data ,
xmlChar * name )
{
Q_UNUSED ( name ) ;
int result = 0 ;
if ( payload ) {
breakPointPtr breakPtr = ( breakPointPtr ) payload ;
breakPoint copy ; /* create a copy of the breakpoint */
copy . lineNo = breakPtr - > lineNo ;
copy . url = xmlStrdup ( breakPtr - > url ) ;
copy . flags = breakPtr - > flags ;
copy . type = breakPtr - > type ;
copy . id = breakPtr - > id ;
if ( copy . url ) {
if ( breakPtr - > templateName ) {
/* template name is used to contain the rules to add template breakpoint */
result = validateTemplateBreakPoint ( breakPtr , & copy , ( xsltTransformContextPtr ) data ) ;
} else {
result = validateBreakPoint ( breakPtr , & copy ) ;
}
} else {
xsldbgGenericErrorFunc ( i18n ( " Error: Out of memory. \n " ) ) ;
}
xmlFree ( copy . url ) ;
}
}