summaryrefslogtreecommitdiffstats
path: root/kxsldbg/kxsldbgpart/libxsldbg/breakpoint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kxsldbg/kxsldbgpart/libxsldbg/breakpoint.cpp')
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/breakpoint.cpp696
1 files changed, 696 insertions, 0 deletions
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/breakpoint.cpp b/kxsldbg/kxsldbgpart/libxsldbg/breakpoint.cpp
new file mode 100644
index 00000000..270ce82d
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/breakpoint.cpp
@@ -0,0 +1,696 @@
+
+/***************************************************************************
+ breakpoint.c - breakpoint implementation
+ -------------------
+ begin : Fri Nov 2 2001
+ copyright : (C) 2001 by Keith Isdale
+ email : k_isdale@tpg.com.au
+ ***************************************************************************/
+
+#include "xsldbg.h"
+#include "breakpoint.h"
+#include "arraylist.h"
+#include "options.h"
+
+extern int xsldbgValidateBreakpoints; /*located in debugXSL.c*/
+
+/*-----------------------------------------------------------
+ Private functions
+-----------------------------------------------------------*/
+
+/**
+ * lineNoItemNew:
+ *
+ * Returns a new hash table for break points
+ */
+xmlHashTablePtr lineNoItemNew(void);
+
+
+/**
+ * lineNoItemFree:
+ * @item: valid hashtable of break points
+ *
+ * Free @item and all its contents
+ */
+void lineNoItemFree(void *item);
+
+
+/**
+ * lineNoItemDelete:
+ * @breakPointHash: Is valid
+ * @breakPtr: Is valid
+ *
+ * Returns 1 if able to delete @breakPtr from @breakPointHash,
+ * 0 otherwise
+ */
+int lineNoItemDelete(xmlHashTablePtr breakPointHash,
+ breakPointPtr breakPtr);
+
+/**
+ * lineNoItemAdd:
+ * @breakPointHash: is valid
+ * @breakPtr: is valid
+ *
+ * Add breakpoint to hash
+ *
+ * Returns 1 if able to add @breakPtr to @breakPointHash,
+ * 0 otherwise
+ */
+int lineNoItemAdd(xmlHashTablePtr breakPointHash, breakPointPtr breakPtr);
+
+/*-----------------------------------------------------------
+ Breakpoint debugger functions
+-----------------------------------------------------------*/
+
+
+/* This is our major structure, it is a list of hash tables. Each
+ hash table has breakpoints with the same line number. A line
+ number is used as an index into this list to get the right hash table.
+ Then its just a matter of a simple hash table lookup */
+arrayListPtr breakList;
+
+/* keep track of what break point id we're up to*/
+int breakPointCounter = 0;
+
+/* What is the current breakpoint is only valid up to the start of
+ xsldbg command prompt. ie don't use it after deletion of breakpoints */
+breakPointPtr activeBreakPointItem = NULL;
+
+
+/**
+ * lineNoItemNew:
+ *
+ * Returns a new hash table for break points
+ */
+xmlHashTablePtr
+lineNoItemNew(void)
+{
+ xmlHashTablePtr hash;
+
+ hash = xmlHashCreate(4);
+
+ return hash;
+}
+
+
+/**
+ * lineNoItemFree:
+ * @item: valid hashtable of break points
+ *
+ * Free @item and all its contents
+ */
+void
+lineNoItemFree(void *item)
+{
+ xmlHashTablePtr hash = (xmlHashTablePtr) item;
+
+ if (item) {
+#if 0
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Freeing breakpoint line hash"
+ " with %d elements \n", xmlHashSize(item));
+#endif
+#endif
+ xmlHashFree(hash, breakPointItemFree);
+ }
+}
+
+
+/**
+ * lineNoItemDelete:
+ * @breakPointHash: is valid
+ * @breakPtr: is valid
+ *
+ * Returns 1 if able to delete @breakPtr from @breakPointHash,
+ * 0 otherwise
+ */
+int
+lineNoItemDelete(xmlHashTablePtr breakPointHash, breakPointPtr breakPtr)
+{
+ int result = 0;
+
+ if (breakPointHash && breakPtr) {
+ if (xmlHashRemoveEntry(breakPointHash, breakPtr->url,
+ breakPointItemFree) == 0){
+ result = 1;
+ }else{
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,"lineNoItemDelete failed");
+#endif
+ }
+
+ }else {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext, "lineNoItemDelete failed args %d %d", breakPointHash, breakPtr);
+#endif
+ }
+ return result;
+}
+
+
+/**
+ * lineNoItemAdd:
+ * @breakPointHash: is valid
+ * @breakPtr: is valid
+ *
+ * Returns 1 if able to add @breakPtr to @breakPointHash,
+ * 0 otherwise
+ */
+int
+lineNoItemAdd(xmlHashTablePtr breakPointHash, breakPointPtr breakPtr)
+{
+ int result = 0;
+
+ if (breakPointHash && breakPtr) {
+ if (xmlHashAddEntry(breakPointHash, breakPtr->url, breakPtr) == 0)
+ result = 1;
+ }
+ return result;
+}
+
+/**
+ * breakPointGetLineNoHash:
+ * @lineNo: Line number of of breakpoints of interest
+ *
+ * Return A hash of breakpoints with same line number
+ *
+ * Returns A hash of breakpoints with a line number of @lineNo
+ */
+xmlHashTablePtr
+breakPointGetLineNoHash(long lineNo)
+{
+ if (!breakList) {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Breakpoints structures not initialized\n");
+#endif
+ return NULL;
+ } else
+ return (xmlHashTablePtr) arrayListGet(breakList, lineNo);
+}
+
+
+/**
+ * breakPointInit:
+ *
+ * Returns 1 if breakpoints have been initialized properly and all
+ * memory required has been obtained,
+ * 0 otherwise
+*/
+int
+breakPointInit(void)
+{
+ int result = 0;
+
+ /* the average file has 395 lines of code so add 100 lines now */
+ breakList = arrayListNew(100, lineNoItemFree);
+ if (breakList) {
+ /*
+ * We don't need to do any thing else, as its done when we add the
+ * breakPoints
+ */
+ result = 1;
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Unable to intialize breakPoints: memory error\n");
+#endif
+ }
+ return result;
+}
+
+
+/**
+ * breakPointFree:
+ *
+ * Free all memory used by breakPoints
+ */
+void
+breakPointFree(void)
+{
+ if (breakList)
+ arrayListFree(breakList);
+ breakList = NULL;
+}
+
+
+/**
+ * breakPointEmpty:
+ *
+ * Empty the break point collection
+ *
+ * Returns 1 if able to empty the breakpoint list of its contents,
+ * 0 otherwise
+ */
+int
+breakPointEmpty(void)
+{
+ return arrayListEmpty(breakList);
+}
+
+
+/**
+ * breakPointItemNew:
+ *
+ * Create a new break point item
+ * Returns valid break point with default values set if successful,
+ * NULL otherwise
+ */
+breakPointPtr
+breakPointItemNew(void)
+{
+ breakPointPtr breakPtr = (breakPointPtr) xmlMalloc(sizeof(breakPoint));
+
+ if (breakPtr) {
+ breakPtr->url = NULL;
+ breakPtr->lineNo = -1;
+ breakPtr->templateName = NULL;
+ breakPtr->modeName = NULL;
+ breakPtr->flags = BREAKPOINT_ENABLED;
+ breakPtr->id = ++breakPointCounter;
+ breakPtr->type = DEBUG_BREAK_SOURCE;
+ }
+ return breakPtr;
+}
+
+
+/**
+ * breakPointItemFree:
+ * @payload: valid breakPointPtr
+ * @name: not used
+ *
+ * Free memory associated with this break point
+ */
+void
+breakPointItemFree(void *payload, xmlChar * name)
+{
+ Q_UNUSED(name);
+ if (payload) {
+ breakPointPtr breakPtr = (breakPointPtr) payload;
+
+ if (breakPtr->url)
+ xmlFree(breakPtr->url);
+ if (breakPtr->templateName)
+ xmlFree(breakPtr->templateName);
+ if (breakPtr->modeName)
+ xmlFree(breakPtr->modeName);
+ xmlFree(breakPtr);
+ }
+}
+
+
+/**
+ * breakPointActiveBreakPoint:
+ *
+ * Get the active break point
+ *
+ * Returns The last break point that we stoped at
+ *
+ * Depreciated
+ */
+breakPointPtr
+breakPointActiveBreakPoint(void)
+{
+ /* This function is depreciated */
+ return NULL; /* activeBreakPointItem; */
+}
+
+
+
+/**
+ * breakPointSetActiveBreakPoint:
+ * @breakPtr: Is valid break point or NULL
+ *
+ * Set the active break point
+ *
+ * Depreciated
+ */
+void
+breakPointSetActiveBreakPoint(breakPointPtr breakPtr)
+{
+ Q_UNUSED(breakPtr);
+ /*
+ * activeBreakPointItem = breakPtr;
+ */
+
+}
+
+
+/**
+ * breakPointAdd:
+ * @url: Non-null, non-empty file name that has been loaded by
+ * debugger
+ * @lineNumber: @lineNumber >= 0 and is available in url specified and
+ * points to an xml element
+ * @templateName: The template name of breakPoint or NULL
+ * @modeName : The mode of breakpoint or NULL
+ * @type: Valid BreakPointTypeEnum
+ *
+ * Add break point at file and line number specified
+ *
+ * Returns 1 if successful,
+ * 0 otherwise
+*/
+int
+breakPointAdd(const xmlChar * url, long lineNumber,
+ const xmlChar * templateName,
+ const xmlChar * modeName,
+ BreakPointTypeEnum type)
+{
+ int result = 0, breakPointType = type;
+ xmlHashTablePtr breakPointHash = NULL; /* hash of breakPoints */
+ breakPointPtr breakPtr;
+
+ if (!breakList) {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Breakpoints structures not initialized\n");
+#endif
+ return result;
+ }
+
+ if (!url || (lineNumber == -1)) {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Invalid url or line number to breakPointAdd\n");
+#endif
+ return result;
+ }
+
+ /* if breakpoint already exists then don;t add it */
+ if (breakPointIsPresent(url, lineNumber)) {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Warning: Breakpoint at file %s: line %d exists\n",
+ url, lineNumber);
+#endif
+ return result;
+ }
+
+ breakPtr = breakPointItemNew();
+ if (breakPtr) {
+ breakPtr->url = (xmlChar *) xmlMemStrdup((char *) url);
+ breakPtr->lineNo = lineNumber;
+ if (templateName)
+ breakPtr->templateName =
+ xmlStrdup( templateName);
+ else
+ breakPtr->templateName = NULL;
+ if (modeName)
+ breakPtr->modeName =
+ xmlStrdup(modeName);
+ else
+ breakPtr->modeName = NULL;
+ breakPtr->type = BreakPointTypeEnum(breakPointType);
+
+ /* add new breakPoint to the right hash table */
+ breakPointHash = breakPointGetLineNoHash(lineNumber);
+ if (breakPointHash) {
+ result = lineNoItemAdd(breakPointHash, breakPtr);
+ } else {
+ /* Grow breakList size */
+ int lineIndex;
+ int newEntries = breakList->count;
+ xmlHashTablePtr hash;
+
+ result = 1;
+ if ((lineNumber < breakList->count) && breakList->count) {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to find breakpoint line hash at %d\n",
+ lineNumber);
+#endif
+ } else {
+ if (breakList->count + newEntries < lineNumber)
+ newEntries = lineNumber - breakList->count + 1;
+
+
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ /*
+ * xsltGenericError(xsltGenericErrorContext,
+ * "Size of line list was %d adding %d entries\n",
+ * breakList->count, newEntries);
+ */
+#endif
+ lineIndex = 0;
+ while ((lineIndex < newEntries) && result) {
+ hash = lineNoItemNew();
+ if (hash) {
+ result = result && arrayListAdd(breakList, hash);
+ } else {
+ result = 0;
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to create hash table breakPoint list: memory error\n");
+#endif
+ return result;
+ }
+ lineIndex++;
+ }
+ /* find the newly added hashtable of breakpoints */
+ breakPointHash = breakPointGetLineNoHash(lineNumber);
+ if (breakPointHash) {
+ result = lineNoItemAdd(breakPointHash, breakPtr);
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to create new breakPoint:interal error\n");
+#endif
+ return result;
+ }
+ }
+
+ }
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to create new breakPoint: memory error\n");
+#endif
+ }
+
+ if (result && (optionsGetIntOption(OPTIONS_GDB) > 1) &&
+ (xsldbgValidateBreakpoints != BREAKPOINTS_BEING_VALIDATED)){
+ breakPointPrint(breakPtr);
+ xsldbgGenericErrorFunc("\n");
+ }
+ return result;
+}
+
+
+/**
+ * breakPointDelete:
+ * @breakPtr: Is valid
+ *
+ * Delete the break point specified if it can be found using
+ * @breakPoint's url and lineNo
+ *
+ * Returns 1 if successful,
+ * 0 otherwise
+*/
+int
+breakPointDelete(breakPointPtr breakPtr)
+{
+ int result = 0;
+ xmlHashTablePtr breakPointHash; /* hash of breakPoints */
+
+ if (!breakPtr)
+ return result;
+
+ breakPointHash = breakPointGetLineNoHash(breakPtr->lineNo);
+ if (breakPointHash) {
+ result = lineNoItemDelete(breakPointHash, breakPtr);
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Breakpoint not found: xslDeleteBreakPoint\n");
+#endif
+ }
+ return result;
+}
+
+
+/**
+ * breakPointEnable:
+ * @breakPtr: A valid breakpoint
+ * @enable: Enable break point if 1, disable if 0, toggle if -1
+ *
+ * Enable or disable a break point
+ *
+ * Returns 1 if successful,
+ * 0 otherwise
+*/
+int
+breakPointEnable(breakPointPtr breakPtr, int enable)
+{
+ int result = 0;
+
+ if (breakPtr) {
+ int enableFlag = 1;
+ if (enable != XSL_TOGGLE_BREAKPOINT){
+ enableFlag = enable;
+ }else {
+ if (breakPtr->flags & BREAKPOINT_ENABLED)
+ enableFlag = 0;
+ }
+ if (enableFlag)
+ breakPtr->flags |= BREAKPOINT_ENABLED;
+ else
+ breakPtr->flags = breakPtr->flags & (BREAKPOINT_ALLFLAGS ^ BREAKPOINT_ENABLED);
+ result = 1;
+ }
+ return result;
+}
+
+
+/**
+ * breakPointLinesCount:
+ *
+ * Return the number of hash tables of break points with the same line number
+ *
+ * Returns The number of hash tables of break points with the same line number
+ */
+int
+breakPointLinesCount(void)
+{
+ if (!breakList) {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Breakpoints structures not initialized\n");
+#endif
+ return 0;
+ } else
+ return arrayListCount(breakList);
+}
+
+
+/**
+ * breakPointLinesList:
+ *
+ * Returns The list of hash tables for break points
+ * Dangerous function to use!!
+ */
+arrayListPtr
+breakPointLineList(void)
+{
+ return breakList;
+}
+
+
+/**
+ * breakPointGet:
+ * @url: Non-null, non-empty file name that has been loaded by
+ * debugger
+ * @lineNumber: lineNumber >= 0 and is available in @url
+ *
+ * Get a break point for the breakpoint collection
+ *
+ * Returns break point if break point exists at location specified,
+ * NULL otherwise
+*/
+breakPointPtr
+breakPointGet(const xmlChar * url, long lineNumber)
+{
+ xmlHashTablePtr breakHash = breakPointGetLineNoHash(lineNumber);
+ breakPointPtr breakPtr = NULL;
+
+ if (!breakHash || !url)
+ return breakPtr;
+
+ breakPtr = (breakPointPtr)xmlHashLookup(breakHash, url);
+ return breakPtr;
+}
+
+
+/**
+ * breakPointPrint:
+ * @breakPtr: A valid break point
+ *
+ * Print the details of @breakPtr
+ *
+ * Returns 1 if successful,
+ * 0 otherwise
+ */
+int
+breakPointPrint(breakPointPtr breakPtr)
+{
+ int result = 0;
+ const char *breakStatusText[2] = {
+ I18N_NOOP("disabled"),
+ I18N_NOOP("enabled")
+ };
+ const char *breakTemplate="";
+ const char *breakMode = "";
+ const char *breakStatus;
+
+
+ if (!breakPtr)
+ return result;
+
+ if (breakPtr->templateName){
+ if (breakPtr->modeName)
+ breakMode = (const char*)breakPtr->modeName;
+ breakTemplate = (const char*)breakPtr->templateName;
+ }
+
+
+ breakStatus = breakStatusText[breakPtr->flags & BREAKPOINT_ENABLED];
+ if (breakPtr->url)
+ xsldbgGenericErrorFunc(i18n("Breakpoint %1 %2 for template: \"%3\" mode: \"%4\" in file \"%5\" at line %6").arg(breakPtr->id).arg(i18n(breakStatus)).arg(xsldbgText(breakTemplate)).arg(xsldbgText(breakMode)).arg(xsldbgUrl(breakPtr->url)).arg(breakPtr->lineNo));
+ else
+ xsldbgGenericErrorFunc(i18n("Breakpoint %1 %2 for template: \"%3\" mode: \"%4\"").arg(breakPtr->id).arg(i18n(breakStatus)).arg(xsldbgText(breakTemplate)).arg(xsldbgText(breakMode)));
+ return ++result;
+}
+
+
+/**
+ * breakPointIsPresent:
+ * @url: Non-null, non-empty file name that has been loaded by
+ * debugger
+ * @lineNumber: @lineNumber >= 0 and is available in @url
+ *
+ * Determine if there is a break point at file and line number specified
+ *
+ * Returns 1 if successful,
+ * 0 otherwise
+*/
+int
+breakPointIsPresent(const xmlChar * url, long lineNumber)
+{
+ int result = 0;
+
+ if (!url || (lineNumber == -1))
+ return result;
+
+ result = (breakPointGet(url, lineNumber) != NULL);
+
+ return result;
+}
+
+
+/**
+ * breakPointIsPresentNode:
+ * @node: node != NULL
+ *
+ * Determine if a node is a break point
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+breakPointIsPresentNode(xmlNodePtr node)
+{
+ int result = 0;
+
+ if (!node || !node->doc)
+ return result;
+
+ if (xmlGetLineNo(node) == -1)
+ return result;
+
+ if (node->doc->URL) {
+ result = breakPointIsPresent(node->doc->URL, xmlGetLineNo(node));
+ }
+
+ return result;
+}