summaryrefslogtreecommitdiffstats
path: root/kxsldbg/kxsldbgpart/libxsldbg/callstack.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kxsldbg/kxsldbgpart/libxsldbg/callstack.cpp')
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/callstack.cpp509
1 files changed, 509 insertions, 0 deletions
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/callstack.cpp b/kxsldbg/kxsldbgpart/libxsldbg/callstack.cpp
new file mode 100644
index 00000000..585a70d1
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/callstack.cpp
@@ -0,0 +1,509 @@
+
+/***************************************************************************
+ callstack.c - call stack implementation
+ -------------------
+ begin : Fri Nov 2 2001
+ copyright : (C) 2001 by Keith Isdale
+ email : k_isdale@tpg.com.au
+ ***************************************************************************/
+
+#include "xsldbg.h"
+#include "utils.h"
+#include "breakpoint.h"
+#include "arraylist.h"
+#include "callstack.h"
+#include "xsldbgmsg.h"
+
+
+/*------------------------------------------------------
+ Private functions
+ -----------------------------------------------------*/
+
+/**
+ * addCallInfo:
+ * @templateName: Template name to add
+ * @templateURI: QName part of template name to add
+ * @modeName: Mode of template
+ * @modeURI: QName part of node of template
+ * @url: The url for the template
+ *
+ * Add template "call" to call stack
+ *
+ * Returns A reference to the added info if successful,
+ * NULL otherwise
+ */
+callPointInfoPtr
+addCallInfo(const xmlChar * templateName, const xmlChar *templateURI,
+ const xmlChar * modeName, const xmlChar* modeURI, const xmlChar * url);
+
+
+/*------------------------------------------------------
+ Xsl call stack related
+-----------------------------------------------------*/
+
+/* keep track of the top and bottom of call stack*/
+
+/* This is the major structure and contains a stack of call points */
+callPointPtr callStackBot, callStackTop;
+
+/* save memory by keep only one copy of data used for several
+ items on call stack */
+callPointInfoPtr callInfo;
+
+/* What frame depth are we to stop at */
+int stopDepth = -1;
+
+
+/**
+ * callStackInit:
+ *
+ * Returns If callStack has been initialized properly and all
+ * memory required has been obtained,
+ * 0 otherwise
+ *
+ * Returns 1 if callStack has been initialized properly and all
+ * memory required has been obtained,
+ * 0 otherwise
+*/
+int
+callStackInit(void)
+{
+
+ callInfo = (callPointInfoPtr) xmlMalloc(sizeof(callPointInfo));
+ if (callInfo) {
+ callInfo->next = NULL;
+ callInfo->templateName = NULL;
+ callInfo->templateURI = NULL;
+ callInfo->modeName = NULL;
+ callInfo->modeURI = NULL;
+ callInfo->url = NULL;
+ }
+ callStackBot = (callPointPtr) xmlMalloc(sizeof(callPoint));
+ if (callStackBot) {
+ callStackBot->next = NULL;
+ callStackBot->info = NULL;
+ callStackBot->lineNo = -1;
+ callStackTop = callStackBot;
+ }
+ return (callInfo != NULL) && (callStackBot != NULL);
+}
+
+
+
+/**
+ * callStackFree:
+ *
+ *
+ * Free all memory used by callStack
+ */
+void
+callStackFree(void)
+{
+
+ callPointInfoPtr curInfo = callInfo, nextInfo;
+ callPointPtr curCall = callStackBot, nextCall;
+
+ /* remove all call info's */
+ while (curInfo) {
+ nextInfo = curInfo->next;
+ if (curInfo->templateName)
+ xmlFree(curInfo->templateName);
+ if (curInfo->templateURI)
+ xmlFree(curInfo->templateURI);
+ if (curInfo->modeName)
+ xmlFree(curInfo->modeName);
+ if (curInfo->modeURI)
+ xmlFree(curInfo->modeURI);
+ if (curInfo->url)
+ xmlFree(curInfo->url);
+ xmlFree(curInfo);
+ curInfo = nextInfo;
+ }
+ curInfo = NULL;
+
+ /* remove all call stack items left. There should be none !! */
+ while (curCall) {
+ nextCall = curCall->next;
+ xmlFree(curCall);
+ curCall = nextCall;
+ }
+
+ callStackBot = NULL;
+ callStackTop = NULL;
+ callInfo = NULL;
+}
+
+
+/**
+ * addCallInfo:
+ * @templateName: Template name to add
+ * @templateURI: QName part of template name to add
+ * @modeName: Mode of template
+ * @modeURI: QName part of node of template
+ * @url: The url for the template
+ *
+ * Add template "call" to call stack
+ *
+ * Returns A reference to the added info if successful,
+ * NULL otherwise
+ */
+callPointInfoPtr
+addCallInfo(const xmlChar * templateName, const xmlChar *templateURI,
+ const xmlChar * modeName, const xmlChar* modeURI, const xmlChar * url)
+{
+ callPointInfoPtr result = NULL, cur = callInfo;
+ int found;
+
+ if (!templateName || !url) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Null template name or url: addCallInfo\n");
+ if (templateName)
+ xsltGenericError(xsltGenericErrorContext, "template :\"%s\"\n",
+ templateName);
+ if (url)
+ xsltGenericError(xsltGenericErrorContext, "url :\"%s\"\n", url);
+
+#endif
+ return result;
+ }
+
+ while (cur->next) {
+ found = 1;
+ if (templateName && cur->templateName
+ && !xmlStrEqual(cur->templateName, templateName))
+ found = 0;
+ if (found && !xmlStrEqual(cur->templateURI, templateURI))
+ found = 0;
+ if (found && !xmlStrEqual(cur->modeName, modeName))
+ found = 0;
+ if (found && !xmlStrEqual(cur->modeURI, modeURI))
+ found = 0;
+ if (found && !xmlStrEqual(cur->url, url))
+ found = 0;
+
+ if (found){
+ result = cur;
+ break;
+ }
+ cur = cur->next;
+ }
+
+ if (!result && cur) {
+ result = (callPointInfoPtr) xmlMalloc(sizeof(callPointInfo));
+ if (result) {
+ if ((cur == callInfo) && !cur->templateName && !cur->templateURI
+ && !cur->modeName && !cur->modeURI
+ && !cur->url){
+ xmlFree(callInfo);
+ callInfo = result;
+ } else{
+ cur->next = result;
+ }
+ result->templateName =
+ (xmlChar *) xmlMemStrdup((char *) templateName);
+ result->templateURI =
+ (xmlChar *) xmlMemStrdup((char *) templateURI);
+ result->modeName =
+ (xmlChar *) xmlMemStrdup((char *) modeName);
+ result->modeURI =
+ (xmlChar *) xmlMemStrdup((char *) modeURI);
+ result->url = (xmlChar *) xmlMemStrdup((char *) url);
+ result->next = NULL;
+ }else {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to create callPointInfo from : addCallInfo\n");
+#endif
+ }
+ }
+ if (!cur){
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to create callPointInfo from : addCallInfo\n");
+#endif
+ }
+ return result;
+}
+
+
+/**
+ * callStackAdd:
+ * @templ: The current template being applied
+ * @source: The source node being processed
+ *
+ * Add template "call" to call stack
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+callStackAdd(xsltTemplatePtr templ, xmlNodePtr source)
+{
+ int result = 0;
+ const char *name = "Default template";
+ callPointInfoPtr info;
+
+ if (!templ || !source)
+ return result;
+
+ if (!source->doc || !source->doc->URL) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Invalid document url in call from : callStackAdd\n");
+#endif
+ return result;
+ }
+
+ /* are at a "frame" break point ie "step down" */
+ if ((xslDebugStatus == DEBUG_STEPDOWN)
+ && (stopDepth == callStackGetDepth())) {
+ xslDebugStatus = DEBUG_STOP;
+ stopDepth = 0;
+ }
+
+ /* this need not be an error just we've got a text in source */
+ if (xmlGetLineNo(source) == -1) {
+ return result;
+ }
+
+ if (templ) {
+ if (templ->name)
+ name = (char *) templ->name;
+ else {
+ if (templ->match)
+ name = (char *) templ->match;
+ }
+ }
+
+ if (!name) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Invalid template name : callStackAdd\n");
+#endif
+ return result;
+ }
+
+ info = addCallInfo((xmlChar *) name, (xmlChar *) templ->nameURI,
+ (xmlChar *) templ->mode, (xmlChar *) templ->modeURI,
+ source->doc->URL);
+
+ if (info) {
+ callPointPtr cur;
+
+ cur = (callPointPtr) xmlMalloc(sizeof(callPoint));
+ if (cur) {
+ callStackTop->next = cur;
+ callStackTop = cur;
+ cur->info = info;
+ cur->lineNo = xmlGetLineNo(source);
+ cur->next = NULL;
+ result = 1;
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to create call point : callStackAdd\n");
+#endif
+ }
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to create call info : callStackAdd\n");
+#endif
+ }
+
+ return result;
+}
+
+
+/**
+ * callStackDrop:
+ *
+ *
+ * Drop the topmost item off the call stack
+ */
+void
+callStackDrop(void)
+{
+
+ if (!callStackBot) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: callStackDrop failed invalid call stack: dbgcallstack.c");
+#endif
+ return;
+ }
+
+ /* are we at a "frame" break point ie "step up". if we've gone too
+ * far stop imediately */
+ if ((xslDebugStatus == DEBUG_STEPUP)
+ && (-1 * callStackGetDepth()) >= stopDepth) {
+ xslDebugStatus = DEBUG_STOP;
+ stopDepth = 0;
+ }
+
+ if (callStackBot->next) {
+ callPointPtr cur = callStackBot;
+
+ while (cur->next && cur->next->next) {
+ cur = cur->next;
+ }
+ if (cur->next)
+ xmlFree(cur->next);
+ cur->next = NULL;
+ callStackTop = cur;
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: callStackDrop failed no items on call stack : dbgcallstack.c");
+#endif
+ }
+}
+
+
+/**
+ * callStackStepup:
+ * @depth:The frame depth to step up to
+ * 0 < @depth <= callStackGetDepth()
+ *
+ * Set the frame depth to step up to
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+callStackStepup(int depth)
+{
+ int result = 0;
+
+ if ((depth > 0) && (depth <= callStackGetDepth())) {
+ stopDepth = -1 * depth;
+ xslDebugStatus = DEBUG_STEPUP;
+ result = 1;
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: callStackStepup failed invalid depth %d: callstack.c", depth);
+#endif
+ }
+ return result;
+}
+
+
+/**
+ * callStackStepdown:
+ * @depth: The frame depth to step down to,
+ * 0 < @depth <= callStackGetDepth()
+ *
+ * Set the frame depth to step down to
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+callStackStepdown(int depth)
+{
+ int result = 0;
+
+ if ((depth > 0) && (depth >= callStackGetDepth())) {
+ stopDepth = depth;
+ xslDebugStatus = DEBUG_STEPDOWN;
+ result = 1;
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: callStackStepdown failed invalid depth %d: dbgcallstack.c", depth);
+#endif
+ }
+ return result;
+}
+
+
+/**
+ * callStackGet:
+ * @depth: 0 < @depth <= callStackGetDepth()
+ *
+ * Retrieve the call point at specified call depth
+
+ * Returns Non-null if depth is valid,
+ * NULL otherwise
+ */
+callPointPtr
+callStackGet(int depth)
+{
+ callPointPtr result = NULL, cur = callStackBot;
+
+ if (!callStackBot) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: callStackGet failed invalid call stack: callstack.c");
+#endif
+ return result;
+ }
+ if ((depth < 1) && (depth > callStackGetDepth())) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: callStackGet failed invalid call depth: callstack.c");
+#endif
+ return result;
+ }
+
+ while (depth > 0 && cur->next) {
+ cur = cur->next;
+ depth--;
+ }
+
+ if (depth == 0)
+ result = cur;
+ else {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: callStackGet failed invalid call depth: callstack.c");
+#endif
+ }
+ return result;
+}
+
+
+/**
+ * callStackGetTop:
+ *
+ * Get the top item in the call stack
+ *
+ * Returns The top of the call stack
+ */
+callPointPtr
+callStackGetTop(void)
+{
+ return callStackTop;
+}
+
+
+/**
+ * callStackGetDepth:
+ *
+ * Return the depth of call stack
+ *
+ * Returns The depth of call stack
+ */
+int
+callStackGetDepth(void)
+{
+ callPointPtr cur = callStackBot;
+ int depthCount = 0;
+
+ if (!callStackBot) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: calldepth failed invalid call stack: dbgcallstack.c");
+#endif
+ return depthCount;
+ }
+
+
+ while (cur->next) {
+ depthCount++;
+ cur = cur->next;
+ }
+ return depthCount;
+}