summaryrefslogtreecommitdiffstats
path: root/kxsldbg/kxsldbgpart/libxsldbg
diff options
context:
space:
mode:
Diffstat (limited to 'kxsldbg/kxsldbgpart/libxsldbg')
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/Makefile.am12
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/allmoc.cpp2
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/arraylist.cpp240
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/arraylist.h291
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/breakpoint.cpp696
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/breakpoint.h633
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/breakpoint_cmds.cpp1036
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/callstack.cpp509
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/callstack.h275
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/cmds.h197
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/debug.cpp235
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/debug.h101
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/debugXSL.cpp2118
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/debugXSL.h1078
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/file_cmds.cpp274
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/files.cpp1420
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/files.h981
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/files_unix.cpp225
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/help.h73
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/help_unix.cpp115
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/nodeview_cmds.cpp609
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/option_cmds.cpp299
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/options.cpp902
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/options.h476
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/options_unix.cpp118
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/os_cmds.cpp100
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/param_cmds.cpp175
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/qtnotifier2.h38
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/search.cpp1584
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/search.h1087
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/search_cmds.cpp88
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/template_cmds.cpp331
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/trace_cmds.cpp77
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/utils.cpp187
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/utils.h217
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/variable_cmds.cpp114
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/xsldbg.cpp1367
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/xsldbg.h188
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/xsldbgconfig.h0
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/xsldbgevent.h302
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/xsldbgio.h41
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/xsldbgmsg.cpp119
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/xsldbgmsg.h210
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/xsldbgnotifier.h48
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/xsldbgthread.cpp184
-rw-r--r--kxsldbg/kxsldbgpart/libxsldbg/xsldbgthread.h90
46 files changed, 19462 insertions, 0 deletions
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/Makefile.am b/kxsldbg/kxsldbgpart/libxsldbg/Makefile.am
new file mode 100644
index 00000000..aaea2e53
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/Makefile.am
@@ -0,0 +1,12 @@
+noinst_LTLIBRARIES = libxsldbg.la
+
+libxsldbg_la_METASOURCES = AUTO
+
+libxsldbg_la_SOURCES = allmoc.cpp xsldbgthread.cpp xsldbg.cpp xsldbgmsg.cpp variable_cmds.cpp utils.cpp trace_cmds.cpp template_cmds.cpp search_cmds.cpp search.cpp param_cmds.cpp os_cmds.cpp options_unix.cpp options.cpp option_cmds.cpp nodeview_cmds.cpp help_unix.cpp files_unix.cpp files.cpp file_cmds.cpp debugXSL.cpp debug.cpp callstack.cpp breakpoint_cmds.cpp breakpoint.cpp arraylist.cpp
+
+libxsldbg_la_LIBADD = $(LIBXSLT_LIBS)
+libxsldbg_la_LDFLAGS = $(all_libraries)
+
+AM_CPPFLAGS = -DDOCS_PATH=\"$(DOCS_PATH)\" -I.. $(LIBXSLT_CFLAGS) $(all_includes)
+
+KDE_OPTIONS= nofinal
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/allmoc.cpp b/kxsldbg/kxsldbgpart/libxsldbg/allmoc.cpp
new file mode 100644
index 00000000..41decae4
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/allmoc.cpp
@@ -0,0 +1,2 @@
+#include "../xsldbgdebugger.h"
+#include "qtnotifier2.h"
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/arraylist.cpp b/kxsldbg/kxsldbgpart/libxsldbg/arraylist.cpp
new file mode 100644
index 00000000..a9de14fe
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/arraylist.cpp
@@ -0,0 +1,240 @@
+
+/***************************************************************************
+ arraylist.c - define array implementation of a list
+ -------------------
+ begin : Sat Nov 10 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 "arraylist.h"
+#include <libxslt/xsltutils.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/**
+ * arrayListNew:
+ * @initialSize: The initial size of list
+ * @deleteFunction: The function to call to free items in the list
+ *
+ * Create a new list with a size of @initialSize
+ *
+ * Returns Non-null on success,
+ * NULL otherwise
+ */
+arrayListPtr
+arrayListNew(int initialSize, freeItemFunc deleteFunction)
+{
+ arrayListPtr list = NULL;
+
+ if (initialSize <= 0) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "arrayListNew invalid initialSize %d\n",
+ initialSize);
+#endif
+ } else
+ list = (arrayListPtr) xmlMalloc(sizeof(arrayList));
+
+ if (list) {
+ list->data = (void **) xmlMalloc(sizeof(void *) * initialSize);
+ list->deleteFunction = deleteFunction;
+ list->count = 0;
+ list->size = initialSize;
+ }
+
+ return list;
+}
+
+
+/**
+ * arrayListFree:
+ * @list: A valid list
+ *
+ * Free memory assocated with array list, if the array list
+ * has a valid deleteFunction then content with be freed with
+ * using that deleteFunction
+ */
+void
+arrayListFree(arrayListPtr list)
+{
+ if (!list)
+ return;
+
+ arrayListEmpty(list);
+ xmlFree(list->data);
+ xmlFree(list);
+}
+
+
+/**
+ * arrayListEmpty:
+ * @list: A valid list
+ *
+ * Empties the list of its content
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+arrayListEmpty(arrayListPtr list)
+{
+ int index, result = 0;
+
+ if (list) {
+ if (list->deleteFunction) {
+ for (index = 0; index < list->count; index++) {
+ if (list->data[index])
+ (*list->deleteFunction) (list->data[index]);
+ }
+ result = 1;
+ list->count = 0;
+ }
+ }
+ return result;
+}
+
+
+/**
+ * arrayListSize:
+ * @list: A valid list
+ *
+ * Return The maximum number elements this list can contain
+ *
+ * Returns The maximum number elements this list can contain
+ */
+int
+arrayListSize(arrayListPtr list)
+{
+ int result = 0;
+
+ if (list)
+ result = list->size;
+
+ return result;
+}
+
+
+/**
+ * arrayListCount:
+ * @list: A valid list
+ *
+ * Return the count of number items in list
+ *
+ * Returns The count of number items in list
+ */
+int
+arrayListCount(arrayListPtr list)
+{
+ int result = 0;
+
+ if (list)
+ result = list->count;
+
+ return result;
+}
+
+
+/**
+ * arrayListAdd:
+ * @list: A valid list
+ * @item: A valid list
+ *
+ * Add @item to @list
+ *
+ * Returns 1 if able to add @item to end of @list,
+ * 0 otherwise
+ */
+int
+arrayListAdd(arrayListPtr list, void *item)
+{
+ int result = 0;
+
+ if (list && item) {
+ if (list->count + 1 > list->size) {
+ /* grow the size of data */
+ void **temp;
+ int newSize, index;
+
+ if (list->size < DOUBLE_SIZE_MAX_ITEM)
+ newSize = list->size * 2;
+ else
+ newSize = (int) (list->size * 1.5);
+ temp = (void **) xmlMalloc(sizeof(void *) * newSize);
+ for (index = 0; index < list->count; index++) {
+ temp[index] = list->data[index];
+ }
+ xmlFree(list->data);
+ list->data = temp;
+ list->size = newSize;
+ }
+ list->data[list->count++] = item;
+ result = 1;
+ }
+ return result;
+}
+
+
+/**
+ * arrayListDelete:
+ * @list: A valid list
+ * @position: 0 =< @position < arrayListCount(@list)
+ *
+ * Delete item at position @position from @list
+ *
+ * Returns 1 if able to delete element in @list at position @position,
+ * 0 otherwise
+ */
+int
+arrayListDelete(arrayListPtr list, int position)
+{
+ int result = 0, index;
+
+ if (list && (list->count > 0) && (position >= 0) &&
+ (position < list->count) && list->data[position]) {
+ if (list->deleteFunction)
+ (*list->deleteFunction) (list->data[position]);
+
+ /* shuffle all elements upwards */
+ for (index = position; index < (list->count - 1); index++) {
+ list->data[index] = list->data[index + 1];
+ }
+ list->count--;
+ result = 1;
+ }
+ return result;
+}
+
+
+
+/**
+ * arrayListGet:
+ * @list: A valid list
+ * @position: 0 =< @position < arrayListCount(@list)
+ *
+ * Get item at position @position from @list
+ *
+ * Returns Non-null if able to retrieve element in @list at position @position,
+ * NULL otherwise
+ */
+void *
+arrayListGet(arrayListPtr list, int position)
+{
+ void *result = NULL;
+
+ if (list && (position >= 0) && (position < list->count)) {
+ result = list->data[position];
+ }
+ return result;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/arraylist.h b/kxsldbg/kxsldbgpart/libxsldbg/arraylist.h
new file mode 100644
index 00000000..81398459
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/arraylist.h
@@ -0,0 +1,291 @@
+
+/**************************************************************************
+ arraylist.h - declare the functions for
+ implementation of the array list
+ -------------------
+ begin : Sat Nov 10 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. *
+ * *
+ **************************************************************************/
+
+#ifndef ARRAYLIST_H
+#define ARRAYLIST_H
+
+#ifdef USE_KDE_DOCS
+
+/**
+ * Provide a fast easy to use array list. Support the basic functions of add
+ * delete, empty, count, free
+ *
+ * @short Array list support
+ *
+ * @author Keith Isdale <k_isdale@tpg.com.au>
+ */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef USE_GNOME_DOCS
+
+#else
+#ifdef USE_KDE_DOCS
+
+#endif
+#endif
+
+
+ typedef void (*freeItemFunc) (void *item);
+ /* A dynamic structure behave like a list */
+ typedef struct _arrayList arrayList;
+ typedef arrayList *arrayListPtr;
+ struct _arrayList {
+ int size, count;
+ void **data;
+ freeItemFunc deleteFunction;
+ };
+
+/* what size of the list do we stop automatic doubling of capacity
+ if array list size growth is needed */
+#define DOUBLE_SIZE_MAX_ITEM 10
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * arrayListNew:
+ * @initialSize: The initial size of list
+ * @deleteFunction: The function to call to free items in the list
+ *
+ * Create a new list with a size of @initialSize
+ *
+ * Returns Non-null on success,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Create a new list with a size of @p initialSize
+ *
+ * @returns Non-null on success,
+ * NULL otherwise
+ *
+ * @param initial The initial size of list
+ * @param deleteFunction the Function to call to free items in the list
+ */
+#endif
+#endif
+ arrayListPtr arrayListNew(int initialSize,
+ freeItemFunc deleteFunction);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * arrayListFree:
+ * @list: A valid list
+ *
+ * Free memory assocated with array list, if the array list
+ * has a valid deleteFunction then content with be freed with
+ * using that deleteFunction
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Free memory assocated with array list, if the array list
+ * has a valid deleteFunction then content with be freed with
+ * using that deleteFunction
+ *
+ * @param list A valid list
+ */
+#endif
+#endif
+ void arrayListFree(arrayListPtr list);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * arrayListEmpty:
+ * @list: A valid list
+ *
+ * Empties the list of its content
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Empties the list of its content
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param list A valid list
+ */
+#endif
+#endif
+ int arrayListEmpty(arrayListPtr list);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * arrayListSize:
+ * @list: A valid list
+ *
+ * Return The maximum number elements this list can contain
+ *
+ * Returns The maximum number elements this list can contain
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Return the maximum number elements this list can contain
+ *
+ * @returns The maximum number elements this list can contain
+ *
+ * @param list A valid list
+ */
+#endif
+#endif
+ int arrayListSize(arrayListPtr list);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * arrayListCount:
+ * @list: A valid list
+ *
+ * Return the count of number items in list
+ *
+ * Returns The count of number items in list
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Return the count of number items in list
+ * @returns The count of number items in list
+ *
+ * @param list A valid list
+ */
+#endif
+#endif
+
+ int arrayListCount(arrayListPtr list);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * arrayListAdd:
+ * @list: A valid list
+ * @item:A valid item
+ *
+ * Add @item to @list
+ *
+ * Returns 1 if able to add @item to end of @list,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Add @p item to @p list
+ *
+ * @returns 1 if able to add @p item to end of @p list,
+ * 0 otherwise
+ *
+ * @param list A valid list
+ * @param item A valid item
+ */
+#endif
+#endif
+ int arrayListAdd(arrayListPtr list, void *item);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * arrayListDelete:
+ * @list: A valid list
+ * @position: 0 =< @position < arrayListCount(@list)
+ *
+ * Delete item at position @position from @list
+ *
+ * Returns 1 if able to delete element in @list at position @position,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * @returns 1 if able to delete element in @p list at position @p position,
+ * 0 otherwise
+ *
+ * @param list A valid list
+ * @param position 0 =< @p position < arrayListCount(@p list)
+ */
+#endif
+#endif
+ int arrayListDelete(arrayListPtr list, int position);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * arrayListGet:
+ * @list: A valid list
+ * @position: 0 =< @position < arrayListCount(@list)
+ *
+ * Get item at position @position from @list
+ *
+ * Returns Non-null if able to retrieve element in @list at position
+ * @position,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * @returns Non-null if able to retrieve element in @p list at position
+ * @p position,
+ * NULL otherwise
+ *
+ * @param list A valid list
+ * @param position 0 =< @p position < arrayListCount(@p list)
+ */
+#endif
+#endif
+ void *arrayListGet(arrayListPtr list, int position);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
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;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/breakpoint.h b/kxsldbg/kxsldbgpart/libxsldbg/breakpoint.h
new file mode 100644
index 00000000..83f2e712
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/breakpoint.h
@@ -0,0 +1,633 @@
+
+/**************************************************************************
+ breakpoint.h - public functions for the
+ breakpoint API
+ -------------------
+ begin : Fri Dec 7 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. *
+ * *
+ **************************************************************************/
+
+
+#ifndef XSLBREAKPOINT_H
+#define XSLBREAKPOINT_H
+
+#ifdef USE_KDE_DOCS
+
+/**
+ * Provide a basic break point support
+ *
+ * @short break point support
+ *
+ * @author Keith Isdale <k_isdale@tpg.com.au>
+ */
+#endif
+
+#ifndef BUILD_DOCS
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/xsltutils.h>
+
+#include "arraylist.h"
+#endif /* BUILD_DOCS */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* indicate that we are to toggle a breakpoint , used for enableBreakPoint */
+#define XSL_TOGGLE_BREAKPOINT -1
+
+ /* Define the types of status whilst debugging */
+#ifndef USE_KDOC
+ typedef enum {
+ DEBUG_NONE = 0, /* must start at zero!! */
+ DEBUG_INIT,
+ DEBUG_STEP,
+ DEBUG_STEPUP,
+ DEBUG_STEPDOWN,
+ DEBUG_NEXT,
+ DEBUG_STOP,
+ DEBUG_CONT,
+ DEBUG_RUN,
+ DEBUG_RUN_RESTART,
+ DEBUG_QUIT,
+ DEBUG_TRACE,
+ DEBUG_WALK
+ } DebugStatusEnum;
+
+
+ typedef enum {
+ DEBUG_BREAK_SOURCE = 300,
+ DEBUG_BREAK_DATA
+ } BreakPointTypeEnum;
+
+
+/*Indicate what type of variable to print out.
+ Is used by print_variable and searching functions */
+ typedef enum {
+ DEBUG_GLOBAL_VAR = 200, /* pick a unique starting point */
+ DEBUG_LOCAL_VAR,
+ DEBUG_ANY_VAR
+ } VariableTypeEnum;
+
+/*What type of flags can breakpoints have */
+ typedef enum {
+ BREAKPOINT_ENABLED = 1,
+ BREAKPOINT_ORPHANED = 2,
+ BREAKPOINT_ALLFLAGS = 255
+ } BreakPointFlags;
+
+/*What state of breakpoint validation can we be in */
+ typedef enum {
+ BREAKPOINTS_ARE_VALID,
+ BREAKPOINTS_NEED_VALIDATION,
+ BREAKPOINTS_BEING_VALIDATED
+ } BreakPointValidationStates;
+#else
+ /* keep kdoc happy */
+ enum DebugStatusEnum {
+ DEBUG_NONE = 0, /* must start at zero!! */
+ DEBUG_INIT,
+ DEBUG_STEP,
+ DEBUG_STEPUP,
+ DEBUG_STEPDOWN,
+ DEBUG_NEXT,
+ DEBUG_STOP,
+ DEBUG_CONT,
+ DEBUG_RUN,
+ DEBUG_RUN_RESTART,
+ DEBUG_QUIT,
+ DEBUG_TRACE,
+ DEBUG_WALK
+ };
+
+
+ enum BreakPointTypeEnum {
+ DEBUG_BREAK_SOURCE = 300,
+ DEBUG_BREAK_DATA
+ };
+
+
+/*Indicate what type of variable to print out.
+ Is used by print_variable and searching functions */
+ enum VariableTypeEnum {
+ DEBUG_GLOBAL_VAR = 200, /* pick a unique starting point */
+ DEBUG_LOCAL_VAR,
+ DEBUG_ANY_VAR
+ } VariableTypeEnum;
+
+/*What type of flags can breakpoints have */
+ enum BreakPointFlags {
+ BREAKPOINT_ENABLED = 1,
+ BREAKPOINT_ORPHANED = 2,
+ BREAKPOINT_ALLFLAGS = 255
+ } BreakPointFlags;
+
+/*What state of breakpoint validation can we be in */
+ enum BreakPointValidationStates {
+ BREAKPOINTS_ARE_VALID,
+ BREAKPOINTS_NEED_VALIDATION,
+ BREAKPOINTS_BEING_VALIDATED
+ } BreakPointValidationStates;
+#endif
+
+ /* The main structure for holding breakpoints */
+ typedef struct _breakPoint breakPoint;
+ typedef breakPoint *breakPointPtr;
+ struct _breakPoint {
+ xmlChar *url;
+ long lineNo;
+ xmlChar *templateName, *modeName;
+ int flags;
+ BreakPointTypeEnum type;
+ int id;
+ };
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * breakPointInit:
+ *
+ * Intialized the breakpoint module
+ *
+ * Returns 1 if breakpoint module haas been initialized properly and all
+ * memory required has been obtained,
+ * 0 otherwise
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Intialized the breakpoint module
+ *
+ * @returns 1 if breakpoint module has been initialized properly and all
+ * memory required has been obtained,
+ * 0 otherwise
+*/
+#endif
+#endif
+ int breakPointInit(void);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * breakPointFree:
+ *
+ * Free all memory used by breakpoint module
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Free all memory used by breakpoint module
+ */
+#endif
+#endif
+ void breakPointFree(void);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * breakPointActiveBreakPoint:
+ *
+ * Get the active break point
+ *
+ * Returns the last break point that we stoped at
+ *
+ * Depreciated
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Get the active break point
+ *
+ * @returns The last break point that we stoped at
+ *
+ * Depreciated
+ */
+#endif
+#endif
+ breakPointPtr breakPointActiveBreakPoint(void);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * breakPointSetActiveBreakPoint:
+ * @breakPtr: Is valid break point or NULL
+ *
+ * Set the active break point
+ *
+ * Depreciated
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Set the active break point
+ *
+ * @param breakPoint Is valid break point or NULL
+ *
+ * Depreciated
+ */
+#endif
+#endif
+ void breakPointSetActiveBreakPoint(breakPointPtr breakPtr);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * 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
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Add break point at file and line number specified
+ *
+ * @returns 1 if successful,
+ * 0 otherwise
+ *
+ * @param url Non-null, non-empty file name that has been loaded by
+ * debugger
+ * @param lineNumber @p lineNumber >= 0 and is available in url specified and
+ * points to an xml element
+ * @param temlateName The template name of break point or NULL
+ * @param modeName : The mode of breakpoint or NULL
+ * @param type Valid BreakPointTypeEnum
+*/
+#endif
+#endif
+ int breakPointAdd(const xmlChar * url, long lineNumber,
+ const xmlChar * templateName,
+ const xmlChar * modeName,
+ BreakPointTypeEnum type);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * 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
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Delete the break point specified if it can be found using
+ * @p breakPtr's url and lineNo
+ *
+ * @returns 1 if successful,
+ * 0 otherwise
+ *
+ * @param breakPoint Is valid
+ *
+*/
+#endif
+#endif
+ int breakPointDelete(breakPointPtr breakPtr);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * breakPointEmpty:
+ *
+ * Empty the break point collection
+ *
+ * Returns 1 if able to empty the breakpoint list of its contents,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Empty the break point collection
+ *
+ * @returns 1 if able to empty the break point list of its contents,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int breakPointEmpty(void);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * 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
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Enable or disable a break point
+ *
+ * @returns 1 if successful,
+ * 0 otherwise
+ *
+ * @param breakPoint A valid breakpoint
+ * @param enable Enable break point if 1, disable if 0, toggle if -1
+*/
+#endif
+#endif
+ int breakPointEnable(breakPointPtr breakPtr, int enable);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * 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
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Get a break point for the breakpoint collection
+ *
+ * @returns break point if break point exists at location specified,
+ * NULL otherwise
+ *
+ * @param url Non-null, non-empty file name that has been loaded by
+ * debugger
+ * @param lineNumber @p lineNumber >= 0 and is available in url specified
+*/
+#endif
+#endif
+ breakPointPtr breakPointGet(const xmlChar * url, long lineNumber);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * 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
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Return A hash of breakpoints with same line number
+ *
+ * @param lineNo : Line number of of breakpoints of interest
+ *
+ * @returns A hash of breakpoints with a line number of @p lineNo
+ */
+#endif
+#endif
+ xmlHashTablePtr breakPointGetLineNoHash(long lineNo);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * breakPointItemNew:
+ *
+ * Create a new break point item
+ * Returns A valid break point with default values set if successful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Create a new break point item
+ *
+ * @returns A valid break point with default values set if successful,
+ * NULL otherwise
+ */
+#endif
+#endif
+ breakPointPtr breakPointItemNew(void);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * breakPointItemFree:
+ * @payload: valid breakPointPtr
+ * @name: not used
+ *
+ * Free memory associated with this break point
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Free memory associated with this break point
+ *
+ * @param payload Valid breakPointPtr
+ * @param name not used
+ *
+ */
+#endif
+#endif
+ void breakPointItemFree(void *payload, xmlChar * name);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * 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
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * 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
+ */
+#endif
+#endif
+ int breakPointLinesCount(void);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * breakPointPrint:
+ * @breakPtr: A valid break point
+ *
+ * Print the details of @breakPtr to @file
+ *
+ * Returns 1 if successful,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Print the details of @p breakPtr to @p file
+ *
+ * @returns 1 if successful,
+ * 0 otherwise
+ *
+ * @param breakPoint A valid break point
+ */
+#endif
+#endif
+ int breakPointPrint(breakPointPtr breakPtr);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * 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
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Determine if there is a break point at file and line number specified
+ *
+ * @returns 1 if successful,
+ * 0 otherwise
+ *
+ * @param url Non-null, non-empty file name that has been loaded by
+ * debugger
+ * @lineNumber @p lineNumber >= 0 and is available in url specified
+*/
+#endif
+#endif
+ int breakPointIsPresent(const xmlChar * url, long lineNumber);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * breakPointIsPresentNode:
+ * @node: node != NULL
+ *
+ * Determine if a node is a break point
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Determine if a node is a break point
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param node Is valid
+ */
+#endif
+#endif
+ int breakPointIsPresentNode(xmlNodePtr node);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * breakPointLinesList:
+ *
+ * Return The list of hash tables for break points
+ * Dangerous function to use!!
+ *
+ * Returns The list of hash tables for break points
+ * Dangerous function to use!!
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Return The list of hash tables for break points
+ * Dangerous function to use!!
+ *
+ * Returns The list of hash tables for break points
+ * Dangerous function to use!!
+ */
+#endif
+#endif
+ arrayListPtr breakPointLineList(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/breakpoint_cmds.cpp b/kxsldbg/kxsldbgpart/libxsldbg/breakpoint_cmds.cpp
new file mode 100644
index 00000000..7935ea8c
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/breakpoint_cmds.cpp
@@ -0,0 +1,1036 @@
+
+/***************************************************************************
+ 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(QString("Error: %1.\n").arg(i18n(errorPrompt)));
+ return result;
+ }
+
+ if (!arg) {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: NULL argument provided\n");
+#endif
+ xsldbgGenericErrorFunc(QString("Error: %1\n").arg(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").arg((char*)arg));
+ noOfFrames = -1;
+ }
+ } else {
+ noOfFrames = 0;
+ }
+
+ if (noOfFrames >0){
+ if (stepup) {
+ result = callStackStepup(callStackGetDepth() - noOfFrames);
+ } else {
+ result = callStackStepdown(callStackGetDepth() + noOfFrames);
+ }
+ }
+
+ if (!result)
+ xsldbgGenericErrorFunc(QString("Error: %1\n").arg(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").arg(xsldbgUrl(*url)).arg(*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").arg(xsldbgUrl(*url)));
+ if (lineNo){
+ xsldbgGenericErrorFunc(i18n("Warning: Breakpoint for file \"%1\" at line %2 does not seem to be valid.\n").arg(xsldbgUrl(*url)).arg(*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").arg(xsldbgUrl(*url)).arg(*lineNo));
+ } else{
+ xsldbgGenericErrorFunc(i18n("Error: Unable to find a data file whose name contains %1.\n").arg(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(QString("Error: %1\n").arg(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").arg((char*)opts[1]));
+ xsldbgGenericErrorFunc(QString("Error: %1\n").arg(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").arg("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").arg("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 = fullQName(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 =
+ fullQName(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").arg(searchPtr->id));
+ validatedBreakPoints++;
+ }
+ }
+ }
+ }else{
+ if (xsldbgValidateBreakpoints != BREAKPOINTS_BEING_VALIDATED){
+ xsldbgGenericErrorFunc(i18n("Warning: Breakpoint exits for file \"%1\" at line %2.\n").arg(xsldbgUrl(tempUrl)).arg(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) + QString("\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").arg(xsldbgUrl(url)).arg(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(QString("Error: %1\n").arg(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").arg((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").arg(xsldbgUrl(url)).arg(lineNo));
+ }else{
+ result = 1;
+ }
+ xmlFree(url);
+ }
+ }
+ } else{
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for command %1.\n").arg("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").arg(breakPointId));
+ }
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Breakpoint %1 does not exist.\n").arg(breakPointId));
+ }
+ } else {
+ breakPtr = findBreakPointByName(arg);
+ if (breakPtr) {
+ result = breakPointDelete(breakPtr);
+ if (!result) {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to delete breakpoint at template %1.\n").arg(xsldbgText(arg)));
+ }
+ } else{
+ xsldbgGenericErrorFunc(i18n("Error: Breakpoint at template \"%1\" does not exist.\n").arg(xsldbgText(arg)));
+ }
+ }
+ if (!result)
+ xsldbgGenericErrorFunc(QString("Error: %1\n").arg(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(QString("Error: %1\n").arg(i18n(errorPrompt)));
+ return result;
+ }
+
+ if (!arg) {
+#ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: NULL argument provided\n");
+#endif
+ xsldbgGenericErrorFunc(QString("Error: %1\n").arg(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").arg((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").arg(xsldbgUrl(url)).arg(lineNo));
+ }
+ xmlFree(url);
+ }
+ }
+ } else
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for command %1.\n").arg("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").arg(breakPointId));
+ }
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Breakpoint %1 does not exist.\n").arg(breakPointId));
+ }
+ } else {
+ breakPtr = findBreakPointByName(arg);
+ if (breakPtr) {
+ result = breakPointEnable(breakPtr, enableType);
+ } else
+ xsldbgGenericErrorFunc(i18n("Error: Breakpoint at template \"%1\" does not exist.\n").arg(xsldbgText(arg)));
+ }
+
+ if (!result)
+ xsldbgGenericErrorFunc(QString("Error: %1\n").arg(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(QString("Warning: Breakpoint %1 is orphaned. Result: %2. Old flags: %3. New flags: %4.\n").arg(breakPtr->id).arg(result).arg(copy->flags).arg(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").arg(breakPtr->id));
+ }
+ }
+ if (!result){
+ xsldbgGenericErrorFunc(i18n("Warning: Validation of breakpoint %1 failed.\n").arg(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").arg(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);
+ }
+}
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;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/callstack.h b/kxsldbg/kxsldbgpart/libxsldbg/callstack.h
new file mode 100644
index 00000000..fd87b9bd
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/callstack.h
@@ -0,0 +1,275 @@
+
+/* *************************************************************************
+ xslcallpoint.h - public functions for the
+ the call stack
+ -------------------
+ begin : Fri Dec 7 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. *
+ * *
+ ************************************************************************* */
+
+#ifndef XSLCALLSTACK_H
+#define XSLCALLSTACK_H
+
+/**
+ * Provide a call stack support
+ *
+ * @short call stack support
+ *
+ * @author Keith Isdale <k_isdale@tpg.com.au>
+ */
+
+#ifndef BUILD_DOCS
+#include "breakpoint.h"
+#endif
+
+#ifdef WITH_XSLT_DEBUG
+#ifndef WITH_XSLT_DEBUG_BREAKPOINTS
+#define WITH_XSLT_DEBUG_BREAKPOINTS
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+ typedef struct _callPointInfo callPointInfo;
+ typedef callPointInfo *callPointInfoPtr;
+ struct _callPointInfo {
+ xmlChar *templateName, *templateURI;
+ xmlChar *modeName, *modeURI;
+ xmlChar *url;
+ callPointInfoPtr next;
+ };
+
+ typedef struct _callPoint callPoint;
+ typedef callPoint *callPointPtr;
+ struct _callPoint {
+ callPointInfoPtr info;
+ long lineNo;
+ callPointPtr next;
+ };
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * 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
+*/
+#endif
+ int
+ callStackInit(void);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * callStackFree:
+ *
+ *
+ * Free all memory used by callStack
+ */
+#endif
+ void
+ callStackFree(void);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * 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
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Add template "call" to call stack
+ *
+ * @param templ The current template being applied
+ * @param source The source node being processed
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int callStackAdd(xsltTemplatePtr templ, xmlNodePtr source);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * callStackDrop:
+ *
+ *
+ * Drop the topmost item off the call stack
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Drop the topmost item off the call stack
+ */
+#endif
+#endif
+ void callStackDrop(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * callStackStepup:
+ * @depth:The frame depth to step up to
+ * 0 < @depth <= callDepth()
+ *
+ * Set the frame depth to step up to
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Set the frame depth to step up to
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param depth The frame depth to step up to
+ * 0 < @p depth <= callDepth()
+ */
+#endif
+#endif
+ int callStackStepup(int depth);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * callStackStepdown:
+ * @depth: The frame depth to step down to,
+ * 0 < @depth <= callDepth()
+ *
+ * Set the frame depth to step down to
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Set the frame depth to step down to
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param depth The frame depth to step down to
+ * 0 < @p depth <= callDepth()
+ */
+#endif
+#endif
+ int callStackStepdown(int depth);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * callStackGet:
+ * @depth: 0 < @depth <= callDepth()
+ *
+ * Retrieve the call point at specified call depth
+
+ * Returns Non-null a if depth is valid,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Retrieve the call point at specified call depth
+
+ * @returns Non-null a if depth is valid,
+ * NULL otherwise
+ *
+ * @param depth 0 < @p depth <= callDepth()
+ */
+#endif
+#endif
+ callPointPtr callStackGet(int depth);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * callStackGetTop:
+ *
+ * Get the top item in the call stack
+ *
+ * Returns The top of the call stack
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Get the top item in the call stack
+ *
+ * @returns The top of the call stack
+ */
+#endif
+#endif
+ callPointPtr callStackGetTop(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * callStackGetDepth:
+ *
+ * Return the depth of call stack
+ *
+ * Returns The depth of call stack
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * @returns the depth of call stack
+ */
+#endif
+#endif
+ int callStackGetDepth(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/cmds.h b/kxsldbg/kxsldbgpart/libxsldbg/cmds.h
new file mode 100644
index 00000000..f12648c7
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/cmds.h
@@ -0,0 +1,197 @@
+
+/***************************************************************************
+ cmds.h - A list of valid commands ID's for xsldbg
+ -------------------
+ begin : Thu Dec 27 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. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef CMDS_H
+#define CMDS_H
+
+/* See the top of debugXSL.c for a list of command names and thier shortcuts */
+#ifndef USE_KDE_DOCS
+typedef enum { /* id's for commands of xslDbgShell */
+ DEBUG_HELP_CMD = 100,
+ DEBUG_BYE_CMD,
+ DEBUG_EXIT_CMD,
+ DEBUG_QUIT_CMD,
+
+ DEBUG_STEP_CMD,
+ DEBUG_STEPUP_CMD,
+ DEBUG_STEPDOWN_CMD,
+ DEBUG_NEXT_CMD,
+ DEBUG_CONT_CMD,
+ DEBUG_RUN_CMD,
+
+ DEBUG_TEMPLATES_CMD,
+ DEBUG_WHERE_CMD,
+ DEBUG_FRAME_CMD,
+ DEBUG_STYLESHEETS_CMD,
+
+ DEBUG_BREAK_CMD,
+ DEBUG_SHOWBREAK_CMD,
+ DEBUG_DELETE_CMD,
+ DEBUG_ENABLE_CMD,
+ DEBUG_DISABLE_CMD,
+
+ DEBUG_LS_CMD,
+ DEBUG_DIR_CMD,
+ DEBUG_DU_CMD,
+ DEBUG_CAT_CMD,
+ DEBUG_PRINT_CMD, /* cat alternative */
+ DEBUG_PWD_CMD,
+ DEBUG_DUMP_CMD,
+ DEBUG_BASE_CMD,
+
+ DEBUG_GLOBALS_CMD,
+ DEBUG_LOCALS_CMD,
+ /* DEBUG_CAT_CMD, already listed */
+ DEBUG_SOURCE_CMD,
+ DEBUG_DATA_CMD,
+ DEBUG_OUTPUT_CMD,
+ DEBUG_CD_CMD,
+
+ /* file related */
+ /* DEBUG_OUTPUT_CMD, already listed */
+ DEBUG_ENTITIES_CMD,
+ DEBUG_SYSTEM_CMD,
+ DEBUG_PUBLIC_CMD,
+ DEBUG_ENCODING_CMD,
+ DEBUG_VALIDATE_CMD,
+ DEBUG_LOAD_CMD,
+ DEBUG_SAVE_CMD,
+ DEBUG_WRITE_CMD,
+ DEBUG_FREE_CMD,
+
+ /* Operating system related */
+ DEBUG_CHDIR_CMD,
+ DEBUG_SHELL_EXEC_CMD,
+ DEBUG_TTY_CMD,
+
+ /* libxslt parameter and options related */
+ DEBUG_ADDPARAM_CMD,
+ DEBUG_DELPARAM_CMD,
+ DEBUG_SHOWPARAM_CMD,
+ DEBUG_SETOPTION_CMD,
+ DEBUG_OPTIONS_CMD, /* print options */
+
+ /* extra options/commands */
+ DEBUG_TRACE_CMD,
+ DEBUG_WALK_CMD,
+ DEBUG_ADDWATCH_CMD,
+ DEBUG_DELWATCH_CMD,
+ DEBUG_SHOWWATCH_CMD,
+
+ /* searching */
+ DEBUG_SEARCH_CMD,
+
+ /* variable change */
+ DEBUG_SET_CMD,
+
+ /* language change */
+ DEBUG_LANG_CMD
+
+ /* NULL */
+
+} CommandsEnum;
+#else
+
+/* Keep kdoc happy*/
+enum CommandsEnum { /* id's for commands of xslDbgShell */
+ DEBUG_HELP_CMD = 100,
+ DEBUG_BYE_CMD,
+ DEBUG_EXIT_CMD,
+ DEBUG_QUIT_CMD,
+
+ DEBUG_STEP_CMD,
+ DEBUG_STEPUP_CMD,
+ DEBUG_STEPDOWN_CMD,
+ DEBUG_NEXT_CMD,
+ DEBUG_CONT_CMD,
+ DEBUG_RUN_CMD,
+
+ DEBUG_TEMPLATES_CMD,
+ DEBUG_WHERE_CMD,
+ DEBUG_FRAME_CMD,
+ DEBUG_STYLESHEETS_CMD,
+
+ DEBUG_BREAK_CMD,
+ DEBUG_SHOWBREAK_CMD,
+ DEBUG_DELETE_CMD,
+ DEBUG_ENABLE_CMD,
+ DEBUG_DISABLE_CMD,
+
+ DEBUG_LS_CMD,
+ DEBUG_DIR_CMD,
+ DEBUG_DU_CMD,
+ DEBUG_CAT_CMD,
+ DEBUG_PRINT_CMD, /* cat alternative */
+ DEBUG_PWD_CMD,
+ DEBUG_DUMP_CMD,
+ DEBUG_BASE_CMD,
+
+ DEBUG_GLOBALS_CMD,
+ DEBUG_LOCALS_CMD,
+ /* DEBUG_CAT_CMD, already listed */
+ DEBUG_SOURCE_CMD,
+ DEBUG_DATA_CMD,
+ DEBUG_OUTPUT_CMD,
+ DEBUG_CD_CMD,
+
+ /* file related */
+ /* DEBUG_OUTPUT_CMD, already listed */
+ DEBUG_ENTITIES_CMD,
+ DEBUG_SYSTEM_CMD,
+ DEBUG_PUBLIC_CMD,
+ DEBUG_ENCODING_CMD,
+ DEBUG_VALIDATE_CMD,
+ DEBUG_LOAD_CMD,
+ DEBUG_SAVE_CMD,
+ DEBUG_WRITE_CMD,
+ DEBUG_FREE_CMD,
+
+ /* Operating system related */
+ DEBUG_CHDIR_CMD,
+ DEBUG_SHELL_EXEC_CMD,
+ DEBUG_TTY_CMD,
+
+ /* libxslt parameter and options related */
+ DEBUG_ADDPARAM_CMD,
+ DEBUG_DELPARAM_CMD,
+ DEBUG_SHOWPARAM_CMD,
+ DEBUG_SETOPTION_CMD,
+ DEBUG_OPTIONS_CMD, /* print options */
+
+ /* extra options/commands */
+ DEBUG_TRACE_CMD,
+ DEBUG_WALK_CMD,
+ DEBUG_ADDWATCH_CMD,
+ DEBUG_DELWATCH_CMD,
+ DEBUG_SHOWWATCH_CMD,
+
+ /* searching */
+ DEBUG_SEARCH_CMD,
+
+ /* variable change */
+ DEBUG_SET_CMD
+
+ /* language change */
+ DEBUG_LANG_CMD
+
+ /* NULL */
+};
+#endif
+
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/debug.cpp b/kxsldbg/kxsldbgpart/libxsldbg/debug.cpp
new file mode 100644
index 00000000..2975f814
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/debug.cpp
@@ -0,0 +1,235 @@
+
+/***************************************************************************
+ 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;
+ }
+ }
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/debug.h b/kxsldbg/kxsldbgpart/libxsldbg/debug.h
new file mode 100644
index 00000000..c38f37eb
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/debug.h
@@ -0,0 +1,101 @@
+
+/**************************************************************************
+ debug.h - declare major debugger functions
+ -------------------
+ begin : Thur Jan 31 2002
+ 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. *
+ * *
+ **************************************************************************/
+
+#ifndef XSL_DEBUG_H
+#define XSL_DEBUG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * debugInit:
+ *
+ * Initialize debugger allocating any memory needed by debugger
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Initialize debugger allocating any memory needed by debugger
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int debugInit(void);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * debugFree:
+ *
+ * Free up any memory taken by debugger
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Free up any memory taken by debugger
+ */
+#endif
+#endif
+ void debugFree(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * debugGotControl:
+ * @reached: 1 if debugger has received control, -1 to read its value,
+ 0 to clear the flag
+ *
+ * Set flag that debuger has received control to value of @reached
+ *
+ * Returns 1 if any break point was reached previously,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Set flag that debuger has received control to value of @p reached
+ *
+ * @returns 1 if any breakpoint was reached previously,
+ * 0 otherwise
+ *
+ * @param reached 1 if debugger has received control, -1 to read its value,
+ * 0 to clear the flag
+ */
+#endif
+#endif
+ int debugGotControl(int reached);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/debugXSL.cpp b/kxsldbg/kxsldbgpart/libxsldbg/debugXSL.cpp
new file mode 100644
index 00000000..39aea804
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/debugXSL.cpp
@@ -0,0 +1,2118 @@
+
+/***************************************************************************
+ debugXSL.c - debugger commands to use
+ -------------------
+ begin : Sun Sep 16 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. *
+ * *
+ ***************************************************************************/
+
+/*
+ * Orinal file : debugXML.c : This is a set of routines used for
+ * debugging the tree produced by the XML parser.
+ *
+ * New file : shell.c : Debug support version
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <daniel@veillard.com>
+ *
+ * Permission obtained to modify the LGPL'd code and extend to include breakpoints, inspections of
+ * stylesheet source, xml data, stylesheet variables
+ */
+
+#ifdef WIN32
+#include <wtypes.h>
+#include <winbase.h> /* needed fort the sleep function */
+#endif
+
+#include "xsldbg.h"
+#include "files.h"
+#include "cmds.h" /* list of command Id's */
+#include "debug.h"
+#include "debugXSL.h"
+#include "options.h"
+#include "breakpoint.h"
+#include "help.h"
+#include <stdlib.h>
+#include <libxslt/transform.h> /* needed by source command */
+#include <libxslt/xsltInternals.h>
+#include <libxml/debugXML.h>
+#include <stdio.h>
+
+/* language change support */
+#ifdef LOCALE_PREFIX
+#include <locale.h>
+#endif
+
+#include "xsldbgmsg.h"
+#include "xsldbgthread.h" /* for get thread status */
+#include "xsldbgio.h"
+
+/* current template being processed */
+xsltTemplatePtr rootCopy;
+
+/* how may items have been printed */
+int printCount;
+
+/* used to sending small amounts data when xsldbg runs as a thread */
+xmlChar messageBuffer[2000];
+
+/* To achieve the same fucntionality of a next command
+ we first do a step, then a step up */
+int nextCommandActive = 0;
+
+/* Do we print the values for watches each time the debugger stops */
+int showWatchesActive = 1;
+
+extern FILE *terminalIO;
+
+int xsldbgStop = 0;
+int xsldbgValidateBreakpoints = BREAKPOINTS_NEED_VALIDATION;
+int xsldbgHasLineNumberFix;
+bool xsldbgReachedFirstTemplate = false;
+
+/* valid commands of xslDbgShell */
+const char *commandNames[] = {
+ "help",
+
+ "bye",
+ "exit",
+ "quit",
+
+ "step",
+ "stepup",
+ "stepdown",
+ "next", /* next ie step over template function call*/
+ "continue",
+ "run",
+
+ "templates",
+ "where",
+ "frame",
+ "stylesheets",
+
+ "break",
+ "showbreak",
+ "delete",
+ "enable",
+ "disable",
+
+ "ls",
+ "dir",
+ "du",
+ "cat",
+ "print",
+ "pwd",
+ "dump",
+ "base",
+
+ "globals",
+ "locals",
+ /* "cat", already listed */
+ "source",
+ "data",
+ "output", /* output file name */
+ "cd",
+
+ /* file related */
+ /* "output", already listed */
+ "entities",
+ "system",
+ "public",
+ "encoding",
+ "validate",
+ "load",
+ "save",
+ "write",
+ "free",
+
+ /* Operating system related */
+ "chdir",
+ "shell",
+ "tty",
+
+ /* libxslt parameter related */
+ "addparam",
+ "delparam",
+ "showparam",
+ "setoption",
+ "options",
+
+ /* extra options */
+ "trace",
+ "walk",
+ "addwatch",
+ "delwatch",
+ "showwatch",
+
+ /* searching */
+ "search",
+
+ /*variable value change */
+ "set",
+
+ /* language change */
+ "lang",
+
+ NULL /* Indicate the end of list */
+};
+
+/* valid commands of xslShell in there alternative|shorter format */
+const char *shortCommandNames[] = {
+ "h",
+
+ "bye",
+ "exit",
+ "q", /*quit */
+
+ "s", /* step */
+ "up", /*stepup */
+ "down", /* stepdown */
+ "n", /* next ie step over function call*/
+ "c", /* continue */
+ "r", /* run */
+
+ "t", /* templates */
+ "w", /* where */
+ "f",
+ "style",
+
+ "b", /* break */
+ "show",
+ "d", /* delete */
+ "e", /* enabled */
+ "disable",
+
+ "ls",
+ "dir",
+ "du",
+ "cat",
+ "print",
+ "pwd",
+ "dump",
+ "base",
+
+ "globals",
+ "locals",
+ /* "cat", already listed */
+ "source",
+ "data",
+ "o", /* output file name */
+ "cd",
+
+
+ /* file related */
+ /* "output", already listed */
+ "ent", /* entities command */
+ "sys", /* sytem command */
+ "pub", /* public command */
+ "encoding",
+ "validate",
+ "load",
+ "save",
+ "write",
+ "free",
+
+ /* Operating system related */
+ "chdir",
+ "shell",
+ "tty",
+
+ /* libxslt parameter related */
+ "addparam",
+ "delparam",
+ "showparam",
+ "setoption",
+ "options",
+
+ /* extra options/commands */
+ "trace",
+ "walk",
+ "watch",
+ "delwatch",
+ "watches",
+
+ /* searching */
+ "search",
+
+ /*variable value change */
+ "set",
+
+ /* language change */
+ "lang",
+
+ NULL /* Indicate the end of list */
+};
+
+
+/* some convenient short cuts when using cd command*/
+const char *cdShortCuts[] = {
+ "<<",
+ ">>",
+ "<-",
+ "->",
+ NULL /* indicate end of list */
+};
+
+/* what to replace shortcuts with */
+const char *cdAlternative[] = {
+ "preceding-sibling::node()",
+ "following-sibling::node()",
+ "ancestor::node()",
+ "descendant::node()",
+ NULL /* indicate end of list */
+};
+
+/* what enum to use for shortcuts */
+enum ShortcutsEnum {
+ DEBUG_PREV_SIBLING = 200,
+ DEBUG_NEXT_SIBLING,
+ DEBUG_ANCESTOR_NODE,
+ DEBUG_DESCENDANT_NODE
+};
+
+
+
+#include <libxml/xpathInternals.h>
+
+#include <libxslt/extra.h>
+#include <string.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/valid.h>
+#include <libxml/debugXML.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/HTMLparser.h>
+
+
+/* -----------------------------------------
+ Private function declarations for debugXSL.c
+ -------------------------------------------*/
+
+
+/* xslDbgCd :
+ * Change directories
+ * @styleCtxt : current stylesheet context
+ * @ctxt : current shell context
+ * @arg : path to change to
+ * @source : is valid
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int xslDbgCd(xsltTransformContextPtr styleCtxt, xmlShellCtxtPtr ctxt,
+ xmlChar * arg, xmlNodePtr source);
+
+
+/**
+ * xslDbgPrintCallStack:
+ * @arg : the number of frame to print, NULL if all items
+ *
+ * Print all items found on the callStack
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int xslDbgPrintCallStack(const xmlChar * arg);
+
+
+/**
+ * xslDbgSleep:
+ * @delay : the number of microseconds to delay exection by
+ *
+ * Delay execution by a specified number of microseconds. On some system
+ * this will not be at all accurate.
+ */
+void xslDbgSleep(long delay);
+
+
+/**
+ * xslDbgWalkContinue:
+ *
+ * Delay execution for time as indicated by OPTION_WALK_SPEED
+ * Can only be called from within shellPrompt!
+ * OPTION_WALK_SPEED != WALKSPEED_STOP
+ *
+ * Returns 1 if walk is to continue,
+ * 0 otherwise
+ */
+int xslDbgWalkContinue(void);
+
+
+
+/**
+ * addBreakPointNode:
+ * @payload : valid breakPointPtr
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+ addBreakPointNode(void *payload, void *data,
+ xmlChar * name);
+
+
+/**
+ * addSourceNode:
+ * @payload : valid xsltStylesheetPtr
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+ addSourceNode(void *payload, void *data,
+ xmlChar * name);
+
+
+/**
+ * addTemplateNode:
+ * @payload : valid xsltTemplatePtr
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+ addTemplateNode(void *payload, void *data,
+ xmlChar * name);
+
+/**
+ * addGlobalNode:
+ * @payload : valid xmlNodePtr of global variable
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+ addGlobalNode(void *payload, void *data,
+ xmlChar * name);
+
+/**
+ * addLocalNode:
+ * @payload : valid xmlNodePtr of local variable
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+ addLocalNode(void *payload, void *data,
+ xmlChar * name);
+
+
+/**
+ * addIncludeNode:
+ * @payload : valid xmlNodePtr of include instuction
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+ addIncludeNode(void *payload, void *data,
+ xmlChar * name);
+
+
+
+/**
+ * addCallStackItems:
+ *
+ * Convert call stack items into format needed, and add to search dataBase
+ */
+void
+ addCallStackItems(void);
+
+
+/**
+ * shellPrompt:
+ * @source: The current stylesheet instruction being executed
+ * @doc: The current document node being processed
+ * @filename: Not used
+ * @input: The function to call to when reading commands from stdio
+ * @output: Where to put the results
+ * @styleCtxt: Is valid
+ *
+ * Present to the user the xsldbg shell
+ */
+void shellPrompt(xmlNodePtr source, xmlNodePtr doc,
+ xmlChar * filename,
+ xmlShellReadlineFunc input,
+ FILE * output, xsltTransformContextPtr styleCtxt);
+
+/* -------------------------------------
+ End private functions
+---------------------------------------*/
+
+
+
+/**
+ * debugXSLGetTemplate:
+ *
+ * Return the last template node found, if an
+ *
+ * Returns The last template node found, if any
+ */
+xsltTemplatePtr
+debugXSLGetTemplate(void)
+{
+ return rootCopy;
+}
+
+
+/****************************************************************
+ * *
+ * The XSL shell related functions *
+ * *
+ ****************************************************************/
+
+
+/* xslDbgCd :
+ * Change directories
+ * @styleCtxt : current stylesheet context
+ * @ctxt : current shell context
+ * @arg : path to change to and in UTF-8
+ * @source : is valid
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgCd(xsltTransformContextPtr styleCtxt, xmlShellCtxtPtr ctxt,
+ xmlChar * arg, xmlNodePtr source)
+{
+ xmlXPathObjectPtr list = NULL;
+ int result = 0;
+ int offset = 2; /* in some cases I'm only interested after first two chars */
+
+ if (!ctxt) {
+ xsldbgGenericErrorFunc(i18n("Error: Debugger has no files loaded. Try reloading files.\n"));
+ return result;
+ }
+
+ if (arg == NULL)
+ arg = (xmlChar *) "";
+ if (arg[0] == 0) {
+ ctxt->node = (xmlNodePtr) ctxt->doc;
+ } else {
+ if ((arg[0] == '-') && (xmlStrLen(arg) > 2)) {
+ if (styleCtxt) {
+ if (arg[1] == 't') {
+ xmlNodePtr templateNode;
+
+ /* quickly find a template */
+ /* skip any white spaces */
+ while (_IS_BLANK(arg[offset]))
+ offset++;
+
+ templateNode =
+ findTemplateNode(styleCtxt->style, &arg[offset]);
+ if (!templateNode) {
+ xsldbgGenericErrorFunc(i18n("Error: The XSLT template named \"%1\" was not found.\n").arg(xsldbgText(&arg[offset])));
+ return result;
+ } else {
+ xsldbgGenericErrorFunc(i18n(" template: \"%1\"\n").arg(xsldbgText(&arg[offset])));
+ ctxt->node = templateNode;
+ result = 1;
+ return result;
+ }
+ } else if (arg[1] == 's') {
+ /*quickly switch to another stylesheet node */
+ xmlXPathContextPtr pctxt;
+
+ if (source) {
+ pctxt = xmlXPathNewContext(source->doc);
+ if (pctxt == NULL) {
+ xmlFree(ctxt);
+ /* xslDebugStatus = DEBUG_QUIT; */
+ return result;
+ }
+ if (!xmlXPathNsLookup(pctxt, (xmlChar *) "xsl"))
+ xmlXPathRegisterNs(pctxt, (xmlChar *) "xsl",
+ XSLT_NAMESPACE);
+ list =
+ xmlXPathEval((xmlChar *) & arg[offset], pctxt);
+ if (pctxt) {
+ xmlFree(pctxt);
+ }
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to cd. No stylesheet loaded.\n"));
+ }
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Unknown arguments to the command %1.\n").arg("cd"));
+ }
+ } else
+ xsldbgGenericErrorFunc(i18n("Error: Unable to cd. No stylesheet loaded.\n"));
+ } else {
+ xmlNodePtr savenode;
+
+ if (styleCtxt) {
+ savenode = styleCtxt->xpathCtxt->node;
+ ctxt->pctxt->node = ctxt->node;
+ styleCtxt->xpathCtxt->node = ctxt->node;
+ if (!xmlXPathNsLookup(ctxt->pctxt, (xmlChar *) "xsl"))
+ xmlXPathRegisterNs(ctxt->pctxt, (xmlChar *) "xsl",
+ XSLT_NAMESPACE);
+ list = xmlXPathEval((xmlChar *) arg, styleCtxt->xpathCtxt);
+ styleCtxt->xpathCtxt->node = savenode;
+ } else if (ctxt->pctxt) {
+ if (!xmlXPathNsLookup(ctxt->pctxt, (xmlChar *) "xsl"))
+ xmlXPathRegisterNs(ctxt->pctxt, (xmlChar *) "xsl",
+ XSLT_NAMESPACE);
+ list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments to the command %1.\n").arg("cd"));
+ }
+ }
+
+ if (list != NULL) {
+ switch (list->type) {
+ case XPATH_NODESET:
+ if (list->nodesetval) {
+ if (list->nodesetval->nodeNr == 1) {
+ ctxt->node = list->nodesetval->nodeTab[0];
+ /* tell the application about the new line
+ * number we are looking at */
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ int breakpoint = 0;
+
+ xsldbgUpdateFileDetails(ctxt->node);
+ notifyXsldbgApp(XSLDBG_MSG_LINE_CHANGED,
+ &breakpoint);
+ }
+ result = 1;
+ } else
+ xsldbgGenericErrorFunc(i18n("Warning: XPath %1 is a Node Set with %n child.", "Warning: XPath %1 is a Node Set with %n children.", list->nodesetval->nodeNr).arg(xsldbgText(arg)) + QString("\n"));
+ } else {
+ xsldbgGenericErrorFunc(i18n("Warning: XPath %1 is an empty Node Set.\n").arg(xsldbgText(arg)));
+ }
+ break;
+
+ default:
+ xmlShellPrintXPathError(list->type, (char *) arg);
+ }
+ xmlXPathFreeObject(list);
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: XPath %1 was not found.\n").arg(xsldbgText(arg)));
+ }
+ if (ctxt->pctxt)
+ ctxt->pctxt->node = NULL;
+ }
+ return result;
+}
+
+
+/**
+ * xslDbgPrintCallStack:
+ * @arg : the number of frame to print, NULL if all items
+ *
+ * Print all items found on the callStack
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgPrintCallStack(const xmlChar * arg)
+{
+ int depth = 0;
+ int result = 1;
+ callPointPtr callPointItem;
+
+ if (arg == NULL) {
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ notifyListStart(XSLDBG_MSG_CALLSTACK_CHANGED);
+ /* we send the oldest frame stack first */
+ for (depth = 1; depth <= callStackGetDepth(); depth++) {
+ callPointItem = callStackGet(depth);
+ if (callPointItem && callPointItem->info) {
+ notifyListQueue(callPointItem);
+ }
+ }
+ notifyListSend();
+ } else {
+ xmlChar *nameTemp, *modeTemp;
+ for (depth = callStackGetDepth(); depth >= 1; depth--) {
+ callPointItem = callStackGet(depth);
+ nameTemp = NULL;
+ modeTemp = NULL;
+ if (callPointItem && callPointItem->info) {
+ if (depth == callStackGetDepth()) {
+ xmlChar *curUrl = xsldbgUrl();
+ long curLine = xsldbgLineNo();
+ /* if possible list the current location */
+ if (rootCopy && (rootCopy->match || rootCopy->name)
+ && curUrl) {
+ xmlChar *rootNameTemp, *rootModeTemp;
+ rootNameTemp = fullQName(rootCopy->nameURI, rootCopy->name);
+ rootModeTemp = fullQName(rootCopy->modeURI, rootCopy->mode);
+ if (rootNameTemp && rootModeTemp){
+ if (rootCopy->match)
+ /* display information about the current XSLT template */
+ xsldbgGenericErrorFunc(i18n("#%1 template: \"%2\" mode: \"%3\"").arg(depth).arg(xsldbgText(rootCopy->match)).arg(xsldbgText(rootModeTemp)));
+ else
+ /* display information about the current XSLT template */
+ xsldbgGenericErrorFunc(i18n("#%1 template: \"%2\" mode: \"%3\"").arg(depth).arg(xsldbgText(rootNameTemp)).arg(xsldbgText(rootModeTemp)));
+ /* display where we are in the source/document file */
+ xsldbgGenericErrorFunc(i18n(" in file \"%1\" at line %2\n").arg(xsldbgUrl(curUrl)).arg(curLine));
+ }else{
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ result = 0;
+ }
+ if (rootNameTemp){
+ xmlFree(rootNameTemp);
+ rootNameTemp = NULL;
+ }
+ if (rootModeTemp){
+ xmlFree(rootModeTemp);
+ rootModeTemp = NULL;
+ }
+ } else if (curUrl) {
+ /* display information about the current XSLT template */
+ xsldbgGenericErrorFunc(i18n("#%1 template: \"LIBXSLT_DEFAULT\" mode: \"\"").arg(depth));
+ /* display where we are in the source/document file */
+ xsldbgGenericErrorFunc(i18n(" in file \"%1\" at line %2\n").arg(xsldbgUrl(curUrl)).arg(curLine));
+ }
+ if (curUrl)
+ xmlFree(curUrl);
+
+ }
+ nameTemp = fullQName(callPointItem->info->templateURI,
+ callPointItem->info->templateName);
+ modeTemp = fullQName(callPointItem->info->modeURI,
+ callPointItem->info->modeName);
+ if (nameTemp && modeTemp){
+ /* display information about the current XSLT template */
+ xsldbgGenericErrorFunc(i18n("#%1 template: \"%2\" mode: \"%3\"").arg(depth - 1).arg(xsldbgText(nameTemp)).arg(xsldbgText(modeTemp)));
+ if (callPointItem->info->url)
+ /* display where we are in the source/document file */
+ xsldbgGenericErrorFunc(i18n(" in file \"%1\" at line %2\n").arg(xsldbgUrl(callPointItem->info->url)).arg(callPointItem->lineNo));
+ else
+ xsldbgGenericErrorFunc("\n");
+ }else{
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ result = 0;
+ }
+ if (nameTemp){
+ xmlFree(nameTemp);
+ nameTemp = NULL;
+ }
+ if(modeTemp){
+ xmlFree(modeTemp);
+ modeTemp = NULL;
+ }
+
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Call stack item not found at depth %d : xslDbgPrintCallStack\n", depth);
+#endif
+ result = 0;
+ break;
+ }
+ }
+ if (callStackGetDepth() == 0)
+ xsldbgGenericErrorFunc(i18n("\tNo items in call stack.\n"));
+ else
+ xsldbgGenericErrorFunc("\n");
+ }
+ } else {
+ long templateDepth = atol((char *) arg);
+
+
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ /* should never happen but just in case, when running as a
+ * thread always provide NO params to the where command */
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Notification of a frame not supported\n");
+#endif
+ result = 0;
+ return result;
+ }
+
+ if (templateDepth >= 0) {
+ callPointItem = callStackGet(templateDepth + 1);
+ if (callPointItem && callPointItem->info) {
+ /* display information about the current XSLT template */
+ xsldbgGenericErrorFunc(i18n("#%1 template: \"%2\"").arg(templateDepth).arg(xsldbgText(callPointItem->info->templateName)));
+ /* should alays be present but .. */
+ if (callPointItem->info->url)
+ /* display where we are in the source/document file */
+ xsldbgGenericErrorFunc(i18n(" in file \"%1\" at line %2\n").arg(xsldbgUrl(callPointItem->info->url)).arg(callPointItem->lineNo));
+ else
+ xsldbgGenericErrorFunc("\n");
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Call stack item not found at templateDepth %d : xslDbgPrintCallStack\n", depth);
+#endif
+ result = 0;
+ }
+ }
+ }
+ return result;
+}
+
+
+/**
+ * xslDbgSleep:
+ * @delay : the number of microseconds to delay exection by
+ *
+ * Delay execution by a specified number of microseconds. On some system
+ * this will not be at all accurate.
+ */
+void
+xslDbgSleep(long delay)
+{
+#ifdef HAVE_USLEEP
+ usleep(delay);
+#else
+#ifdef WIN32
+ Sleep(delay / 1000);
+#else
+ /* try to delay things by doing a lot of floating point
+ * multiplication
+ */
+ long loop1, loop2;
+ float f1 = 1.0000001, f2;
+
+ for (loop1 = 0; loop1 < 100000 * delay; loop1++)
+ for (loop2 = 0; loop2 < 100000; loop2++) {
+ f2 = f1 * f1;
+ }
+#endif
+#endif
+}
+
+
+/**
+ * xslDbgWalkContinue:
+ *
+ * Delay execution for time as indicated by OPTION_WALK_SPEED
+ * Can only be called from within shellPrompt!
+ * OPTION_WALK_SPEED != WALKSPEED_STOP
+ *
+ * Returns 1 if walk is to continue,
+ * 0 otherwise
+ */
+int
+xslDbgWalkContinue(void)
+{
+ int result = 0, speed = optionsGetIntOption(OPTIONS_WALK_SPEED);
+
+ /* We need to ensure that output is realy sent. Otherwise
+ * walking using xemacs under WIN32 will not work */
+ fflush(stderr);
+
+ switch (speed) {
+ case WALKSPEED_1:
+ case WALKSPEED_2:
+ case WALKSPEED_3:
+ case WALKSPEED_4:
+ case WALKSPEED_5:
+ case WALKSPEED_6:
+ case WALKSPEED_7:
+ case WALKSPEED_8:
+ case WALKSPEED_9:
+ /* see options.h for defintion of WALKDAY */
+ xslDbgSleep(speed * WALKDELAY);
+ result = 1;
+ break;
+
+ default: /* stop walking */
+ optionsSetIntOption(OPTIONS_WALK_SPEED, WALKSPEED_STOP);
+ xslDebugStatus = DEBUG_STOP;
+ break;
+ }
+
+ return result;
+}
+
+
+/**
+ * addBreakPointNode:
+ * @payload : valid breakPointPtr
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+addBreakPointNode(void *payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(name);
+ xmlNodePtr node = searchBreakPointNode((breakPointPtr) payload);
+
+ searchAdd(node);
+}
+
+
+/**
+ * addSourceNode:
+ * @payload : valid xsltStylesheetPtr
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+addSourceNode(void *payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(name);
+ xmlNodePtr node = searchSourceNode((xsltStylesheetPtr) payload);
+
+ searchAdd(node);
+}
+
+
+/**
+ * addTemplateNode:
+ * @payload : valid xsltTemplatePtr
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+addTemplateNode(void *payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(name);
+ xmlNodePtr node =
+ searchTemplateNode(((xsltTemplatePtr) payload)->elem);
+ searchAdd(node);
+}
+
+
+/**
+ * addGlobalNode:
+ * @payload : valid xmlNodePtr of global variable
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+addGlobalNode(void *payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(name);
+ xmlNodePtr node = searchGlobalNode((xmlNodePtr) payload);
+
+ searchAdd(node);
+}
+
+
+/**
+ * addLocalNode:
+ * @payload : valid xmlNodePtr of local variable
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+addLocalNode(void *payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(name);
+ xmlNodePtr node = searchLocalNode((xmlNodePtr) payload);
+
+ searchAdd(node);
+}
+
+
+/**
+ * addIncludeNode:
+ * @payload : valid xmlNodePtr of include instuction
+ * @data : not used
+ * @name : not used
+ *
+ * Convert payload into format needed, and add to search dataBase
+ */
+void
+addIncludeNode(void *payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(name);
+ xmlNodePtr node = searchIncludeNode((xmlNodePtr) payload);
+
+ searchAdd(node);
+}
+
+
+/**
+ * addCallStackItems:
+ *
+ * Convert call stack items into format needed, and add to search dataBase
+ */
+void
+addCallStackItems(void)
+{
+ callPointPtr item;
+ xmlNodePtr node;
+ int depth;
+
+ for (depth = callStackGetDepth(); depth > 0; depth--) {
+ item = callStackGet(depth);
+ if (item) {
+ node = searchCallStackNode(item);
+ if (node)
+ searchAdd(node);
+ }
+ }
+}
+
+
+/**
+ * updateSearchData:
+ * @styleCtxt: Not used
+ * @style: Is valid
+ * @data: Not used but MUST be NULL for the moment
+ * @variableTypes: What types of variables to look
+ *
+ * Update the searchDatabase
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+updateSearchData(xsltTransformContextPtr styleCtxt,
+ xsltStylesheetPtr style,
+ void *data, VariableTypeEnum variableTypes)
+{
+ Q_UNUSED(styleCtxt);
+ Q_UNUSED(variableTypes);
+ int result = 0;
+
+ if (!style) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to update search database no stylesheet loaded\n");
+#endif
+ return result;
+ }
+ searchEmpty();
+ xsldbgGenericErrorFunc(i18n("Information: Updating search database. This may take a while...\n"));
+ /* add items to the search dataBase */
+ addCallStackItems();
+ xsldbgGenericErrorFunc(i18n("Information: Looking for breakpoints.\n"));
+ walkBreakPoints((xmlHashScanner) addBreakPointNode, data);
+ xsldbgGenericErrorFunc(i18n("Information: Looking for imports and top-level stylesheets.\n"));
+ walkStylesheets((xmlHashScanner) addSourceNode, data, style);
+ xsldbgGenericErrorFunc(i18n("Information: Looking for xsl:includes.\n"));
+ walkIncludeInst((xmlHashScanner) addIncludeNode, data, style);
+ xsldbgGenericErrorFunc(i18n("Information: Looking for templates.\n"));
+ walkTemplates((xmlHashScanner) addTemplateNode, data, style);
+ xsldbgGenericErrorFunc(i18n("Information: Looking for global variables.\n"));
+ walkGlobals((xmlHashScanner) addGlobalNode, data, style);
+ xsldbgGenericErrorFunc(i18n("Information: Looking for local variables.\n"));
+ walkLocals((xmlHashScanner) addLocalNode, data, style);
+ xsldbgGenericErrorFunc(i18n("Information: Formatting output.\n"));
+
+ result = searchSave(NULL);
+ return result;
+}
+
+
+/**
+ * debugXSLBreak:
+ * @templ: The source node being executed
+ * @node: The data node being processed
+ * @root: The template being applied to "node"
+ * @ctxt: The transform context for stylesheet being processed
+ *
+ * A break point has been found so pass control to user
+ */
+void
+debugXSLBreak(xmlNodePtr templ, xmlNodePtr node, xsltTemplatePtr root,
+ xsltTransformContextPtr ctxt)
+{
+ xmlDocPtr tempDoc = NULL;
+ xmlNodePtr tempNode = NULL;
+ rootCopy = root;
+ static const xmlChar *lastTemplate = NULL;
+ xmlBufferPtr buffer = xmlBufferCreate();
+ static char mybuff[6] = " 0\n\x0";
+
+ if (ctxt && templ && root && !xsldbgReachedFirstTemplate)
+ xsldbgReachedFirstTemplate = true;
+
+ if (templ == NULL) {
+ tempDoc = xmlNewDoc((xmlChar *) "1.0");
+ if (!tempDoc)
+ return;
+ tempNode = xmlNewNode(NULL, (xmlChar *) "xsldbg_default_node");
+ if (!tempNode) {
+ xmlFreeDoc(tempDoc);
+ return;
+ }
+ xmlAddChild((xmlNodePtr) tempDoc, tempNode);
+ templ = tempNode;
+ }
+
+ if (node == NULL)
+ node = (xmlNodePtr) filesGetMainDoc();
+
+ if (node == NULL) {
+ tempDoc = xmlNewDoc((xmlChar *) "1.0");
+ if (!tempDoc)
+ return;
+ tempNode = xmlNewNode(NULL, (xmlChar *) "xsldbg_default_node");
+ if (!tempNode) {
+ xmlFreeDoc(tempDoc);
+ return;
+ }
+ xmlAddChild((xmlNodePtr) tempDoc, tempNode);
+ node = tempNode;
+ }
+ if (root) {
+ xmlChar *nameTemp = NULL, *modeTemp = NULL;
+ nameTemp = fullQName(root->nameURI, root->name);
+ modeTemp = fullQName(root->modeURI, root->mode);
+ if (!nextCommandActive){
+ /* we only want messages if we are not
+ in the process of completing the next command */
+ if (terminalIO == NULL) {
+
+ if (root->match){
+ xsldbgGenericErrorFunc(i18n("\nReached template: \"%1\" mode: \"%2\"\n").arg(xsldbgText(root->match)).arg(xsldbgText(modeTemp)));
+ if (lastTemplate != root->match && buffer){
+ xmlBufferCCat(buffer, "\nreached matched template:");
+ xmlBufferCat(buffer, root->match);
+ xmlBufferCCat(buffer, mybuff);
+ xsltCopyTextString(ctxt, ctxt->insert,xmlBufferContent(buffer),0);
+ mybuff[1]++;
+ lastTemplate = root->match;
+ }
+ }else{
+ xsldbgGenericErrorFunc(i18n("\nReached template: \"%1\" mode: \"%2\"\n").arg(xsldbgText(nameTemp)).arg(xsldbgText(modeTemp)));
+ if (lastTemplate != root->name && buffer){
+ xmlBufferCCat(buffer, "\nreached named template:");
+ xmlBufferCat(buffer,root->match);
+ xmlBufferCCat(buffer,mybuff);
+ xsltCopyTextString(ctxt, ctxt->insert,xmlBufferContent(buffer),0);
+ mybuff[1]++;
+ lastTemplate = root->name;
+ }
+
+ }
+ if (buffer)
+ xmlBufferFree(buffer);
+ } else {
+ if ((xslDebugStatus == DEBUG_TRACE) ||
+ (xslDebugStatus == DEBUG_WALK)) {
+ QString message;
+ if (root->match)
+ message = i18n("\nReached template: \"%1\" mode: \"%2\"\n").arg(xsldbgText(root->match)).arg(xsldbgText(modeTemp));
+ else
+ message = i18n("\nReached template: \"%1\" mode: \"%2\"\n").arg(xsldbgText(nameTemp)).arg(xsldbgText(modeTemp));
+ fprintf(terminalIO, "%s", message.local8Bit().data());
+ }
+ }
+ }
+ if (nameTemp)
+ xmlFree(nameTemp);
+ if (modeTemp)
+ xmlFree(modeTemp);
+ }
+
+ shellPrompt(templ, node, (xmlChar *) "index.xsl",
+ (xmlShellReadlineFunc) xslDbgShellReadline, stdout, ctxt);
+ if (tempDoc)
+ xmlFreeDoc(tempDoc);
+}
+
+
+/* Highly modified function based on xmlShell */
+
+/**
+ * shellPrompt:
+ * @source: The current stylesheet instruction being executed
+ * @doc: The current document node being processed
+ * @filename: Not used
+ * @input: The function to call to when reading commands from stdio
+ * @output: Where to put the results
+ * @styleCtxt: Is valid
+ *
+ * Present to the user the xsldbg shell
+ */
+void
+shellPrompt(xmlNodePtr source, xmlNodePtr doc, xmlChar * filename,
+ xmlShellReadlineFunc input, FILE * output,
+ xsltTransformContextPtr styleCtxt)
+{
+ xmlChar prompt[DEBUG_BUFFER_SIZE] = "/ > ";
+ xmlChar *cmdline = NULL, *cur;
+ int nbargs = 0;
+ int loadedFiles = 0;
+ int commandId = -1; /* stores what was the last
+ * command id entered by user */
+ xmlChar command[DEBUG_BUFFER_SIZE]; /* holds the command user entered */
+ xmlChar arg[DEBUG_BUFFER_SIZE]; /* holds any extra arguments to
+ * command entered */
+ xmlChar dir[DEBUG_BUFFER_SIZE]; /* temporary buffer used by where
+ * and pwd commands */
+ int cmdResult; /* result of last command */
+ int shortCutId = -1; /* used by cd command */
+ int i;
+ static int showSource = 1; /* Do we first show source or data ? */
+ xmlChar *baseUri = NULL; /* for used for included xml entities */
+ const xmlChar *breakUri;
+
+ /* for convenience keep track of which node was last
+ * selected of source and doc */
+ xmlNodePtr lastSourceNode, lastDocNode;
+
+
+ xmlShellCtxtPtr ctxt;
+ int exitShell = 0; /* Indicate when to exit xslShell */
+
+ if (source == NULL){
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Source NULL in shellPrompt\n");
+#endif
+ return;
+ }
+ if (doc == NULL){
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: doc NULL in shellPrompt\n");
+#endif
+ return;
+ }
+ if (filename == NULL){
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: fileName NULL in shellPrompt\n");
+#endif
+ return;
+ }
+ if (input == NULL){
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Input function NULL in shellPrompt\n");
+#endif
+ return;
+ }
+ if (output == NULL){
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Output NULL in shellPrompt\n");
+#endif
+ return;
+ }
+ ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt));
+ if (ctxt == NULL){
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ return;
+ }
+
+ /* flag that we've received control */
+ debugGotControl(1);
+ ctxt->loaded = 0;
+ lastSourceNode = source;
+ lastDocNode = doc;
+ /* show the doc or source first? */
+ if (showSource) {
+ ctxt->doc = source->doc;
+ ctxt->node = source;
+ xsldbgUpdateFileDetails(source);
+ } else {
+ ctxt->doc = doc->doc;
+ ctxt->node = (xmlNodePtr) doc;
+ xsldbgUpdateFileDetails((xmlNodePtr) doc);
+ }
+
+ ctxt->input = input;
+ ctxt->output = output;
+ ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
+
+
+ if (xsldbgStop == 1){
+ xslDebugStatus = DEBUG_STOP;
+ optionsSetIntOption(OPTIONS_TRACE, TRACE_OFF);
+ optionsSetIntOption(OPTIONS_WALK_SPEED, WALKSPEED_STOP);
+ xsldbgStop = 0;
+ }
+
+ /* let any listener know that we got to a new line */
+ if (xslDebugStatus != DEBUG_TRACE) {
+ /* don't send notify message if we are tracing stylesheet */
+ int breakpoint = 1;
+
+ notifyXsldbgApp(XSLDBG_MSG_LINE_CHANGED, &breakpoint);
+ }
+
+
+ /* If using a thread and the thread is running then we don't need to
+ * send this as the application will see the XSLDBG_MSG_LINE_CHANGED message */
+ if ((getThreadStatus() == XSLDBG_MSG_THREAD_NOTUSED) ||
+ (xslDebugStatus == DEBUG_TRACE)) {
+ QString messageTxt;
+ if (!nextCommandActive && ctxt->node && ctxt->node && ctxt->node->doc
+ && ctxt->node->doc->URL) {
+ if (!showSource) {
+ baseUri = filesGetBaseUri(ctxt->node);
+ if (baseUri != NULL)
+ breakUri = baseUri;
+ else
+ breakUri = ctxt->node->doc->URL;
+ } else
+ breakUri = ctxt->node->doc->URL;
+
+ if (xmlGetLineNo(ctxt->node) != -1)
+ messageTxt = i18n("Breakpoint for file \"%1\" at line %2.\n").arg(xsldbgUrl(breakUri)).arg(xmlGetLineNo(ctxt->node));
+ else
+ messageTxt = i18n("Breakpoint at text node in file \"%1\".\n").arg(xsldbgUrl(breakUri));
+ if (baseUri != NULL) {
+ xmlFree(baseUri);
+ baseUri = NULL;
+ }
+
+ if (((xslDebugStatus == DEBUG_TRACE) ||
+ (xslDebugStatus == DEBUG_WALK)) && (terminalIO != NULL))
+ fprintf(terminalIO, "%s", messageTxt.utf8().data());
+ else
+ xsldbgGenericErrorFunc(messageTxt);
+
+ }
+ }
+ if ((showWatchesActive && (xslDebugStatus == DEBUG_TRACE)) ||
+ (xslDebugStatus == DEBUG_WALK)){
+ ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
+ if (ctxt->pctxt) {
+ xslDbgShellShowWatches(styleCtxt, ctxt, 0);
+ xsldbgGenericErrorFunc("\n");
+ xmlXPathFreeContext(ctxt->pctxt);
+ ctxt->pctxt = NULL;
+ }
+ }
+
+ if (xslDebugStatus == DEBUG_TRACE) {
+ if (ctxt->filename)
+ xmlFree(ctxt->filename);
+ xmlFree(ctxt);
+ return; /* All done. Trace next instruction/node */
+ }
+ if (xslDebugStatus == DEBUG_WALK) {
+ if (xslDbgWalkContinue()) {
+ if (ctxt->filename)
+ xmlFree(ctxt->filename);
+ xmlFree(ctxt);
+ return; /* All done. Walk to next instruction/node */
+ }
+ }
+
+ ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
+ if (ctxt->pctxt == NULL) {
+ xmlFree(ctxt);
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ return;
+ }
+
+ if (showWatchesActive){
+ xslDbgShellShowWatches(styleCtxt, ctxt, 0);
+ xsldbgGenericErrorFunc("\n");
+ }
+
+ while (!exitShell && (xslDebugStatus != DEBUG_QUIT)) {
+ if (getThreadStatus() != XSLDBG_MSG_THREAD_RUN) {
+ if (ctxt->node == (xmlNodePtr) ctxt->doc)
+ snprintf((char *) prompt, DEBUG_BUFFER_SIZE - 1,
+ "(xsldbg) %s > ", "/");
+ else if ((ctxt->node->name) && (ctxt->node->ns))
+ snprintf((char *) prompt, DEBUG_BUFFER_SIZE - 1,
+ "(xsldbg) %s:%s > ", ctxt->node->ns->prefix,
+ ctxt->node->name);
+ else if (ctxt->node->name)
+ snprintf((char *) prompt, DEBUG_BUFFER_SIZE - 1,
+ "(xsldbg) %s > ", ctxt->node->name);
+
+ else
+ snprintf((char *) prompt, DEBUG_BUFFER_SIZE - 1,
+ "(xsldbg) ? > ");
+
+ prompt[sizeof(prompt) - 1] = 0;
+
+ /*
+ * Get a new command line
+ */
+ if (nextCommandActive && (xslDebugStatus == DEBUG_STEP))
+ /* we are processing the "next command" do the next
+ part of the command which is the up command */
+ cmdline = xmlStrdup((xmlChar*)"up");
+ else
+ cmdline = (xmlChar *) ctxt->input((char *) prompt);
+ if (cmdline && (optionsGetIntOption(OPTIONS_UTF8_INPUT) == 0)) {
+ /* we are getting encoded characters from the command line
+ * so decode them into UTF-8 */
+ xmlChar *tempResult = filesDecode(cmdline);
+
+ if (tempResult) {
+ xmlFree(cmdline);
+ cmdline = tempResult;
+ }
+ }
+ } else {
+ /* don't need a prompt for running as when running as a thread */
+ xmlStrCpy(messageBuffer, "");
+ if (nextCommandActive && (xslDebugStatus == DEBUG_STEP))
+ /* we are processing the "next command" do the next
+ part of the command which is the up command */
+ cmdline = xmlStrdup((xmlChar*)"up");
+ else
+ cmdline = (xmlChar *) ctxt->input((char *) messageBuffer);
+ }
+
+ if (cmdline == NULL)
+ break;
+
+ /* don't allow next command to be active more than at one breakpoint */
+ if (nextCommandActive)
+ nextCommandActive = 0;
+
+ notifyXsldbgApp(XSLDBG_MSG_PROCESSING_INPUT, NULL);
+
+ /* remove leading/trailing blanks */
+ trimString(cmdline);
+
+ /*
+ * Parse the command itself
+ */
+ cur = cmdline;
+ nbargs = 0;
+ while ((*cur == ' ') || (*cur == '\t'))
+ cur++;
+ i = 0;
+ while ((*cur != ' ') && (*cur != '\t') &&
+ (*cur != '\n') && (*cur != '\r')) {
+ if (*cur == 0)
+ break;
+ command[i++] = *cur++;
+ }
+ command[i] = 0;
+ if (i == 0)
+ continue;
+ nbargs++;
+
+ /*
+ * Parse the argument
+ */
+ while ((*cur == ' ') || (*cur == '\t'))
+ cur++;
+ i = 0;
+ while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
+ if (*cur == 0)
+ break;
+ arg[i++] = *cur++;
+ }
+ arg[i] = 0;
+ if (i != 0)
+ nbargs++;
+
+
+ commandId = lookupName(command, (xmlChar **) commandNames);
+ /* try command shorts if command is not found */
+ if (commandId < 0)
+ commandId =
+ lookupName(command, (xmlChar **) shortCommandNames);
+
+ cmdResult = -1; /* flag that it contains no result */
+ /*
+ * start interpreting the command
+ */
+ switch (commandId + DEBUG_HELP_CMD) {
+ /* --- Help related commands --- */
+ case DEBUG_HELP_CMD:
+ cmdResult = helpTop(arg);
+ if (!cmdResult)
+ xsldbgGenericErrorFunc(i18n("Unable to print local help. Online help can be found at http://xsldbg.sourceforge.net/docs/index.html.\n"));
+ break;
+
+
+ /* --- Running related commands --- */
+ case DEBUG_BYE_CMD:
+ case DEBUG_EXIT_CMD:
+ case DEBUG_QUIT_CMD:
+ /* allow the stylesheet to exit */
+ xslDebugStatus = DEBUG_QUIT;
+ exitShell++;
+ cmdResult = 1;
+ break;
+
+ case DEBUG_NEXT_CMD:
+ xslDebugStatus = DEBUG_STEP;
+ exitShell++;
+ cmdResult = 1;
+ /* Do the the next part of this command
+ which is the up command */
+ nextCommandActive = 1;
+ break;
+
+ case DEBUG_STEP_CMD:
+ xslDebugStatus = DEBUG_STEP;
+ exitShell++;
+ cmdResult = 1;
+ break;
+
+ case DEBUG_STEPUP_CMD:
+ {
+ xmlChar *noOfFrames = arg;
+
+ /* skip until next space character */
+ while (*noOfFrames && (*noOfFrames != ' ')) {
+ noOfFrames++;
+ }
+ cmdResult = xslDbgShellFrameBreak(noOfFrames, 1);
+ exitShell++;
+ }
+ break;
+
+ case DEBUG_STEPDOWN_CMD:
+ {
+ xmlChar *noOfFrames = arg;
+
+ /* skip until next space character */
+ while (*noOfFrames && (*noOfFrames != ' ')) {
+ noOfFrames++;
+ }
+ cmdResult = xslDbgShellFrameBreak(noOfFrames, 0);
+ exitShell++;
+ }
+ break;
+
+ /* continue to next break point */
+ case DEBUG_CONT_CMD:
+ xslDebugStatus = DEBUG_CONT;
+ exitShell++;
+ cmdResult = 1;
+ break;
+
+ /* restart */
+ case DEBUG_RUN_CMD:
+ xslDebugStatus = DEBUG_RUN_RESTART;
+ exitShell++;
+ cmdResult = 1;
+ break;
+
+
+ /* --- Template related commands --- */
+ case DEBUG_TEMPLATES_CMD:
+ {
+ int allFiles = 1, verbose = 1;
+
+ if (xmlStrLen(arg) && (xmlStrCmp(arg, "this") == 0)) {
+ allFiles = 0;
+ }
+
+ /* be verbose when printing template names */
+ /* if args is not empty then print names this stylesheet */
+ cmdResult =
+ xslDbgShellPrintTemplateNames(styleCtxt, ctxt, arg,
+ verbose, allFiles);
+ break;
+ }
+
+
+ case DEBUG_WHERE_CMD:
+ /* Print the current working directory as well */
+ xslDbgPrintCallStack(NULL);
+ if (getThreadStatus() != XSLDBG_MSG_THREAD_RUN) {
+ if (!xmlShellPwd(ctxt, (char *) dir, ctxt->node, NULL)){
+ xsldbgGenericErrorFunc((const char*)dir);
+ xsldbgGenericErrorFunc("\n");
+ }
+ }
+ cmdResult = 1;
+
+ break;
+
+ case DEBUG_FRAME_CMD:
+ cmdResult = xslDbgPrintCallStack(arg);
+ break;
+
+ case DEBUG_STYLESHEETS_CMD:
+ cmdResult = xslDbgShellPrintStyleSheets(arg);
+ break;
+
+ /* --- Break point related commands --- */
+ case DEBUG_BREAK_CMD:
+ if (xmlStrLen(arg)) {
+ if (styleCtxt)
+ cmdResult =
+ xslDbgShellBreak(arg, styleCtxt->style,
+ styleCtxt);
+ else
+ cmdResult = xslDbgShellBreak(arg, NULL, styleCtxt);
+ } else {
+ /* select current node to break at */
+ xmlChar buff[100];
+ xmlChar *tempBaseName = filesGetBaseUri(ctxt->node);
+ if (tempBaseName){
+ snprintf((char *) buff, sizeof(buff), "-l %s %ld",
+ tempBaseName,
+ xmlGetLineNo(ctxt->node));
+ xmlFree(tempBaseName);
+ }
+ if (styleCtxt)
+ cmdResult =
+ xslDbgShellBreak(buff, styleCtxt->style,
+ styleCtxt);
+ else
+ cmdResult =
+ xslDbgShellBreak(buff, NULL, styleCtxt);
+ }
+
+ break;
+
+ case DEBUG_SHOWBREAK_CMD:
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ notifyListStart(XSLDBG_MSG_BREAKPOINT_CHANGED);
+ walkBreakPoints((xmlHashScanner)
+ xslDbgShellPrintBreakPoint, NULL);
+ notifyListSend();
+ } else {
+ xsldbgGenericErrorFunc("\n");
+ printCount = 0; /* printCount will get updated by
+ * xslDbgShellPrintBreakPoint */
+
+ walkBreakPoints((xmlHashScanner)
+ xslDbgShellPrintBreakPoint, NULL);
+ if (printCount == 0)
+ xsldbgGenericErrorFunc(i18n("\nNo breakpoints are set for the file.\n"));
+ else
+ xsldbgGenericErrorFunc(i18n("\tTotal of %n breakpoint present.","\tTotal of %n breakpoints present.", printCount) + QString("\n"));
+ }
+ cmdResult = 1;
+ break;
+
+ case DEBUG_DELETE_CMD:
+ if (xmlStrLen(arg))
+ cmdResult = xslDbgShellDelete((xmlChar *) arg);
+ else {
+ breakPointPtr breakPtr = NULL;
+ xmlChar* tempBaseName = filesGetBaseUri(ctxt->node);
+
+ if (tempBaseName){
+ breakPtr =
+ breakPointGet(tempBaseName,
+ xmlGetLineNo(ctxt->node));
+ xmlFree(tempBaseName);
+ }
+ if (!breakPtr || !breakPointDelete(breakPtr)) {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to delete breakpoint.\n"));
+ cmdResult = 0;
+ }
+ }
+ break;
+
+ case DEBUG_ENABLE_CMD:
+ if (xmlStrLen(arg))
+ cmdResult =
+ xslDbgShellEnable(arg, XSL_TOGGLE_BREAKPOINT);
+ else {
+ breakPointPtr breakPtr = NULL;
+ xmlChar * tempBaseName = filesGetBaseUri(ctxt->node);
+
+ if (tempBaseName){
+ breakPtr =
+ breakPointGet(tempBaseName,
+ xmlGetLineNo(ctxt->node));
+ xmlFree(tempBaseName);
+ }
+ if (!breakPtr ||
+ (!breakPointEnable(breakPtr, !(breakPtr->flags & BREAKPOINT_ENABLED)))) {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to enable/disable breakpoint.\n"));
+ cmdResult = 0;
+ }
+ }
+ break;
+
+ case DEBUG_DISABLE_CMD:
+ if (xmlStrLen(arg))
+ cmdResult = xslDbgShellEnable(arg, 0);
+ else {
+ breakPointPtr breakPtr = NULL;
+ xmlChar *tempBaseName = filesGetBaseUri(ctxt->node);
+
+ if (tempBaseName){
+ breakPtr =
+ breakPointGet(tempBaseName,
+ xmlGetLineNo(ctxt->node));
+ xmlFree(tempBaseName);
+ }
+ if (!breakPtr || !breakPointEnable(breakPtr, 0)) {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to enable/disable breakpoint.\n"));
+ cmdResult = 0;
+ }
+ }
+ break;
+
+
+
+ /* --- Node view related commands --- */
+ case DEBUG_LS_CMD:
+ cmdResult = xslDbgShellPrintList(ctxt, arg, 0);
+ break;
+
+ case DEBUG_DIR_CMD:
+ cmdResult = xslDbgShellPrintList(ctxt, arg, 1);
+ break;
+
+ case DEBUG_DU_CMD:
+ xmlShellDu(ctxt, NULL, ctxt->node, NULL);
+ cmdResult = 1;
+ break;
+
+ case DEBUG_CAT_CMD:
+ case DEBUG_PRINT_CMD:
+ cmdResult = xslDbgShellCat(styleCtxt, ctxt, arg);
+ break;
+
+ case DEBUG_PWD_CMD:
+ if (!xmlShellPwd(ctxt, (char *) dir, ctxt->node, NULL)) {
+ xmlChar* tempBaseName = filesGetBaseUri(ctxt->node);
+ if(tempBaseName){
+ xsldbgGenericErrorFunc("\n");
+ xsldbgGenericErrorFunc((char*)dir);
+ xsldbgGenericErrorFunc(i18n(" in file \"%1\" at line %2").arg(xsldbgUrl(tempBaseName)).arg(xmlGetLineNo(ctxt->node)));
+ xmlFree(tempBaseName);
+ cmdResult = 1;
+ }
+ }
+ if (cmdResult)
+ xsldbgGenericErrorFunc("\n");
+ else
+ xsldbgGenericErrorFunc(i18n("Error: Unable to print working directory.\n"));
+ break;
+
+ case DEBUG_DUMP_CMD:
+ xmlDebugDumpDocument(stdout, ctxt->doc);
+ cmdResult = 1;
+ break;
+
+ case DEBUG_BASE_CMD:
+ xmlShellBase(ctxt, NULL, ctxt->node, NULL);
+ cmdResult = 1;
+ break;
+
+
+ /* --- Variable related commands --- */
+ case DEBUG_GLOBALS_CMD:
+ if (loadedFiles == 0)
+ cmdResult = xslDbgShellPrintVariable(styleCtxt, arg,
+ DEBUG_GLOBAL_VAR);
+ else {
+ xsldbgGenericErrorFunc(i18n("Error: Need to use the run command first.\n"));
+ cmdResult = 0;
+ }
+ break;
+
+ case DEBUG_LOCALS_CMD:
+ if (loadedFiles == 0)
+ /* if gdb compatability mode is enable print the globals then
+ * the locals */
+ if (optionsGetIntOption(OPTIONS_GDB) == 1) {
+ cmdResult =
+ xslDbgShellPrintVariable(styleCtxt, arg,
+ DEBUG_GLOBAL_VAR);
+ if (cmdResult == 1)
+ cmdResult =
+ xslDbgShellPrintVariable(styleCtxt, arg,
+ DEBUG_LOCAL_VAR);
+ } else
+ cmdResult =
+ xslDbgShellPrintVariable(styleCtxt, arg,
+ DEBUG_LOCAL_VAR);
+ else {
+ xsldbgGenericErrorFunc(i18n("Error: Need to use the run command first.\n"));
+ cmdResult = 0;
+ }
+ break;
+
+
+ /* It's difficult to put the following commands into
+ * a separe file so they stay here! */
+ /* --- Node selection related commands --- */
+ case DEBUG_SOURCE_CMD:
+ cmdResult = 1; /* only one case where this will command fail */
+ xsldbgValidateBreakpoints = BREAKPOINTS_NEED_VALIDATION;
+ if (xmlStrLen(arg) == 0) {
+ if (ctxt->doc == doc->doc)
+ lastDocNode = ctxt->node;
+ ctxt->doc = source->doc;
+ ctxt->node = lastSourceNode;
+ if (ctxt->pctxt)
+ xmlXPathFreeContext(ctxt->pctxt);
+ ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
+ showSource = 1;
+ xsldbgUpdateFileDetails((xmlNodePtr) ctxt->node);
+ /* let any listener know that we got to a new line */
+ notifyXsldbgApp(XSLDBG_MSG_LINE_CHANGED, NULL);
+ if (ctxt->pctxt == NULL) {
+ xmlFree(ctxt);
+ xslDebugStatus = DEBUG_QUIT;
+ return;
+ } else
+ break;
+ } else {
+ /* load new stylesheet file, actual loading happens later */
+ xmlChar *expandedName = filesExpandName(arg);
+
+ if (expandedName) {
+ xsldbgGenericErrorFunc(i18n("Load of source deferred. Use the run command.\n"));
+
+ optionsSetStringOption(OPTIONS_SOURCE_FILE_NAME,
+ expandedName);
+ notifyXsldbgApp(XSLDBG_MSG_FILE_CHANGED, 0L);
+ loadedFiles = 1;
+ xmlFree(expandedName);
+ cmdResult = 1;
+ } else {
+ cmdResult = 0;
+ }
+ }
+ break;
+
+ case DEBUG_DATA_CMD:
+ cmdResult = 1; /* only one case where this will command fail */
+ xsldbgValidateBreakpoints = BREAKPOINTS_NEED_VALIDATION;
+ if (xmlStrLen(arg) == 0) {
+ if (ctxt->doc == source->doc)
+ lastSourceNode = ctxt->node;
+ ctxt->doc = doc->doc;
+ ctxt->node = lastDocNode;
+ if (ctxt->pctxt)
+ xmlXPathFreeContext(ctxt->pctxt);
+ ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
+ showSource = 0;
+ xsldbgUpdateFileDetails((xmlNodePtr) ctxt->node);
+ /* let any listener know that we got to a new line */
+ notifyXsldbgApp(XSLDBG_MSG_LINE_CHANGED, NULL);
+ if (ctxt->pctxt == NULL) {
+ xmlFree(ctxt);
+ xslDebugStatus = DEBUG_QUIT;
+ return;
+ } else
+ break;
+ } else {
+ /* load new xml file actual loading hapens later */
+ xmlChar *expandedName = filesExpandName(arg);
+
+ if (expandedName) {
+ xsldbgGenericErrorFunc(i18n("Load of data file deferred. Use the run command.\n"));
+
+ optionsSetStringOption(OPTIONS_DATA_FILE_NAME,
+ expandedName);
+ notifyXsldbgApp(XSLDBG_MSG_FILE_CHANGED, 0L);
+ loadedFiles = 1;
+ xmlFree(expandedName);
+ cmdResult = 1;
+ } else {
+ cmdResult = 0;
+ }
+ }
+ break;
+
+ case DEBUG_OUTPUT_CMD:
+ /* set the output file name to use */
+ cmdResult = xslDbgShellOutput(arg);
+ break;
+
+ case DEBUG_CD_CMD:
+ /* use dir as a working buffer */
+ xmlStrnCpy(dir, arg, 2);
+ dir[2] = '\0';
+ shortCutId = lookupName(dir, (xmlChar **) cdShortCuts);
+ if (shortCutId >= 0) {
+ if (xmlStrLen(arg) == 2) {
+ cmdResult = xslDbgCd(styleCtxt, ctxt, (xmlChar *)
+ cdAlternative[shortCutId],
+ source);
+ } else {
+
+ xmlStrCpy(dir, cdAlternative[shortCutId]);
+ xmlStrCat(dir, &arg[2]);
+ cmdResult = xslDbgCd(styleCtxt, ctxt, dir, source);
+ }
+
+ } else
+ cmdResult = xslDbgCd(styleCtxt, ctxt, arg, source);
+ break;
+
+
+ /* --- File related commands --- */
+ case DEBUG_ENTITIES_CMD:
+ cmdResult = xslDbgEntities();
+ break;
+
+ case DEBUG_SYSTEM_CMD:
+ /* strip off a single argument. I need to do it this
+ way because I've already public this API */
+ {
+ xmlChar *systemID;
+ if (splitString(arg, 1, &systemID) == 1){
+ cmdResult = xslDbgSystem(systemID);
+ }else{
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("system"));
+ }
+ }
+ break;
+
+ case DEBUG_PUBLIC_CMD:
+ /* strip off a single argument. I need to do it this
+ way because I've already public this API */
+ {
+ xmlChar *publicID;
+ if (splitString(arg, 1, &publicID) == 1){
+ cmdResult = xslDbgPublic(publicID);
+ }else{
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("public"));
+ }
+ }
+ break;
+
+ case DEBUG_ENCODING_CMD:
+ cmdResult = xslDbgEncoding(arg);
+ break;
+
+ case DEBUG_VALIDATE_CMD:
+ xsldbgGenericErrorFunc(i18n("Warning: The %1 command is disabled.\n").arg("validate"));
+ cmdResult = 0;
+ /*
+ * xmlShellValidate(ctxt, arg, NULL, NULL);
+ */
+ break;
+
+ case DEBUG_LOAD_CMD:
+ cmdResult = optionsLoad();
+ /* restart xsldbg and activate new configuration */
+ if (cmdResult == 1) {
+ xslDebugStatus = DEBUG_RUN_RESTART;
+ exitShell++;
+ }
+ break;
+
+ case DEBUG_SAVE_CMD:
+ cmdResult = optionsSave();
+ break;
+
+ case DEBUG_WRITE_CMD:
+ xsldbgGenericErrorFunc(i18n("Warning: The %1 command is disabled.\n").arg("write"));
+ cmdResult = 0;
+ /*
+ * xmlShellWrite(ctxt, arg, NULL, NULL);
+ */
+ break;
+
+ case DEBUG_FREE_CMD:
+ xsldbgGenericErrorFunc(i18n("Warning: The %1 command is disabled.\n").arg("free"));
+ cmdResult = 0;
+ /*
+ * if (arg[0] == 0) {
+ * xmlMemShow(stdout, 0);
+ * } else {
+ * int len = 0;
+ * sscanf(arg, "%d", &len);
+ * xmlMemShow(stdout, len);
+ * }
+ */
+ break;
+
+
+ /* operating system related */
+ case DEBUG_CHDIR_CMD:
+ cmdResult = xslDbgShellChangeWd(arg);
+ break;
+
+ case DEBUG_SHELL_EXEC_CMD:
+ cmdResult = xslDbgShellExecute(arg, 1);
+ break;
+
+
+ /* libxslt parameter related commands */
+ case DEBUG_ADDPARAM_CMD:
+ cmdResult = xslDbgShellAddParam(arg);
+ break;
+
+ case DEBUG_DELPARAM_CMD:
+ cmdResult = xslDbgShellDelParam(arg);
+ break;
+
+ case DEBUG_SHOWPARAM_CMD:
+ cmdResult = xslDbgShellShowParam(arg);
+ break;
+
+
+
+ /* option related commmands */
+ case DEBUG_SETOPTION_CMD:
+ cmdResult = xslDbgShellSetOption(arg);
+ break;
+
+ case DEBUG_OPTIONS_CMD:
+ cmdResult = xslDbgShellOptions();
+ break;
+
+
+
+ /* misc commands */
+ case DEBUG_TTY_CMD:
+ if (openTerminal(arg)) {
+ /* gdb does to say anything after redirecting its
+ output */
+ if (optionsGetIntOption(OPTIONS_GDB) < 2)
+ xsldbgGenericErrorFunc(i18n("Opening terminal %1.\n").arg(xsldbgText(arg)));
+ cmdResult = 1;
+ } else
+ cmdResult = 0;
+ break;
+
+
+ /* language selection for messages */
+ case DEBUG_LANG_CMD:
+#ifdef LOCALE_PREFIX
+ if (xmlStrlen(arg) > 0){
+ setlocale(LC_MESSAGES, (char*)arg);
+ textdomain("kdewebdev/xsldsbg");
+ bindtextdomain("kdewebdev/xsldbg", LOCALE_PREFIX);
+ cmdResult = 1;
+ }else{
+ xsldbgGenericErrorFunc(i18n("Error: Missing arguments for the command %1.\n").arg("lang"));
+ cmdResult = 0;
+ }
+#else
+ xsldbgGenericErrorFunc(i18n("Warning: The %1 command is disabled\n").arg("lang"));
+ cmdResult = 1;
+#endif
+ break;
+
+ /* tracing related commands */
+ case DEBUG_TRACE_CMD:
+ if (xslDbgShellTrace(arg)) {
+ exitShell++;
+ cmdResult = 1;
+ } else
+ cmdResult = 0;
+
+ break;
+
+ case DEBUG_WALK_CMD:
+ if (xslDbgShellWalk(arg)) {
+ exitShell++;
+ cmdResult = 1;
+ } else
+ cmdResult = 0;
+ break;
+
+ case DEBUG_ADDWATCH_CMD:
+ cmdResult = xslDbgShellAddWatch(arg);
+ break;
+
+ case DEBUG_DELWATCH_CMD:
+ cmdResult = xslDbgShellDeleteWatch(arg);
+ break;
+
+ case DEBUG_SHOWWATCH_CMD:
+ trimString(arg);
+ switch (arg[0]){
+ case '\0':
+ cmdResult = xslDbgShellShowWatches(styleCtxt, ctxt, 1);
+ break;
+
+ case '0':
+ case '1':
+ showWatchesActive = arg[0] - '0';
+ cmdResult = 1;
+ break;
+
+ default:
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("showmatch"));
+ }
+ break;
+
+
+ /* search related commands */
+ case DEBUG_SEARCH_CMD:
+ cmdResult =
+ xslDbgShellSearch(styleCtxt, filesGetStylesheet(),
+ arg);
+ break;
+
+
+
+ case DEBUG_SET_CMD:
+ cmdResult = xslDbgShellSetVariable(styleCtxt, arg);
+ break;
+
+ default:
+ xsldbgGenericErrorFunc(i18n("Error: Unknown command %1. Try help.\n").arg(xsldbgText(command)));
+ cmdResult = 0;
+ }
+
+ /* KDbg likes to get the marker after every command so here it is */
+ if ((optionsGetIntOption(OPTIONS_GDB) >1) && optionsGetIntOption(OPTIONS_VERBOSE) && !nextCommandActive
+ && (commandId != DEBUG_STEPUP_CMD - DEBUG_HELP_CMD)) {
+ if (ctxt->node && ctxt->node &&
+ ctxt->node->doc && ctxt->node->doc->URL) {
+
+ if (xmlGetLineNo(ctxt->node) != -1)
+ xsldbgGenericErrorFunc(i18n("Breakpoint for file \"%1\" at line %2.\n").arg(xsldbgUrl(ctxt->node->doc->URL)).arg(xmlGetLineNo(ctxt->node)));
+ else
+ xsldbgGenericErrorFunc(i18n("Breakpoint at text node in file \"%1\".\n").arg(xsldbgUrl(ctxt->node->doc->URL)));
+ }
+ }
+
+ /* notify any listeners of that the command failed */
+ if (cmdResult == 0 && (xmlStrlen(messageBuffer) > 0)) {
+ snprintf((char *) messageBuffer, sizeof(messageBuffer),
+ "\nRequest to xsldbg failed:%s\n", cmdline);
+ notifyTextXsldbgApp(XSLDBG_MSG_TEXTOUT,
+ (char *) messageBuffer);
+ }
+
+ xmlFree(cmdline);
+ cmdline = NULL;
+ }
+
+ xmlXPathFreeContext(ctxt->pctxt);
+
+ if (ctxt->filename)
+ xmlFree(ctxt->filename);
+
+ xmlFree(ctxt);
+
+ if (cmdline)
+ xmlFree(cmdline);
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/debugXSL.h b/kxsldbg/kxsldbgpart/libxsldbg/debugXSL.h
new file mode 100644
index 00000000..df50a53b
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/debugXSL.h
@@ -0,0 +1,1078 @@
+
+/**************************************************************************
+ debugXSL.h - describes the core xsldbg shell functions
+ -------------------
+ begin : Sun Sep 16 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. *
+ * *
+ **************************************************************************/
+
+/*
+ * Orinal file : debugXML.h : This is a set of routines used for
+ * debugging the tree produced by the XML parser.
+ *
+ * New file : debugXSL.h : Debug support version
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <daniel@veillard.com>
+ *
+ * Permission abtained to modify the LGPL'd code and extend to include
+ * break points, inspections of stylesheet source, xml data, stylesheet
+ * variables Keith Isdale <k_isdale@tpg.com.au>
+ */
+
+#ifndef __DEBUG_XSL__
+#define __DEBUG_XSL__
+
+#ifdef USE_XSLDBG_AS_THREAD
+#include "xsldbgmsg.h"
+#include "xsldbgthread.h"
+#endif
+
+/* We want skip most of these includes when building documentation*/
+#ifndef BUILD_DOCS
+#include "utils.h"
+#include "breakpoint.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DEBUG_BUFFER_SIZE 500 /*used by xslDbgShell */
+
+/* how may items have been printed */
+ extern int printCount;
+
+ /* used to indicated that xsldbg should stop tracing/walking
+ value : 1 stop tracing at start of next cycle
+ value : 0 normal operation
+ */
+
+ extern int xsldbgStop;
+ extern int xsldbgValidateBreakpoints;
+ /* Some versions of libxml/libxslt need a different type of
+ line numbers handling */
+ extern int xsldbgHasLineNumberFix;
+ extern bool xsldbgReachedFirstTemplate;
+
+/****************************************************************
+ * *
+ * The XSL shell related structures and functions *
+ * *
+ ****************************************************************/
+
+/*
+ Note that functions that have a prefix of xslDbgShell are NOT implemented
+ in debugXSL.c unless stated
+
+ All functions with the prefix of debygXSL are implemented in debugXSL.c
+
+ */
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * debugXSLBreak:
+ * @templ: The source node being executed
+ * @node: The data node being processed
+ * @root: The template being applied to "node"
+ * @ctxt: The transform context for stylesheet being processed
+ *
+ * A break point has been found so pass control to user
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * A break point has been found so pass control to user
+ *
+ * @param templ The source node being executed
+ * @param node The data node being processed
+ * @param root The template being applied to "node"
+ * @param ctxt transform context for stylesheet being processed
+ */
+#endif
+#endif
+ void debugXSLBreak(xmlNodePtr templ, xmlNodePtr node,
+ xsltTemplatePtr root, xsltTransformContextPtr ctxt);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * debugXSLGetTemplate:
+ *
+ * Get the last template node found, if any
+ *
+ * Returns The last template node found, if any
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Get the last template node found, if any
+ *
+ * @returns the last template node found, if any
+ */
+#endif
+#endif
+ xsltTemplatePtr debugXSLGetTemplate(void);
+
+
+
+/* -----------------------------------------
+ Break Point related commands
+
+ They are implemented in breakpoint_cmds.c
+ ------------------------------------------- */
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * 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
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Set a "frame" break point either up or down from here
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param arg Is valid and in UTF-8
+ * @param stepup If != 1 then we step up, otherwise step down
+ */
+#endif
+#endif
+ int xslDbgShellFrameBreak(xmlChar * arg, int stepup);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * 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
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Add break point specified by arg
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param arg Is valid and in UTF-8
+ * @param style Is valid
+ * @param ctxt Is valid
+ */
+#endif
+#endif
+ int xslDbgShellBreak(xmlChar * arg, xsltStylesheetPtr style,
+ xsltTransformContextPtr ctxt);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellDelete:
+ * @arg: Is valid and in UTF-8
+ *
+ * Delete break point specified by arg
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Delete break point specified by arg
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param arg Is valid and in UTF-8
+ */
+#endif
+#endif
+ int xslDbgShellDelete(xmlChar * arg);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellEnableBreakPoint:
+ * @payload: A valid xslBreakPointPtr
+ * @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
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Enable/disable break points via use of scan of break points
+ *
+ * @param payload Is valid xslBreakPointPtr
+ * @param data Enable type, a pointer to an integer
+ * for a value of
+ * @li 1 enable break point
+ * @li 0 disable break point
+ * @li -1 toggle enabling of break point
+ * @param name Not used
+*/
+#endif
+#endif
+ void xslDbgShellEnableBreakPoint(void *payload, void *data,
+ xmlChar * name);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellEnable:
+ * @arg : is valid enable "commmand text" 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
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Enable/disable break point specified by arg using enable
+ *
+ * @param arg: is valid enable "commmand text" and in UTF-8
+ * @param enableType : enable break point if 1, disable if 0, toggle if -1
+ *
+ * @returns 1 if successful,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int xslDbgShellEnable(xmlChar * arg, int enableType);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellPrintBreakPoint:
+ * @payload: A valid xslBreakPointPtr
+ * @data: Not used
+ * @name: Not used
+ *
+ * Print data given by scan of break points
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Print data given by scan of break points
+ *
+ * @param payload Is valid xslBreakPointPtr
+ * @param data Not used
+ * @param name Not used
+*/
+#endif
+#endif
+ void xslDbgShellPrintBreakPoint(void *payload, void *data,
+ xmlChar * name);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellValidateBreakPoint:
+ * @payload: A valid xslBreakPointPtr
+ * @data: Not used
+ * @name: Not used
+ *
+ * Print an warning if a breakpoint is invalid
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Print an warning if a breakpoint is invalid
+ *
+ * @param payload Is valid xslBreakPointPtr
+ * @param data Not used
+ * @param name Not used
+*/
+#endif
+#endif
+ void xslDbgShellValidateBreakPoint(void *payload, void *data,
+ xmlChar * name);
+
+
+/* -----------------------------------------
+ Template related commands
+
+ They are implemented in template_cmds.c
+ ------------------------------------------- */
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellPrintStyleSheets:
+ * @arg: The stylesheets of interests and in UTF-8, is NULL for all stylesheets
+ *
+ * Print stylesheets that can be found in loaded stylsheet
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Print stylesheets that can be found in loaded stylsheet
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param arg The stylesheets of interests and in UTF-8, is NULL for all stylesheets
+ *
+ */
+#endif
+#endif
+ int xslDbgShellPrintStyleSheets(xmlChar * arg);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellPrintTemplateNames:
+ * @styleCtxt: Is valid
+ * @ctxt: Not used
+ * @arg: Not used
+ * @verbose: If 1 then print extra messages about templates found,
+ * otherwise print normal messages only
+ * @allFiles: If 1 then look for all templates in stylsheets found in
+ * @styleCtxt
+ * otherwise look in the stylesheet found by
+ * debugXSLBreak function
+ *
+ * Print out the list of template names found that match critieria
+*
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Print out the list of template names found that match critieria
+ *
+ * @param styleCtxt Is valid
+ * @param ctxt Not used
+ * @param arg Not used
+ * @param verbose If 1 then print extra messages about templates found,
+ * otherwise print normal messages only
+ * @param allFiles If 1 then look for all templates in stylsheets found in
+ * @p styleCtxt
+ * otherwise look in the stylesheet found by
+ * debugXSLBreak function
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int xslDbgShellPrintTemplateNames(xsltTransformContextPtr styleCtxt,
+ xmlShellCtxtPtr ctxt,
+ xmlChar * arg, int verbose,
+ int allFiles);
+
+
+
+
+/* -----------------------------------------
+
+ Node viewing related commands
+
+ ------------------------------------------- */
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellPrintList:
+ * @ctxt: The current shell context
+ * @arg: What xpath to display and in UTF-8
+ * @dir: If 1 print in dir mode?,
+ * otherwise ls mode
+ *
+ * Print list of nodes in either ls or dir format
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Print list of nodes in either ls or dir format
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param ctxt The current shell context
+ * @param arg What xpath to display and in UTF-8
+ * @param dir If 1 print in dir mode,
+ * otherwise ls mode
+ */
+#endif
+#endif
+ int xslDbgShellPrintList(xmlShellCtxtPtr ctxt, xmlChar * arg, int dir);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellCat:
+ * @styleCtxt: the current stylesheet context
+ * @ctxt: The current shell context
+ * @arg: The xpath to print and in UTF-8
+ *
+ * Print the result of an xpath expression. This can include variables
+ * if styleCtxt is not NULL
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Print the result of an xpath expression. This can include variables
+ * if styleCtxt is not NULL
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param styleCtxt Current stylesheet context
+ * @param ctxt Current shell context
+ * @param arg The xpath to print and in UTF-8
+ */
+#endif
+#endif
+ int xslDbgShellCat(xsltTransformContextPtr styleCtxt,
+ xmlShellCtxtPtr ctxt, xmlChar * arg);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellPrintVariable:
+ * @styleCtxt: The current stylesheet context
+ * @arg: The name of variable to look for '$' prefix is optional and in UTF-8
+ * @type: A valid VariableTypeEnum
+ *
+ * Print the value variable specified by args.
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Print the value variable specified by args.
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+
+ *
+ * @param styleCtxt The current stylesheet context
+ * @param arg The name of variable to look for '$' prefix is optional and in UTF-8
+ * @param type Is valid VariableTypeEnum
+ */
+#endif
+#endif
+ int xslDbgShellPrintVariable(xsltTransformContextPtr styleCtxt,
+ xmlChar * arg, VariableTypeEnum type);
+
+
+/* -----------------------------------------
+
+ File related command
+
+ Implemented in file_cmds.c
+ ------------------------------------------- */
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellOutput:
+ * @arg : Is valid, either a local file name which will be expanded
+ * if needed, or a "file://" protocol URI
+ *
+ * Set the output file name to use
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * xslDbgShellOutput:
+ * @arg : Is valid, either a local file name which will be expanded
+ * if needed, or a "file://" protocol URI
+ *
+ * Set the output file name to use
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int xslDbgShellOutput(const xmlChar *arg);
+
+
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * xslDbgEntities:
+ *
+ * Print list of entites found
+ *
+ * Returns 1 on sucess,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+#endif
+#endif
+ int xslDbgEntities(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * xslDbgSystem:
+ * @arg : Is valid in UTF-8
+ *
+ * Print what a system file @arg maps to via the current xml catalog
+ *
+ * Returns 1 on sucess,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Print what a system file @p arg maps to via the current xml catalog
+ *
+ * @param arg Is valid in UTF-8
+ *
+ * @returns 1 on sucess,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int xslDbgSystem(const xmlChar * arg);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * xslDbgPublic:
+ * @arg : Is valid PublicID in UTF-8
+ *
+ * Print what a public ID @arg maps to via the current xml catalog
+ *
+ * Returns 1 on sucess,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Print what a public ID @p arg maps to via the current xml catalog
+ *
+ * @param arg Is valid PublicID in UTF-8
+ *
+ * @returns 1 on sucess,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int xslDbgPublic(const xmlChar * arg);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * xslDbgEncoding:
+ * @arg: Is valid encoding supported by libxml2
+ *
+ * Set current encoding to use for output to standard output
+ *
+ * Returns 1 on sucess,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Set current encoding to use for output to standard output
+ *
+ * @param arg Is valid encoding supported by libxml2
+ *
+ *
+ * Returns 1 on sucess,
+ */
+#endif
+#endif
+ int xslDbgEncoding(xmlChar * arg);
+
+/* -----------------------------------------
+
+ Operating system related commands
+
+ Implemented in os_cmds.c
+ ------------------------------------------- */
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellChangeWd:
+ * @path: The path to change to and in UTF-8
+ *
+ * Change the current working directory of the operating system
+ *
+ * Returns 1 if able to change xsldbg's working directory to @path
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * @returns 1 if able to change xsldbg working direcorty to @p path
+ * 0 otherwise
+ *
+ * @param path Operating system path(directory) to change to and in UTF-8
+ */
+#endif
+#endif
+ int xslDbgShellChangeWd(xmlChar * path);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellExecute:
+ * @name: The name of command string to be executed by operating system shell
+ * @verbose: If 1 then print extra debugging messages,
+ * normal messages otherwise
+ *
+ * Execute an operating system command
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * @returns 1 if able to execute command @p name,
+ * 0 otherwise
+ *
+ * @param name The name of command string to be executed
+ * by operating system shell
+ * @param verbose If 1 then print extra debugging messages,
+ * normal messages otherwise
+ */
+#endif
+#endif
+ int xslDbgShellExecute(xmlChar * name, int verbose);
+
+
+
+
+/* -----------------------------------------
+
+ libxslt parameter related commands
+
+ Implemented in param_cmds.c
+ ------------------------------------------- */
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellAddParam:
+ * @arg: A string comprised of two words separated by
+ * one or more spaces which are in UTF-8.
+ *
+ * Add a libxslt parameter to be sent to libxslt later on
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/*
+ * Add a parameter to be sent to libxslt later on
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param arg A string comprised of two words separated by
+ * one or more spaces which are in UTF-8
+ */
+#endif
+#endif
+ int xslDbgShellAddParam(xmlChar * arg);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellDelParam:
+ * @arg: A single white space trimmed parameter number to look for
+ *
+ * Delete a libxslt parameter that was to be sent to libxslt later on
+ *
+ * Returns 1 if able to delete parameter @name,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Delete a libxslt parameter that was to be sent to libxslt later on
+ *
+ * @returns 1 if able to delete parameter @p name,
+ * 0 otherwise
+ *
+ * @param arg A single white space trimmed libxslt parameter number to look for
+ */
+#endif
+#endif
+ int xslDbgShellDelParam(xmlChar * arg);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellShowParam:
+ * @arg: Not used
+ *
+ * Print list of current paramters
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Print list of current paramters
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param arg Not used
+ */
+#endif
+#endif
+ int xslDbgShellShowParam(xmlChar * arg);
+
+
+ /* -----------------------------------------
+ *
+ * Option related commands
+ *
+ * Implemented in option_cmds.c
+ *
+ * ------------------------------------------- */
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellSetOption:
+ * @arg: Is valid, and in the format <NAME> <VALUE>
+ *
+ * Set the value of an option
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Set the value of an option
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param arg is valid, and in format <NAME> <VALUE>
+ *
+ */
+#endif
+#endif
+ int xslDbgShellSetOption(xmlChar * arg);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellOptions:
+ *
+ * Prints out values for user options
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Prints out values for user options
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int xslDbgShellOptions(void);
+
+
+ /**
+ * xslDbgShellShowWatches:
+ * @styleCtxt: the current stylesheet context
+ * @ctxt: The current shell context
+ * @showWarnings : If 1 then showWarning messages,
+ * otherwise do not show warning messages
+ *
+ * Print the current watches and their values
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+ int xslDbgShellShowWatches(xsltTransformContextPtr styleCtxt,
+ xmlShellCtxtPtr ctx,int showWarnings);
+
+ /**
+ * xslDbgShellAddWatch:
+ * @arg : A valid xPath of expression to watch the value of
+ *
+ * Add expression to list of expressions to watch value of
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+ int xslDbgShellAddWatch(xmlChar* arg);
+
+ /**
+ * xslDbgShellDeleteWatch:
+ * @arg : A watch ID to remove
+ *
+ * Delete a given watch ID from our list of expressions to watch
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+ int xslDbgShellDeleteWatch(xmlChar* arg);
+
+
+ /* -----------------------------------------
+ *
+ * Tracing, walking related commands
+ *
+ * Implemented in shell.c
+ *
+ * ------------------------------------------- */
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellTrace:
+ * @arg: Not used
+ *
+ * Start the tracing of the stylesheet. First need to restart it.
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Start the tracing of the stylesheet. First need to restart it.
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param arg Not used
+ */
+#endif
+#endif
+ int xslDbgShellTrace(xmlChar * arg);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellWalk:
+ * @arg: An interger between 0 and 9 indicate the speed of walk
+ *
+ * Start walking through the stylesheet.
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Start walking through the stylesheet.
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param arg An interger between 0 and 9 indicate the speed of walk
+ */
+#endif
+#endif
+ int xslDbgShellWalk(xmlChar * arg);
+
+
+
+ /* -----------------------------------------
+ *
+ * Seach related commands
+ *
+ * Implemented in search_cmds.c
+ * ------------------------------------------- */
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellSearch:
+ * @styleCtxt: Is valid
+ * @style: Is valid
+ * @arg: The xpath query to use for searching dataBase
+ *
+ * Displays the result of performing a query on the search dataBase
+ *
+ * Returns 1 if able to run query with @arg,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * @returns 1 if able to run query with @p arg,
+ * 0 otherwise
+ *
+ * @param styleCtxt Is valid
+ * @param style Is valid
+ * @param arg The xpath query to use for searching dataBase
+ */
+#endif
+#endif
+ int xslDbgShellSearch(xsltTransformContextPtr styleCtxt,
+ xsltStylesheetPtr style, xmlChar * arg);
+
+
+/* -----------------------------------------
+
+ Seach related commands
+
+ Implemented in variable_cmds.c
+ ------------------------------------------- */
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xslDbgShellSetVariable:
+ * @styleCtxt : Is valid
+ * @arg : Is valid must be in the format of
+ * <VARIABLE_NAME> <XPATH>
+ *
+ * Change the value of a global or local variable
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Change the value of a global or local variable
+ *
+ * @param styleCtxt Is valid
+ * @param arg Is valid must be in the format of
+ * <VARIABLE_NAME> <XPATH>
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+#endif
+#endif
+
+ int xslDbgShellSetVariable(xsltTransformContextPtr styleCtxt,
+ xmlChar * arg);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+ /* __DEBUG_XSL__ */
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/file_cmds.cpp b/kxsldbg/kxsldbgpart/libxsldbg/file_cmds.cpp
new file mode 100644
index 00000000..083b33b2
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/file_cmds.cpp
@@ -0,0 +1,274 @@
+
+/***************************************************************************
+ file_cmds.c - define file command related functions
+ -------------------
+ begin : Sat Jan 19 2002
+ copyright : (C) 2002 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 <stdio.h>
+#include <libxml/tree.h>
+#include <libxml/catalog.h>
+
+#include "xsldbg.h"
+#include "debugXSL.h"
+#include "files.h"
+#include "options.h"
+#include "utils.h"
+#include "xsldbgthread.h"
+
+static char buffer[500];
+
+/**
+ * xslDbgEntities:
+ *
+ * Print list of entites found
+ *
+ * Returns 1 on sucess,
+ * 0 otherwise
+ */
+int
+xslDbgEntities(void)
+{
+ int result = 0;
+
+ if (filesEntityList()) {
+ int entityIndex;
+ entityInfoPtr entInfo;
+
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ /* notify that we are starting new list of entity names */
+ notifyListStart(XSLDBG_MSG_ENTITIY_CHANGED);
+ for (entityIndex = 0;
+ entityIndex < arrayListCount(filesEntityList());
+ entityIndex++) {
+ entInfo = (entityInfoPtr) arrayListGet(filesEntityList(),
+ entityIndex);
+ if (entInfo)
+ notifyListQueue(entInfo);
+
+ }
+ notifyListSend();
+ result = 1;
+ } else {
+ for (entityIndex = 0;
+ entityIndex < arrayListCount(filesEntityList());
+ entityIndex++) {
+ entInfo = (entityInfoPtr) arrayListGet(filesEntityList(),
+ entityIndex);
+ if (entInfo) {
+ /* display identifier of an XML entity */
+ xsldbgGenericErrorFunc(i18n("Entity %1 ").arg(xsldbgText(entInfo->SystemID)));
+ if (entInfo->PublicID)
+ xsldbgGenericErrorFunc(xsldbgText(entInfo->PublicID));
+ xsldbgGenericErrorFunc("\n");
+ }
+ }
+ if (arrayListCount(filesEntityList()) == 0) {
+ xsldbgGenericErrorFunc(i18n("No external General Parsed entities present.\n"));
+ } else {
+ xsldbgGenericErrorFunc(i18n("\tTotal of %n entity found.", "\tTotal of %n entities found.", arrayListCount(filesEntityList())) + QString("\n"));
+ }
+
+ result = 1;
+ }
+ }
+ return result;
+}
+
+
+/**
+ * xslDbgSystem:
+ * @arg : Is valid
+ *
+ * Print what a system file @arg maps to via the current xml catalog
+ *
+ * Returns 1 on sucess,
+ * 0 otherwise
+ */
+int
+xslDbgSystem(const xmlChar * arg)
+{
+ int result = 0;
+ xmlChar *name;
+
+ if (!arg || (xmlStrlen(arg) == 0)) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: NULL argument provided\n");
+#endif
+ return result;
+ }
+
+ name = xmlCatalogResolveSystem(arg);
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ if (name) {
+ notifyXsldbgApp(XSLDBG_MSG_RESOLVE_CHANGE, name);
+ result = 1;
+ xmlFree(name);
+ } else {
+ notifyXsldbgApp(XSLDBG_MSG_RESOLVE_CHANGE, "");
+ xsldbgGenericErrorFunc(i18n("SystemID \"%1\" was not found in current catalog.\n").arg(xsldbgText(arg)));
+ }
+ } else {
+ if (name) {
+ xsldbgGenericErrorFunc(i18n("SystemID \"%1\" maps to: \"%2\"\n").arg(xsldbgText(arg)).arg(xsldbgText(name)));
+ xmlFree(name);
+ result = 1;
+ } else {
+ xsldbgGenericErrorFunc(i18n("SystemID \"%1\" was not found in current catalog.\n").arg(xsldbgText(arg)));
+ }
+ }
+
+ return result;
+}
+
+
+/**
+ * xslDbgPublic:
+ * @arg : Is valid
+ *
+ * Print what a public ID @arg maps to via the current xml catalog
+ *
+ * Returns 1 on sucess,
+ * 0 otherwise
+ */
+int
+xslDbgPublic(const xmlChar * arg)
+{
+ int result = 0;
+ xmlChar *name;
+
+ if (!arg || (xmlStrlen(arg) == 0)) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: NULL argument provided\n");
+#endif
+ return result;
+ }
+
+ name = xmlCatalogResolvePublic(arg);
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ if (name) {
+ notifyXsldbgApp(XSLDBG_MSG_RESOLVE_CHANGE, name);
+ result = 1;
+ xmlFree(name);
+ } else {
+ notifyXsldbgApp(XSLDBG_MSG_RESOLVE_CHANGE, "");
+ xsldbgGenericErrorFunc(i18n("PublicID \"%1\" was not found in current catalog.\n").arg(xsldbgText(arg)));
+ }
+ } else {
+ if (name) {
+ xsldbgGenericErrorFunc(i18n("PublicID \"%1\" maps to: \"%2\"\n").arg(xsldbgText(arg)).arg(xsldbgText(name)));
+ xmlFree(name);
+ result = 1;
+ } else {
+ xsldbgGenericErrorFunc(i18n("PublicID \"%1\" was not found in current catalog.\n").arg(xsldbgText(arg)));
+ }
+ xsltGenericError(xsltGenericErrorContext, "%s", buffer);
+ }
+ return result;
+}
+
+
+/**
+ * xslDbgEncoding:
+ * @arg: Is valid encoding supported by libxml2
+ *
+ * Set current encoding to use for output to standard output
+ *
+ * Returns 1 on sucess,
+ * 0 otherwise
+ */
+int
+xslDbgEncoding(xmlChar * arg)
+{
+ int result = 0;
+ xmlChar *opts[2];
+
+ if (!arg) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: NULL argument provided\n");
+#endif
+ return result;
+ }
+
+ if (splitString(arg, 1, opts) == 1) {
+ if (filesSetEncoding((char *) opts[0])) {
+ optionsSetStringOption(OPTIONS_ENCODING, opts[0]);
+ result = 1;
+ }
+ } else
+ xsldbgGenericErrorFunc(i18n("Error: Missing arguments for the command %1.\n").arg("encoding"));
+ return result;
+}
+
+
+/**
+ * xslDbgShellOutput:
+ * @arg : Is valid, either a local file name which will be expanded
+ * if needed, or a "file://" protocol URI
+ *
+ * Set the output file name to use
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int xslDbgShellOutput(const xmlChar *arg)
+{
+ int result = 0;
+ if (arg && (xmlStrLen(arg) > 0)){
+ if (!xmlStrnCmp(arg, "file:/", 6)){
+ /* convert URI to local file name */
+ xmlChar *outputFileName = filesURItoFileName(arg);
+ if (outputFileName){
+ optionsSetStringOption(OPTIONS_OUTPUT_FILE_NAME,
+ outputFileName);
+ notifyXsldbgApp(XSLDBG_MSG_FILE_CHANGED, 0L);
+ xmlFree(outputFileName);
+ result = 1;
+ }
+ } else if (xmlStrEqual(arg, (xmlChar*)"-")) {
+ optionsSetStringOption(OPTIONS_OUTPUT_FILE_NAME,
+ NULL);
+ notifyXsldbgApp(XSLDBG_MSG_FILE_CHANGED, 0L);
+ result = 1;
+ } else if (!xmlStrnCmp(arg, "ftp://", 6) || !xmlStrnCmp(arg, "http://", 7)){
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("output"));
+ return 0;
+ } else {
+ /* assume that we were provided a local file name
+ * that may need expanding
+ */
+ xmlChar *expandedName = filesExpandName(arg);
+
+ // The output file must not be the same as our SOURCE or DATA file
+ if (expandedName &&
+ (!xmlStrEqual(optionsGetStringOption(OPTIONS_SOURCE_FILE_NAME), expandedName)) &&
+ (!xmlStrEqual(optionsGetStringOption(OPTIONS_DATA_FILE_NAME), expandedName)) ){
+ optionsSetStringOption(OPTIONS_OUTPUT_FILE_NAME, expandedName);
+ notifyXsldbgApp(XSLDBG_MSG_FILE_CHANGED, 0L);
+ xmlFree(expandedName);
+ result = 1;
+ }else{
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("output"));
+ }
+ }
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Missing arguments for the command %1.\n").arg("output"));
+ }
+
+ return result;
+}
+
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/files.cpp b/kxsldbg/kxsldbgpart/libxsldbg/files.cpp
new file mode 100644
index 00000000..73d3713b
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/files.cpp
@@ -0,0 +1,1420 @@
+
+/***************************************************************************
+ files.h - define file related functions
+ -------------------
+ begin : Sat Nov 10 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. *
+ * *
+ ***************************************************************************/
+
+/* We want skip most of these includes when building documentation */
+#ifndef BUILD_DOCS
+
+#include "xsldbg.h"
+#include <stdio.h>
+#include <libxml/entities.h>
+#include <libxml/tree.h>
+#include <libxml/catalog.h>
+#include <libxml/parserInternals.h>
+#include <libxml/encoding.h> /* needed by filesTranslate, filesEncoding functions */
+#include <libxml/uri.h> /* needed for xmlURIUnescapeString */
+#include "debugXSL.h"
+#include "files.h"
+#include "utils.h"
+#include "options.h"
+#include "xsldbgthread.h"
+#ifdef WIN32
+#include <direct.h>
+#endif
+
+#endif /* BUILD_DOCS */
+
+
+/* top xml document */
+static xmlDocPtr topDocument;
+
+/* temporary xml document */
+static xmlDocPtr tempDocument;
+
+/* used as a scratch pad for temporary results*/
+static xmlChar filesBuffer[DEBUG_BUFFER_SIZE];
+
+/* top stylsheet */
+static xsltStylesheetPtr topStylesheet;
+
+/* what is the base path for top stylesheet */
+static xmlChar *stylePathName = NULL;
+
+/* what is the path for current working directory*/
+static xmlChar *workingDirPath = NULL;
+
+static arrayListPtr entityNameList = NULL;
+
+/* Current encoding to use for standard output*/
+static xmlCharEncodingHandlerPtr stdoutEncoding = NULL;
+
+/* input and output buffers for encoding*/
+static xmlBufferPtr encodeInBuff = NULL;
+static xmlBufferPtr encodeOutBuff = NULL;
+
+/* Current line number and URI for xsldbg*/
+static int currentLineNo = -1;
+static xmlChar *currentUrl = NULL;
+
+/* -----------------------------------------
+ Private function declarations for files.c
+ -------------------------------------------*/
+
+/**
+ * guessStylesheetHelper:
+ * @payload: valid xsltStylesheetPtr
+ * @data: valid searchInfoPtr of type SEARCH_NODE
+ * @name: not used
+ *
+ * Try to guess what the complete file/URI is. If successful the search
+ * info will be set to found and the search data will contain the
+ * file name found. We are given our payload via walkStylesheets
+ */
+static void guessStylesheetHelper(void *payload, void *data,
+ xmlChar * name);
+
+
+/**
+ * guessStylesheetHelper2:
+ * @payload: valid xmlNodePtr of the included stylesheet
+ * @data: valid searchInfoPtr of type SEARCH_NODE
+ * @name: not used
+ *
+ * Try to guess what the complete file/URI is. If successful the search
+ * info will be set to found and the search data will contain the
+ * file name found. We are given our payload via walkIncludes
+ */
+static void guessStylesheetHelper2(void *payload, void *data,
+ xmlChar * name);
+
+
+entityInfoPtr filesNewEntityInfo(const xmlChar * SystemID,
+ const xmlChar * PublicID);
+
+void filesFreeEntityInfo(entityInfoPtr info);
+
+void filesAddEntityName(const xmlChar * SystemID,
+ const xmlChar * PublicID);
+
+
+/* -------------------------------------
+ End private functions
+---------------------------------------*/
+
+
+FILE *terminalIO;
+
+/* No longer needed
+ static FILE *oldStdin, *oldStdout, *oldStderr;*/
+
+
+//static char *ttyName = NULL; /* what is the name of the default terminal */
+static char *termName = NULL; /* what is the name of terminal we are redirected to */
+
+
+/**
+ * redirectToTerminal:
+ * @device: terminal to redirect i/o to , will not work under win32
+ *
+ * Open communications to the terminal device @device
+ *
+ * Returns 1 if sucessful
+ * 0 otherwise
+ */
+int
+openTerminal(xmlChar * device)
+{
+ int result = 0;
+
+ if (!device) { /* Failed; there's no device */
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: NULL argument provided\n");
+#endif
+ return result;
+ }
+
+ /*
+ * On RISC OS, you get one terminal - the screen.
+ * we assume that the parameter is meant to be an output device as
+ * per normal - we can use vdu:, rawvdu: or :tt, or a filename for
+ * normal VDU output, VDU output without newline expansion,
+ * C terminal output with control code escaping, or a raw file
+ * respectively.
+ * The name passed is expected to be in native file format - no
+ * URI escaping here.
+ * One assumes that you might use a socket or a pipe here.
+ */
+
+ if (terminalIO) {
+ fclose(terminalIO);
+ terminalIO = NULL;
+ }
+
+
+ switch (device[0]) {
+ case '\0':
+ case '0':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* look like we are supposed to close the terminal
+ * but we've already done that
+ */
+ break;
+
+ case '1':
+ if (termName) {
+ terminalIO = fopen((char *) termName, "w");
+ if (terminalIO != NULL) {
+ xmlFree(termName);
+ termName = xmlMemStrdup((char *) device);
+ result = 1;
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to open terminal %1.\n").arg(xsldbgText(termName)));
+ }
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Did not previously open terminal.\n"));
+ }
+ break;
+
+ case '2':
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Warning: Terminal level 2 not implemented\n");
+#endif
+ break;
+
+
+ default:
+ terminalIO = fopen((char *) device, "w");
+ if (terminalIO != NULL) {
+ if (termName)
+ xmlFree(termName);
+ termName = xmlMemStrdup((char *) device);
+ result = 1;
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to open terminal %1.\n").arg(xsldbgText(device)));
+ }
+
+ }
+
+ return result;
+}
+
+
+/**
+ * guessStylesheetHelper:
+ * @payload: valid xsltStylesheetPtr
+ * @data: valid searchInfoPtr of type SEARCH_NODE
+ * @name: not used
+ *
+ * Try to guess what the complete file/URI is. If successful the search
+ * info will be set to found and the search data will contain the
+ * file name found. We are given our payload via walkStylesheets
+ */
+void
+guessStylesheetHelper(void *payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(name);
+ xsltStylesheetPtr style = (xsltStylesheetPtr) payload;
+ searchInfoPtr searchCriteria = (searchInfoPtr) data;
+ nodeSearchDataPtr searchData = NULL;
+ /* where did the directory/URI separator occur */
+ char *lastSlash;
+
+ if (!style || !style->doc || !searchCriteria || !searchCriteria->data
+ || (searchCriteria->type != SEARCH_NODE))
+ return;
+
+ searchData = (nodeSearchDataPtr) searchCriteria->data;
+ if (searchData->nameInput && (searchData->absoluteNameMatch == NULL)) {
+ /* at this point we know that we have not made an absolute match
+ * but we may have made a relative match */
+ if (xmlStrCmp(style->doc->URL, searchData->nameInput) == 0) {
+ /* absolute path match great! */
+ searchData->absoluteNameMatch =
+ (xmlChar *) xmlMemStrdup((char *) style->doc->URL);
+ searchData->node = (xmlNodePtr) style->doc;
+ searchCriteria->found = 1;
+ return;
+ }
+
+
+ /* try to guess we assume that the files are unique */
+ xmlStrCpy(filesBuffer, "__#!__");
+ /* try relative to top stylesheet directory */
+ if (stylePath()) {
+ xmlStrCpy(filesBuffer, stylePath());
+ xmlStrCat(filesBuffer, searchData->nameInput);
+ }
+ if (xmlStrCmp(style->doc->URL, filesBuffer) == 0) {
+ /* guessed right! */
+ searchData->guessedNameMatch =
+ (xmlChar *) xmlMemStrdup((char *) filesBuffer);
+ searchData->node = (xmlNodePtr) style->doc;
+ searchCriteria->found = 1;
+ return;
+ }
+
+ if (workingPath()) {
+ /* try relative to working directory */
+ xmlStrCpy(filesBuffer, workingPath());
+ xmlStrCat(filesBuffer, searchData->nameInput);
+ }
+ if (xmlStrCmp(style->doc->URL, filesBuffer) == 0) {
+ /* guessed right! */
+ searchData->guessedNameMatch =
+ (xmlChar *) xmlMemStrdup((char *) filesBuffer);
+ searchData->node = (xmlNodePtr) style->doc;
+ searchCriteria->found = 1;
+ return;
+ }
+
+
+ /* Find the last separator of the stylsheet's URL */
+ lastSlash = xmlStrChr(style->doc->URL, URISEPARATORCHAR);
+ if (!lastSlash)
+ lastSlash = xmlStrChr(style->doc->URL, PATHCHAR);
+
+ if (lastSlash) {
+ /* Last try, assume nameInput contains only a file name
+ * Strip of the file name at end of the stylesheet doc URL */
+ lastSlash++; /* skip the slash */
+ if (xmlStrCmp(lastSlash, searchData->nameInput) == 0) {
+ /* guessed right! */
+ searchData->guessedNameMatch =
+ (xmlChar *) xmlMemStrdup((char *) style->doc->URL);
+ searchData->node = (xmlNodePtr) style->doc;
+ searchCriteria->found = 1;
+ }
+ }
+ }
+}
+
+
+/**
+ * guessStylesheetHelper2:
+ * @payload: valid xmlNodePtr of the included stylesheet
+ * @data: valid searchInfoPtr of type SEARCH_NODE
+ * @name: not used
+ *
+ * Try to guess what the complete file/URI is. If successful the search
+ * info will be set to found and the search data will contain the
+ * file name found. We are given our payload via walkIncludes
+ */
+void
+guessStylesheetHelper2(void *payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(name);
+ xmlNodePtr node = (xmlNodePtr) payload;
+ searchInfoPtr searchCriteria = (searchInfoPtr) data;
+ nodeSearchDataPtr searchData = NULL;
+ /* where did the directory/URI separator occur */
+ char *lastSlash;
+
+ if (!node || !node->doc || !searchCriteria || !searchCriteria->data ||
+ (searchCriteria->type != SEARCH_NODE))
+ return;
+
+ searchData = (nodeSearchDataPtr) searchCriteria->data;
+ if (searchData->nameInput && (searchData->absoluteNameMatch == NULL)) {
+ /* at this point we know that we have not made an absolute match
+ * but we may have made a relative match */
+ if (xmlStrCmp(node->doc->URL, searchData->nameInput) == 0) {
+ /* absolute path match great! */
+ searchData->absoluteNameMatch =
+ (xmlChar *) xmlMemStrdup((char *) node->doc->URL);
+ searchData->node = node;
+ searchCriteria->found = 1;
+ return;
+ }
+
+
+ /* try to guess we assume that the files are unique */
+ xmlStrCpy(filesBuffer, "__#!__");
+ /* try relative to top stylesheet directory */
+ if (stylePath()) {
+ xmlStrCpy(filesBuffer, stylePath());
+ xmlStrCat(filesBuffer, searchData->nameInput);
+ }
+ if (xmlStrCmp(node->doc->URL, filesBuffer) == 0) {
+ /* guessed right! */
+ searchData->guessedNameMatch =
+ (xmlChar *) xmlMemStrdup((char *) filesBuffer);
+ searchData->node = node;
+ searchCriteria->found = 1;
+ return;
+ }
+
+ if (workingPath()) {
+ /* try relative to working directory */
+ xmlStrCpy(filesBuffer, workingPath());
+ xmlStrCat(filesBuffer, searchData->nameInput);
+ }
+ if (xmlStrCmp(node->doc->URL, filesBuffer) == 0) {
+ /* guessed right! */
+ searchData->guessedNameMatch =
+ (xmlChar *) xmlMemStrdup((char *) filesBuffer);
+ searchData->node = node;
+ searchCriteria->found = 1;
+ return;
+ }
+
+
+ /* Find the last separator of the stylsheet's URL */
+ lastSlash = xmlStrChr(node->doc->URL, URISEPARATORCHAR);
+ if (!lastSlash)
+ lastSlash = xmlStrChr(node->doc->URL, PATHCHAR);
+
+ if (lastSlash) {
+ /* Last try, assume nameInput contains only a file name
+ * Strip of the file name at end of the stylesheet doc URL */
+ lastSlash++; /* skip the slash */
+ if (xmlStrCmp(lastSlash, searchData->nameInput) == 0) {
+ /* guessed right! */
+ searchData->guessedNameMatch =
+ (xmlChar *) xmlMemStrdup((char *) node->doc->URL);
+ searchData->node = node;
+ searchCriteria->found = 1;
+ }
+ }
+ }
+}
+
+
+/**
+ * guessStylesheetName:
+ * @searchInf: Is valid
+ *
+ * Try to find a matching stylesheet name
+ * Sets the values in @searchinf depending on outcome of search
+ */
+void
+guessStylesheetName(searchInfoPtr searchCriteria)
+{
+ nodeSearchDataPtr searchData;
+
+ if (!searchCriteria)
+ return;
+
+ searchData = (nodeSearchDataPtr) searchCriteria->data;
+ if (searchData->nameInput == NULL)
+ return; /* must supply name of file to look for */
+
+ walkStylesheets((xmlHashScanner) guessStylesheetHelper,
+ searchCriteria, filesGetStylesheet());
+ if (!searchCriteria->found) {
+ /* try looking in the included stylesheets */
+ walkIncludes((xmlHashScanner) guessStylesheetHelper2,
+ searchCriteria, filesGetStylesheet());
+ }
+}
+
+
+/**
+ * stylePath:
+ *
+ * Return The base path for the top stylesheet ie
+ * ie URL minus the actual file name
+ *
+ * Returns The base path for the top stylesheet ie
+ * ie URL minus the actual file name
+ */
+xmlChar *
+stylePath(void)
+{
+ return stylePathName;
+}
+
+
+/**
+ * workingPath:
+ *
+ * Return the working directory as set by changeDir function
+ *
+ * Returns The working directory as set by changeDir function
+ */
+xmlChar *
+workingPath(void)
+{
+ return workingDirPath;
+}
+
+
+/**
+ * changeDir:
+ * @path: The path to adopt as new working directory
+ *
+ * Change working directory to path
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+changeDir(const xmlChar * path)
+{
+ int result = 0;
+ int charIndex;
+ const char endString[2] = { PATHCHAR, '\0' };
+ xmlChar *expandedName = NULL;
+
+
+ if (path && (xmlStrLen(path) > 0)) {
+ expandedName = filesExpandName(path);
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Empty path provided to changeDir");
+#endif
+ return result;
+ }
+
+ if (!expandedName)
+ return result; /* out of memory ? */
+
+ if (xmlStrLen(expandedName) + 1 > sizeof(filesBuffer)) {
+ xsldbgGenericErrorFunc(i18n("Error: The file name \"%1\" is too long.\n").arg(xsldbgText(path)));
+ return result;
+ }
+
+ xmlStrCpy(filesBuffer, expandedName);
+ /* strip off any extra PATHCHAR's as win32's chdir function
+ * fails if we don't */
+ charIndex = xmlStrLen(filesBuffer) - 1;
+ while (charIndex && (filesBuffer[charIndex] == PATHCHAR)) {
+ charIndex--;
+ }
+ filesBuffer[charIndex + 1] = '\0';
+
+
+ if (chdir((char *) filesBuffer) == 0) {
+ if (workingDirPath)
+ xmlFree(workingDirPath);
+ /* must have path char at end of path name */
+ xmlStrCat(filesBuffer, endString);
+ workingDirPath = (xmlChar *) xmlMemStrdup((char *) filesBuffer);
+ result = 1;
+ }
+ xmlFree(expandedName); /* this will always be valid time */
+ if (!result) {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to change to directory %1.\n").arg(xsldbgText(path)));
+ } else {
+ if (xslDebugStatus != DEBUG_NONE)
+ xsldbgGenericErrorFunc(i18n("Changed to directory %1.\n").arg(xsldbgText(path)));
+ }
+ return result;
+}
+
+
+/**
+ * filesLoadXmlFile:
+ * @path: xml file to load
+ * @fileType: A valid FileTypeEnum
+ *
+ * Load specified file type, freeing any memory previously used
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+filesLoadXmlFile(const xmlChar * path, FileTypeEnum fileType)
+{
+ int result = 0;
+
+ if (!filesFreeXmlFile(fileType))
+ return result;
+
+ switch (fileType) {
+ case FILES_XMLFILE_TYPE:
+ if (path && xmlStrLen(path)) {
+ if (optionsGetIntOption(OPTIONS_SHELL)) {
+ xsldbgGenericErrorFunc(i18n("Setting XML Data file name to %1.\n").arg(xsldbgText(path)));
+ }
+ optionsSetStringOption(OPTIONS_DATA_FILE_NAME, path);
+ }
+ topDocument = xsldbgLoadXmlData();
+ if (topDocument)
+ result = 1;
+ break;
+
+ case FILES_SOURCEFILE_TYPE:
+ if (path && xmlStrLen(path)) {
+ if (optionsGetIntOption(OPTIONS_SHELL)) {
+ xsldbgGenericErrorFunc(i18n("Setting stylesheet file name to %1.\n").arg(xsldbgText(path)));
+ }
+ optionsSetStringOption(OPTIONS_SOURCE_FILE_NAME, path);
+ }
+ topStylesheet = xsldbgLoadStylesheet();
+ if (topStylesheet && topStylesheet->doc) {
+ /* look for last slash (or baskslash) of URL */
+ char *lastSlash = xmlStrrChr(topStylesheet->doc->URL,
+ PATHCHAR);
+ const char *docUrl =
+ (const char *) topStylesheet->doc->URL;
+
+ result = 1;
+ if (docUrl && lastSlash) {
+ stylePathName = (xmlChar *) xmlMemStrdup(docUrl);
+ stylePathName[lastSlash - docUrl + 1] = '\0';
+ if (optionsGetIntOption(OPTIONS_SHELL)) {
+ xsldbgGenericErrorFunc(i18n("Setting stylesheet base path to %1.\n").arg(xsldbgText(stylePathName)));
+ }
+ } else {
+ const char cwd[4] = { '.', PATHCHAR, '\0' };
+
+ /* ie for *nix this becomes "./" */
+ stylePathName = xmlStrdup(BAD_CAST cwd);
+ }
+
+ /* try to find encoding for this stylesheet */
+ if (optionsGetIntOption(OPTIONS_AUTOENCODE))
+ filesSetEncoding((char *) topStylesheet->encoding);
+ }
+ break;
+
+ case FILES_TEMPORARYFILE_TYPE:
+ if (!path || !xmlStrLen(path)) {
+ xsldbgGenericErrorFunc(i18n("Missing file name.\n"));
+ break;
+ }
+ topDocument = xsldbgLoadXmlTemporary(path);
+ if (tempDocument)
+ result = 1;
+ break;
+ }
+ return result;
+}
+
+
+/**
+ * filesFreeXmlFile:
+ * @fileType: A valid FileTypeEnum
+ *
+ * Free memory associated with the xml file
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+filesFreeXmlFile(FileTypeEnum fileType)
+{
+ int result = 0, type = fileType;
+
+ switch (type) {
+ case FILES_XMLFILE_TYPE:
+ if (topDocument)
+ xmlFreeDoc(topDocument);
+ topDocument = NULL;
+ result = 1;
+ break;
+
+ case FILES_SOURCEFILE_TYPE:
+ if (topStylesheet)
+ xsltFreeStylesheet(topStylesheet);
+ if (stylePathName)
+ xmlFree(stylePathName);
+ stylePathName = NULL;
+ topStylesheet = NULL;
+ result = 1;
+ break;
+
+ case FILES_TEMPORARYFILE_TYPE:
+ if (tempDocument)
+ xmlFreeDoc(tempDocument);
+ tempDocument = NULL;
+ result = 1;
+ break;
+ }
+ return result;
+}
+
+
+/**
+ * filesGetStylesheet:
+ *
+ * Return The topmost stylesheet non-null on success,
+ * NULL otherwise
+ *
+ * Returns The topmost stylesheet non-null on success,
+ * NULL otherwise
+ */
+xsltStylesheetPtr
+filesGetStylesheet(void)
+{
+ return topStylesheet;
+}
+
+
+/**
+ * filesGetTemporaryDoc:
+ *
+ * Return The current "temporary" document
+ *
+ * Returns The current "temporary" document
+ */
+xmlDocPtr
+filesGetTemporaryDoc(void)
+{
+ return tempDocument;
+}
+
+
+/**
+ * filesGetMainDoc:
+ *
+ * Return The main docment
+ *
+ * Returns The main docment
+ */
+xmlDocPtr
+filesGetMainDoc(void)
+{
+ return topDocument;
+}
+
+
+/**
+ * filesReloaded:
+ * @reloaded: if = -1 then ignore @reloaded
+ * otherwise change the status of files to value of @reloaded
+ *
+ * Returns 1 if stylesheet or its xml data file has been "flaged" as reloaded,
+ * 0 otherwise
+ */
+int
+filesReloaded(int reloaded)
+{
+ static int changed = 0;
+
+ if (reloaded >= 0) {
+ changed = reloaded;
+ }
+
+ return changed;
+}
+
+
+
+/**
+ * filesInit:
+ *
+ * Initialize the file related structures
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+filesInit(void)
+{
+ int result = 0;
+
+ terminalIO = NULL;
+#ifdef __riscos
+ ttyName = ":tt"; /* Default tty */
+#endif
+#ifdef HAVE_UNISTD
+ ttyName = ttyname(fileno(stdin));
+ /* save out io for when/if we send debugging to a terminal */
+ oldStdin = stdin;
+ oldStdout = stdout;
+ oldStderr = stderr;
+#endif
+ topDocument = NULL;
+ tempDocument = NULL;
+ topStylesheet = NULL;
+ entityNameList = arrayListNew(4, (freeItemFunc) filesFreeEntityInfo);
+#if defined(HAVE_INCLUDE_FIX) && (LIBXML_VERSION < 20508)
+ xmlSetEntityReferenceFunc(filesEntityRef);
+#endif
+
+ /* setup the encoding */
+ encodeInBuff = xmlBufferCreate();
+ encodeOutBuff = xmlBufferCreate();
+
+ /* check the result so far and lastly perform platform specific
+ * initialization */
+ if (entityNameList && encodeInBuff && encodeOutBuff &&
+ filesPlatformInit())
+ result = 1;
+ return result;
+}
+
+/**
+ * filesFree:
+ *
+ * Free memory used by file related structures
+ */
+void
+filesFree(void)
+{
+ int result;
+
+ if (terminalIO) {
+ fclose(terminalIO);
+ terminalIO = NULL;
+ }
+ if (termName) {
+ xmlFree(termName);
+ termName = NULL;
+ }
+
+ result = filesFreeXmlFile(FILES_SOURCEFILE_TYPE);
+ if (result)
+ result = filesFreeXmlFile(FILES_XMLFILE_TYPE);
+ if (result)
+ result = filesFreeXmlFile(FILES_TEMPORARYFILE_TYPE);
+ if (!result){
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to free memory used by XML/XSLT files\n");
+#endif
+ }
+ if (stylePathName) {
+ xmlFree(stylePathName);
+ stylePathName = NULL;
+ }
+
+ if (workingDirPath) {
+ xmlFree(workingDirPath);
+ workingDirPath = NULL;
+ }
+
+ if (entityNameList) {
+ arrayListFree(entityNameList);
+ entityNameList = NULL;
+ }
+
+ /* Free memory used by encoding related structures */
+ if (encodeInBuff)
+ xmlBufferFree(encodeInBuff);
+
+ if (encodeOutBuff)
+ xmlBufferFree(encodeOutBuff);
+
+ /* close current encoding */
+ filesSetEncoding(NULL);
+
+ if (currentUrl)
+ xmlFree(currentUrl);
+
+ /* free any memory used by platform specific files module */
+ filesPlatformFree();
+}
+
+
+/**
+ * filesIsSourceFile:
+ * @fileName : is valid
+ *
+ * Returns true if @name has the ".xsl" externsion
+ */
+int
+filesIsSourceFile(xmlChar * fileName)
+{
+ return strstr((char *) fileName, ".xsl") ||
+ strstr((char *) fileName, ".Xsl") ||
+ strstr((char *) fileName, ".XSL");
+}
+
+
+
+entityInfoPtr
+filesNewEntityInfo(const xmlChar * SystemID, const xmlChar * PublicID)
+{
+
+ entityInfoPtr result = (entityInfoPtr) xmlMalloc(sizeof(entityInfo));
+
+ if (result) {
+ if (SystemID)
+ result->SystemID = xmlStrdup(SystemID);
+ else
+ result->SystemID = xmlStrdup(BAD_CAST "");
+
+ if (PublicID)
+ result->PublicID = xmlStrdup(PublicID);
+ else
+ result->PublicID = xmlStrdup(BAD_CAST "");
+ }
+ return result;
+}
+
+void
+filesFreeEntityInfo(entityInfoPtr info)
+{
+ if (!info)
+ return;
+
+ if (info->SystemID)
+ xmlFree(info->SystemID);
+
+ if (info->PublicID)
+ xmlFree(info->PublicID);
+ xmlFree(info);
+}
+
+/**
+ * filesAddEntityName:
+ * @name : is valid
+ *
+ * Add name to entity name list of know external entities if
+ * it does not already exist in list
+ */
+void
+
+filesAddEntityName(const xmlChar * SystemID, const xmlChar * PublicID)
+{
+ int entityIndex = 0;
+ entityInfoPtr tempItem;
+
+ if (!SystemID || !filesEntityList())
+ return;
+
+ for (entityIndex = 0;
+ entityIndex < arrayListCount(filesEntityList()); entityIndex++) {
+ tempItem =
+ (entityInfoPtr) arrayListGet(filesEntityList(), entityIndex);
+ if (tempItem && xmlStrEqual(SystemID, tempItem->SystemID)) {
+ /* name aready exits so don't add it */
+ return;
+ }
+
+ }
+
+ tempItem = filesNewEntityInfo(SystemID, PublicID);
+ arrayListAdd(filesEntityList(), tempItem);
+}
+
+
+/**
+ * filesEntityRef :
+ * @ent : Is valid as provided by libxslt
+ * @firstNode : Is valid
+ * @lastNode : Is Valid
+ *
+ * Fixes the nodes from firstNode to lastNode so that debugging can occur
+ */
+void
+
+filesEntityRef(xmlEntityPtr ent, xmlNodePtr firstNode, xmlNodePtr lastNode)
+{
+ xmlNodePtr node = firstNode;
+ if (!firstNode || !ent || !ent->SystemID ||
+ (ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) )
+ return;
+
+ if (ent->ExternalID)
+ filesAddEntityName(ent->SystemID, ent->ExternalID);
+ else
+ filesAddEntityName(ent->URI, BAD_CAST "");
+ while (node){
+ filesSetBaseUri(node, ent->URI);
+ if (node != lastNode)
+ node = node->next;
+ else
+ node = NULL;
+ }
+}
+
+
+
+ /**
+ * filesSetBaseUri:
+ * @node : Is valid and has a doc parent
+ * @uri : Is Valid
+ *
+ * Set the base uri for this node. Function is used when xml file
+ * has external entities in its DTD
+ *
+ * Returns 1 if successful,
+ * 0 otherwise
+ */
+
+int
+filesSetBaseUri(xmlNodePtr node, const xmlChar * uri)
+{
+ int result = 0;
+
+ if (!node || !uri)
+ return result;
+ else {
+ if (node->type == XML_ELEMENT_NODE){
+ xmlChar *xsldbgUrlCopy = xmlGetProp(node, BAD_CAST "xsldbg:uri");
+ if (!xsldbgUrlCopy)
+ xmlNewProp(node, BAD_CAST "xsldbg:uri", uri);
+ else
+ xmlFree(xsldbgUrlCopy);
+ }
+ result = 1;
+ }
+ return result;
+}
+
+
+ /**
+ * filesGetBaseUri:
+ * @node : Is valid and has a doc parent
+ *
+ * Get a copy of the base uri for this node. Function is most usefull
+ * used when xml file has external entities in its DTD
+ *
+ * Returns the a copy of the base uri for this node,
+ * NULL otherwise
+ */
+xmlChar *
+filesGetBaseUri(xmlNodePtr node)
+{
+ xmlChar *result = NULL;
+
+ if (!node || !node->doc)
+ return result;
+
+ while (node && node->parent) {
+ /*
+ * result = xmlGetNsProp(node, BAD_CAST "uri", XSLDBG_XML_NAMESPACE);
+ */
+ if (node->type == XML_ELEMENT_NODE) {
+ result = xmlGetProp(node, BAD_CAST "xsldbg:uri");
+ if (result)
+ break;
+ }
+ node = node->parent;
+ }
+
+ if (!result && node->doc && node->doc->URL)
+ result = xmlStrdup(node->doc->URL);
+
+ return result;
+}
+
+
+
+
+/**
+ * filesEntityList:
+ *
+ * Return the list entity names used for documents loaded
+ *
+ * Returns the list entity names used for documents loaded
+ */
+arrayListPtr
+filesEntityList(void)
+{
+ return entityNameList;
+}
+
+extern int intVolitileOptions[OPTIONS_LAST_INT_OPTIONID - OPTIONS_FIRST_INT_OPTIONID + 1];
+
+/**
+ * filesLoadCatalogs:
+ *
+ * Load the catalogs specifed by OPTIONS_CATALOG_NAMES if
+ * OPTIONS_CATALOGS is enabled
+ * Returns 1 if sucessful
+ * 0 otherwise
+ */
+int
+filesLoadCatalogs(void)
+{
+ int result = 0;
+ const char *catalogs = NULL;
+
+ xmlCatalogCleanup();
+ if (optionsGetIntOption(OPTIONS_CATALOGS)) {
+ if (optionsGetStringOption(OPTIONS_CATALOG_NAMES) == NULL) {
+ /* use the SGML catalog */
+#ifdef __riscos
+ catalogs = getenv("SGML$CatalogFiles");
+#else
+ catalogs = getenv("SGML_CATALOG_FILES");
+#endif
+ if (catalogs == NULL) {
+#ifdef __riscos
+ xsldbgGenericErrorFunc("Warning: Environment variable SGML$CatalogFiles is not set.\n");
+#else
+ xsldbgGenericErrorFunc("Warning: Environment variabe SGML_CATALOG_FILES FILES not set.\n");
+#endif
+ } else
+ /* copy the current catalog name(s) for user to see */
+ optionsSetStringOption(OPTIONS_CATALOG_NAMES,
+ (xmlChar *) catalogs);
+ } else
+ /* Use the current catalog settings from users*/
+ catalogs = (char *)
+ optionsGetStringOption(OPTIONS_CATALOG_NAMES);
+
+ result = 1;
+ }
+
+ if (catalogs){
+ /* Load the new cataog selection */
+ xmlLoadCatalogs(catalogs);
+ }else{
+ /* Use default catalogs */
+ xmlInitializeCatalog();
+ }
+ return result;
+}
+
+
+
+
+ /**
+ * filesEncode:
+ * @text: Is valid, text to translate from UTF-8,
+ *
+ * Return A new string of converted @text
+ *
+ * Returns A new string of converted @text, may be NULL
+ */
+xmlChar *
+filesEncode(const xmlChar * text)
+{
+ xmlChar *result = NULL;
+
+ if (!text)
+ return result;
+
+ if (!stdoutEncoding || !encodeInBuff || !encodeOutBuff)
+ return xmlStrdup(text); /* no encoding active return as UTF-8 */
+
+ xmlBufferEmpty(encodeInBuff);
+ xmlBufferEmpty(encodeOutBuff);
+ xmlBufferCat(encodeInBuff, text);
+
+ if (xmlCharEncOutFunc(stdoutEncoding, encodeOutBuff, encodeInBuff)
+ >= 0) {
+ result = xmlStrdup(xmlBufferContent(encodeOutBuff));
+ } else {
+ xsldbgGenericErrorFunc(i18n("Encoding of text failed.\n"));
+ return xmlStrdup(text); /* panic, return as UTF-8 */
+ }
+ return result;
+}
+
+
+
+ /**
+ * filesDeccode:
+ * @text: Is valid, text to translate from current encoding to UTF-8,
+ *
+ * Return A string of converted @text
+ *
+ * Returns A string of converted @text, may be NULL
+ */
+xmlChar *
+filesDecode(const xmlChar * text)
+{
+ xmlChar *result = NULL;
+
+ if (!text)
+ return result;
+
+ if (!stdoutEncoding || !encodeInBuff || !encodeOutBuff)
+ return xmlStrdup(text); /* no encoding active return as UTF-8 */
+
+ xmlBufferEmpty(encodeInBuff);
+ xmlBufferEmpty(encodeOutBuff);
+ xmlBufferCat(encodeInBuff, text);
+
+ if (xmlCharEncInFunc(stdoutEncoding, encodeOutBuff, encodeInBuff)
+ >= 0) {
+ result = xmlStrdup(xmlBufferContent(encodeOutBuff));
+ } else {
+ xsldbgGenericErrorFunc(i18n("Encoding of text failed.\n"));
+ return xmlStrdup(text); /* panic, return @text unchanged */
+ }
+ return result;
+}
+
+
+ /*
+ * filesSetEncoding:
+ * @encoding : Is a valid encoding supported by the iconv library or NULL
+ *
+ * Opens encoding for all standard output to @encoding. If @encoding
+ * is NULL then close current encoding and use UTF-8 as output encoding
+ *
+ * Returns 1 if successful in setting the encoding of all standard output
+ * to @encoding
+ * 0 otherwise
+ */
+int
+filesSetEncoding(const char *encoding)
+{
+ int result = 0;
+
+ if (encoding) {
+ /* don't switch encoding unless we've found a valid encoding */
+ xmlCharEncodingHandlerPtr tempEncoding =
+ xmlFindCharEncodingHandler(encoding);
+ if (tempEncoding) {
+ filesSetEncoding(NULL); /* re-use code to close encoding */
+ stdoutEncoding = tempEncoding;
+ result =
+ (xmlCharEncOutFunc(stdoutEncoding, encodeOutBuff, NULL)
+ >= 0);
+ if (!result) {
+ xmlCharEncCloseFunc(stdoutEncoding);
+ stdoutEncoding = NULL;
+ xsldbgGenericErrorFunc(i18n("Unable to initialize encoding %1.").arg(xsldbgText(encoding)));
+ } else
+ optionsSetStringOption(OPTIONS_ENCODING,
+ (xmlChar *) encoding);
+ } else {
+ xsldbgGenericErrorFunc(i18n("Invalid encoding %1.\n").arg(xsldbgText(encoding)));
+ }
+ } else {
+ /* close encoding and use UTF-8 */
+ if (stdoutEncoding)
+ result = (xmlCharEncCloseFunc(stdoutEncoding) >= 0);
+ else
+ result = 1;
+ stdoutEncoding = NULL;
+ }
+ return result;
+}
+
+
+
+ /**
+ * filesMoreFile:
+ * @fileName : May be NULL
+ * @file : May be NULL
+ *
+ * Do a "more" like print of file specified by @fileName OR
+ * @file. If both are provided @file will be used. The content
+ * of file chosen must be in UTF-8, and will be printed in
+ * the current encoding selected.The function will pause output
+ * after FILES_NO_LINES lines have been printed waiting for
+ * user to enter "q" to quit or any other text to continue.
+ *
+ * Returns 1 if successful,
+ * 0 otherwise
+ */
+int
+filesMoreFile(const xmlChar * fileName, FILE * file)
+{
+ int result = 0;
+ int openedFile = 0;
+ int lineCount;
+ int reachedEof = 0;
+
+ if (fileName && !file) {
+#ifdef __riscos
+ /* convert into RISC OS format a *nix style file name */
+ fileName = (const xmlChar *) riscosfilename((char *) fileName);
+#endif
+ file = fopen((char *) fileName, "r");
+ openedFile = 1; /* since we opened the file we must close it */
+ }
+ if (file) {
+ while (!feof(file) && !reachedEof) {
+ lineCount = 0;
+ while (!feof(file) && (lineCount < FILES_NO_LINES) &&
+ !reachedEof) {
+ if (fgets((char *) filesBuffer, sizeof(filesBuffer), file)) {
+ xsltGenericError(xsltGenericErrorContext, "%s",
+ filesBuffer);
+ lineCount++;
+ } else {
+ reachedEof = 1;
+ }
+ }
+
+ if (!feof(file) && !reachedEof) {
+ xsldbgGenericErrorFunc(i18n(" ----- more ---- \n"));
+ fflush(stderr);
+ if (fgets((char *) filesBuffer, sizeof(filesBuffer), stdin)) {
+ if ((*filesBuffer == 'q') || (*filesBuffer == 'Q'))
+ reachedEof = 1;
+ } else {
+ reachedEof = 1;
+ }
+ }
+ }
+
+ if (openedFile) {
+ fclose(file);
+ }
+ xsltGenericError(xsltGenericErrorContext, "\n");
+ result = 1;
+ } else {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: No valid file provided to print\n");
+#endif
+ }
+
+
+ return result;
+}
+
+
+ /**
+ * filesSearchResultsPath:
+ *
+ * Get the base path to be used for storing search results
+ *
+ * Returns The base path to be used for storing search results
+ */
+const xmlChar *
+filesSearchResultsPath()
+{
+ const xmlChar *result;
+
+ if (optionsGetStringOption(OPTIONS_SEARCH_RESULTS_PATH))
+ result = optionsGetStringOption(OPTIONS_SEARCH_RESULTS_PATH);
+ else
+ result = stylePath();
+
+ return result;
+}
+
+
+ /**
+ * filesURItoFileName:
+ * @uri : A valid URI that uses the "file://" prefix
+ *
+ * Return A copy of the conversion of @uri to a file name
+ * that is suitable to be used with the fopen function.
+ * May be NULL, if out of memory, @uri does not use the
+ * "file://" prefix, or unable to convert to a valid file name
+ *
+ * Returns A copy of the conversion of @uri to a file name
+ * that is suitable to be used with the fopen function.
+ * May be NULL, if out of memory, @uri does not use the
+ * "file://" prefix, or unable to convert to a valid file name
+ *
+ */
+xmlChar *filesURItoFileName(const xmlChar* uri)
+{
+ xmlChar *result = NULL;
+ xmlChar *unescapedFileName = NULL;
+ const xmlChar* tempName = NULL;
+
+ if (uri){
+ if (!xmlStrnCmp(uri, "file://localhost", 16 )){
+ tempName = uri + 16;
+ }else{
+#if defined(WIN32) && ! defined(CYGWIN)
+ if (!xmlStrnCmp(uri, "file:///", 8))
+ tempName = uri + 8;
+#else
+ if (!xmlStrnCmp(uri, "file:/", 6))
+ tempName = uri + 5; // we need the leading '/'*/
+ while (tempName[0] == '/' && tempName[1] == '/' )
+ tempName++;
+#endif
+ }
+
+ /* If we've found something check to see if the file name
+ found is to be valid */
+ if (tempName)
+ result = (xmlChar*) xmlStrdup(tempName);
+ unescapedFileName = (xmlChar*) xmlStrdup(tempName);
+ if (result && unescapedFileName){
+ if (PATHCHAR != URISEPARATORCHAR){
+ /* Must convert path separators first */
+ xmlChar *probe = result;
+ while(*probe != '\0'){
+ if (*probe == (xmlChar)URISEPARATORCHAR)
+ *probe = (xmlChar)PATHCHAR;
+ probe++;
+ }
+ }
+ /* Now unescape the file name in result so far
+ * NB: An unescaped name takes less memory that an escaped name
+ */
+ xmlURIUnescapeString((char*)result, -1, (char*)unescapedFileName);
+ xmlFree(result);
+ /* success we've got an local unescaped file name */
+ result = unescapedFileName;
+ }else{
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ if (result){
+ xmlFree(result);
+ }
+ if (unescapedFileName) /* not needed, here for completeness */
+ xmlFree(unescapedFileName);
+
+ result = NULL;
+ }
+ }else{
+ xsldbgGenericErrorFunc(i18n("Error: Unable to convert %1 to local file name.\n").arg(xsldbgText(uri)));
+ }
+
+
+ return result;
+}
+
+
+/* TODO in xsldbg 3.x rename these to use files prefix */
+
+/**
+ * xsldbgUpdateFileDetails:
+ * @node : A valid node
+ *
+ * Update the URL and line number that we stoped at
+ */
+void
+xsldbgUpdateFileDetails(xmlNodePtr node)
+{
+ if ((node != NULL) && (node->doc != NULL)){
+ if (currentUrl != NULL)
+ xmlFree(currentUrl);
+ currentUrl = filesGetBaseUri(node);
+ currentLineNo = xmlGetLineNo(node);
+ }
+}
+
+
+/**
+ * xsldbgLineNo:
+ *
+ * What line number are we at
+ *
+ * Returns The current line number of xsldbg, may be -1
+ **/
+int
+xsldbgLineNo(void)
+{
+ return currentLineNo;
+}
+
+
+/**
+ * xsldbgUrl:
+ *
+ * What URL did we stop at
+ *
+ * Returns A NEW copy of URL stopped at. Caller must free memory for URL.
+ * May be NULL
+ */
+xmlChar *
+xsldbgUrl(void)
+{
+ if (currentUrl != NULL)
+ return (xmlChar *) xmlMemStrdup((char *) currentUrl);
+ else
+ return NULL;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/files.h b/kxsldbg/kxsldbgpart/libxsldbg/files.h
new file mode 100644
index 00000000..05e49828
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/files.h
@@ -0,0 +1,981 @@
+
+/***************************************************************************
+ files.h - define file related functions
+ -------------------
+ begin : Sat Nov 10 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef FILES_H
+#define FILES_H
+
+#ifndef BUILD_DOCS
+
+#include "search.h"
+#include "arraylist.h"
+
+#endif
+
+#ifdef USE_KDE_DOCS
+
+/**
+ * Provide a file support
+ *
+ * @short file support
+ *
+ * @author Keith Isdale <k_isdale@tpg.com.au>
+ */
+#endif
+
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* need chdir function */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ extern FILE *terminalIO;
+
+#define XSLDBG_XML_NAMESPACE \
+ (const xmlChar *) "http://xsldbg.sourceforge.net/namespace"
+
+ typedef struct _entityInfo entityInfo;
+ typedef entityInfo *entityInfoPtr;
+ struct _entityInfo {
+ xmlChar *SystemID;
+ xmlChar *PublicID;
+ };
+
+
+ /* how many lines do we print before pausing when
+ * performing "more" on a UTF-8 file. See function filesMoreFile */
+#define FILES_NO_LINES 20
+
+ /* Define the types of file names that we are intested in when creating
+ * search results */
+#ifndef USE_KDOC
+ typedef enum {
+ FILES_SEARCHINPUT,
+ FILES_SEARCHXSL,
+ FILES_SEARCHRESULT
+ } FilesSearchFileNameEnum;
+#else
+ /* keep kdoc happy */
+ enum FilesSearchFileNameEnum {
+ FILES_SEARCHINPUT,
+ FILES_SEARCHXSL,
+ FILES_SEACHRESULT
+ };
+#endif
+
+
+
+ /*-----------------------------------------------------------
+ General function for working with files
+ -----------------------------------------------------------*/
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesEntityRef :
+ * @ent : Is valid as provided by libxslt
+ * @firstNode : Is valid
+ * @lastNode : Is Valid
+ *
+ * Fixes the nodes from firstNode to lastNode so that debugging can occur
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Fixes the nodes from firstNode to lastNode so that debugging can occur
+ *
+ * @param uri Is valid as provided by libxslt
+ * @param firstNode Is valid
+ * @param lastNode Is Valid
+ */
+#endif
+#endif
+ void filesEntityRef(xmlEntityPtr ent, xmlNodePtr firstNode,
+ xmlNodePtr lastNode);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesEntityList:
+ *
+ * Return the list entity names used for documents loaded
+ *
+ * Returns The list entity names used for documents loaded
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Return the list entity names used for documents loaded
+ *
+ * @returns The list entity names used for documents loaded
+ */
+#endif
+#endif
+ arrayListPtr filesEntityList(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesSetBaseUri:
+ * @node : Is valid and has a doc parent
+ * @uri : Is Valid
+ *
+ * Set the base uri for this node. Function is used when xml file
+ * has external entities in its DTD
+ *
+ * Returns 1 if successful,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Set the base uri for this node. Function is used when xml file
+ * has external entities in its DTD
+ *
+ * @param node Is valid and has a doc parent
+ * @param uri Is Valid
+ *
+ * @returns 1 if successful,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int filesSetBaseUri(xmlNodePtr node, const xmlChar * uri);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesGetBaseUri:
+ * @node : Is valid and has a doc parent
+ *
+ * Get a copy of the base uri for this node. Function is most usefull
+ * used when xml file has external entities in its DTD
+ *
+ * Returns the a copy of the base uri for this node,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Get a copy of the base uri for this node. Function is most usefull
+ * used when xml file has external entities in its DTD
+ *
+ * @param node : Is valid and has a doc parent
+ *
+ * @returns The a copy of the base uri for this node,
+ * NULL otherwise
+ */
+#endif
+#endif
+ xmlChar *filesGetBaseUri(xmlNodePtr node);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesTempFileName:
+ * @fleNumber : Number of temp file required
+ * where @fileNumber is
+ * 0 : file name used by cat command
+ * 1 : file name used by profiling output
+ *
+ * Return the name of tempfile requirested
+ *
+ * This is a platform specific interface
+ *
+ * Returns The name of temp file to be used for temporary results if sucessful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Return the name of tempfile requested.
+ * @param fleNumber : Number of temp file required
+ * where @p fileNumber is
+ * 0 : file name used by cat command
+ * 1 : file name used by profiling output
+ *
+ * This is a platform specific interface
+ *
+ * Returns The name of temp file to be used for temporary results if sucessful,
+ * NULL otherwise
+ */
+#endif
+#endif
+ const char *filesTempFileName(int fileNumber);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesLoadCatalogs:
+ *
+ * Load the catalogs specifed by OPTIONS_CATALOG_NAMES if
+ * OPTIONS_CATALOGS is enabled
+ *
+ * Returns 1 if sucessful
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Load the catalogs specifed by OPTIONS_CATALOG_NAMES if
+ * OPTIONS_CATALOGS is enabled
+ *
+ * @returns 1 if sucessful
+ * 0 otherwise
+ */
+#endif
+#endif
+ int filesLoadCatalogs(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesEncode:
+ * @text: Is valid, text to translate from UTF-8,
+ *
+ * Return A string of converted @text
+ *
+ * Returns A string of converted @text, may be NULL
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Return A string of converted @text
+ *
+ * @param text Is valid, text to translate from UTF-8,
+ *
+ * Returns A string of converted @text, may be NULL
+ */
+#endif
+#endif
+ xmlChar *filesEncode(const xmlChar * text);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesDeccode:
+ * @text: Is valid, text to translate from current encoding to UTF-8,
+ *
+ * Return A string of converted @text
+ *
+ * Returns A string of converted @text, may be NULL
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Return A string of converted @text
+ *
+ * @param test Is valid, text to translate from current encoding to UTF-8,
+ *
+ * Returns A string of converted @text, may be NULL
+ */
+#endif
+#endif
+ xmlChar *filesDecode(const xmlChar * text);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesSetEncoding:
+ * @encoding : Is a valid encoding supported by the iconv library or NULL
+ *
+ * Opens encoding for all standard output to @encoding. If @encoding
+ * is NULL then close current encoding and use UTF-8 as output encoding
+ *
+ * Returns 1 if successful in setting the encoding of all standard output
+ * to @encoding
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Opens encoding for all standard output to @p encoding. If @p encoding
+ * is NULL then close current encoding and use UTF-8 as output encoding
+ *
+ * @param encoding Is a valid encoding supported by the iconv library or NULL
+ *
+ * Returns 1 if successful in setting the encoding of all standard output
+ * to @p encoding
+ * 0 otherwise
+ */
+#endif
+#endif
+ int filesSetEncoding(const char *encoding);
+
+
+#ifndef USE_KDOC
+ /* used by filesLoadXmlFile, filesFreeXmlFile functions */
+ typedef enum {
+ FILES_XMLFILE_TYPE = 100, /* pick a unique starting point */
+ FILES_SOURCEFILE_TYPE,
+ FILES_TEMPORARYFILE_TYPE
+ } FileTypeEnum;
+#else
+
+ /* used by filesLoadXmlFile, filesFreeXmlFile functions */
+ enum FileTypeEnum {
+ FILES_XMLFILE_TYPE = 100, /* pick a unique starting point */
+ FILES_SOURCEFILE_TYPE,
+ FILES_TEMPORARYFILE_TYPE
+ };
+#endif
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * openTerminal
+ * @device: terminal to redirect i/o to , will not work under win32
+ *
+ * Open communications to the terminal device @device
+ * Returns 1 if sucessful
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Open communications to the terminal device @p device
+ *
+ * @param device Terminal to redirect i/o to , will not work under win32
+ *
+ * @returns 1 if sucessful
+ * 0 otherwise
+ */
+#endif
+#endif
+ int openTerminal(xmlChar * device);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * guessStyleSheetName:
+ * @searchInf : Is valid
+ *
+ * Try to find a matching stylesheet name
+ * Sets the values in @searchinf depending on outcome of search
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Try to find a matching stylesheet name
+ * Sets the values in @p searchinf depending on outcome of search
+ *
+ * @param searchInf Is valid
+ */
+#endif
+#endif
+ void guessStylesheetName(searchInfoPtr searchInf);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * stylePath:
+ *
+ * Returns the base path for the top stylesheet ie
+ * ie URL minus the actual file name
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Return the base path for the top stylesheet ie
+ * ie URL minus the actual file name
+ *
+ * @returns The base path for the top stylesheet ie
+ * ie URL minus the actual file name
+ */
+#endif
+#endif
+ xmlChar *stylePath(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * workingPath:
+ *
+ * Return the working directory as set by changeDir function
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Return the working directory as set by changeDir function
+ *
+ * @return the working directory as set by changeDir function
+ */
+#endif
+#endif
+ xmlChar *workingPath(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * changeDir:
+ * @path : path to adopt as new working directory
+ *
+ * Change working directory to path
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Change working directory to path
+ *
+ * @param path The operating system path(directory) to adopt as
+ * new working directory
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int changeDir(const xmlChar * path);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesLoadXmlFile:
+ * @path : xml file to load
+ * @fileType : A valid FileTypeEnum
+ *
+ * Load specified file type, freeing any memory previously used
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Load specified file type, freeing any memory previously used
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param path The xml file to load
+ * @param fileType A valid FileTypeEnum
+ */
+#endif
+#endif
+ int filesLoadXmlFile(const xmlChar * path, FileTypeEnum fileType);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesFreeXmlFile:
+ * @fileType : A valid FileTypeEnum
+ *
+ * Free memory associated with the xml file
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Free memory associated with the xml file
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param fileType : A valid FileTypeEnum
+ */
+#endif
+#endif
+ int filesFreeXmlFile(FileTypeEnum fileType);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesGetStylesheet:
+ *
+ * Return the topmost stylesheet
+ *
+ * Returns non-null on success,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Return the topmost stylesheet
+ *
+ * @returns Non-null on success,
+ * NULL otherwise
+ */
+#endif
+#endif
+ xsltStylesheetPtr filesGetStylesheet(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesGetTemporaryDoc:
+ *
+ * Return the current "temporary" document
+ *
+ * Returns the current "temporary" document
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Return the current "temporary" document
+ *
+ * @returns non-null on success,
+ * NULL otherwise
+ */
+#endif
+#endif
+ xmlDocPtr filesGetTemporaryDoc(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesGetMainDoc:
+ *
+ * Returns the main docment
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Return the main docment
+ *
+ * @returns the main document
+ */
+#endif
+#endif
+ xmlDocPtr filesGetMainDoc(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesReloaded:
+ * @reloaded : if = -1 then ignore @reloaded
+ * otherwise change the status of files to value of @reloaded
+ *
+ * Returns 1 if stylesheet or its xml data file has been "flaged" as reloaded,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * @returns 1 if stylesheet or its xml data file has been "flaged" as reloaded,
+ * 0 otherwise
+ *
+ * @param reloaded If = -1 then ignore @p reloaded
+ * otherwise change the status of files to value of @p reloaded
+ */
+#endif
+#endif
+ int filesReloaded(int reloaded);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesInit:
+ *
+ * Initialize the file module
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Initialize the file module
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int filesInit(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesFree:
+ *
+ * Free memory used by file related structures
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Free memory used by file related structures
+ */
+#endif
+#endif
+ void filesFree(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesIsSourceFile:
+ * @fileName : Is valid
+ *
+ * Test if filename could be a stylesheet
+ *
+ * Returns true if @name has the ".xsl" extension
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Test if filename could be a stylesheet
+ *
+ * @returns True if @name has the ".xsl" extension
+ *
+ * @param fileName Is valid
+ */
+#endif
+#endif
+ int filesIsSourceFile(xmlChar * fileName);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesMoreFile:
+ * @fileName : May be NULL
+ * @file : May be NULL
+ *
+ * Do a "more" like print of file specified by @fileName OR
+ * @file. If both are provided @file will be used. The content
+ * of file chosen must be in UTF-8, and will be printed in
+ * the current encoding selected.The function will pause output
+ * after FILES_NO_LINES lines have been printed waiting for
+ * user to enter "q" to quit or any other text to continue.
+ *
+ * Returns 1 if successful,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Do a "more" like print of file specified by @fileName OR
+ * @file. If both are provided @file will be used. The content
+ * of file chosen must be in UTF-8, and will be printed in
+ * the current encoding selected. The function will pause output
+ * after FILES_NO_LINES lines have been printed waiting for
+ * user to enter "q" to quit or any other text to continue.
+ *
+ * @returns 1 if successful,
+ * 0 otherwise
+ *
+ * @param fileName May be NULL
+ * @param file May be NULL
+ *
+ */
+#endif
+#endif
+ int filesMoreFile(const xmlChar * fileName, FILE * file);
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesSearchResultsPath:
+ *
+ * Get the base path to be used for storing search results
+ *
+ * Returns The base path to be used for storing search results
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Get the base path to be used for storing search results
+ *
+ * @returns The base path to be used for storing search results
+ */
+#endif
+#endif
+ const xmlChar *filesSearchResultsPath(void);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesURItoFileName:
+ * @uri : A valid URI that uses the "file://" prefix
+ *
+ * Return A copy of the conversion of @uri to a file name
+ * that is suitable to be used with the fopen function.
+ * May be NULL, if out of memory, @uri does not use the
+ * "file://" prefix, or unable to convert to a valid file name
+ *
+ * Returns A copy of the conversion of @uri to a file name
+ * that is suitable to be used with the fopen function.
+ * May be NULL, if out of memory, @uri does not use the
+ * "file://" prefix, or unable to convert to a valid file name
+ *
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Return A copy of the conversion of @uri to a file name
+ * that is suitable to be used with the fopen function.
+ * May be NULL, if out of memory, @uri does not use the
+ * "file://" protocol, or unable to convert to a valid file name
+ *
+ * Returns A copy of the conversion of @uri to a file name
+ * that is suitable to be used with the fopen function.
+ * May be NULL, if out of memory, @uri does not use the
+ * "file://" prefix, or unable to convert to a valid file name
+ *
+ * @param uri A valid URI that uses the "file://" prefix
+ *
+ */
+#endif
+#endif
+ xmlChar *filesURItoFileName(const xmlChar* uri);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xsldbgUpdateFileDetails:
+ * @node : A valid node
+ *
+ * Update the URL and line number that we stoped at
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Update the URL and line number that we stoped at
+ *
+ * @param node A valid node
+ */
+#endif
+#endif
+ void xsldbgUpdateFileDetails(xmlNodePtr node);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * xsldbgLineNo:
+ *
+ * What line number are we at
+ *
+ * Returns The current line number of xsldbg, may be -1
+ **/
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * What line number are we at
+ *
+ * @returns The current line number of xsldbg, may be -1
+ **/
+#endif
+#endif
+ int xsldbgLineNo(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * xsldbgUrl:
+ *
+ * What URL did we stop at
+ *
+ * Returns A NEW copy of URL stopped at. Caller must free memory for URL,
+ * may be NULL
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * What URL did we stop at
+ *
+ * @returns A NEW copy of URL stopped at. Caller must free memory for URL,
+ * may be NULL
+ */
+#endif
+#endif
+ xmlChar *xsldbgUrl(void);
+
+ /*-----------------------------------------------------------
+ Platform specific file functions
+ -----------------------------------------------------------*/
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesPlatformInit:
+ *
+ * Intialize the platform specific files module
+ *
+ * This is a platform specific interface
+ *
+ * Returns 1 if sucessful
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Intialize the platform specific files module
+ *
+ * This is a platform specific interface
+ *
+ * @returns 1 if sucessful
+ * 0 otherwise
+ */
+#endif
+#endif
+ int filesPlatformInit(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesPlatformFree:
+ *
+ * Free memory used by the platform specific files module
+ *
+ * This is a platform specific interface
+ *
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Free memory used by the platform specific files module
+ *
+ * This is a platform specific interface
+ *
+ */
+#endif
+#endif
+ void filesPlatformFree(void);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesExpandName:
+ * @fileName : A valid fileName
+ *
+ * Converts a fileName to an absolute path
+ * If operating system supports it a leading "~" in the fileName
+ * will be converted to the user's home path. Otherwise
+ * the same name will be returned
+ *
+ * Returns A copy of the converted @fileName or a copy of
+ * the @fileName as supplied. May return NULL
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Converts a fileName to an absolute path
+ * If operating system supports it a leading "~" in the fileName
+ * will be converted to the user's home path. Otherwise
+ * the same name will be returned
+ *
+ * Returns A copy of the converted @p fileName or a copy of
+ * the @p fileName as supplied. May return NULL
+ *
+ * @param fileName A valid fileName
+ */
+#endif
+#endif
+ xmlChar *filesExpandName(const xmlChar * fileName);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+ /**
+ * filesSearchFileName:
+ * @fileType : Is valid
+ *
+ * Return a copy of the file name to use as an argument to searching
+ *
+ * Returns A copy of the file name to use as an argument to searching
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Return a copy of the file name to use as an argument to searching
+ *
+ * @returns A copy of the file name to use as an argument to searching
+ *
+ * @param fileType Is valid
+ *
+ */
+#endif
+#endif
+ xmlChar *filesSearchFileName(FilesSearchFileNameEnum fileType);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/files_unix.cpp b/kxsldbg/kxsldbgpart/libxsldbg/files_unix.cpp
new file mode 100644
index 00000000..5c1bcbff
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/files_unix.cpp
@@ -0,0 +1,225 @@
+
+/***************************************************************************
+ files_unix.c - file functions *nix platform
+ specific
+ -------------------
+ begin : Tue Jan 29 2002
+ 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 "files.h"
+#include "utils.h"
+#include "options.h"
+
+static char *tempNames[2] = { NULL, NULL };
+
+ /**
+ * filesPlatformInit:
+ *
+ * Intialize the platform specific files module
+ *
+ * This is a platform specific interface
+ *
+ *
+ * Returns 1 if sucessful
+ * 0 otherwise
+ */
+int
+filesPlatformInit(void)
+{
+ const char *namePrefix = "/tmp/";
+ int nameIndex;
+ int result = 1;
+
+ /* The "base" names for files files to use */
+ const char *names[] = {
+ "_xsldbg_tmp1.txt",
+ "_xsldbg_tmp2.txt"
+ };
+
+ if (getenv("USER")) {
+ for (nameIndex = 0; nameIndex < 2; nameIndex++) {
+ tempNames[nameIndex] = (char*)
+ xmlMalloc(strlen(namePrefix) + strlen(getenv("USER")) +
+ strlen(names[nameIndex]) + 1);
+ if (tempNames[nameIndex]) {
+ xmlStrCpy(tempNames[nameIndex], namePrefix);
+ xmlStrCat(tempNames[nameIndex], getenv("USER"));
+ xmlStrCat(tempNames[nameIndex], names[nameIndex]);
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ break;
+ result = 0;
+ }
+ }
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: USER environment variable is not set.\n"));
+ }
+ return result;
+}
+
+
+ /**
+ * filesPlatformFree:
+ *
+ * Free memory used by the platform specific files module
+ *
+ * This is a platform specific interface
+ *
+ */
+void
+filesPlatformFree(void)
+{
+ int nameIndex;
+
+ for (nameIndex = 0; nameIndex < 2; nameIndex++) {
+ if (tempNames[nameIndex])
+ xmlFree(tempNames[nameIndex]);
+ }
+}
+
+ /**
+ * filesTempFileName:
+ * @fileNumber : Number of temp file required
+ *
+ * Return the name of tempfile. For each call to this function
+ * with the same @fileNumber the same file name will be returned
+ * File number : 0 is used by cat command
+ * File number : 1 is used by profiling output
+ *
+ * This is a platform specific interface
+ *
+ * Returns The name of temp file to be used for temporary results,
+ * NULL otherwise
+ */
+const char *
+filesTempFileName(int fileNumber)
+{
+
+ const char *result = NULL;
+
+ if ((fileNumber < 0) || ((fileNumber + 1) > 2)){ //don't use > (int) sizeof(tempNames), it depends on the platform and is wrong even on i586
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to allocate temporary file %d for xsldbg\n",
+ fileNumber);
+#endif
+ }else{
+ result = tempNames[fileNumber];
+ }
+
+ return result;
+}
+
+
+
+ /**
+ * filesExpandName:
+ * @fileName : A valid fileName
+ *
+ * Converts a fileName to an absolute path
+ * If operating system supports it a leading "~" in the fileName
+ * will be converted to the user's home path. Otherwise
+ * the same name will be returned
+ *
+ * Returns A copy of the converted @fileName or a copy of
+ * the @fileName as supplied. May return NULL
+ */
+xmlChar *
+filesExpandName(const xmlChar * fileName)
+{
+ xmlChar *result = NULL;
+
+ if (fileName) {
+ if ((fileName[0] == '~') && getenv("HOME")) {
+ result =
+ (xmlChar *) xmlMalloc(xmlStrLen(fileName) +
+ strlen(getenv("HOME")) + 1);
+ if (result) {
+ xmlStrCpy(result, getenv("HOME"));
+ xmlStrCat(result, &fileName[1]);
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ }
+ } else if (!xmlStrnCmp(fileName, "file:/", 6)){
+ /* return a copy of the corrected path */
+ result = filesURItoFileName(fileName);
+ }else{
+ /* return a copy only */
+ result = xmlStrdup(fileName);
+ }
+ }
+ return result;
+}
+
+
+ /**
+ * filesSearchFileName:
+ * @fileType : Is valid
+ *
+ * Return a copy of the file name to use as an argument to searching
+ *
+ * Returns A copy of the file name to use as an argument to searching
+ */
+xmlChar *
+filesSearchFileName(FilesSearchFileNameEnum fileType)
+{
+ xmlChar *result = NULL;
+ int type = fileType;
+ int preferHtml = optionsGetIntOption(OPTIONS_PREFER_HTML);
+ const xmlChar *baseDir = NULL;
+ const xmlChar *name = NULL;
+ static const char *searchNames[] = {
+ /* Note: File names here are in native format, to be appended to the
+ * help directory name or search results path
+ */
+ /* First list names when prefer html is false */
+ "searchresult.xml", /* input */
+ "search.xsl", /* stylesheet to use */
+ "searchresult.txt", /* where to put the result */
+ /*Now for the names to use when prefer html is true */
+ "searchresult.xml", /* input */
+ "searchhtml.xsl", /* stylesheet to use */
+ "searchresult.html" /* where to put the result */
+ };
+
+ if (!optionsGetStringOption(OPTIONS_DOCS_PATH)
+ || !filesSearchResultsPath()) {
+ xsldbgGenericErrorFunc(i18n("Error: The value of the option docspath or searchresultspath is empty. See help on setoption or options command for more information.\n"));
+ return result;
+ }
+
+
+ name = (xmlChar *) searchNames[(preferHtml * 3) + type];
+ switch (type) {
+ case FILES_SEARCHINPUT:
+ baseDir = filesSearchResultsPath();
+ break;
+
+ case FILES_SEARCHXSL:
+ baseDir = optionsGetStringOption(OPTIONS_DOCS_PATH);
+ break;
+
+ case FILES_SEARCHRESULT:
+ baseDir = filesSearchResultsPath();
+ break;
+ }
+
+ result = (xmlChar*)xmlMalloc(xmlStrLen(baseDir) + xmlStrLen(name) + 1);
+ if (result) {
+ xmlStrCpy(result, baseDir);
+ xmlStrCat(result, name);
+ }
+ return result;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/help.h b/kxsldbg/kxsldbgpart/libxsldbg/help.h
new file mode 100644
index 00000000..de77a71d
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/help.h
@@ -0,0 +1,73 @@
+
+/***************************************************************************
+ help.h - describe the help support functions
+ -------------------
+ begin : Sun Sep 16 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef XSLDBG_HELP_H
+#define XSLDBG_HELP_H
+
+#ifdef USE_KDE_DOCS
+
+/**
+ * Provide a help system for user
+ *
+ * @short help system support
+ *
+ * @author Keith Isdale <k_isdale@tpg.com.au>
+ */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * helpTop:
+ * @args : Is valid command or empty string
+ *
+ * Display help about the command in @arg
+ *
+ * This is a platform specific interface
+ *
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Display help about the command in @p arg
+ *
+ *
+ * This is a platform specific interface
+ *
+ * @param args Is valid or empty string
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int helpTop(const xmlChar * args);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/help_unix.cpp b/kxsldbg/kxsldbgpart/libxsldbg/help_unix.cpp
new file mode 100644
index 00000000..d3e91f92
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/help_unix.cpp
@@ -0,0 +1,115 @@
+
+/***************************************************************************
+ help.c - help system for *nix platform
+ -------------------
+ begin : Tue Jan 29 2002
+ 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. *
+ * *
+ ***************************************************************************/
+
+/*
+ * Uses docs/xsldoc.xsl docs/xsldoc.xml and xslproc to generate text
+ */
+
+#include "xsldbg.h"
+#include "options.h"
+#include "utils.h"
+#include "debugXSL.h"
+#include "help.h"
+#include "files.h"
+#include <stdlib.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+
+/**
+ * helpTop:
+ * @args : Is valid command or empty string
+ *
+ * Display help about the command in @args
+ *
+ * This is a platform specific interface
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+helpTop(const xmlChar * args)
+{
+
+ //Extra phrases to support translation of help display see kdewebdev/doc/xsldbg/xsldbghelp.xml and kdewebdev/kxsldbg/xsldbghelp.xsl
+ static const char* xsldbghelp_translations[] =
+ {
+ I18N_NOOP("xsldbg version"),
+ I18N_NOOP("Help document version"),
+ I18N_NOOP("Help not found for command")
+ };
+
+ QString xsldbgVerTxt(i18n("xsldbg version"));
+ QString helpDocVerTxt(i18n("Help document version"));
+ QString helpErrorTxt(i18n("Help not found for command"));
+
+
+ char buff[500], helpParam[100];
+
+ const char *docsDirPath =
+ (const char *) optionsGetStringOption(OPTIONS_DOCS_PATH);
+ int result = 0;
+
+ if (xmlStrLen(args) > 0) {
+ snprintf(helpParam, 100, "--param help:%c'%s'%c", QUOTECHAR, args,
+ QUOTECHAR);
+ } else
+ xmlStrCpy(helpParam, "");
+ if (docsDirPath && filesTempFileName(0)) {
+ snprintf((char *) buff, sizeof(buff), "%s %s"
+ " --param xsldbg_version:%c'%s'%c "
+ " --param xsldbgVerTxt:%c'%s'%c "
+ " --param helpDocVerTxt:%c'%s'%c "
+ " --param helpErrorTxt:%c'%s'%c "
+ " --output %s "
+ " --cd %s "
+ "xsldbghelp.xsl xsldbghelp.xml",
+ XSLDBG_BIN, helpParam,
+ QUOTECHAR, VERSION, QUOTECHAR,
+ QUOTECHAR, xsldbgVerTxt.utf8().data(), QUOTECHAR,
+ QUOTECHAR, helpDocVerTxt.utf8().data(), QUOTECHAR,
+ QUOTECHAR, helpErrorTxt.utf8().data(), QUOTECHAR,
+ filesTempFileName(0),
+ docsDirPath);
+ if (xslDbgShellExecute((xmlChar *) buff, optionsGetIntOption(OPTIONS_VERBOSE)) == 0) {
+ if (docsDirPath)
+ xsldbgGenericErrorFunc(i18n("Error: Unable to display help. Help files not found in %1 or xsldbg not found in path.\n").arg(docsDirPath)); /* FIXME: Comments not correct - the command is that invoked */
+ else
+ xsldbgGenericErrorFunc(i18n("Error: Unable to find xsldbg or help files.\n"));
+ } else {
+ if (filesMoreFile((xmlChar*)filesTempFileName(0), NULL) == 1) {
+ result = 1;
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to print help file.\n"));
+ }
+ }
+
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: No path to documentation; aborting help.\n"));
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+#ifdef USE_DOCS_MACRO
+ xsltGenericError(xsltGenericErrorContext,"MACRO has been defined look at Makefile.am\n");
+#else
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Environment variable %s is not set to the directory of xsldbg documentation.\n",
+ XSLDBG_DOCS_DIR_VARIABLE);
+#endif
+#endif
+ }
+ return result;
+}
+
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/nodeview_cmds.cpp b/kxsldbg/kxsldbgpart/libxsldbg/nodeview_cmds.cpp
new file mode 100644
index 00000000..5fcbef00
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/nodeview_cmds.cpp
@@ -0,0 +1,609 @@
+
+/***************************************************************************
+ nodeview_cmds.c - node viewing 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 <libxml/xpathInternals.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+#include <ctype.h> /* for isspace*/
+#include "debugXSL.h"
+#include "arraylist.h"
+#include "breakpoint.h"
+#include "xsldbgmsg.h"
+#include "xsldbgthread.h" /* for getThreadStatus */
+#include "files.h"
+#include "options.h"
+
+
+/* -----------------------------------------
+ Private function declarations for nodeview_cmds.c
+ -------------------------------------------*/
+static xmlChar nodeViewBuffer[500];
+static int printVariableValue = 0;
+
+/*
+ * xslDbgShellPrintNames:
+ * Print a name of variable found by scanning variable table
+ * It is used by print_variable function.
+ * @payload : not used
+ * @data : not used
+ * @name : the variable name
+ */
+void *xslDbgShellPrintNames(void *payload,
+ void *data, xmlChar * name);
+
+/**
+ * xslDbgCatToFile:
+ * @node : Is valid
+ * @file : Is valid
+ *
+ * Send the results of cat command in @node to @file
+ */
+static void xslDbgCatToFile(xmlNodePtr node, FILE * file);
+
+
+/**
+ * printXPathObject:
+ * @item : XPath object to print
+ * @xPath : The XPath used to find item
+ *
+ * Print an XPath object
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+static int printXPathObject(xmlXPathObjectPtr item, xmlChar* xPath);
+
+/* -------------------------------------
+ End private functions
+---------------------------------------*/
+
+
+/**
+ * xslDbgShellPrintList:
+ * @ctxt: The current shell context
+ * @arg: What xpath to display and in UTF-8
+ * @dir: If 1 print in dir mode?,
+ * otherwise ls mode
+ *
+ * Print list of nodes in either ls or dir format
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgShellPrintList(xmlShellCtxtPtr ctxt, xmlChar * arg, int dir)
+{
+ xmlXPathObjectPtr list;
+ int result = 0;
+
+ if (!ctxt || !arg) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: NULL arguments provided\n");
+#endif
+ return result;
+ }
+
+ if (arg[0] == 0) {
+ if (dir)
+ xmlShellDir(ctxt, NULL, ctxt->node, NULL);
+ else
+ xmlShellList(ctxt, NULL, ctxt->node, NULL);
+ result = 1; /*assume that this worked */
+ } else {
+ ctxt->pctxt->node = ctxt->node;
+ ctxt->pctxt->node = ctxt->node;
+ if (!xmlXPathNsLookup(ctxt->pctxt, (xmlChar *) "xsl"))
+ xmlXPathRegisterNs(ctxt->pctxt, (xmlChar *) "xsl",
+ XSLT_NAMESPACE);
+ list = xmlXPathEval(arg, ctxt->pctxt);
+ if (list != NULL) {
+ switch (list->type) {
+ case XPATH_NODESET:{
+ int indx;
+
+ for (indx = 0;
+ indx < list->nodesetval->nodeNr; indx++) {
+ if (dir)
+ xmlShellList(ctxt, NULL,
+ list->nodesetval->
+ nodeTab[indx], NULL);
+ else
+ xmlShellList(ctxt, NULL,
+ list->nodesetval->
+ nodeTab[indx], NULL);
+ }
+ result = 1;
+ break;
+ }
+ default:
+ xmlShellPrintXPathError(list->type, (char *) arg);
+ }
+ xmlXPathFreeObject(list);
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").arg(xsldbgText(arg)));
+ }
+ ctxt->pctxt->node = NULL;
+ }
+ return result;
+}
+
+
+
+/**
+ * xslDbgCatToFile:
+ * @node : Is valid
+ * @file : Is valid
+ *
+ * Send the results of cat command in @node to @file
+ */
+void
+xslDbgCatToFile(xmlNodePtr node, FILE * file)
+{
+ if (!node || !file)
+ return;
+
+ /* assume that HTML usage is enabled */
+ if (node->doc->type == XML_HTML_DOCUMENT_NODE) {
+ if (node->type == XML_HTML_DOCUMENT_NODE)
+ htmlDocDump(file, (htmlDocPtr) node);
+ else
+ htmlNodeDumpFile(file, node->doc, node);
+ } else if (node->type == XML_DOCUMENT_NODE) {
+ /* turn off encoding for the moment and just dump UTF-8
+ * which will be converted by xsldbgGeneralErrorFunc */
+ xmlDocPtr doc = (xmlDocPtr) node;
+ const xmlChar *encoding = doc->encoding;
+
+ if (encoding) {
+ xsldbgGenericErrorFunc(i18n("Information: Temporarily setting document's encoding to UTF-8. Previously was %1.\n").arg(xsldbgText(encoding)));
+ }
+ doc->encoding = (xmlChar *) "UTF-8";
+ xmlDocDump(file, (xmlDocPtr) node);
+ doc->encoding = encoding;
+ } else {
+ xmlElemDump(file, node->doc, node);
+ }
+}
+
+
+/**
+ * printXPathObject:
+ * @item : XPath object to print
+ * @xPath : The XPath used to find item
+ *
+ * Print an XPath object
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+
+static int
+printXPathObject(xmlXPathObjectPtr item, xmlChar* xPath){
+ int result = 0;
+ if (item){
+ switch (item->type) {
+ case XPATH_BOOLEAN:
+ xsltGenericError(xsltGenericErrorContext,
+ "= %s\n%s\n", xPath,
+ xmlBoolToText(item->boolval));
+ result = 1;
+ break;
+
+ case XPATH_NUMBER:
+ xsltGenericError(xsltGenericErrorContext,
+ "= %s\n%0g\n", xPath, item->floatval);
+ result = 1;
+ break;
+
+ /* case XPATH_NODESET:*/
+ default:{
+ /* We may need to convert this XPath to a string,
+ plus ensure that we print required the number of
+ lines of text */
+ int indx;
+
+ const char *fileName = filesTempFileName(0);
+ FILE *file = NULL;
+
+ if (!fileName)
+ break;
+ file = fopen(fileName, "w+");
+ if (!file) {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to save temporary results to %1.\n").arg(xsldbgText(fileName)));
+ break;
+ } else {
+ fprintf(file, "= %s\n", xPath);
+ switch(item->type){
+
+ case XPATH_NODESET:
+ if (item->nodesetval){
+ for (indx = 0;
+ indx < item->nodesetval->nodeNr; indx++){
+ xslDbgCatToFile(item->nodesetval->
+ nodeTab[indx], file);
+ }
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").arg(xsldbgText(xPath)));
+ }
+ break;
+
+ case XPATH_STRING:
+ if (item->stringval)
+ fprintf(file, "\'%s\'", item->stringval);
+ else
+ fprintf(file, "%s", i18n("NULL string value supplied.").utf8().data());
+ break;
+
+ default:{
+ xmlXPathObjectPtr tempObj =
+ xmlXPathObjectCopy(item);
+ if (tempObj)
+ tempObj = xmlXPathConvertString(tempObj);
+ if (tempObj && tempObj->stringval){
+ fprintf(file, "%s", tempObj->stringval);
+ }else{
+ fprintf(file, "%s", i18n("Unable to convert XPath to string.").utf8().data());
+ }
+ if (tempObj)
+ xmlXPathFreeObject(tempObj);
+ }
+ break;
+ fprintf(file,"\n");
+
+ } /* inner switch statement */
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ fclose(file);
+ file = NULL;
+ /* send the data to application */
+ notifyXsldbgApp(XSLDBG_MSG_FILEOUT, fileName);
+ } else {
+ int lineCount = 0, gdbModeEnabled = 0;
+
+ /* save the value of option to speed things up
+ * a bit */
+ gdbModeEnabled =
+ optionsGetIntOption(OPTIONS_GDB);
+ rewind(file);
+
+ /* when gdb mode is enable then only print the first
+ * GDB_LINES_TO_PRINT lines */
+ while (!feof(file)) {
+ if (fgets
+ ((char *) nodeViewBuffer, sizeof(nodeViewBuffer),
+ file))
+ xsltGenericError
+ (xsltGenericErrorContext, "%s",
+ nodeViewBuffer);
+ if (gdbModeEnabled) {
+ lineCount++;
+ /* there is an overhead of two lines
+ * when print expression values */
+ if (lineCount ==
+ GDB_LINES_TO_PRINT + 2) {
+ xsltGenericError
+ (xsltGenericErrorContext,
+ "...");
+ break;
+ }
+ }
+ }
+ xsltGenericError
+ (xsltGenericErrorContext, "\n");
+ }
+ if (file)
+ fclose(file);
+ result = 1;
+ break;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+
+/**
+ * xslDbgShellCat:
+ * @styleCtxt: the current stylesheet context
+ * @ctxt: The current shell context
+ * @arg: The xpath to print (in UTF-8)
+ *
+ * Print the result of an xpath expression. This can include variables
+ * if styleCtxt is not NULL
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+
+int
+xslDbgShellCat(xsltTransformContextPtr styleCtxt, xmlShellCtxtPtr ctxt,
+ xmlChar * arg)
+{
+ xmlXPathObjectPtr list;
+ int result = 0;
+ static const char * QUIET_STR = "-q";
+ bool silenceCtxtErrors = false;
+
+ if ((arg == NULL) || (xmlStrLen(arg) == 0))
+ arg = (xmlChar *) ".";
+
+ /* Do we quietly ingore style context errors */
+ if (strncasecmp((char*)arg, QUIET_STR, strlen(QUIET_STR))== 0){
+ silenceCtxtErrors = true;
+ arg = arg + strlen(QUIET_STR);
+ while (isspace(*arg)){
+ arg++;
+ }
+ }
+
+ if (!styleCtxt || !ctxt || !ctxt->node) {
+ if (!(!xsldbgReachedFirstTemplate && silenceCtxtErrors))
+ xsldbgGenericErrorFunc(i18n("Warning: Unable to print expression. No stylesheet was properly loaded.\n"));
+ return 0;
+ }
+
+ if ((arg == NULL) || (xmlStrLen(arg) == 0))
+ arg = (xmlChar *) ".";
+
+ ctxt->pctxt->node = ctxt->node;
+ if (!styleCtxt) {
+ list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
+ } else {
+ xmlNodePtr savenode = styleCtxt->xpathCtxt->node;
+
+ ctxt->pctxt->node = ctxt->node;
+ styleCtxt->xpathCtxt->node = ctxt->node;
+ if (!xmlXPathNsLookup(styleCtxt->xpathCtxt, (xmlChar *) "xsl"))
+ xmlXPathRegisterNs(styleCtxt->xpathCtxt, (xmlChar *) "xsl",
+ XSLT_NAMESPACE);
+ list = xmlXPathEval((xmlChar *) arg, styleCtxt->xpathCtxt);
+ styleCtxt->xpathCtxt->node = savenode;
+ }
+ if (list != NULL) {
+ result = printXPathObject(list, arg);
+ xmlXPathFreeObject(list);
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").arg(xsldbgText(arg)));
+ }
+ ctxt->pctxt->node = NULL;
+ return result;
+}
+
+/* only used by xslDbgPrintNames and xslDbgPrintVariable cound number of variables */
+static int varCount;
+
+/*
+ * xslDbgShellPrintNames:
+ * Print a name of variable found by scanning variable table
+ * It is used by print_variable function.
+ * @payload : Global variable of type xsltStackElemPtr
+ * @data : not used
+ * @name : the variable name
+ */
+void *
+xslDbgShellPrintNames(void *payload,
+ void *data, xmlChar * name)
+{
+ Q_UNUSED(payload);
+ Q_UNUSED(data);
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ notifyListQueue(payload);
+ } else if (payload && name) {
+ xmlChar * fullQualifiedName = nodeViewBuffer;
+ xsltStackElemPtr item = (xsltStackElemPtr)payload;
+ if (item->nameURI == NULL){
+ snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s", item->name);
+ }else{
+ snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s:%s",
+ item->nameURI, item->name);
+ }
+ if (printVariableValue == 0){
+ xsldbgGenericErrorFunc(i18n(" Global %1\n").arg(xsldbgText(fullQualifiedName)));
+ }else{
+ if (item->computed == 1){
+ xsldbgGenericErrorFunc(i18n(" Global "));
+ printXPathObject(item->value, fullQualifiedName);
+ }else if (item->tree){
+ xsldbgGenericErrorFunc(i18n(" Global = %1\n").arg(xsldbgText(fullQualifiedName)));
+ xslDbgCatToFile(item->tree, stderr);
+ }else if (item->select){
+ xsldbgGenericErrorFunc(i18n(" Global = %1\n%2").arg(xsldbgText(fullQualifiedName)).arg(xsldbgText(item->select)));
+ }else{
+ /* can't find a value give only a variable name an error message */
+ xsldbgGenericErrorFunc(i18n(" Global = %1\n%2").arg(xsldbgText(fullQualifiedName)).arg(i18n("Warning: No value assigned to variable.\n")));
+ }
+ xsltGenericError(xsltGenericErrorContext, "\n\032\032\n");
+ }
+ varCount++;
+ }
+ return NULL;
+}
+
+
+
+/**
+ * xslDbgShellPrintVariable:
+ * @styleCtxt: The current stylesheet context
+ * @arg: The name of variable to look for '$' prefix is optional and in UTF-8
+ * @type: A valid VariableTypeEnum
+ *
+ * Print the value variable specified by args.
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgShellPrintVariable(xsltTransformContextPtr styleCtxt, xmlChar * arg,
+ VariableTypeEnum type)
+{
+ int result = 0;
+ /* command argument to include both name and its value */
+ static const char * FULLNAME_STR = "-f";
+ /* Quietly exit if an invalid stylesheet is provided */
+ static const char * QUIET_STR = "-q";
+ bool silenceCtxtErrors = false;
+
+ if (!arg) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: NULL argument provided\n");
+#endif
+ return result;
+ }
+
+ varCount = 0;
+ /* Do we quietly ingore style context errors */
+ if (strncasecmp((char*)arg, QUIET_STR, strlen(QUIET_STR))== 0){
+ silenceCtxtErrors = true;
+ arg = arg + strlen(QUIET_STR);
+ while (isspace(*arg)){
+ arg++;
+ }
+ }
+
+ if (!styleCtxt) {
+ if (!(!xsldbgReachedFirstTemplate && silenceCtxtErrors))
+ xsldbgGenericErrorFunc(i18n("Error: Debugger has no files loaded or libxslt has not reached a template.\nTry reloading files or taking more steps.\n"));
+ return result;
+ }
+
+ /* Do we include the name as well as its value */
+ if (strncasecmp((char*)arg, FULLNAME_STR, strlen(FULLNAME_STR))== 0){
+ printVariableValue = 1;
+ arg = arg + strlen(FULLNAME_STR);
+ while (isspace(*arg)){
+ arg++;
+ }
+ }
+ if (arg[0] == 0) {
+ /* list variables of type requested */
+ if (type == DEBUG_GLOBAL_VAR) {
+ if (styleCtxt->globalVars) {
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ notifyListStart(XSLDBG_MSG_GLOBALVAR_CHANGED);
+ /* list global variables */
+ xmlHashScan(styleCtxt->globalVars,
+ (xmlHashScanner) xslDbgShellPrintNames,
+ NULL);
+ notifyListSend();
+ } else
+ /* list global variables */
+ xmlHashScan(styleCtxt->globalVars,
+ (xmlHashScanner) xslDbgShellPrintNames,
+ NULL);
+ result = 1;
+ /* ensure that the locals follow imediately after the
+ * globals when in gdb mode */
+ if (optionsGetIntOption(OPTIONS_GDB) == 0)
+ xsltGenericError(xsltGenericErrorContext, "\n");
+ } else {
+ if (getThreadStatus() != XSLDBG_MSG_THREAD_RUN) {
+ /* Don't show this message when running as a thread as it
+ * is annoying */
+ xsldbgGenericErrorFunc(i18n("Error: Libxslt has not initialized variables yet; try stepping to a template.\n"));
+ } else {
+ /* send an empty list */
+ notifyListStart(XSLDBG_MSG_GLOBALVAR_CHANGED);
+ notifyListSend();
+ result = 1;
+ }
+ }
+ } else {
+ /* list local variables */
+ if (styleCtxt->varsNr && styleCtxt->varsTab) {
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ notifyListStart(XSLDBG_MSG_LOCALVAR_CHANGED);
+ for (int i = styleCtxt->varsNr; i > styleCtxt->varsBase; i--) {
+ xsltStackElemPtr item = styleCtxt->varsTab[i-1];
+ while (item) {
+ notifyListQueue(item);
+ item = item->next;
+ }
+ }
+ notifyListSend();
+ } else {
+ xmlChar * fullQualifiedName = nodeViewBuffer;
+ for (int i = styleCtxt->varsNr; i > styleCtxt->varsBase; i--) {
+ xsltStackElemPtr item = styleCtxt->varsTab[i-1];
+ while (item) {
+ if (item->name) {
+ if (item->nameURI == NULL){
+ snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s",
+ item->name);
+ }else{
+
+ snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s:%s",
+ item->nameURI, item->name);
+ }
+ if (printVariableValue == 0){
+ xsldbgGenericErrorFunc(i18n(" Local %1").arg(xsldbgText(fullQualifiedName)));
+ }else{
+ if (item->computed == 1){
+ xsldbgGenericErrorFunc(i18n(" Local "));
+ printXPathObject(item->value, fullQualifiedName);
+ }else if (item->tree){
+ xsldbgGenericErrorFunc(i18n(" Local = %1\n").arg(xsldbgText(fullQualifiedName)));
+ xslDbgCatToFile(item->tree, stderr);
+ }else if (item->select){
+ xsldbgGenericErrorFunc(i18n(" Local = %1\n%2").arg(xsldbgText(fullQualifiedName)).arg(xsldbgText(item->select)));
+ }else{
+ /* can't find a value give only a variable name and an error */
+ xsldbgGenericErrorFunc(i18n(" Local = %1\n%2").arg(xsldbgText(fullQualifiedName)).arg(i18n("Warning: No value assigned to variable.\n")));
+ }
+ }
+ xsltGenericError(xsltGenericErrorContext, "\n\032\032\n");
+ }
+ item = item->next;
+ }
+ }
+ }
+ result = 1;
+ xsltGenericError(xsltGenericErrorContext, "\n");
+ } else {
+ if (getThreadStatus() != XSLDBG_MSG_THREAD_RUN) {
+ /* Don't show this message when running as a thread as it
+ * is annoying */
+ xsldbgGenericErrorFunc(i18n("Error: Libxslt has not initialized variables yet; try stepping past the xsl:param elements in the template.\n"));
+ } else {
+ /* send an empty list */
+ notifyListStart(XSLDBG_MSG_LOCALVAR_CHANGED);
+ notifyListSend();
+ result = 1;
+ }
+ }
+ }
+ } else {
+ /* Display the value of variable */
+ if (arg[0] == '$') {
+ printXPathObject(xmlXPathEval(arg, styleCtxt->xpathCtxt), arg);
+ xsltGenericError(xsltGenericErrorContext, "\032\032\n");
+ } else {
+ xmlStrCpy(nodeViewBuffer, "$");
+ xmlStrCat(nodeViewBuffer, arg);
+ printXPathObject(xmlXPathEval((xmlChar*)nodeViewBuffer,styleCtxt->xpathCtxt),
+ (xmlChar*)nodeViewBuffer);
+ xsltGenericError(xsltGenericErrorContext, "\032\032\n");
+ }
+
+ }
+
+ printVariableValue = 0;
+ return result;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/option_cmds.cpp b/kxsldbg/kxsldbgpart/libxsldbg/option_cmds.cpp
new file mode 100644
index 00000000..0bc54364
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/option_cmds.cpp
@@ -0,0 +1,299 @@
+
+/***************************************************************************
+ option_cmds.c - implementation for option
+ related commands
+
+ -------------------
+ begin : Fri Feb 1 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 "utils.h"
+#include "options.h"
+#include "xsldbgmsg.h"
+#include "xsldbgthread.h"
+#include "debugXSL.h"
+
+
+/**
+ * xslDbgShellSetOption:
+ * @arg : Is valid, and in the format <NAME> <VALUE>
+ *
+ * Set the value of an option
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgShellSetOption(xmlChar * arg)
+{
+ int result = 0;
+
+ if (!arg) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: NULL argument provided\n");
+#endif
+ return result;
+ }
+
+ if (xmlStrLen(arg) > 0) {
+ xmlChar *opts[2];
+ long optValue;
+ long optID;
+
+
+ if (splitString(arg, 2, opts) == 2) {
+ bool invertOption = false;
+ optID = optionsGetOptionID(opts[0]);
+ if ((optID == -1) && (opts[0][0] == 'n') && (opts[0][1] == 'o')){
+ optID = optionsGetOptionID(&opts[0][2]);
+ if (optID != -1){
+ // invert the value the user provides
+ invertOption = true;
+ }
+ }
+
+ if (optID >= OPTIONS_FIRST_INT_OPTIONID) {
+ if (optID <= OPTIONS_LAST_INT_OPTIONID) {
+ /* handle setting integer option */
+ if ((xmlStrlen(opts[1]) == 0) ||
+ !sscanf((char *) opts[1], "%ld", &optValue)) {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to parse %1 as an option value.\n").arg(xsldbgText(opts[1])));
+ } else {
+ if (invertOption)
+ optValue = !optValue;
+ result = optionsSetIntOption(OptionTypeEnum(optID), optValue);
+ }
+ } else {
+ /* handle setting a string option */
+ result = optionsSetStringOption(OptionTypeEnum(optID), opts[1]);
+
+ }
+ } else {
+ static xmlExternalEntityLoader xsldbgDefaultEntLoader = 0;
+ bool invertOption = false;
+ bool enableNet = false;
+
+ if (!xsldbgDefaultEntLoader)
+ xsldbgDefaultEntLoader = xmlGetExternalEntityLoader();
+
+ if (xmlStrEqual(opts[0], (const xmlChar *)"nonet" ))
+ invertOption = true;
+
+ if (xmlStrEqual(&opts[0][2*invertOption], (const xmlChar *)"net" )){
+ if (sscanf((char *) opts[1], "%ld", &optValue)) {
+ if (invertOption)
+ optValue = !optValue;
+ if (optValue)
+ enableNet = true;
+ result = true;
+ if (enableNet)
+ xmlSetExternalEntityLoader(xsldbgDefaultEntLoader);
+ else
+ xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
+ }else{
+ xsldbgGenericErrorFunc(i18n("Error: Unable to parse %1 as an option value.\n").arg(xsldbgText(opts[1])));
+ }
+ } else
+ xsldbgGenericErrorFunc(i18n("Error: Unknown option name %1.\n").arg(xsldbgText(opts[0])));
+ }
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Missing arguments for the command %1.\n").arg("setoption"));
+ }
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Missing arguments for the command %1.\n").arg("setoption"));
+ }
+
+ return result;
+}
+
+
+
+/**
+ * xslDbgShellOptions:
+ *
+ * Prints out values for user options
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgShellOptions(void)
+{
+ int result = 1;
+ int optionIndex;
+ const xmlChar *optionName, *optionValue;
+
+ /* Print out the integer options and thier values */
+ if (getThreadStatus() != XSLDBG_MSG_THREAD_RUN) {
+ for (optionIndex = OPTIONS_XINCLUDE;
+ optionIndex <= OPTIONS_VERBOSE; optionIndex++) {
+ /* skip any non-user options */
+ optionName = optionsGetOptionName(OptionTypeEnum(optionIndex));
+ if (optionName && (optionName[0] != '*')) {
+ xsldbgGenericErrorFunc(i18n("Option %1 = %2\n").arg(xsldbgText(optionName)).arg(optionsGetIntOption(OptionTypeEnum(optionIndex))));
+
+ }
+ }
+ /* Print out the string options and thier values */
+ for (optionIndex = OPTIONS_OUTPUT_FILE_NAME;
+ optionIndex <= OPTIONS_DATA_FILE_NAME; optionIndex++) {
+ optionName = optionsGetOptionName(OptionTypeEnum(optionIndex));
+ if (optionName && (optionName[0] != '*')) {
+ optionValue = optionsGetStringOption(OptionTypeEnum(optionIndex));
+ if (optionValue) {
+ xsldbgGenericErrorFunc(i18n("Option %1 = \"%2\"\n").arg(xsldbgText(optionName)).arg((char*)optionValue));
+ } else {
+ xsldbgGenericErrorFunc(i18n("Option %1 = \"\"\n").arg(xsldbgText(optionName)));
+
+ }
+ }
+
+ }
+ xsldbgGenericErrorFunc("\n");
+ } else {
+ /* we are now notifying the application of the value of options */
+ parameterItemPtr paramItem;
+
+ notifyListStart(XSLDBG_MSG_INTOPTION_CHANGE);
+ /* send the integer options and their values */
+ for (optionIndex = OPTIONS_XINCLUDE;
+ optionIndex <= OPTIONS_VERBOSE; optionIndex++) {
+ /* skip any non-user options */
+ optionName = optionsGetOptionName(OptionTypeEnum(optionIndex));
+ if (optionName && (optionName[0] != '*')) {
+ paramItem = optionsParamItemNew(optionName, 0L);
+ if (!paramItem) {
+ notifyListSend(); /* send what ever we've got so far */
+ return 0; /* out of memory */
+ }
+ paramItem->intValue = optionsGetIntOption(OptionTypeEnum(optionIndex));
+ notifyListQueue(paramItem); /* this will be free later */
+ }
+ }
+
+ notifyListSend();
+ notifyListStart(XSLDBG_MSG_STRINGOPTION_CHANGE);
+ /* Send the string options and thier values */
+ for (optionIndex = OPTIONS_OUTPUT_FILE_NAME;
+ optionIndex <= OPTIONS_DATA_FILE_NAME; optionIndex++) {
+ optionName = optionsGetOptionName(OptionTypeEnum(optionIndex));
+ if (optionName && (optionName[0] != '*')) {
+ paramItem =
+ optionsParamItemNew(optionName,
+ optionsGetStringOption
+ (OptionTypeEnum(optionIndex)));
+ if (!paramItem) {
+ notifyListSend(); /* send what ever we've got so far */
+ return 0; /* out of memory */
+ } else
+ notifyListQueue(paramItem); /* this will be freed later */
+ }
+ }
+ notifyListSend();
+ }
+
+ return result;
+}
+
+
+ /**
+ * xslDbgShellShowWatches:
+ * @styleCtxt: the current stylesheet context
+ * @ctxt: The current shell context
+ * @showWarnings : If 1 then showWarning messages,
+ * otherwise do not show warning messages
+ *
+ * Print the current watches and their values
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+ int xslDbgShellShowWatches(xsltTransformContextPtr styleCtxt,
+ xmlShellCtxtPtr ctx,int showWarnings)
+{
+ int result = 0, counter;
+ xmlChar* watchExpression;
+ if ((showWarnings == 1) && (arrayListCount(optionsGetWatchList()) == 0)){
+ xsldbgGenericErrorFunc(i18n("\tNo expression watches set.\n"));
+ }
+ for ( counter = 0;
+ counter < arrayListCount(optionsGetWatchList());
+ counter++){
+ watchExpression = (xmlChar*)arrayListGet(optionsGetWatchList(), counter);
+ if (watchExpression){
+ xsldbgGenericErrorFunc(i18n(" WatchExpression %1 ").arg(counter + 1));
+ result = xslDbgShellCat(styleCtxt, ctx, watchExpression);
+ }else
+ break;
+ }
+
+ return result;
+}
+
+
+ /**
+ * xslDbgShellAddWatch:
+ * @arg : A valid xPath of expression to watch the value of
+ *
+ * Add expression to list of expressions to watch value of
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+ int xslDbgShellAddWatch(xmlChar* arg)
+{
+ int result = 0;
+ if (arg){
+ trimString(arg);
+ result = optionsAddWatch(arg);
+ if (!result)
+ xsldbgGenericErrorFunc(i18n("Error: Unable to add watch expression \"%1\". It already has been added or it cannot be watched.\n").arg(xsldbgText(arg)));
+ }
+ return result;
+}
+
+ /**
+ * xslDbgShellDeleteWatch:
+ * @arg : A watch ID to remove or "*" to remove all watches
+ *
+ * Delete a given watch ID from our list of expressions to watch
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+ int xslDbgShellDeleteWatch(xmlChar* arg)
+{
+ int result = 0;
+ long watchID;
+ if (arg){
+ trimString(arg);
+ if (arg[0] == '*') {
+ arrayListEmpty(optionsGetWatchList());
+ }else if ((xmlStrlen(arg) == 0) ||
+ !sscanf((char *) arg, "%ld", &watchID)) {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to parse %1 as a watchID.\n").arg(xsldbgText(arg)));
+ return result;
+ } else {
+ result = optionsRemoveWatch(watchID);
+ if (!result)
+ xsldbgGenericErrorFunc(i18n("Error: Watch expression %1 does not exist.\n").arg(watchID));
+ }
+ }
+ return result;
+}
+
+
+
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/options.cpp b/kxsldbg/kxsldbgpart/libxsldbg/options.cpp
new file mode 100644
index 00000000..9f667eb3
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/options.cpp
@@ -0,0 +1,902 @@
+
+/***************************************************************************
+ options.c - provide the implementation for option
+ related functions
+ -------------------
+ begin : Sat Nov 10 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 "xsldbgthread.h"
+#include "options.h"
+#include "arraylist.h"
+#include "xsldbgmsg.h"
+#include "utils.h"
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <qfileinfo.h>
+#include <qstringlist.h>
+
+
+/* keep track of our integer/boolean options */
+static int intOptions[OPTIONS_LAST_INT_OPTIONID - OPTIONS_FIRST_INT_OPTIONID + 1];
+
+/* make use that use of options are safe by only copying
+ critical values from intVolitleOptions just before stylesheet is started
+ */
+int intVolitileOptions[OPTIONS_LAST_INT_OPTIONID - OPTIONS_FIRST_INT_OPTIONID + 1];
+
+/* keep track of our string options */
+static xmlChar *stringOptions[OPTIONS_LAST_STRING_OPTIONID -
+ OPTIONS_FIRST_STRING_OPTIONID + 1];
+
+/* keep track of our parameters */
+static arrayListPtr parameterList;
+
+/* what are the expressions to be printed out when xsldbg stops */
+static arrayListPtr watchExpressionList;
+
+
+/* the names for our options
+ Items that start with *_ are options that CANNOT be used by the user
+ Once you set an option you need to give a run command to activate
+ new settings */
+const char *optionNames[] = {
+ "xinclude", /* Use xinclude during xml parsing */
+ "docbook", /* Use of docbook sgml parsing */
+ "timing", /* Use of timing */
+ "profile", /* Use of profiling */
+ "valid", /* Enable file validation */
+ "out", /* Enable output to stdout */
+ "html", /* Enable the use of html parsing */
+ "debug", /* Enable the use of xml tree debugging */
+ "shell", /* Enable the use of debugger shell */
+ "gdb", /* Run in gdb modem prints more messages */
+ "preferhtml", /* Prefer html output for search results */
+ "autoencode", /* Try to use the encoding from the stylesheet */
+ "utf8input", /* All input from "user" will be in UTF-8 */
+ "stdout", /* Print all error messages to stdout,
+ * normally error messages go to stderr */
+ "autorestart", /* When finishing the debug of a XSLT script
+ automaticly restart at the beginning */
+ "verbose", /* Be verbose with messages */
+ "repeat", /* The number of times to repeat */
+ "*_trace_*", /* Trace execution */
+ "*_walkspeed_*", /* How fast do we walk through code */
+ "catalogs", /* do we use catalogs in SGML_CATALOG_FILES */
+ "output", /* what is the output file name */
+ "source", /* The stylesheet source to use */
+ "docspath", /* Path of xsldbg's documentation */
+ "catalognames", /* The names of the catalogs to use when the catalogs option is active */
+ "encoding", /* What encoding to use for standard output */
+ "searchresultspath", /* Where do we store the results of search */
+ "data", /* The xml data file to use */
+ NULL /* indicate end of list */
+};
+
+
+
+// find the translated help documentation directory
+// langLookupDir code modified from langLookup function in kdebase/khelpcenter/view.cpp
+
+static QString langLookupDir( const QString &fname )
+{
+ QStringList search;
+
+ // assemble the local search paths
+ QStringList localDoc = KGlobal::dirs()->resourceDirs("html");
+ // also look in each of the KDEDIR paths
+ QString kdeDirs = getenv("KDEDIRS");
+ QStringList kdeDirsList = QStringList::split(":", kdeDirs);
+ if (!kdeDirs.isEmpty() && !kdeDirsList.isEmpty()){
+ for (QStringList::iterator it = kdeDirsList.begin(); it != kdeDirsList.end(); it++)
+ localDoc.append((*it) + "/share/doc/HTML/") ;
+ }
+
+ // look up the different languages
+ for (uint id=0; id < localDoc.count(); id++)
+ {
+ QStringList langs = KGlobal::locale()->languageList();
+ langs.append( "en" );
+ langs.remove( "C" );
+ QStringList::ConstIterator lang;
+ for (lang = langs.begin(); lang != langs.end(); ++lang)
+ search.append(QString("%1%2/%3/%4").arg(localDoc[id]).arg(*lang).arg("xsldbg").arg(fname));
+ }
+
+ // try to locate the file
+ QStringList::Iterator it;
+ for (it = search.begin(); it != search.end(); ++it)
+ {
+ QString baseDir = (*it).left((*it).findRev('/')) ;
+ QFileInfo info(baseDir + "/"+ fname);
+ if (info.exists() && info.isFile() && info.isReadable())
+ return baseDir;
+ }
+
+ return QString::null;
+}
+
+
+/**
+ * optionsInit:
+ *
+ * Intialize the options module
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+optionsInit(void)
+{
+ int optionId;
+
+ for (optionId = 0;
+ optionId <= OPTIONS_LAST_INT_OPTIONID - OPTIONS_FIRST_INT_OPTIONID; optionId++) {
+ intOptions[optionId] = 0;
+ intVolitileOptions[optionId] = 0;
+ }
+
+ for (optionId = 0;
+ optionId <= OPTIONS_LAST_STRING_OPTIONID - OPTIONS_FIRST_STRING_OPTIONID;
+ optionId++) {
+ stringOptions[optionId] = NULL;
+ }
+
+ /* init our parameter list */
+ parameterList = arrayListNew(10, (freeItemFunc) optionsParamItemFree);
+
+ /* setup the docs path */
+ optionsSetStringOption(OPTIONS_DOCS_PATH, (const xmlChar*)(langLookupDir("xsldbghelp.xml").utf8().data()));
+
+ optionsSetIntOption(OPTIONS_TRACE, TRACE_OFF);
+ optionsSetIntOption(OPTIONS_WALK_SPEED, WALKSPEED_STOP);
+ /* always try to use encoding if found */
+ optionsSetIntOption(OPTIONS_AUTOENCODE, 1);
+ /* start up with auto restart turned off */
+ optionsSetIntOption(OPTIONS_AUTORESTART, 0);
+ /* start up with gdb mode turned on */
+ optionsSetIntOption(OPTIONS_GDB, 1);
+ /* start up with output mode turned on */
+ optionsSetIntOption(OPTIONS_OUT, 1);
+ /* start up with validation turned on */
+ optionsSetIntOption(OPTIONS_VALID, 1);
+ /* start up with xinclude turned on */
+ optionsSetIntOption(OPTIONS_XINCLUDE, 1);
+
+ /* set output default as standard output. Must be changed if not using
+ * xsldbg's command line. Or the tty command is used */
+ optionsSetStringOption(OPTIONS_OUTPUT_FILE_NAME, NULL);
+
+ /* init our list of expressions to watch which are only a list of
+ strings ie xmlChar*'s */
+ watchExpressionList = arrayListNew(10, (freeItemFunc) xmlFree);
+
+ return (parameterList && watchExpressionList);
+}
+
+
+/**
+ * optionsFree:
+ *
+ * Free memory used by the options module
+ */
+void
+optionsFree(void)
+{
+ int string_option;
+
+ for (string_option = OPTIONS_FIRST_STRING_OPTIONID;
+ string_option <= OPTIONS_LAST_STRING_OPTIONID; string_option++) {
+ optionsSetStringOption(OptionTypeEnum(string_option), NULL);
+ }
+
+ /* Free up memory used by parameters and watches*/
+ arrayListFree(parameterList);
+ arrayListFree(watchExpressionList);
+ parameterList = NULL;
+ watchExpressionList = NULL;
+}
+
+
+ /**
+ * optionsGetOptionID:
+ * @optionName : A valid option name see documentation for "setoption"
+ * command and program usage documentation
+ *
+ * Find the option id for a given option name
+ *
+ * Returns The optionID for @optionName if successful, where
+ * OPTIONS_FIRST_OPTIONID<= optionID <= OPTIONS_LAST_OPTIONID,
+ * otherwise returns -1
+ */
+int
+optionsGetOptionID(xmlChar * optionName)
+{
+ int result = -1;
+ int optID = lookupName(optionName, (xmlChar **) optionNames);
+
+ if (optID >= 0) {
+ result = optID + OPTIONS_FIRST_OPTIONID;
+ }
+
+ return result;
+}
+
+
+ /**
+ * optionsGetOptionName:
+ * @ID : A valid option ID
+ *
+ * Get the name text for an option
+ *
+ * Returns The name of option if @ID is valid,
+ * NULL otherwise
+ */
+const xmlChar *
+optionsGetOptionName(OptionTypeEnum ID)
+{
+ const xmlChar *result = 0;
+ if ( (ID >= OPTIONS_FIRST_OPTIONID) && (ID <= OPTIONS_LAST_OPTIONID)){
+ /* An option ID is always valid at the moment */
+ result = (const xmlChar *) optionNames[ID - OPTIONS_FIRST_OPTIONID];
+ }
+
+ return result;
+}
+
+
+/**
+ * optionsSetIntOption:
+ * @optionType: A valid boolean option
+ * @value: 1 to enable, 0 otherwise
+ *
+ * Set the state of a boolean xsldbg option to @value
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+optionsSetIntOption(OptionTypeEnum optionType, int value)
+{
+ int type = optionType, result = 1;
+
+ if ((type >= OPTIONS_FIRST_INT_OPTIONID) && (type <= OPTIONS_LAST_INT_OPTIONID)) {
+ /* make sure that use of options are safe by only copying
+ * critical values from intVolitleOptions just before
+ * stylesheet is started
+ */
+ intVolitileOptions[type - OPTIONS_FIRST_INT_OPTIONID] = value;
+
+ /* the following types must be activated imediately */
+ switch (type) {
+
+ case OPTIONS_TRACE:
+ case OPTIONS_WALK_SPEED:
+ case OPTIONS_GDB:
+ intOptions[type - OPTIONS_FIRST_INT_OPTIONID] = value;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ if ((type >= OPTIONS_FIRST_OPTIONID) && (type <= OPTIONS_LAST_OPTIONID)){
+ xsldbgGenericErrorFunc(i18n("Error: Option %1 is not a valid boolean/integer option.\n").arg(xsldbgText(optionNames[type - OPTIONS_FIRST_OPTIONID])));
+ }else{
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsldbgGenericErrorFunc(QString("Error: Invalid arguments for the command %1.\n").arg("setoption"));
+#endif
+ }
+ result = 0;
+ }
+ return result;
+}
+
+
+/**
+ * optionsGetIntOption:
+ * @optionType: A valid boolean option to query
+ *
+ * Return the state of a boolean option
+ *
+ * Returns The state of a boolean xsldbg option.
+ * ie 1 for enabled , 0 for disabled
+ */
+int
+optionsGetIntOption(OptionTypeEnum optionType)
+{
+ int type = optionType, result = 0;
+
+ if ((type >= OPTIONS_FIRST_INT_OPTIONID) && (type <= OPTIONS_LAST_INT_OPTIONID)) {
+ result = intOptions[type - OPTIONS_FIRST_INT_OPTIONID];
+ } else {
+ if ((type >= OPTIONS_FIRST_OPTIONID) && (type <= OPTIONS_LAST_OPTIONID)){
+ xsldbgGenericErrorFunc(i18n("Error: Option %1 is not a valid boolean/integer option.\n").arg(xsldbgText(optionNames[type - OPTIONS_FIRST_OPTIONID])));
+ }else{
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsldbgGenericErrorFunc(QString("Error: Invalid arguments for the command %1.\n").arg("options"));
+#endif
+ }
+ }
+ return result;
+}
+
+
+
+/**
+ * optionsSetStringOption:
+ * @optionType: A valid string option
+ * @value: The value to copy
+ *
+ * Set value for a string xsldbg option to @value.
+ * Any memory used currently by option @optionType will be freed
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+optionsSetStringOption(OptionTypeEnum optionType, const xmlChar * value)
+{
+ int type = optionType, result = 0;
+
+ if ((type >= OPTIONS_FIRST_STRING_OPTIONID) &&
+ (type <= OPTIONS_LAST_STRING_OPTIONID)) {
+ int optionId = type - OPTIONS_FIRST_STRING_OPTIONID;
+
+ if (stringOptions[optionId])
+ xmlFree(stringOptions[optionId]);
+ if (value)
+ stringOptions[optionId] =
+ (xmlChar *) xmlMemStrdup((char *) value);
+ else /* we want to be able to provide a NULL value */
+ stringOptions[optionId] = NULL;
+ result = 1;
+ } else{
+ if ((type >= OPTIONS_FIRST_OPTIONID) && (type <= OPTIONS_LAST_OPTIONID)){
+ xsldbgGenericErrorFunc(i18n("Error: Option %1 is not a valid string xsldbg option.\n").arg(xsldbgText(optionNames[type - OPTIONS_LAST_OPTIONID])));
+ }else{
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsldbgGenericErrorFunc(QString("Error: Invalid arguments for the command %1.\n").arg("setoption"));
+#endif
+ }
+ }
+ return result;
+}
+
+
+/**
+ * optionsGetStringOption:
+ * @optionType: A valid string option
+ *
+ * Get value for a string xsldbg option of @optionType
+
+ * Returns current option value which may be NULL
+ */
+const xmlChar *
+optionsGetStringOption(OptionTypeEnum optionType)
+{
+ int type = optionType;
+ xmlChar *result = NULL;
+
+ if ((type >= OPTIONS_FIRST_STRING_OPTIONID) &&
+ (type <= OPTIONS_LAST_STRING_OPTIONID)) {
+ int optionId = type - OPTIONS_FIRST_STRING_OPTIONID;
+ result = stringOptions[optionId];
+ } else{
+ if ((type >= OPTIONS_FIRST_OPTIONID) && (type <= OPTIONS_LAST_OPTIONID)){
+ xsldbgGenericErrorFunc(i18n("Error: Option %1 is not a valid string xsldbg option.\n").arg(xsldbgText(optionNames[type - OPTIONS_FIRST_OPTIONID])));
+ }else{
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsldbgGenericErrorFunc(QString("Error: Invalid arguments for the command %1.\n").arg("options"));
+#endif
+ }
+ }
+ return result;
+}
+
+
+ /**
+ * optionsCopyVolitleOptions:
+ *
+ * Copy volitile options to the working area for xsldbg to be used
+ * just after xsldbg starts its processing loop
+ */
+void
+optionsCopyVolitleOptions(void)
+{
+ int optionId;
+
+ for (optionId = 0;
+ optionId <= OPTIONS_LAST_INT_OPTIONID - OPTIONS_FIRST_INT_OPTIONID; optionId++) {
+ intOptions[optionId] = intVolitileOptions[optionId];
+ }
+}
+
+
+/**
+ * optionsParamItemNew:
+ * @name: Is valid
+ * @value: Is valid
+ *
+ * Create a new libxslt parameter item
+ * Returns non-null if sucessful
+ * NULL otherwise
+ */
+parameterItemPtr
+optionsParamItemNew(const xmlChar * name, const xmlChar * value)
+{
+ parameterItemPtr result = NULL;
+
+ if (name) {
+ result = (parameterItem *) xmlMalloc(sizeof(parameterItem));
+ if (result) {
+ result->name = (xmlChar *) xmlMemStrdup((char *) name);
+ if (value)
+ result->value = (xmlChar *) xmlMemStrdup((char *) value);
+ else
+ result->value = (xmlChar *) xmlMemStrdup("");
+ result->intValue = -1;
+ }
+ }
+ return result;
+}
+
+
+/**
+ * optionsParamItemFree:
+ * @item: Is valid
+ *
+ * Free memory used by libxslt parameter item @item
+ */
+void
+optionsParamItemFree(parameterItemPtr item)
+{
+ if (item) {
+ if (item->name)
+ xmlFree(item->name);
+ if (item->value)
+ xmlFree(item->value);
+ xmlFree(item);
+ }
+
+}
+
+
+/**
+ * optionsGetParamItemList:
+ *
+ * Return the list of libxlt parameters
+ *
+ * Returns The list of parameters to provide to libxslt when doing
+ * stylesheet transformation if successful
+ * NULL otherwise
+ */
+arrayListPtr
+optionsGetParamItemList(void)
+{
+ return parameterList;
+}
+
+
+/**
+ * optionsPrintParam:
+ * @paramId: 0 =< paramID < arrayListCount(getParamList())
+ *
+ * Print parameter information
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+optionsPrintParam(int paramId)
+{
+ int result = 0;
+ parameterItemPtr paramItem =
+ (parameterItemPtr) arrayListGet(optionsGetParamItemList(),
+ paramId);
+
+ if (paramItem && paramItem->name && paramItem->value) {
+ xsldbgGenericErrorFunc(i18n(" Parameter %1 %2=\"%3\"\n").arg(paramId).arg(xsldbgText(paramItem->name)).arg(xsldbgText(paramItem->value)));
+ result = 1;
+ }
+ return result;
+}
+
+
+/**
+ * optionsPrintParamList:
+ *
+ * Prints all items in parameter list
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+optionsPrintParamList(void)
+{
+ int result = 1;
+ int paramIndex = 0;
+ int itemCount = arrayListCount(optionsGetParamItemList());
+
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ if (itemCount > 0) {
+ while (result && (paramIndex < itemCount)) {
+ result = optionsPrintParam(paramIndex++);
+ }
+ }
+ } else {
+ if (itemCount > 0) {
+ xsltGenericError(xsltGenericErrorContext, "\n");
+ while (result && (paramIndex < itemCount)) {
+ result = optionsPrintParam(paramIndex++);
+ }
+ } else
+ xsldbgGenericErrorFunc(i18n("\nNo parameters present.\n"));
+ }
+ return result;
+}
+
+
+ /**
+ * optionsNode:
+ * @optionType : Is valid, option to convert to a xmlNodePtr
+ *
+ * Convert option into a xmlNodePtr
+ *
+ * Returns the option @optionType as a xmlNodePtr if successful,
+ * NULL otherwise
+ */
+xmlNodePtr
+optionsNode(OptionTypeEnum optionType)
+{
+ xmlNodePtr node = NULL;
+ char numberBuffer[10];
+ int result = 1;
+
+ numberBuffer[0] = '\0';
+ if (optionType <= OPTIONS_VERBOSE) {
+ /* integer option */
+ node = xmlNewNode(NULL, (xmlChar *) "intoption");
+ if (node) {
+ snprintf(numberBuffer, sizeof(numberBuffer), "%d",
+ optionsGetIntOption(optionType));
+ result = result && (xmlNewProp
+ (node, (xmlChar *) "name",
+ (xmlChar *) optionNames[optionType -
+ OPTIONS_XINCLUDE])
+ != NULL);
+ if (result)
+ result = result && (xmlNewProp(node, (xmlChar *) "value",
+ (xmlChar *) numberBuffer) !=
+ NULL);
+ if (!result) {
+ xmlFreeNode(node);
+ node = NULL;
+ }
+
+ }
+ } else {
+ /* string option */
+ node = xmlNewNode(NULL, (xmlChar *) "stringoption");
+ if (node) {
+ result = result && (xmlNewProp
+ (node, (xmlChar *) "name",
+ (xmlChar *) optionNames[optionType -
+ OPTIONS_XINCLUDE])
+ != NULL);
+ if (result) {
+ if (optionsGetStringOption(optionType))
+ result = result && (xmlNewProp
+ (node, (xmlChar *) "value",
+ optionsGetStringOption
+ (optionType)) != NULL);
+ else
+ result = result && (xmlNewProp
+ (node, (xmlChar *) "value",
+ (xmlChar *) "") != NULL);
+ }
+
+ if (!result) {
+ xmlFreeNode(node);
+ node = NULL;
+ }
+
+ }
+ }
+ return node;
+}
+
+
+ /**
+ * optionsReadDoc:
+ * @doc : Is valid xsldbg config document, in the format as indicated
+ * by config.dtd
+ *
+ * Read options from document provided.
+ *
+ * Returns 1 if able to read @doc and load options found,
+ * 0 otherwise
+ */
+int
+optionsReadDoc(xmlDocPtr doc)
+{
+ int result = 1;
+ xmlChar *name, *value;
+ int optID;
+ xmlNodePtr node;
+
+ /* very primative search for config node
+ * we skip the DTD and then go straight to the first child of
+ * config node */
+ if (doc && doc->children->next && doc->children->next->children) {
+ /* find the first configuration option */
+ node = doc->children->next->children;
+ while (node && result) {
+ if (node->type == XML_ELEMENT_NODE) {
+ if (xmlStrCmp(node->name, "intoption") == 0) {
+ name = xmlGetProp(node, (xmlChar *) "name");
+ value = xmlGetProp(node, (xmlChar *) "value");
+ if (name && value && (atoi((char *) value) >= 0)) {
+ optID = lookupName(name, (xmlChar **) optionNames);
+ if (optID >= 0)
+ result =
+ optionsSetIntOption(OptionTypeEnum(optID + OPTIONS_XINCLUDE),
+ atoi((char *) value));
+ }
+ if (name)
+ xmlFree(name);
+ if (value)
+ xmlFree(value);
+ } else if (xmlStrCmp(node->name, "stringoption") == 0) {
+ name = xmlGetProp(node, (xmlChar *) "name");
+ value = xmlGetProp(node, (xmlChar *) "value");
+ if (name && value) {
+ optID = lookupName(name, (xmlChar **) optionNames);
+ if (optID >= 0)
+ result =
+ optionsSetStringOption(OptionTypeEnum(optID + OPTIONS_XINCLUDE),
+ value);
+ }
+ if (name)
+ xmlFree(name);
+ if (value)
+ xmlFree(value);
+ }
+ }
+ node = node->next;
+ }
+ }
+ return result;
+}
+
+
+
+/**
+ * optionsSavetoFile:
+ * @fileName : Must be NON NULL be a local file that can be written to
+ *
+ * Save configuation to file specified
+ *
+ * Returns 1 if able to save options to @fileName,
+ * 0 otherwise
+ */
+int
+optionsSavetoFile(xmlChar * fileName)
+{
+ int result = 0;
+ int optionIndex = 0;
+ xmlDocPtr configDoc;
+ xmlNodePtr rootNode;
+ xmlNodePtr node = NULL;
+
+ if (!fileName) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: NULL file name provided\n");
+#endif
+ return result;
+ }
+
+ configDoc = xmlNewDoc((xmlChar *) "1.0");
+ rootNode = xmlNewNode(NULL, (xmlChar *) "config");
+
+ if (configDoc && rootNode) {
+ xmlCreateIntSubset(configDoc, (xmlChar *) "config", (xmlChar *)
+ "-//xsldbg//DTD config XML V1.0//EN",
+ (xmlChar *) "config.dtd");
+ xmlAddChild((xmlNodePtr) configDoc, rootNode);
+
+ /*now to do the work of adding configuration items */
+ for (optionIndex = OPTIONS_XINCLUDE;
+ optionIndex <= OPTIONS_DATA_FILE_NAME; optionIndex++) {
+ result = 1;
+ if (optionNames[optionIndex - OPTIONS_XINCLUDE][0] == '*')
+ continue; /* don't save non user options */
+
+ node = optionsNode(OptionTypeEnum(optionIndex));
+ if (node)
+ xmlAddChild(rootNode, node);
+ else {
+ result = 0;
+ break;
+ }
+ }
+
+ if (result) {
+ /* so far so good, now to serialize it to disk */
+ if (!xmlSaveFormatFile((char *) fileName, configDoc, 1))
+ result = 0;
+ }
+
+ xmlFreeDoc(configDoc);
+ } else {
+
+ if (configDoc)
+ xmlFreeDoc(configDoc);
+
+ if (rootNode)
+ xmlFreeNode(rootNode);
+
+ }
+
+ return result;
+}
+
+
+
+ /**
+ * optionsConfigState:
+ * @value : Is valid
+ *
+ * Set/Get the state of configuration loading/saving
+ *
+ * Returns The current/new value of configuration flag. Where
+ * @value means:
+ * OPTIONS_CONFIG_READVALUE : No change return current
+ * value of read configuration flag
+ * OPTIONS_CONFIG_WRITING : Clear flag and return
+ * OPTIONS_CONFIG_WRITING which mean configuration
+ * file is being written
+ * OPTIONS_CONFIG_READING : Set flag and return
+ * OPTIONS_CONFIG_READING, which means configuration
+ * file is being read
+ * OPTIONS_CONFIG_IDLE : We are neither reading or writing
+ * configuration and return OPTIONS_CONFIG_IDLE
+ */
+int
+optionsConfigState(OptionsConfigState value)
+{
+ int result = OPTIONS_CONFIG_IDLE;
+
+ /* work around as some compiler refuse to switch on enums */
+ int configValue = value;
+
+ /* hold the current state of configuration reading/writing */
+ static int configState = OPTIONS_CONFIG_IDLE;
+
+ switch (configValue) {
+ case OPTIONS_CONFIG_READVALUE:
+ /* read the current value only */
+ result = configState;
+ break;
+
+ case OPTIONS_CONFIG_READING:
+ case OPTIONS_CONFIG_WRITING:
+ /* update the value */
+ result = configValue;
+ configState = configValue;
+ break;
+ }
+
+ return result;
+}
+
+ /**
+ * optionsAddWatch:
+ * @xPath : A valid xPath to evaluate in a context and
+ * has not already been addded
+ *
+ * Add xPath to be evaluated and printed out each time the debugger stops
+ *
+ * Returns 1 if able to add xPath to watched
+ * 0 otherwise
+ */
+ int optionsAddWatch(const xmlChar* xPath)
+{
+ int result = 0;
+ if (!xPath || (xmlStrlen(xPath) == 0)){
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Invalid XPath supplied\n");
+#endif
+ } else{
+ if (optionsGetWatchID(xPath) == 0){
+ xmlChar * nameCopy = xmlStrdup(xPath);
+ if (nameCopy){
+ arrayListAdd(watchExpressionList, nameCopy);
+ result = 1;
+ }
+ }
+ }
+
+ return result;
+}
+
+
+ /**
+ * optionsGetWatchID:
+ * @xPath : A valid watch expression that has already been added
+ *
+ * Finds the ID of watch expression previously added
+ *
+ * Returns 0 if not found,
+ * otherwise returns the ID of watch expression
+ */
+ int optionsGetWatchID(const xmlChar* xPath)
+{
+ int result = 0, counter;
+ xmlChar* watchExpression;
+ if (!xPath){
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Invalid xPath supplied\n");
+#endif
+ } else{
+ for ( counter = 0;
+ counter < arrayListCount(watchExpressionList);
+ counter++){
+ watchExpression = (xmlChar*)arrayListGet(watchExpressionList, counter);
+ if (watchExpression){
+ if (xmlStrEqual(xPath, watchExpression)){
+ result = counter + 1;
+ break;
+ }
+ }else{
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
+ /**
+ * optionsRemoveWatch:
+ * @watchID : A valid watchID as indicated by last optionsPrintWatches
+ * @showWarnings : Print more error messages if 1,
+ * print less if 0
+ *
+ * Remove the watch with given ID from our list of expressions to watch
+ *
+ * Returns 1 if able to remove to watch expression
+ * 0 otherwise
+ */
+ int optionsRemoveWatch(int watchID)
+{
+ return arrayListDelete(watchExpressionList, watchID - 1);
+}
+
+ /**
+ * optionsGetWatchList:
+ *
+ * Return the current list of expressions to watch
+ *
+ * Return the current list of expressions to watch
+ */
+ arrayListPtr optionsGetWatchList()
+{
+ return watchExpressionList;
+}
+
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/options.h b/kxsldbg/kxsldbgpart/libxsldbg/options.h
new file mode 100644
index 00000000..60ab69d3
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/options.h
@@ -0,0 +1,476 @@
+
+/***************************************************************************
+ options.h - define option related functions
+ -------------------
+ begin : Sat Nov 10 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef OPTIONS_H
+#define OPTIONS_H
+
+#include "arraylist.h"
+
+/**
+ * Provide a mechanism to change option. The Options structure is not in use,
+ * it has been added so that kdoc puts all option related
+ * functions together
+ *
+ * @short file support
+ *
+ * @author Keith Isdale <k_isdale@tpg.com.au>
+ */
+
+/* We want skip most of these includes when building documentation */
+#ifndef BUILD_DOCS
+#include <libxslt/xslt.h>
+#endif
+
+/* ---------------------------------------
+ Misc options
+-------------------------------------------*/
+
+/** The largest number lines of text can be print print printing documents
+ This is equivant to gdb shorting of evaluation values
+ */
+#define GDB_LINES_TO_PRINT 3
+
+
+ enum OptionsConfigState {
+ OPTIONS_CONFIG_READVALUE = -1, /* Read configuration flag */
+ OPTIONS_CONFIG_READING = 1, /* Configuration file is being read */
+ OPTIONS_CONFIG_WRITING, /* Configuration file is being written */
+ OPTIONS_CONFIG_IDLE /* We are neither reading or writing */
+ };
+
+ enum OptionTypeEnum {
+ OPTIONS_XINCLUDE = 500, /* Use xinclude during xml parsing */
+ OPTIONS_FIRST_BOOL_OPTIONID = OPTIONS_XINCLUDE,
+ OPTIONS_FIRST_INT_OPTIONID = OPTIONS_XINCLUDE,
+ OPTIONS_FIRST_OPTIONID = OPTIONS_XINCLUDE,
+ OPTIONS_DOCBOOK, /* Use of docbook sgml parsing */
+ OPTIONS_TIMING, /* Use of timing */
+ OPTIONS_PROFILING, /* Use of profiling */
+ OPTIONS_VALID, /* Enables file validation */
+ OPTIONS_OUT, /* Enables output to stdout */
+ OPTIONS_HTML, /* Enable the use of html parsing */
+ OPTIONS_DEBUG, /* Enable the use of xml tree debugging */
+ OPTIONS_SHELL, /* Enable the use of debugger shell */
+ OPTIONS_GDB, /* Run in gdb modem prints more messages) */
+ OPTIONS_PREFER_HTML, /* Prefer html output for search results */
+ OPTIONS_AUTOENCODE, /* try to use the encoding from the stylesheet */
+ OPTIONS_UTF8_INPUT, /* All input from user is in UTF-8.This normaly
+ * used when xsldbg is running as a thread */
+ OPTIONS_STDOUT, /* Print all error messages to stdout,
+ * normally error messages go to stderr */
+ OPTIONS_AUTORESTART, /* When finishing the debug of a XSLT script
+ automaticly restart at the beginning */
+ OPTIONS_VERBOSE, /* Be verbose with messages */
+ OPTIONS_LAST_BOOL_OPTIONID = OPTIONS_VERBOSE,
+ OPTIONS_REPEAT, /* The number of times to repeat */
+ OPTIONS_TRACE, /* Trace execution */
+ OPTIONS_WALK_SPEED, /* How fast do we walk through code */
+ OPTIONS_CATALOGS, /* Get the catalogs from SGML_CATALOG_FILES and
+ * store it in OPTIONS_CATALOG_NAMES */
+ OPTIONS_LAST_INT_OPTIONID = OPTIONS_CATALOGS,
+ OPTIONS_OUTPUT_FILE_NAME, /* what is the output file name */
+ OPTIONS_FIRST_STRING_OPTIONID = OPTIONS_OUTPUT_FILE_NAME,
+ OPTIONS_SOURCE_FILE_NAME, /* the stylesheet source to use */
+ OPTIONS_DOCS_PATH, /* path of xsldbg's documentation */
+ OPTIONS_CATALOG_NAMES, /* the names of the catalogs to use when catalogs option is active */
+ OPTIONS_ENCODING, /* What encoding to use for standard output */
+ OPTIONS_SEARCH_RESULTS_PATH, /* Where do we store the results of searching */
+ OPTIONS_DATA_FILE_NAME, /* xml data file to use */
+ OPTIONS_LAST_STRING_OPTIONID = OPTIONS_DATA_FILE_NAME,
+ OPTIONS_LAST_OPTIONID = OPTIONS_DATA_FILE_NAME
+ };
+
+ /* define what tracing is used */
+ enum TraceModeEnum {
+ TRACE_OFF = 600, /* disable tracing */
+ TRACE_ON, /* enable tracing */
+ TRACE_RUNNING, /* tracing is running */
+ TRACE_FINISHED /* not needed but just in case */
+ };
+
+ /* what speeds can we walk through a stylesheet */
+ /* must start walkSpeed enums from zero !! */
+ enum WalkSpeedEnum {
+ WALKSPEED_0 = 0,
+ WALKSPEED_STOP = WALKSPEED_0,
+ WALKSPEED_1,
+ WALKSPEED_FAST = WALKSPEED_1,
+ WALKSPEED_2,
+ WALKSPEED_3,
+ WALKSPEED_4,
+ WALKSPEED_5,
+ WALKSPEED_NORMAL = WALKSPEED_5,
+ WALKSPEED_6,
+ WALKSPEED_7,
+ WALKSPEED_8,
+ WALKSPEED_9,
+ WALKSPEED_SLOW = WALKSPEED_9
+ };
+
+extern int intVolitileOptions[OPTIONS_LAST_INT_OPTIONID - OPTIONS_FIRST_INT_OPTIONID + 1];
+
+/* how many microseconds is each speed increase worth*/
+#define WALKDELAY 250000
+
+
+/* for non win32 environments see the macro in xsldebugger/Makefile.am
+ Win32 type systems see macro in libxslt/xsltwin32config.h
+*/
+#ifdef __riscos
+
+/* The environment variable name we are going to use is the readable version
+ of the application name */
+#define XSLDBG_DOCS_DIR_VARIABLE "XSLDebugDocs$Dir"
+#else
+
+/* The environment variable name on normal systems */
+#define XSLDBG_DOCS_DIR_VARIABLE "XSLDBG_DOCS_DIR"
+#endif
+
+/* used to keep track of libxslt paramters
+ see Parameter related options near end of file
+*/
+ typedef struct _parameterItem parameterItem;
+ typedef parameterItem *parameterItemPtr;
+ struct _parameterItem {
+ xmlChar *name; /* libxslt parameter name */
+ xmlChar *value; /* libxslt parameter value */
+ int intValue; /* reserved */
+ };
+
+
+
+/**
+ * Initialized the options module
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+ int optionsInit(void);
+
+
+
+/**
+ * Free memory used by the options module
+ */
+ void optionsFree(void);
+
+
+ /**
+ * Find the option id for a given option name
+ *
+ * @returns The optionID for @optionName if successful, where
+ * OPTIONS_XINCLUDE<= optionID <= OPTIONS_DATA_FILE_NAME,
+ * otherwise returns -1
+ *
+ * @param optionName A valid option name see documentation for "setoption"
+ * command and program usage documentation
+ *
+ */
+ int optionsGetOptionID(xmlChar * optionName);
+
+
+
+ /**
+ * Get the name text for an option
+ *
+ * Returns The name of option if @ID is valid,
+ * NULL otherwise
+ *
+ * @param ID A valid option ID
+ *
+ */
+ const xmlChar *optionsGetOptionName(OptionTypeEnum ID);
+
+
+/**
+ * Set the value of an integer xsldbg option to @p value
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param optionType Is a valid integer option
+ * @param value Is the valid to adopt
+ */
+ int optionsSetIntOption(OptionTypeEnum optionType, int value);
+
+
+/**
+ * @returns The state of a integer xsldbg option
+ *
+ * @param optionType Is a valid integer option
+ */
+ int optionsGetIntOption(OptionTypeEnum optionType);
+
+
+/**
+ * Set value for a string xsldbg option to @p value.
+ * Any memory used currently by option @p optionType will be freed
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param optionType A valid string option
+ * @param value The value to copy
+ */
+ int optionsSetStringOption(OptionTypeEnum optionType,
+ const xmlChar * value);
+
+
+/**
+ * Get value for a string xsldbg option of @p optionType
+ *
+ * @returns current option value which may be NULL
+ *
+ * @param optionType A valid string option
+ */
+ const xmlChar *optionsGetStringOption(OptionTypeEnum optionType);
+
+
+ /**
+ * Copy volitile options to the working area for xsldbg to be used
+ * just after xsldbg starts its processing loop
+ */
+ void optionsCopyVolitleOptions(void);
+
+
+
+/*---------------------------------------------
+ Parameter related options
+-------------------------------------------------*/
+
+
+/**
+ * Return the list of libxlt parameters
+ *
+ * @returns The list of parameters to provide to libxslt when doing
+ * stylesheet transformation if successful
+ * NULL otherwise
+ */
+ arrayListPtr optionsGetParamItemList(void);
+
+
+
+/**
+ * Create a new libxslt parameter item
+ *
+ * @returns non-null if sucessful
+ * NULL otherwise
+ *
+ * @param name Is valid
+ * @param value Is valid
+ */
+ parameterItemPtr optionsParamItemNew(const xmlChar * name,
+ const xmlChar * value);
+
+
+/**
+ * Free memory used by libxslt parameter item @p item
+ *
+ * @param item Is valid
+ */
+ void optionsParamItemFree(parameterItemPtr item);
+
+
+/**
+ * Prints all items in parameter list
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+ int optionsPrintParam(int paramId);
+
+
+
+/**
+ * Prints all items in parameter list
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+ int optionsPrintParamList(void);
+
+/* ---------------------------------------------
+ Option serialization functions
+-------------------------------------------------*/
+
+ /**
+ * Convert option into a xmlNodePtr
+ *
+ * @returns The option @p optionType as a xmlNodePtr if successful,
+ * NULL otherwise
+ *
+ * @param optionType Is valid, option to convert to a xmlNodePtr
+ *
+ */
+ xmlNodePtr optionsNode(OptionTypeEnum optionType);
+
+
+
+ /**
+ * Read options from document provided.
+ *
+ * @returns 1 if able to read @p doc and load options found,
+ * 0 otherwise
+ *
+ * @param doc Is valid xsldbg config document, in the format as indicated
+ * by config.dtd
+ */
+ int optionsReadDoc(xmlDocPtr doc);
+
+
+ /**
+ * Save configuation to file specified
+ *
+ * @returns 1 if able to save options to @fileName,
+ * 0 otherwise
+ *
+ * @fileName : Must be NON NULL be a local file that can be written to
+ */
+ int optionsSavetoFile(xmlChar * fileName);
+
+
+/* ---------------------------------------------
+ Platform specific option functions
+-------------------------------------------------*/
+
+ /**
+ * Intialize the platform specific options module
+ *
+ * This is a platform specific interface
+ *
+ * @returns 1 if sucessful
+ * 0 otherwise
+ */
+ int optionsPlatformInit(void);
+
+
+ /**
+ * Free memory used by the platform specific options module
+ *
+ * This is a platform specific interface
+ *
+ */
+ void optionsPlatformFree(void);
+
+
+ /**
+ * Return xsldbg's the configuration file name
+ *
+ * Returns A copy of the file name that will be used to load xsldbgs
+ * configuration from,
+ * NULL otherwise
+ *
+ * This is a platform specific interface
+ *
+ */
+ xmlChar *optionsConfigFileName(void);
+
+
+ /**
+ * Load options from configuration file/registry
+ *
+ * This is a platform specific interface
+ *
+ * Returns 1 if able to load options
+ * 0 otherwise
+ */
+ int optionsLoad(void);
+
+
+ /**
+ * Save options to configuration file/registry
+ *
+ * This is a platform specific interface
+ *
+ * Returns 1 if able to load options
+ * 0 otherwise
+ */
+ int optionsSave(void);
+
+
+ /**
+ * Set/Get the state of configuration loading/saving. Normally only used
+ * by RISC OS
+ *
+ *
+ * Returns The current/new value of configuration flag. Where
+ * @p value means:
+ * OPTIONS_CONFIG_READVALUE : No change return current
+ * value of read configuration flag
+ * OPTIONS_CONFIG_WRITING : Clear flag and return
+ * OPTIONS_CONFIG_WRITING which mean configuration
+ * file is being written
+ * OPTIONS_CONFIG_READING : Set flag and return
+ * OPTIONS_CONFIG_READING, which means configuration
+ * file is being read
+ * OPTIONS_CONFIG_IDLE : We are neither reading or writing
+ * configuration and return OPTIONS_CONFIG_IDLE
+ *
+ * @param value Is valid
+ *
+ */
+ int optionsConfigState(OptionsConfigState value);
+
+ /**
+ * optionsAddWatch:
+ * @xPath : A valid xPath to evaluate in a context and
+ * has not already been addded
+ *
+ * Add xPath to be evaluated and printed out each time the debugger stops
+ *
+ * Returns 1 if able to add xPath to watched
+ * 0 otherwise
+ */
+ int optionsAddWatch(const xmlChar* xPath);
+
+ /**
+ * optionsGetWatchID:
+ * @xPath : A valid watch expression that has already been added
+ *
+ * Finds the ID of watch expression previously added
+ *
+ * Returns 0 if not found,
+ * otherwise returns the ID of watch expression
+ */
+ int optionsGetWatchID(const xmlChar* xPath);
+
+
+ /**
+ * optionsRemoveWatch:
+ * @watchID : A valid watchID as indicated by last optionsPrintWatches
+ *
+ * Remove the watch with given ID from our list of expressions to watch
+ *
+ * Returns 1 if able to remove to watch expression
+ * 0 otherwise
+ */
+ int optionsRemoveWatch(int watchID);
+
+
+ /**
+ * optionsGetWatchList:
+ *
+ * Return the current list of expressions to watch
+ *
+ * Return the current list of expressions to watch
+ */
+ arrayListPtr optionsGetWatchList(void);
+
+
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/options_unix.cpp b/kxsldbg/kxsldbgpart/libxsldbg/options_unix.cpp
new file mode 100644
index 00000000..27c7d2f1
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/options_unix.cpp
@@ -0,0 +1,118 @@
+
+/***************************************************************************
+ options_unix.c - *nix specific option functions
+ -------------------
+ begin : Tue Jan 29 2002
+ 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 <libxml/parser.h>
+#include <stdlib.h>
+#include <string.h>
+#include "xsldbg.h"
+#include "options.h"
+
+ /**
+ * optionsPlatformInit:
+ *
+ * Intialize the platform specific options module
+ *
+ * This is a platform specific interface
+ *
+ * Returns 1 if sucessful
+ * 0 otherwise
+ */
+int
+optionsPlatformInit(void)
+{
+ return 1;
+}
+
+
+ /**
+ * optionsPlatformFree:
+ *
+ * Free memory used by the platform specific options module
+ *
+ * This is a platform specific interface
+ *
+ */
+void
+optionsPlatformFree(void)
+{
+ /* empty */
+}
+
+ /**
+ * optionsConfigFileName:
+ *
+ * Returns A copy of the file name that will be used to load xsldbgs
+ * configuration from,
+ * NULL otherwise
+ */
+xmlChar *
+optionsConfigFileName(void)
+{
+ xmlChar *result = NULL;
+ const char *homeDir = getenv("HOME");
+ const char *configName = "xsldbg.rc";
+ int bufferSize = 0;
+
+ if (homeDir) {
+ /* give ourselves a bit of room to move */
+ bufferSize = strlen(homeDir) + strlen(configName) + 10;
+ result = (xmlChar *) xmlMalloc(bufferSize);
+ snprintf((char *) result, bufferSize, "%s/%s", homeDir,
+ configName);
+ }
+ return result;
+}
+
+
+ /**
+ * optionsLoad:
+ *
+ * Load options from configuration file/registry
+ *
+ * This is a platform specific interface
+ *
+ * Returns 1 if able to load options
+ * 0 otherwise
+ */
+int
+optionsLoad(void)
+{
+ int result = 0;
+ xmlDocPtr doc = xmlParseFile((char *) optionsConfigFileName());
+
+ if (doc)
+ result = optionsReadDoc(doc);
+ return 0;
+}
+
+
+ /**
+ * optionsSave:
+ *
+ * Save options to configuration file/registry
+ *
+ * This is a platform specific interface
+ *
+ * Returns 1 if able to save options
+ * 0 otherwise
+ */
+int
+optionsSave(void)
+{
+ return optionsSavetoFile(optionsConfigFileName());
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/os_cmds.cpp b/kxsldbg/kxsldbgpart/libxsldbg/os_cmds.cpp
new file mode 100644
index 00000000..dac5bb0f
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/os_cmds.cpp
@@ -0,0 +1,100 @@
+
+/***************************************************************************
+ os_cmds.c - operating system 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"
+
+/* -----------------------------------------
+
+ Operating system related commands
+
+ ------------------------------------------- */
+
+
+/**
+ * xslDbgShellChangeWd:
+ * @path: The path to change to
+ *
+ * Change the current working directory of the operating system
+ *
+ * Returns 1 if able to change xsldbg's working directory to @path
+ * 0 otherwise
+ */
+int
+xslDbgShellChangeWd(xmlChar * path)
+{
+ int result = 0;
+
+ if (xmlStrLen(path)) {
+ /* call function in files.c to do the work */
+ result = changeDir(path);
+ } else
+ xsldbgGenericErrorFunc(i18n("Error: Missing arguments for the command %1.\n").arg("chdir"));
+ return result;
+}
+
+
+/**
+ * xslDbgShellExecute:
+ * @name: The name of command string to be executed by operating system shell
+ * @verbose: If 1 then print extra debugging messages,
+ * normal messages otherwise
+ *
+ * Execute an operating system command
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgShellExecute(xmlChar * name, int verbose)
+{
+ int result = 0;
+
+ /* Quick check to see if we have a command processor; embedded systems
+ * may not have such a thing */
+ if (system(NULL) == 0) {
+ xsldbgGenericErrorFunc(i18n("Error: No command processor available for shell command \"%1\".\n").arg(xsldbgText(name)));
+ } else {
+ int return_code;
+
+ if (verbose)
+ xsldbgGenericErrorFunc(i18n("Information: Starting shell command \"%1\".\n").arg(xsldbgText(name)));
+
+ return_code = system((char *) name);
+ /* JRF: Strictly system returns an implementation defined value -
+ * we are interpreting that value here, so we need
+ * implementation specific code to handle each case */
+
+#ifdef __riscos
+ /* on RISC OS -2 means 'system call failed', otherwise it is the
+ * return code from the sub-program */
+ if (return_code != -2) {
+#else
+ if (return_code == 0) {
+#endif
+ if (verbose)
+ xsldbgGenericErrorFunc(i18n("Information: Finished shell command.\n"));
+ result = 1;
+ } else {
+ if (verbose)
+ xsldbgGenericErrorFunc(i18n("Error: Unable to run command. System error %1.\n").arg(return_code));
+ }
+ }
+ return result;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/param_cmds.cpp b/kxsldbg/kxsldbgpart/libxsldbg/param_cmds.cpp
new file mode 100644
index 00000000..e4255797
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/param_cmds.cpp
@@ -0,0 +1,175 @@
+
+/***************************************************************************
+ param_cmds.c - libxslt parameter 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 "options.h"
+
+#include "xsldbgmsg.h"
+#include "xsldbgthread.h" /* for get thread status */
+
+
+/* -----------------------------------------
+
+ libxslt parameter related commands
+
+ ------------------------------------------- */
+
+/**
+ * xslDbgShellAddParam:
+ * @arg: A string comprised of two words separated by
+ * one or more spaces which are in UTF-8
+ *
+ * Add a libxslt parameter to be sent to libxslt later on
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+*/
+int
+xslDbgShellAddParam(xmlChar * arg)
+{
+ int result = 0;
+ parameterItemPtr paramItem = NULL;
+ static const char *errorPrompt = I18N_NOOP("Failed to add parameter");
+ xmlChar *opts[2];
+
+ if (!arg) {
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("addparam"));
+ }else{
+ if ((xmlStrLen(arg) > 1) && splitString(arg, 2, opts) == 2) {
+ int count;
+ for (count = 0; count < arrayListCount(optionsGetParamItemList()); count++){
+ paramItem = (parameterItemPtr)arrayListGet(optionsGetParamItemList(), count);
+ if (paramItem != NULL){
+ if (xmlStrCmp(opts[0], paramItem->name) == 0){
+ /* parameter exist just update its value */
+ if (paramItem->value)
+ xmlFree(paramItem->value);
+ paramItem->value = xmlStrdup(opts[1]);
+ return 1;
+ }
+ }
+ }
+ paramItem = optionsParamItemNew(opts[0], opts[1]);
+ result = arrayListAdd(optionsGetParamItemList(), paramItem);
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("addparam"));
+ }
+ }
+ if (!result)
+ xsldbgGenericErrorFunc(QString("Error: %1\n").arg(i18n(errorPrompt)));
+ else {
+ xsldbgGenericErrorFunc("\n");
+ }
+ return result;
+}
+
+
+/**
+ * xslDbgShellDelParam:
+ * @arg: A single white space trimmed parameter number to look for
+ *
+ * Delet a libxslt parameter to be sent to libxslt later on
+ *
+ * Returns 1 if able to delete parameter @name,
+ * 0 otherwise
+ */
+int
+xslDbgShellDelParam(xmlChar * arg)
+{
+ int result = 0;
+ static const char *errorPrompt = I18N_NOOP("Failed to delete parameter");
+ long paramId;
+ xmlChar *opts[2];
+
+ if (!arg) {
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("delparam"));
+ }else{
+ if (xmlStrLen(arg) > 0) {
+ if (splitString(arg, 1, opts) == 1) {
+ if ((xmlStrlen(opts[0]) == 0) ||
+ !sscanf((char *) opts[0], "%ld", &paramId)) {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to parse %1 as a line number.\n").arg(xsldbgText(opts[0])));
+ } else {
+ result =
+ arrayListDelete(optionsGetParamItemList(), paramId);
+ if (!result)
+ xsldbgGenericErrorFunc(i18n("Error: Unable to find parameter %1.\n").arg(paramId));
+ }
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("delparam"));
+ }
+ } else {
+ /* Delete all parameters */
+ arrayListEmpty(optionsGetParamItemList());
+ result = 1;
+ }
+ }
+ if (!result)
+ xsldbgGenericErrorFunc(QString("Error: %1\n").arg(i18n(errorPrompt)));
+ else
+ xsldbgGenericErrorFunc("\n");
+
+ return result;
+}
+
+
+/**
+ * xslDbgShellShowParam:
+ * @arg: Not used
+ *
+ * Print list of current paramters
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgShellShowParam(xmlChar * arg)
+{
+ Q_UNUSED(arg);
+ int result = 0;
+ static const char *errorPrompt = I18N_NOOP("Unable to print parameters");
+
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ int paramIndex = 0;
+ int itemCount = arrayListCount(optionsGetParamItemList());
+
+ notifyListStart(XSLDBG_MSG_PARAMETER_CHANGED);
+
+ if (itemCount > 0) {
+ parameterItemPtr paramItem = NULL;
+
+ while (paramIndex < itemCount) {
+ paramItem = (parameterItemPtr)
+ arrayListGet(optionsGetParamItemList(), paramIndex++);
+ if (paramItem != NULL)
+ notifyListQueue(paramItem);
+ }
+ }
+ notifyListSend();
+ result = 1;
+ } else {
+
+ if (optionsPrintParamList())
+ result = 1;
+ else
+ xsldbgGenericErrorFunc(QString("Error: %1\n").arg(i18n(errorPrompt)));
+ xsldbgGenericErrorFunc("\n");
+ }
+ return result;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/qtnotifier2.h b/kxsldbg/kxsldbgpart/libxsldbg/qtnotifier2.h
new file mode 100644
index 00000000..dfe57f0c
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/qtnotifier2.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ qtnotifier.h - notify the qt app of changes
+ -------------------
+ begin : Sun Dec 23 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef QTNOTIFIER_H
+#define QTNOTIFIER_H
+
+#if defined WIN32
+#include <libxsldbg/xsldbgwin32config.h>
+#endif
+
+#include "xsldbgnotifier.h"
+
+
+class XsldbgDebuggerBase;
+
+extern "C" {
+
+ void connectNotifier(XsldbgDebuggerBase *debugger);
+ int qtNotifyXsldbgApp(XsldbgMessageEnum type, const void *data);
+ int qtNotifyStateXsldbgApp(XsldbgMessageEnum type, int commandId, XsldbgCommandStateEnum commandState, const char *text);
+ int qtNotifyTextXsldbgApp(XsldbgMessageEnum type, const char *text);
+}
+
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/search.cpp b/kxsldbg/kxsldbgpart/libxsldbg/search.cpp
new file mode 100644
index 00000000..68fcd7e1
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/search.cpp
@@ -0,0 +1,1584 @@
+
+/***************************************************************************
+ search.c - search implementation
+ -------------------
+ begin : Fri Nov 2 2001
+ copyright : (C) 2001 by Keith Isdale
+ email : k_isdale@tpg.com.au
+ ***************************************************************************/
+
+
+#include "xsldbg.h"
+#include "debugXSL.h"
+#include "breakpoint.h"
+#include "search.h"
+#include "options.h"
+#include "files.h"
+
+#ifdef __riscos
+
+/* Include for filename conversions */
+#include "libxml/riscos.h"
+#endif
+
+/* our private function*/
+void scanForBreakPoint(void *payload, void *data,
+ xmlChar * name);
+
+/* store all data in this document so we can write it to file*/
+static xmlDocPtr searchDataBase;
+
+/* the topmost node in document*/
+static xmlNodePtr searchDataBaseRoot;
+
+/* what was the last query that was run */
+static xmlChar *lastQuery;
+
+#define BUFFER_SIZE 500
+static xmlChar searchBuffer[BUFFER_SIZE];
+
+/* -----------------------------------------
+ Private function declarations for dbgsearch.c
+ -------------------------------------------*/
+
+/**
+ * findNodeByLineNoHelper:
+ * @payload: valid xsltStylesheetPtr
+ * @data: valid searchInfoPtr
+ * @name: not used
+ *
+ * We are walking through stylesheets looking for a match
+ */
+void
+ findNodeByLineNoHelper(void *payload, void *data,
+ xmlChar * name);
+
+/**
+ * globalVarHelper:
+ * @payload: valid xsltStylesheetPtr
+ * @data: is valid
+ * @name: not used
+ *
+ * Helper to find the global variables. We are given control via
+ * walkStylesheets globalWalkFunc will always be set to the
+ * walkFunc to call
+ */
+void
+ globalVarHelper(void **payload, void *data,
+ xmlChar * name);
+
+/**
+ * localVarHelper:
+ * @payload: valid xsltTemplatePtr
+ * @data: is valid
+ * @name: not used
+ *
+ * Helper to find the local variables. We are given control via walkTemplates
+ * globalWalkFunc will always be set to the walkFunc to call
+ * localWalkFunc will always be set to the walkFunc to call
+ */
+void
+ localVarHelper(void **payload, void *data,
+ xmlChar * name);
+
+
+/* -------------------------------------
+ End private functions
+ ---------------------------------------*/
+
+
+/**
+ * searchInit:
+ *
+ * Initialize the search module
+ *
+ * Returns 1 if search structures have been initialized properly and all
+ * memory required has been obtained,
+ * 0 otherwise
+*/
+int
+searchInit(void)
+{
+ searchDataBase = NULL;
+ searchDataBaseRoot = NULL;
+ lastQuery = NULL;
+ if (!searchEmpty()) {
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ }
+ return (searchRootNode() != NULL);
+}
+
+
+/**
+ * searchFree:
+ *
+ * Free all memory used by the search module
+ */
+void
+searchFree(void)
+{
+ if (searchDataBase) {
+ xmlFreeDoc(searchDataBase);
+ searchDataBase = NULL;
+ searchDataBaseRoot = NULL;
+ }
+}
+
+
+/**
+ * searchNewInfo:
+ * @type: What type of search is required
+ *
+ * Create a new search
+ *
+ * Returns A valid search info pointer if successful
+ * NULL otherwise
+ */
+searchInfoPtr
+searchNewInfo(SearchEnum type)
+{
+ searchInfoPtr result = NULL;
+ int searchType = type;
+
+ switch (searchType) {
+ case SEARCH_BREAKPOINT:
+ result = (searchInfoPtr) xmlMalloc(sizeof(searchInfo));
+ if (result) {
+ breakPointSearchDataPtr searchData;
+
+ result->type = SEARCH_BREAKPOINT;
+ searchData = (breakPointSearchDataPtr)
+ xmlMalloc(sizeof(breakPointSearchData));
+ if (searchData) {
+ searchData->id = -1;
+ searchData->templateName = NULL;
+ searchData->breakPtr = NULL;
+ result->data = searchData;
+ } else {
+ xmlFree(result);
+ result = NULL;
+ }
+ }
+ break;
+
+ case SEARCH_NODE:
+ result = (searchInfoPtr) xmlMalloc(sizeof(searchInfo));
+ if (result) {
+ nodeSearchDataPtr searchData;
+
+ result->type = SEARCH_NODE;
+ searchData =
+ (nodeSearchDataPtr) xmlMalloc(sizeof(nodeSearchData));
+ if (searchData) {
+ searchData->node = NULL;
+ searchData->lineNo = -1;
+ searchData->url = NULL;
+ searchData->nameInput = NULL;
+ searchData->guessedNameMatch = NULL;
+ searchData->absoluteNameMatch = NULL;
+ result->data = searchData;
+ } else {
+ xmlFree(result);
+ result = NULL;
+ }
+ }
+ break;
+
+ case SEARCH_XSL:
+ break;
+
+ case SEARCH_VARIABLE:
+ result = (searchInfoPtr) xmlMalloc(sizeof(searchInfo));
+ if (result) {
+ variableSearchDataPtr searchData;
+
+ result->type = SEARCH_VARIABLE;
+ searchData = (variableSearchDataPtr)
+ xmlMalloc(sizeof(variableSearchData));
+ if (searchData) {
+ searchData->name = NULL;
+ searchData->nameURI = NULL;
+ searchData->select = NULL;
+ result->data = searchData;
+ } else {
+ xmlFree(result);
+ result = NULL;
+ }
+ }
+ break;
+
+ }
+ if (result) {
+ result->found = 0;
+ result->error = 0;
+ }
+ return result;
+}
+
+
+/**
+ * searchFreeInfo:
+ * @info: valid search info
+ *
+ * Free memory used by @info
+ */
+void
+searchFreeInfo(searchInfoPtr info)
+{
+ if (info) {
+ if (info->data) {
+ switch (info->type) {
+ case SEARCH_BREAKPOINT:
+ {
+ breakPointSearchDataPtr searchData =
+ (breakPointSearchDataPtr) info->data;
+
+ if (searchData->templateName)
+ xmlFree(searchData->templateName);
+ }
+ break;
+
+ case SEARCH_NODE:
+ {
+ nodeSearchDataPtr searchData =
+ (nodeSearchDataPtr) info->data;
+
+ if (searchData->url)
+ xmlFree(searchData->url);
+
+ if (searchData->nameInput)
+ xmlFree(searchData->nameInput);
+
+ if (searchData->guessedNameMatch)
+ xmlFree(searchData->guessedNameMatch);
+
+ if (searchData->absoluteNameMatch)
+ xmlFree(searchData->absoluteNameMatch);
+
+ /* we never free searchData->node as we did not create it! */
+ }
+ break;
+
+ case SEARCH_XSL:
+ break;
+
+ case SEARCH_VARIABLE:
+ {
+ variableSearchDataPtr searchData =
+ (variableSearchDataPtr) info->data;
+
+ if (searchData->name)
+ xmlFree(searchData->name);
+
+ if (searchData->nameURI)
+ xmlFree(searchData->nameURI);
+
+ if (searchData->select)
+ xmlFree(searchData->select);
+ }
+ break;
+
+ }
+ xmlFree(info->data);
+ }
+ xmlFree(info);
+ }
+}
+
+
+/**
+ * searchEmpty:
+ *
+ * Empty the seach dataBase of its contents
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+searchEmpty(void)
+{
+ if (searchDataBase) {
+ xmlFreeDoc(searchDataBase);
+ }
+ searchDataBase = xmlNewDoc((xmlChar *) "1.0");
+ searchDataBaseRoot = NULL;
+ if (searchDataBase) {
+ xmlCreateIntSubset(searchDataBase,
+ (xmlChar *) "search", (xmlChar *)
+ "-//xsldbg//DTD search XML V1.1//EN",
+ (xmlChar *) "search_v1_1.dtd");
+ searchDataBaseRoot = xmlNewNode(NULL, (xmlChar *) "search");
+ if (searchDataBaseRoot)
+ xmlAddChild((xmlNodePtr) searchDataBase, searchDataBaseRoot);
+ }
+ if (lastQuery)
+ xmlFree(lastQuery);
+ lastQuery = NULL;
+ if (searchRootNode() == NULL) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to clear old search results, memory error?\n");
+#endif
+ }
+
+ return (searchRootNode() != NULL);
+}
+
+
+/**
+ * searchDoc:
+ *
+ * Return the document used for seaching ie the search dataBase
+ *
+ * Returns The document used for searching
+ * Dangerous function to use! Does NOT return a copy of
+ * search data so don't free it
+ */
+xmlDocPtr
+searchDoc(void)
+{
+ return searchDataBase;
+}
+
+
+/**
+ * searchRootNode:
+ *
+ * Get the topmost node in the search dataBase
+ *
+ * Returns The topmost xml node in search dataBase.
+ * Dangerous function to use! Does NOT return a copy of
+ * search root node so don't free it
+ */
+xmlNodePtr
+searchRootNode(void)
+{
+ return searchDataBaseRoot;
+}
+
+
+/**
+ * searchAdd:
+ * @node: Is valid
+ *
+ * Add a node to the search dataBase
+ *
+ * Returns 1 if able to add @node to top node in search dataBase,
+ * 0 otherwise
+ */
+int
+searchAdd(xmlNodePtr node)
+{
+ int result = 0;
+
+ if (node && searchDataBaseRoot
+ && xmlAddChild(searchDataBaseRoot, node)) {
+ result = 1;
+ }
+
+ return result;
+}
+
+
+/**
+ * searchSave:
+ * @fileName: A valid file name, or NULL for the default
+ *
+ * Save the search dataBase to @fileName
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+searchSave(const xmlChar * fileName)
+{
+
+ int result = 0;
+ xmlChar *searchInput = NULL;
+
+ if (fileName == NULL)
+ searchInput = filesSearchFileName(FILES_SEARCHINPUT);
+ else
+ searchInput = xmlStrdup(fileName);
+
+ if (xmlSaveFormatFile((char *) searchInput, searchDataBase, 1) != -1){
+ result = 1;
+ }else{
+ xsldbgGenericErrorFunc(i18n("Error: Unable to write search Database to file %1. Try setting the \"searchresultspath\" option to a writable path.\n").arg(xsldbgText(searchInput)));
+ }
+
+ if (searchInput)
+ xmlFree(searchInput);
+
+ return result;
+}
+
+
+/**
+ * searchQuery:
+ * @query: The query to run . If NULL then query is "//search/ *"
+ * @tempFile: Where do we load the search dataBase from to execute
+ * query. If tempFile is NULL "searchresult.xml" is used
+ * @outputFile : Where do we store the result. If NULL
+ * then default to "searchresult.html"
+ *
+ * Send query as parameter for execution of search.xsl using
+ * data stored in @tempFile
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+searchQuery(const xmlChar * tempFile, const xmlChar * outputFile,
+ const xmlChar * query)
+{
+ int result = 0;
+
+ /* The file name of where the input is comming from */
+ xmlChar *searchInput = NULL;
+
+ /* The XSL file name to use during transformation of searchInput */
+ xmlChar *searchXSL = NULL;
+
+ /* Where to store the result of transformation */
+ xmlChar *searchOutput = NULL;
+
+
+ /* if a tempFile if provided its up you to make sure that it is correct !! */
+ if (tempFile == NULL)
+ searchInput = filesSearchFileName(FILES_SEARCHINPUT);
+ else
+ searchInput = xmlStrdup(tempFile);
+
+ searchXSL = filesSearchFileName(FILES_SEARCHXSL);
+
+ /* if a outputFile if provided its up you to make sure that it is correct */
+ if (outputFile == NULL)
+ searchOutput = filesSearchFileName(FILES_SEARCHRESULT);
+ else
+ searchOutput = xmlStrdup(outputFile);
+
+ if (!query || (xmlStrlen(query) == 0))
+ query = (xmlChar *) "--param query //search/*";
+
+ /* see configure.in for the definition of XSLDBG_BIN, the name of our binary */
+ if (searchInput && searchXSL && searchOutput) {
+ if (optionsGetIntOption(OPTIONS_CATALOGS) == 0)
+ snprintf((char *) searchBuffer, sizeof(searchBuffer),
+ "%s -o %s %s %s %s", XSLDBG_BIN,
+ searchOutput, query, searchXSL, searchInput);
+ else
+ /* assume that we are to use catalogs as well in our query */
+ snprintf((char *) searchBuffer, sizeof(searchBuffer),
+ "%s --catalogs -o %s %s %s %s", XSLDBG_BIN,
+ searchOutput, query, searchXSL, searchInput);
+ result = xslDbgShellExecute(searchBuffer, 1);
+
+ if (result && (optionsGetIntOption(OPTIONS_PREFER_HTML) == 0)) {
+ /* try printing out the file */
+ result = filesMoreFile(searchOutput, NULL);
+ }
+
+ xsldbgGenericErrorFunc(i18n("Information: Transformed %1 using %2 and saved to %3.\n").arg(xsldbgText(searchInput)).arg(xsldbgText(searchXSL)).arg(xsldbgText(searchOutput)));
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments to command %1.\n").arg("search"));
+ }
+
+ if (searchInput)
+ xmlFree(searchInput);
+
+ if (searchXSL)
+ xmlFree(searchXSL);
+
+ if (searchOutput)
+ xmlFree(searchOutput);
+
+ return result;
+}
+
+
+/**
+ * scanForBreakPoint:
+ * @payload: A valid breakPointPtr
+ * @data: The criteria to look for and a valid searchInfoPtr of
+ * type SEARCH_BREAKPOINT
+ * @name: Not used
+ *
+ * Test if break point matches criteria given by @data. If so then
+ * set @data->found to 1 and stores reference to break point found in
+ * @data->data->node
+ * otherwise @data is unchanged
+*/
+void
+scanForBreakPoint(void *payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(name);
+ breakPointPtr breakPtr = (breakPointPtr) payload;
+ searchInfoPtr searchInf = (searchInfoPtr) data;
+ breakPointSearchDataPtr searchData = NULL;
+ int found = 0;
+
+ if (!payload || !searchInf || !searchInf->data
+ || (searchInf->type != SEARCH_BREAKPOINT) || searchInf->found)
+ return;
+
+ searchData = (breakPointSearchDataPtr) searchInf->data;
+
+ if (searchData->id && (breakPtr->id == searchData->id))
+ found = 1;
+ else if (searchData->templateName && breakPtr->templateName &&
+ (xmlStrCmp(breakPtr->templateName, searchData->templateName)
+ == 0))
+ found = 1;
+
+ if (found) {
+ searchInf->found = 1;
+ searchData->breakPtr = breakPtr;
+ }
+}
+
+
+
+/**
+ * scanForNode:
+ * @payload: A valid xmlNodePtr
+ * @data: The criteria to look for and a valid searchInfo of
+ * type SEARCH_NODE
+ * @name: Not used
+
+ * Test if node matches criteria given by @data if so then set @data->found
+ * to 1 and stores reference to node found in @data->data->node
+ * otherwise @data is unchanged
+ */
+void
+scanForNode(void *payload, void *data, xmlChar * name)
+{
+ Q_UNUSED(name);
+ searchInfoPtr searchInf = (searchInfoPtr) data;
+ nodeSearchDataPtr searchData = NULL;
+ xmlNodePtr node = (xmlNodePtr) payload;
+ xmlChar *baseUri = NULL;
+ int match = 1;
+
+ if (!node || !node->doc || !node->doc->URL ||
+ !searchInf || (searchInf->type != SEARCH_NODE))
+ return;
+
+ searchData = (nodeSearchDataPtr) searchInf->data;
+
+ if (searchData->lineNo >= 0)
+ match = searchData->lineNo == xmlGetLineNo(node);
+
+ if (searchData->url)
+ baseUri = filesGetBaseUri(node);
+ if (baseUri) {
+ match = match && (xmlStrCmp(searchData->url, baseUri) == 0);
+ xmlFree(baseUri);
+ } else {
+ match = match && (xmlStrcmp(searchData->url, node->doc->URL) == 0);
+ }
+
+ if (match) {
+ searchData->node = node;
+ searchInf->found = 1;
+ }
+
+}
+
+
+/**
+ * findNodeByLineNoHelper:
+ * @payload: A valid xsltStylesheetPtr
+ * @data: A valid searchInfoPtr
+ * @name: Not used
+ *
+ * We are walking through stylesheets looking for a match
+ */
+void
+findNodeByLineNoHelper(void *payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(name);
+ xsltStylesheetPtr style = (xsltStylesheetPtr) payload;
+ searchInfoPtr searchInf = (searchInfoPtr) data;
+
+ if (!payload || !searchInf || !style->doc)
+ return;
+
+ walkChildNodes((xmlHashScanner) scanForNode, searchInf,
+ (xmlNodePtr) style->doc);
+
+ /* try the included stylesheets */
+ if (!searchInf->found)
+ walkIncludes((xmlHashScanner) scanForNode, searchInf, style);
+}
+
+
+/**
+ * findNodeByLineNo:
+ * @ctxt: Valid ctxt to look into
+ * @url: Non-null, non-empty file name that has been loaded by debugger
+ * @lineNumber: @lineNumber >= 0 and is available in @url
+ *
+ * Finds the closest line number in file specified that can be a point
+ *
+ * Returns The node at line number number specified if successfull,
+ * NULL otherwise
+ */
+xmlNodePtr
+findNodeByLineNo(xsltTransformContextPtr ctxt,
+ const xmlChar * url, long lineNumber)
+{
+ xmlNodePtr result = NULL;
+ searchInfoPtr searchInf = searchNewInfo(SEARCH_NODE);
+ nodeSearchDataPtr searchData = NULL;
+
+ if (!searchInf) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Unable to create searchInfo in findNodeByLineNo\n");
+#endif
+ return result;
+ }
+
+ if (!ctxt || !url || (lineNumber == -1)) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Invalid ctxt, url or line number to findNodeByLineNo\n");
+#endif
+ return result;
+ }
+
+ searchData = (nodeSearchDataPtr) searchInf->data;
+ searchData->url = (xmlChar *) xmlMemStrdup((char *) url);
+ searchData->lineNo = lineNumber;
+ walkStylesheets((xmlHashScanner) findNodeByLineNoHelper, searchInf,
+ ctxt->style);
+ if (!searchInf->found) {
+ /* try searching the document set */
+ xsltDocumentPtr document = ctxt->document;
+
+ while (document && !searchInf->found) {
+ walkChildNodes((xmlHashScanner) scanForNode, searchInf,
+ (xmlNodePtr) document->doc);
+ document = document->next;
+ }
+ }
+ result = searchData->node;
+ searchFreeInfo(searchInf);
+
+ return result;
+}
+
+
+/**
+ * findTemplateNode:
+ * @style: A valid stylesheet collection to look into
+ * @name: A valid template name to look for
+ *
+ * Find a template node
+ *
+ * Returns The template node found if successful,
+ * NULL otherwise
+ */
+xmlNodePtr
+findTemplateNode(xsltStylesheetPtr style, const xmlChar * name)
+{
+ xmlNodePtr result = NULL;
+ xmlChar *templName;
+ xsltTemplatePtr templ;
+
+ if (!style || !name) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Invalid stylesheet or template name : findTemplateNode\n");
+#endif
+ return result;
+ }
+
+ while (style) {
+ templ = style->templates;
+
+ while (templ) {
+ if (templ->match)
+ templName = (xmlChar *) templ->match;
+ else
+ templName = (xmlChar *) templ->name;
+
+ if (templName) {
+ if (!xmlStrCmp((char *) templName, (char *) name)) {
+ return templ->elem;
+ }
+ }
+ templ = templ->next;
+ }
+ if (style->next)
+ style = style->next;
+ else
+ style = style->imports;
+ }
+
+ if (!result)
+ xsldbgGenericErrorFunc(i18n("Error: XSLT template named \"%1\" was not found.\n").arg(xsldbgText(name)));
+ return result;
+}
+
+
+/**
+ * findBreakPointByName:
+ * @templateName: The template name to look for
+ *
+ * Find the breakpoint at template with "match" or "name" equal
+ * to templateName
+ *
+ * Returns The break point that matches @templateName
+ * NULL otherwise
+*/
+breakPointPtr
+findBreakPointByName(const xmlChar * templateName)
+{
+ breakPointPtr result = NULL;
+ searchInfoPtr searchInf = searchNewInfo(SEARCH_BREAKPOINT);
+ breakPointSearchDataPtr searchData;
+
+ if (!searchInf || (searchInf->type != SEARCH_BREAKPOINT))
+ return result;
+
+ searchData = (breakPointSearchDataPtr) searchInf->data;
+ searchData->templateName = (xmlChar *) xmlStrdup(templateName);
+ if (templateName) {
+ walkBreakPoints((xmlHashScanner) scanForBreakPoint, searchInf);
+ if (!searchInf->found) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Breakpoint with template name of \"%s\" not found\n",
+ templateName);
+#endif
+ } else
+ result = searchData->breakPtr;
+ }
+
+ searchFreeInfo(searchInf);
+
+ return result;
+}
+
+
+/**
+ * findBreakPointById:
+ * @id: The break point id to look for
+ *
+ * Find a break point by its id
+ *
+ * Returns The break point with given the break point id if found,
+ * NULL otherwise
+ */
+breakPointPtr
+findBreakPointById(int id)
+{
+ breakPointPtr result = NULL;
+ searchInfoPtr searchInf = searchNewInfo(SEARCH_BREAKPOINT);
+ breakPointSearchDataPtr searchData;
+
+ if (!searchInf || !searchInf->data)
+ return result;
+
+ searchData = (breakPointSearchDataPtr) searchInf->data;
+ if (id >= 0) {
+ searchData->id = id;
+ walkBreakPoints((xmlHashScanner) scanForBreakPoint, searchInf);
+ if (!searchInf->found) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: Breakpoint id %d not found\n", id);
+#endif
+ } else
+ result = searchData->breakPtr;
+ }
+
+ searchFreeInfo(searchInf);
+ return result;
+}
+
+
+/**
+ * findNodesByQuery:
+ * @query: The xpath query to run, see docs/en/search.dtd for more details
+ *
+ * Find nodes in search dataBase using an xpath query
+ *
+ * Returns The nodes that match the given query on success,
+ * NULL otherwise
+ */
+xmlXPathObjectPtr
+findNodesByQuery(const xmlChar * query)
+{
+ Q_UNUSED(query);
+ xmlXPathObjectPtr list = NULL;
+
+ return list;
+}
+
+
+
+/**
+ * walkBreakPoints:
+ * @walkFunc: The function to callback for each break point found
+ * @data: The extra data to pass onto walkFunc
+ *
+ * Walks through all break points calling walkFunc for each. The payload
+ * sent to walkFunc is of type breakPointPtr
+ */
+void
+walkBreakPoints(xmlHashScanner walkFunc, void *data)
+{
+ int lineNo;
+ xmlHashTablePtr hashTable;
+
+ if (!walkFunc)
+ return;
+
+ for (lineNo = 0; lineNo < breakPointLinesCount(); lineNo++) {
+ hashTable = breakPointGetLineNoHash(lineNo);
+ if (hashTable) {
+ xmlHashScan(hashTable, walkFunc, data);
+ }
+ }
+}
+
+
+/**
+ * walkTemplates:
+ * @walkFunc: The function to callback for each template found
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Walks through all templates calling walkFunc for each. The payload
+ * of walkFunc is of type xsltTemplatePtr
+ */
+void
+walkTemplates(xmlHashScanner walkFunc, void *data, xsltStylesheetPtr style)
+{
+ xsltTemplatePtr templ;
+
+ if (!walkFunc || !style)
+ return;
+
+ while (style) {
+ templ = style->templates;
+ while (templ) {
+ (*walkFunc) (templ, data, NULL);
+ templ = templ->next;
+ }
+ if (style->next)
+ style = style->next;
+ else
+ style = style->imports;
+ }
+}
+
+
+/**
+ * walkStylesheets:
+ * @walkFunc: The function to callback for each stylesheet found
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Walks through all templates calling walkFunc for each. The payload
+ * sent to walkFunc is of type xsltStylesheetPtr
+ */
+void
+walkStylesheets(xmlHashScanner walkFunc, void *data,
+ xsltStylesheetPtr style)
+{
+ xsltStylesheetPtr next;
+
+ if (!walkFunc || !style)
+ return;
+
+ next = style->next;
+ while (style) {
+ (*walkFunc) (style, data, NULL);
+ if (style->imports)
+ style = style->imports;
+ else
+ style = next;
+ }
+}
+
+
+
+xmlHashScanner globalWalkFunc = NULL;
+
+/**
+ * globalVarHelper:
+ * @payload: valid xsltStylesheetPtr
+ * @data: is valid
+ * @name: not used
+ *
+ * Helper to find the global variables. We are given control via
+ * walkStylesheets globalWalkFunc will always be set to the
+ * walkFunc to call
+ */
+void
+globalVarHelper(void **payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(name);
+ xsltStylesheetPtr style = (xsltStylesheetPtr) payload;
+ xsltStackElemPtr global;
+
+ if (style) {
+ global = style->variables;
+
+ while (global &&global->comp) {
+ (*globalWalkFunc) (global->comp->inst, data, NULL);
+ global = global->next;
+ }
+ }
+}
+
+
+/**
+ * walkGlobals:
+ * @walkFunc: The function to callback for each gobal variable found
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Call walkFunc for each global variable. The payload
+ * sent to walkFunc is of type xmlNodePtr
+ */
+void
+walkGlobals(xmlHashScanner walkFunc, void *data,
+ xsltStylesheetPtr style)
+{
+ Q_UNUSED(data);
+ if (!walkFunc || !style)
+ return;
+
+ globalWalkFunc = walkFunc;
+
+ walkStylesheets((xmlHashScanner) globalVarHelper, data, style);
+}
+
+
+
+xmlHashScanner localWalkFunc = NULL;
+
+/**
+ * localVarHelper:
+ * @payload: valid xsltTemplatePtr
+ * @data: is valid
+ * @name: not used
+ *
+ * Helper to find the local variables. We are given control via walkTemplates
+ * globalWalkFunc will always be set to the walkFunc to call
+ * localWalkFunc will always be set to the walkFunc to call
+ */
+void
+localVarHelper(void **payload, void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(name);
+ xsltTemplatePtr templ = (xsltTemplatePtr) payload;
+ xmlNodePtr node;
+
+ if (templ && templ->elem) {
+ node = templ->elem->children;
+
+ while (node) {
+ if (IS_XSLT_NAME(node, "param")
+ || IS_XSLT_NAME(node, "variable")) {
+ (*localWalkFunc) (node, data, NULL);
+ node = node->next;
+ } else
+ break;
+ }
+ }
+}
+
+
+/**
+ * walkLocals:
+ * @walkFunc: The function to callback for each local variable found
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Walks through all local variables calling walkFunc for each. The payload
+ * of walkFunc is of type xmlNodePtr
+ */
+void
+walkLocals(xmlHashScanner walkFunc, void *data, xsltStylesheetPtr style)
+{
+ if (!walkFunc || !style)
+ return;
+
+ localWalkFunc = walkFunc;
+
+ walkTemplates((xmlHashScanner) localVarHelper, data, style);
+
+}
+
+
+/**
+ * walkIncludes:
+ * @walkFunc: The function to callback for each included stylesheet
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Walks through all included stylesheets calling walkFunc for each.
+ * The payload of walkFunc is of type xmlNodePtr
+ */
+
+void
+walkIncludes(xmlHashScanner walkFunc, void *data, xsltStylesheetPtr style)
+{
+ xsltDocumentPtr document; /* included xslt documents */
+
+ if (!walkFunc || !style)
+ return;
+
+ while (style) {
+ document = style->docList;
+ /* look at included documents */
+ while (document) {
+ (*walkFunc) ((xmlNodePtr) document->doc, data, NULL);
+ document = document->next;
+ }
+ /* try next stylesheet */
+ if (style->next)
+ style = style->next;
+ else
+ style = style->imports;
+ }
+}
+
+
+/**
+ * walkIncludeInst:
+ * @walkFunc: The function to callback for each xsl:include instruction found
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Walks through all xsl:include calling walkFunc for each. The payload
+ * of walkFunc is of type xmlNodePtr
+ */
+void
+walkIncludeInst(xmlHashScanner walkFunc, void *data,
+ xsltStylesheetPtr style)
+{
+ xmlNodePtr node = NULL, styleChild = NULL;
+
+ if (!walkFunc || !style)
+ return;
+
+ while (style) {
+ /*look for stylesheet node */
+ if (style->doc) {
+ node = (xmlNodePtr) style->doc->children;
+ while (node) {
+ /* not need but just in case :) */
+ if (IS_XSLT_NAME(node, "stylesheet")
+ || IS_XSLT_NAME(node, "transform")) {
+ styleChild = node->children; /* get the topmost elements */
+ break;
+ } else
+ node = node->next;
+ }
+
+ /* look for includes */
+ while (styleChild) {
+ if (IS_XSLT_NAME(styleChild, "include"))
+ (*walkFunc) (styleChild, data, NULL);
+ styleChild = styleChild->next;
+ }
+ }
+ /* try next stylesheet */
+ if (style->next)
+ style = style->next;
+ else
+ style = style->imports;
+ }
+}
+
+
+/**
+ * walkChildNodes:
+ * @walkFunc: The function to callback for each child/sibling found
+ * @data: The extra data to pass onto walkFunc
+ * @node: Is valid
+ *
+ * Call walkFunc for each child of @node the payload sent to walkFunc is
+ * a xmlNodePtr
+ */
+void
+walkChildNodes(xmlHashScanner walkFunc, void *data, xmlNodePtr node)
+{
+ xmlNodePtr child = NULL;
+ searchInfoPtr searchInf = (searchInfoPtr) data;
+
+ if (!walkFunc || !searchInf || !searchInf->data)
+ return;
+
+ while (node && !searchInf->found) {
+ (walkFunc) (node, data, NULL);
+ child = node->children;
+ if (child && !searchInf->found) {
+ walkChildNodes(walkFunc, data, child);
+ }
+ node = node->next;
+ }
+}
+
+
+/**
+ * searchBreakPointNode:
+ * @breakPtr: Is valid
+ *
+ * Convert @breakPtr into search dataBase format
+ *
+ * Returns @breakPtr as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+xmlNodePtr
+searchBreakPointNode(breakPointPtr breakPtr)
+{
+
+ xmlNodePtr node = NULL;
+ int result = 1;
+
+ if (breakPtr) {
+ node = xmlNewNode(NULL, (xmlChar *) "breakpoint");
+ if (node) {
+ /* if unable to create any property failed then result will be equal to 0 */
+ result = result
+ && (xmlNewProp(node, (xmlChar *) "url", breakPtr->url) !=
+ NULL);
+ sprintf((char *) searchBuffer, "%ld", breakPtr->lineNo);
+ result = result
+ &&
+ (xmlNewProp(node, (xmlChar *) "line", (xmlChar *) searchBuffer)
+ != NULL);
+ if (breakPtr->templateName) {
+ result = result
+ &&
+ (xmlNewProp
+ (node, (xmlChar *) "template",
+ breakPtr->templateName) != NULL);
+ }
+ sprintf((char *) searchBuffer, "%d", breakPtr->flags & BREAKPOINT_ENABLED);
+ result = result
+ &&
+ (xmlNewProp
+ (node, (xmlChar *) "enabled", (xmlChar *) searchBuffer)
+ != NULL);
+ sprintf((char *) searchBuffer, "%d", breakPtr->type);
+ result = result
+ &&
+ (xmlNewProp(node, (xmlChar *) "type", (xmlChar *) searchBuffer)
+ != NULL);
+ sprintf((char *) searchBuffer, "%d", breakPtr->id);
+ result = result
+ && (xmlNewProp(node, (xmlChar *) "id", (xmlChar *) searchBuffer)
+ != NULL);
+ } else
+ result = 0;
+ if (!result) {
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ }
+ }
+ return node;
+}
+
+
+/**
+ * searchTemplateNode:
+ * @templNode: Is valid
+ *
+ * Convert @templateNode into search dataBase format
+ *
+ * Returns @templNode as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+xmlNodePtr
+searchTemplateNode(xmlNodePtr templNode)
+{
+ xmlNodePtr node = NULL;
+ xmlChar *value;
+ int result = 1;
+
+ if (templNode) {
+ node = xmlNewNode(NULL, (xmlChar *) "template");
+ if (node) {
+ /* if unable to create any property failed then result will be equal to 0 */
+ value = xmlGetProp(templNode, (xmlChar *) "match");
+ if (value) {
+ result = result
+ && (xmlNewProp(node, (xmlChar *) "match", value) !=
+ NULL);
+ xmlFree(value);
+ }
+ value = xmlGetProp(templNode, (xmlChar *) "name");
+ if (value) {
+ result = result
+ && (xmlNewProp(node, (xmlChar *) "name", value) !=
+ NULL);
+ xmlFree(value);
+ }
+ if (templNode->doc) {
+ result = result
+ &&
+ (xmlNewProp
+ (node, (xmlChar *) "url",
+ templNode->doc->URL) != NULL);
+ }
+ sprintf((char *) searchBuffer, "%ld", xmlGetLineNo(templNode));
+ result = result
+ &&
+ (xmlNewProp(node, (xmlChar *) "line", (xmlChar *) searchBuffer)
+ != NULL);
+ if (result) {
+ xmlNodePtr textNode = searchCommentNode(templNode);
+
+ if (textNode && !xmlAddChild(node, textNode))
+ result = 0;
+ }
+ } else
+ result = 0;
+ if (!result) {
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ }
+ }
+ return node;
+}
+
+
+/**
+ * searchGlobalNode:
+ * @globalVariable: Is valid
+ *
+ * Convert @globalVariable into search dataBase format
+ *
+ * Returns @globalVariable as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+xmlNodePtr
+searchGlobalNode(xmlNodePtr variable)
+{
+ xmlNodePtr node = NULL;
+ int result = 1;
+ xmlChar *value;
+
+ if (variable) {
+ node = xmlNewNode(NULL, (xmlChar *) "variable");
+ if (node) {
+ /* if unable to create any property failed then result will be equal to 0 */
+ if (variable->doc) {
+ result = result &&
+ (xmlNewProp(node, (xmlChar *) "url",
+ variable->doc->URL) != NULL);
+ sprintf((char *) searchBuffer, "%ld", xmlGetLineNo(variable));
+ result = result
+ && (xmlNewProp(node, (xmlChar *) "line",
+ (xmlChar *) searchBuffer) != NULL);
+ }
+ value = xmlGetProp(variable, (xmlChar *) "name");
+ if (value) {
+ result = result
+ && (xmlNewProp(node, (xmlChar *) "name", value) !=
+ NULL);
+ xmlFree(value);
+ }
+ value = xmlGetProp(variable, (xmlChar *) "select");
+ if (value) {
+ result = result
+ && (xmlNewProp(node, (xmlChar *) "select", value) !=
+ NULL);
+ xmlFree(value);
+ }
+ if (result) {
+ xmlNodePtr textNode = searchCommentNode(variable);
+
+ if (textNode && !xmlAddChild(node, textNode))
+ result = 0;
+ }
+ } else
+ result = 0;
+ }
+ if (!result) {
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ }
+ return node;
+}
+
+
+/**
+ * searchLocalNode:
+ * @localvariable: Is valid
+ *
+ * Convert @localVariable into search dataBase format
+ *
+ * Returns @localVariable as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+xmlNodePtr
+searchLocalNode(xmlNodePtr variable)
+{
+ xmlNodePtr node = NULL;
+ int result = 1;
+ xmlChar *value;
+ xmlNodePtr parent;
+
+ if (variable) {
+ node = searchGlobalNode(variable);
+ if (node) {
+ /* if unable to create any property failed then result will be equal to 0 */
+ parent = variable->parent;
+ /* try to find out what template this variable belongs to */
+ if (parent && IS_XSLT_NAME(parent, "template")) {
+ value = xmlGetProp(parent, (xmlChar *) "name");
+ if (value) {
+ result = result
+ &&
+ (xmlNewProp(node, (xmlChar *) "templname", value)
+ != NULL);
+ xmlFree(value);
+ }
+ value = xmlGetProp(parent, (xmlChar *) "match");
+ if (value) {
+ result = result
+ &&
+ (xmlNewProp(node, (xmlChar *) "templmatch", value)
+ != NULL);
+ xmlFree(value);
+ }
+ }
+ } else
+ result = 0;
+ }
+ if (!result) {
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ }
+ return node;
+}
+
+
+/**
+ * searchSourceNode:
+ * @style: Is valid
+ *
+ * Convert @style into search dataBase format
+ *
+ * Returns @style as a new xmlNode in search dataBase format if successful,
+ * NULL otherwise
+ */
+xmlNodePtr
+searchSourceNode(xsltStylesheetPtr style)
+{
+ xmlNodePtr node = NULL;
+ int result = 1;
+
+ if (style) {
+ if (style->parent == NULL)
+ node = xmlNewNode(NULL, (xmlChar *) "source");
+ else
+ node = xmlNewNode(NULL, (xmlChar *) "import");
+ if (node) {
+ /* if unable to create any property failed then result will be equal to 0 */
+ if (style->doc) {
+ result = result &&
+ (xmlNewProp(node, (xmlChar *) "href", style->doc->URL)
+ != NULL);
+ if (style->parent && style->parent->doc) {
+ result = result &&
+ (xmlNewProp(node, (xmlChar *) "parent",
+ style->parent->doc->URL) != NULL);
+ }
+ if (result) {
+ xmlNodePtr textNode =
+ searchCommentNode((xmlNodePtr) style->doc);
+ if (textNode && !xmlAddChild(node, textNode))
+ result = 0;
+ }
+ }
+ } else
+ result = 0;
+ }
+ if (!result) {
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ }
+ return node;
+}
+
+
+/**
+ * searchIncludeNode:
+ * @include: Is a valid xsl:include instruction
+ *
+ * Convert @include into search dataBase format
+ *
+ * Returns @include as a new xmlNode in search dataBase format if successful,
+ * NULL otherwise
+ */
+xmlNodePtr
+searchIncludeNode(xmlNodePtr include)
+{
+ xmlNodePtr node = NULL;
+ int result = 1;
+ xmlChar *value;
+
+ if (include) {
+ node = xmlNewNode(NULL, (xmlChar *) "include");
+ if (node) {
+ /* if unable to create any property failed then result will be equal to 0 */
+ if (include->doc) {
+ value = xmlGetProp(include, (xmlChar *) "href");
+ if (value) {
+ result = result
+ && (xmlNewProp(node, (xmlChar *) "href", value) !=
+ NULL);
+ xmlFree(value);
+ }
+ if (include->parent && include->parent->doc) {
+ result = result &&
+ (xmlNewProp(node, (xmlChar *) "url",
+ include->parent->doc->URL) != NULL);
+ sprintf((char *) searchBuffer, "%ld", xmlGetLineNo(include));
+ result = result
+ && (xmlNewProp(node, (xmlChar *) "line",
+ (xmlChar *) searchBuffer) != NULL);
+ }
+ if (result) {
+ xmlNodePtr textNode = searchCommentNode(include);
+
+ if (textNode && !xmlAddChild(node, textNode))
+ result = 0;
+ }
+ }
+ } else
+ result = 0;
+ }
+ if (!result) {
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ }
+ return node;
+}
+
+
+/**
+ * searchCallStackNode:
+ * @callStackItem: Is valid
+ *
+ * Convert @callStackItem into search dataBase format
+ *
+ * Returns @callStackItem as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+xmlNodePtr
+searchCallStackNode(callPointPtr callStackItem)
+{
+ xmlNodePtr node = NULL;
+ int result = 1;
+
+ if (callStackItem) {
+ node = xmlNewNode(NULL, (xmlChar *) "callstack");
+ if (node) {
+ /* if unable to create any property failed then result will be equal to 0 */
+ if (callStackItem->info && callStackItem->info->url)
+ result = result
+ &&
+ (xmlNewProp
+ (node, (xmlChar *) "url", callStackItem->info->url)
+ != NULL);
+ sprintf((char *) searchBuffer, "%ld", callStackItem->lineNo);
+ result = result
+ &&
+ (xmlNewProp(node, (xmlChar *) "line", (xmlChar *) searchBuffer)
+ != NULL);
+ if (callStackItem->info && callStackItem->info->templateName) {
+ result = result &&
+ (xmlNewProp
+ (node, (xmlChar *) "template",
+ callStackItem->info->templateName) != NULL);
+ }
+ } else
+ result = 0;
+ if (!result) {
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ }
+ }
+ return node;
+}
+
+
+static xmlChar *commentText(xmlNodePtr node);
+
+/*
+ * Returns A copy of comment text that applies to node,
+ * NULL otherwise
+ */
+xmlChar *
+commentText(xmlNodePtr node)
+{
+ xmlChar *result = NULL;
+
+ if (node) {
+ if (node->type == XML_COMMENT_NODE)
+ result = xmlNodeGetContent(node);
+ }
+
+ return result;
+}
+
+/**
+ * searchCommentNode:
+ * @sourceNode: Is valid
+ *
+ * Find documentation comment that applies to @node. If found convert comment
+ * into search dataBase format required
+ *
+ * Returns Documentation comment for @node as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+xmlNodePtr
+searchCommentNode(xmlNodePtr sourceNode)
+{
+ xmlNodePtr node = NULL, textChild = NULL;
+ xmlChar *text = NULL;
+ int result = 0;
+
+ if (sourceNode) {
+ text = commentText(sourceNode->prev);
+ if (!text) {
+ text = commentText(sourceNode->children);
+ }
+
+ if (text) {
+ node = xmlNewNode(NULL, (xmlChar *) "comment");
+ textChild = xmlNewText(text);
+ if (node && textChild && xmlAddChild(node, textChild)) {
+ result = 1;
+ }
+ if (!result) {
+ if (node) {
+ xmlFreeNode(node);
+ node = NULL;
+ }
+ if (textChild)
+ xmlFreeNode(textChild);
+ }
+
+ xmlFree(text);
+ }
+ }
+ return node;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/search.h b/kxsldbg/kxsldbgpart/libxsldbg/search.h
new file mode 100644
index 00000000..20fc82b4
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/search.h
@@ -0,0 +1,1087 @@
+
+/* *************************************************************************
+ xslsearch.h - public functions for
+ searching
+ -------------------
+ begin : Fri Dec 7 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. *
+ * *
+ ************************************************************************* */
+
+#ifndef XSLSEARCH_H
+#define XSLSEARCH_H
+
+#ifdef USE_KDE_DOCS
+
+/**
+ * Provide a searching support
+ *
+ * @short search support
+ *
+ * @author Keith Isdale <k_isdale@tpg.com.au>
+ */
+#endif
+
+/* We want skip most of these includes when building documentation*/
+#ifndef BUILD_DOCS
+#include "breakpoint.h"
+#include "callstack.h"
+#endif
+
+
+#ifdef WITH_XSLT_DEBUG
+#ifndef WITH_XSLT_DEBUG_BREAKPOINTS
+#define WITH_XSLT_DEBUG_BREAKPOINTS
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* what types of searches are there */
+#ifndef USE_KDOC
+ typedef enum {
+ SEARCH_BREAKPOINT = 400,
+ SEARCH_NODE,
+ SEARCH_XSL,
+ SEARCH_VARIABLE
+ } SearchEnum;
+#else
+ /* keep kdoc happy */
+ enum SearchEnum {
+ SEARCH_BREAKPOINT = 400,
+ SEARCH_NODE,
+ SEARCH_XSL,
+ SEARCH_VARIABLE
+ };
+#endif
+
+ /* define a common structure to be used when searching */
+ typedef struct _searchInfo searchInfo;
+ typedef searchInfo *searchInfoPtr;
+ struct _searchInfo {
+ int found; /* found is 1 if search is finished */
+ int type; /* what type of search see SearchEnum */
+ int error; /* did an error occur */
+ void *data; /* extra data to pass to walkFunc */
+ };
+
+
+ /* data to pass to via searchInfoPtr when searching for break points */
+ typedef struct _breakPointSearchData breakPointSearchData;
+ typedef breakPointSearchData *breakPointSearchDataPtr;
+ struct _breakPointSearchData {
+ int id; /* what id to look for,
+ * if -1 then ignore */
+ xmlChar *templateName; /* template to look for
+ * if NULL then ignore */
+ breakPointPtr breakPtr; /* the break point found by search */
+ };
+
+
+ /* data to pass via searchInfoPtr when searching for nodes */
+ typedef struct _nodeSearchData nodeSearchData;
+ typedef nodeSearchData *nodeSearchDataPtr;
+ struct _nodeSearchData {
+ long lineNo; /* what line number to look for
+ * if < 0 then ignore */
+ xmlChar *url; /* what URl to look for
+ * if NULL then ignore */
+ int fileSearch; /* if true then we are trying
+ * to match a file name */
+ xmlChar *nameInput; /* what file/node name are we
+ * trying to match */
+ xmlChar *guessedNameMatch; /* possible name match */
+ xmlChar *absoluteNameMatch; /* full name match */
+ xmlNodePtr node; /* the node that the match
+ * occured in */
+ };
+
+ /* data to pass to via searchInfoPtr when searching for variables points */
+ typedef struct _variableSearchData variableSearchData;
+ typedef variableSearchData *variableSearchDataPtr;
+ struct _variableSearchData {
+ xmlChar *name;
+ xmlChar *nameURI;
+ xmlChar *select; /* new value to adopt if any */
+ };
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchInit:
+ *
+ * Initialize the search module
+ *
+ * Returns 1 if search structures have been initialized properly and all
+ * memory required has been obtained,
+ * 0 otherwise
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Initialize the search module
+ *
+ * @returns 1 if search structures have been initialized properly and all
+ * memory required has been obtained,
+ * 0 otherwise
+*/
+#endif
+#endif
+ int searchInit(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchFree:
+ *
+ * Free all memory used by the search module
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Free all memory used by the search module
+ */
+#endif
+#endif
+ void searchFree(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchNewInfo:
+ * @type: What type of search is required
+ *
+ * Create a new search
+ *
+ * Returns A valid search info pointer if successful
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Create a new search
+ *
+ * @returns valid search info pointer if successful
+ * NULL otherwise
+ *
+ * @param type What type of search is required
+ */
+#endif
+#endif
+ searchInfoPtr searchNewInfo(SearchEnum type);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchFreeInfo:
+ * @info: A valid search info
+ *
+ * Free memory used by @info
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Free memory used by @p info
+ *
+ * @param info A valid search info
+ *
+ */
+#endif
+#endif
+ void searchFreeInfo(searchInfoPtr info);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchEmpty:
+ *
+ * Empty the seach data base of its contents
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Empty the seach dataBase of its contents
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ */
+#endif
+#endif
+ int searchEmpty(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchDoc:
+ *
+ * Return the document used for seaching ie the search dataBase
+ *
+ * Returns The document used for searching
+ * Dangerous function to use! Does NOT return a copy of
+ * search data so don't free it
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Return the document used for seaching ie the search dataBase
+ *
+ * @returns the document used for searching
+ * Dangerous function to use! Does NOT return a copy of
+ * search data so don't free it
+ */
+#endif
+#endif
+ xmlDocPtr searchDoc(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchRootNode:
+ *
+ * Get the topmost node in the search dataBase
+ *
+ * Returns The topmost xml node in search dataBase.
+ * Dangerous function to use! Does NOT return a copy of
+ * search root node so don't free it
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Get the topmost node in the search dataBase
+ *
+ * @returns The topmost xml node in search dataBase.
+ * Dangerous function to use! Does NOT return a copy of
+ * search root node so don't free it
+ */
+#endif
+#endif
+ xmlNodePtr searchRootNode(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchAdd:
+ * @node: Is valid
+ *
+ * Add a node to the search dataBase
+ *
+ * Returns 1 if able to add @node to top node in search dataBase ,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Add a node to the search dataBase
+ *
+ * @returns 1 if able to add @p node to top node in search dataBase,
+ * 0 otherwise
+ *
+ * @param node Is valid
+ */
+#endif
+#endif
+ int searchAdd(xmlNodePtr node);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchSave:
+ * @fileName: A valid file name, or NULL for the default
+ *
+ * Save the search dataBase to @fileName
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Save the search dataBase to @p fileName
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param fileName Valid file name
+ */
+#endif
+#endif
+ int searchSave(const xmlChar * fileName);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchQuery:
+ * @query: The query to run . If NULL then query is "//search/ *"
+ * @tempFile: Where do we load the search dataBase from to execute
+ * query. If tempFile is NULL "searchresult.xml" is used
+ * @outputFile : Where do we store the result. If NULL
+ * then default to "searchresult.html"
+ *
+ * Send query as parameter for execution of search.xsl using
+ * data stored in @tempFile
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Send query as parameter for execution of search.xsl using
+ * data stored in @p tempFile
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param query The Query to run. If NULL then @p query defaults to "//search/ *"
+ * @param tempFile Where do we load the search dataBase from to execute
+ * query. If @p tempFile is NULL default is "search.data"
+ * @param outputFile Where do we store the result. If NULL
+ * then default to "searchresult.html"
+ */
+#endif
+#endif
+ int searchQuery(const xmlChar * tempFile, const xmlChar * outputFile,
+ const xmlChar * query);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * updateSearchData:
+ * @styleCtxt: Not used
+ * @style: Is valid
+ * @data: Not used but MUST be NULL for the moment
+ * @variableTypes: What types of variables to look
+ *
+ * Update the searchDatabase
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Update the search dataBase
+ *
+ * @returns 1 if able to update the search dataBase,
+ * 0 otherwise
+ * @param styleCtxt Not used
+ * @param style Is valid
+ * @param data Not used but MUST be NULL for the moment
+ * @param variableTypes What types of variables to look
+ */
+#endif
+#endif
+ int updateSearchData(xsltTransformContextPtr styleCtxt,
+ xsltStylesheetPtr style,
+ void *data, VariableTypeEnum variableTypes);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * scanForBreakPoint:
+ * @payload: A valid breakPointPtr
+ * @data: The criteria to look for and a valid searchInfoPtr of
+ * type SEARCH_BREAKPOINT
+ * @name: Not used
+ *
+ * Test if break point matches criteria given by @data. If so then
+ * set @data->found to 1 and stores reference to break point found in
+ * @data->data->node
+ * otherwise @data is unchanged
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Test if break point matches criteria given by @p data. If so then
+ * set @p data->found to 1 and stores reference to break point found in
+ * @p data->data->node
+ * otherwise @p data is unchanged
+ *
+ * @param payload A valid breakPointPtr
+ * @param data The criteria to look for and a valid searchInfoPtr of
+ * type SEARCH_BREAKPOINT
+ * @param name Not used
+ *
+*/
+#endif
+#endif
+ void scanForBreakPoint(void *payload, void *data, xmlChar * name);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * scanForNode:
+ * @payload: A valid xmlNodePtr
+ * @data: The criteria to look for and a valid searchInfo of
+ * type SEARCH_NODE
+ * @name: Not used
+
+ * Test if node matches criteria given by @data if so then set @data->found
+ * to 1 and stores reference to node found in @data->data->node
+ * otherwise @data is unchanged
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Test if node matches criteria given by @p data if so then
+ * set @p data->found to 1 and stores reference to node found in
+ * @p data->data->node.
+ * otherwise @p data is unchanged
+ *
+ * @param payload A valid xmlNodePtr
+ * @param data The criteria to look for and a valid searchInfo of
+ * type SEARCH_NODE
+ * @param name Not used
+*/
+#endif
+#endif
+ void scanForNode(void *payload, void *data, xmlChar * name);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * findNodeByLineNo:
+ * @ctxt: Valid ctxt to look into
+ * @url: Non-null, non-empty file name that has been loaded by debugger
+ * @lineNumber: @lineNumber >= 0 and is available in @url
+ *
+ * Finds the closest line number in file specified that can be a point
+ *
+ * Returns The node at line number number specified if successfull,
+ * NULL otherwise
+ */
+
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Find the closest line number in file specified that can be a point
+ *
+ * @returns The node at line number specified if successful,
+ * NULL otherwise
+ *
+ * @param ctxt Valid ctxt to look into
+ * @param url Non-null, non-empty file name that has been loaded by
+ * debugger
+ * @param lineNumber @p lineNumber >= 0 and is available in @p url
+*/
+#endif
+#endif
+ xmlNodePtr findNodeByLineNo(xsltTransformContextPtr ctxt,
+ const xmlChar * url, long lineNumber);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * findTemplateNode:
+ * @style: A valid stylesheet collection to look into
+ * @name: A valid template name to look for
+ *
+ * Find a template node
+ *
+ * Returns The template node found if successful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Find a template node
+ *
+ * @returns The template node found if successful,
+ * NULL otherwise
+ *
+ * @param style A Valid stylesheet collection to look into
+ * @param name Valid template name to look for
+ */
+#endif
+#endif
+ xmlNodePtr findTemplateNode(xsltStylesheetPtr style,
+ const xmlChar * name);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * findBreakPointByName:
+ * @templateName: The template name to look for
+ *
+ * Find the breakpoint at template with "match" or "name" equal
+ * to templateName
+ *
+ * Returns The break point that matches @templateName
+ * NULL otherwise
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Find the breakpoint at template with "match" or "name" equal
+ * to templateName
+ *
+ * @returns The break point that matches @p templateName
+ * NULL otherwise
+ *
+ * @param templateName Valid template name to look for
+*/
+#endif
+#endif
+ breakPointPtr findBreakPointByName(const xmlChar * templateName);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * findBreakPointById:
+ * @id: The break point id to look for
+ *
+ * Find a break point by its id
+ *
+ * Returns The break point with given the break point id if found,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Find a break point by its id
+ *
+ * @returns The break point with given the break point id if found,
+ * NULL otherwise
+ *
+ * @param id The break point id to look for
+ */
+#endif
+#endif
+ breakPointPtr findBreakPointById(int id);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * findNodesByQuery:
+ * @query: The xpath query to run, see docs/en/search.dtd for more details
+ *
+ * Find nodes in search dataBase using an xpath query
+ *
+ * Returns The nodes that match the given query on success,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Find nodes in search dataBase using an xpath query
+ *
+ * @returns The nodes that match the given query on success,
+ * NULL otherwise
+ *
+ * @param query The xpath query to run, see docs/en/search.dtd for more details
+ */
+#endif
+#endif
+ xmlXPathObjectPtr findNodesByQuery(const xmlChar * query);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * walkBreakPoints:
+ * @walkFunc: The function to callback for each break point found
+ * @data: The extra data to pass onto walkFunc
+ *
+ * Walks through all break points calling walkFunc for each. The payload
+ * sent to walkFunc is of type breakPointPtr
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Walks through all break points calling walkFunc for each. The payload
+ * sent to walkFunc is of type breakPointPtr
+ *
+ * @param walkFunc The function to callback for each break point found
+ * @param data The extra data to pass onto @p walkFunc
+ */
+#endif
+#endif
+ void walkBreakPoints(xmlHashScanner walkFunc, void *data);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * walkTemplates:
+ * @walkFunc: The function to callback for each template found
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Walks through all templates calling walkFunc for each. The payload
+ * of walkFunc is of type xsltTemplatePtr
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Walks through all templates found in @p style calling walkFunc for each.
+ * The payload of walkFunc is of type xsltTemplatePtr
+ *
+ * @param walkFunc The function to callback for each template found
+ * @param data The extra data to pass onto @p walkFunc
+ * @param style The stylesheet to start from
+ */
+#endif
+#endif
+ void walkTemplates(xmlHashScanner walkFunc, void *data,
+ xsltStylesheetPtr style);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * walkStylesheets:
+ * @walkFunc: The function to callback for each stylesheet found
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Walks through all templates calling walkFunc for each. The payload
+ * sent to walkFunc is of type xsltStylesheetPtr
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Walks through all stylesheets found in @p style calling walkFunc for
+ * each. The payload sent to walkFunc is of type xsltStylesheetPtr
+ *
+ * @param walkFunc The function to callback for each stylesheet found
+ * @param data The extra data to pass onto @p walkFunc
+ * @param style The stylesheet to start from
+ */
+#endif
+#endif
+ void walkStylesheets(xmlHashScanner walkFunc, void *data,
+ xsltStylesheetPtr style);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * walkGlobals:
+ * @walkFunc: The function to callback for each gobal variable found
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Call walkFunc for each global variable. The payload
+ * sent to walkFunc is of type xmlNodePtr
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Call walkFunc for each global variable found in @p style. The payload
+ * sent to walkFunc is of type xmlNodePtr
+ *
+ * @param walkFunc The function to callback for each gobal variable found
+ * @param data The extra data to pass onto @p walkFunc
+ * @param style The stylesheet to start from
+ */
+#endif
+#endif
+ void walkGlobals(xmlHashScanner walkFunc,
+ void *data, xsltStylesheetPtr style);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * walkLocals:
+ * @walkFunc: The function to callback for each local variable found
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Walks through all local variables calling walkFunc for each. The payload
+ * of walkFunc is of type xmlNodePtr
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Walks through all local variables found in @p style calling
+ * walkFunc for each. The payload of walkFunc is of type xmlNodePtr
+ *
+ * @param walkFunc The function to callback for each local variable found
+ * @param data The extra data to pass onto @p walkFunc
+ * @param style The stylesheet to start from
+ */
+#endif
+#endif
+ void walkLocals(xmlHashScanner walkFunc, void *data,
+ xsltStylesheetPtr style);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * walkIncludes:
+ * @walkFunc: The function to callback for each included stylesheet
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Walks through all included stylesheets calling walkFunc for each.
+ * The payload of walkFunc is of type xmlNodePtr
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Walks through all included stylesheets found in @p style,
+ * calling walkFunc for each. The payload of walkFunc is of
+ * type xmlNodePtr
+ *
+ * @param walkFunc The function to callback for each included stylesheet
+ * @param data The extra data to pass onto @p walkFunc
+ * @param style The stylesheet to start from
+ */
+#endif
+#endif
+ void walkIncludes(xmlHashScanner walkFunc, void *data,
+ xsltStylesheetPtr style);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * walkIncludeInst:
+ * @walkFunc: The function to callback for each xsl:include instruction found
+ * @data: The extra data to pass onto walkFunc
+ * @style: The stylesheet to start from
+ *
+ * Walks through all xsl:include calling walkFunc for each. The payload
+ * of walkFunc is of type xmlNodePtr
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Walks through all xsl:include calling walkFunc for each. The payload
+ * of walkFunc is of type xmlNodePtr
+ *
+ * @param walkFunc The function to callback for each xsl:include instruction found
+ * @param data The extra data to pass onto @p walkFunc
+ * @param style The stylesheet to start from
+ */
+#endif
+#endif
+ void walkIncludeInst(xmlHashScanner walkFunc, void *data,
+ xsltStylesheetPtr style);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * walkChildNodes:
+ * @walkFunc: The function to callback for each child/sibling found
+ * @data: The extra data to pass onto walkFunc
+ * @node: Is valid
+ *
+ * Call walkFunc for each child of @node the payload sent to walkFunc is
+ * a xmlNodePtr
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Call walkFunc for each child of @p node the payload sent to walkFunc is
+ * a xmlNodePtr
+ *
+ * @param walkFunc The function to callback for each child/sibling found
+ * @param data The extra data to pass onto @p walkFunc
+ * @param node Valid xmlNodePtr
+ */
+#endif
+#endif
+ void walkChildNodes(xmlHashScanner walkFunc, void *data,
+ xmlNodePtr node);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchBreakPointNode:
+ * @breakPtr: Is valid
+ *
+ * Convert @breakPtr into search dataBase format
+ *
+ * Returns @breakPtr as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Convert @p breakPtr into search dataBase format
+ *
+ * @returns @p breakPtr as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ *
+ * @param breakPtr Is valid
+ */
+#endif
+#endif
+ xmlNodePtr searchBreakPointNode(breakPointPtr breakPtr);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchTemplateNode:
+ * @templNode: Is valid
+ *
+ * Convert @templateNode into search dataBase format
+ *
+ * Returns @templNode as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Convert @p templateNode into search dataBase format
+ *
+ * @returns @p templNode as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ *
+ * @param templNode A valid template node
+ */
+#endif
+#endif
+ xmlNodePtr searchTemplateNode(xmlNodePtr templNode);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchGlobalNode:
+ * @globalVariable: Is valid
+ *
+ * Convert @globalVariable into search dataBase format
+ *
+ * Returns @globalVariable as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Convert @p globalVariable into search dataBase format
+ *
+ * @returns @p globalVariable as a new xmlNode in search dataBase
+ * format if successful,
+ * NULL otherwise
+ *
+ * @param globalVariable A valid xmlNodePtr node
+ *
+ */
+#endif
+#endif
+ xmlNodePtr searchGlobalNode(xmlNodePtr globalVariable);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchLocalNode:
+ * @localvariable: Is valid
+ *
+ * Convert @localVariable into search dataBase format
+ *
+ * Returns @localVariable as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Convert @p localVariable into search dataBase format
+ *
+ * @returns @p localVariable as a new xmlNode in search dataBase
+ * format if successful,
+ * NULL otherwise
+ *
+ * @param localVariable Is valid
+ *
+ */
+#endif
+#endif
+ xmlNodePtr searchLocalNode(xmlNodePtr localVariable);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchSourceNode:
+ * @style: Is valid
+ *
+ * Convert @style into search dataBase format
+ *
+ * Returns @style as a new xmlNode in search dataBase format if successful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Convert @p style into search dataBase format
+ *
+ * @returns @p style as a new xmlNode in search dataBase format if successful,
+ * NULL otherwise
+ *
+ * @param style Is valid
+ */
+#endif
+#endif
+ xmlNodePtr searchSourceNode(xsltStylesheetPtr style);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchIncludeNode:
+ * @include: Is a valid xsl:include instruction
+ *
+ * Convert @include into search dataBase format
+ *
+ * Returns @include as a new xmlNode in search dataBase format if successful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Convert @p include into search dataBase format
+ *
+ * @returns @p include as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ *
+ * @param include Is a valid xsl:include instruction
+ *
+ */
+#endif
+#endif
+ xmlNodePtr searchIncludeNode(xmlNodePtr include);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchCallStackNode:
+ * @callStackItem: Is valid
+ *
+ * Convert @callStackItem into search dataBase format
+ *
+ * Returns @callStackItem as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ *Convert @p include into search dataBase format
+ *
+ * @returns @p callStackItem as a new xmlNode in search dataBase
+ * format if successful,
+ * NULL otherwise
+ * @param callStackItem Is valid
+ */
+#endif
+#endif
+ xmlNodePtr searchCallStackNode(callPointPtr callStackItem);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * searchCommentNode:
+ * @sourceNode: Is valid
+ *
+ * Find documentation comment that applies to @sourceNode. If found convert comment
+ * into search dataBase format required
+ *
+ * Returns Documentation comment for @node as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+ /**
+ * Find documentation comment that applies to @p sourceNode. If found convert comment
+ * into search dataBase format required
+ *
+ * Returns Documentation comment for @node as a new xmlNode in search dataBase format
+ * if successful,
+ * NULL otherwise
+ *
+ * @param node Is valid
+ */
+#endif
+#endif
+ xmlNodePtr searchCommentNode(xmlNodePtr node);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/search_cmds.cpp b/kxsldbg/kxsldbgpart/libxsldbg/search_cmds.cpp
new file mode 100644
index 00000000..1dc65190
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/search_cmds.cpp
@@ -0,0 +1,88 @@
+
+/***************************************************************************
+ search_cmds.c - search related 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 "options.h"
+#include "search.h"
+
+/* -----------------------------------------
+
+ Seach related commands
+
+ ------------------------------------------- */
+
+
+/**
+ * xslDbgShellSearch:
+ * @styleCtxt: Is valid
+ * @style: Is valid
+ * @arg: The xpath query to use for searching dataBase and in UTF-8
+ *
+ * Displays the result of performing a query on the search dataBase
+ *
+ * Returns 1 if able to run query with @arg,
+ * 0 otherwise
+ */
+int
+xslDbgShellSearch(xsltTransformContextPtr styleCtxt,
+ xsltStylesheetPtr style, xmlChar * arg)
+{
+ int result = 0;
+ xmlChar buff[DEBUG_BUFFER_SIZE];
+ const xmlChar *sortOption = (xmlChar *) "-sort ";
+ int sortOptionLen = xmlStrLen(sortOption);
+
+ if (optionsGetStringOption(OPTIONS_DOCS_PATH) == NULL) {
+ xsldbgGenericErrorFunc(i18n("Error: No path to documentation; aborting searching.\n"));
+#ifdef USE_DOCS_MACRO
+ xsldbgGenericErrorFunc(i18n("Error: Error in value of USE_DOCS_MACRO; look at Makefile.am.\n"));
+#else
+ xsldbgGenericErrorFunc(i18n("Error: Required environment variable %1 not set to the directory of xsldbg documentation.\n").arg((const char*)XSLDBG_DOCS_DIR_VARIABLE));
+#endif
+ return result; /* failed */
+ }
+
+ if (!styleCtxt || !style) {
+ xsldbgGenericErrorFunc(i18n("Error: Stylesheet not valid, files not loaded yet?\n"));
+ return result;
+ }
+
+ result = updateSearchData(styleCtxt, style, NULL, DEBUG_ANY_VAR);
+ trimString(arg);
+ if (xmlStrLen(arg) == 0) {
+ arg = (xmlChar *) "//search/*";
+ }
+ strncpy((char *) buff, (char *) arg, sortOptionLen);
+ if (xmlStrEqual(buff, sortOption)) {
+ /* yep do sorting as well */
+ if (snprintf
+ ((char *) buff, DEBUG_BUFFER_SIZE,
+ "--param dosort 1 --param query \"%s\"",
+ &arg[sortOptionLen])) {
+ result = result && searchQuery(NULL, NULL, buff);
+ }
+ } else {
+ if (snprintf
+ ((char *) buff, DEBUG_BUFFER_SIZE,
+ "--param dosort 0 --param query \"%s\"", arg)) {
+ result = result && searchQuery(NULL, NULL, buff);
+ }
+ }
+ return result;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/template_cmds.cpp b/kxsldbg/kxsldbgpart/libxsldbg/template_cmds.cpp
new file mode 100644
index 00000000..10deb686
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/template_cmds.cpp
@@ -0,0 +1,331 @@
+
+/***************************************************************************
+ template_cmds.c - template 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 "xsldbgmsg.h"
+#include "xsldbgthread.h" /* for getThreadStatus */
+
+static int printCounter; /* Dangerous name think of a better one */
+
+/* -----------------------------------------
+ Private function declarations for files.c
+ -------------------------------------------*/
+
+/**
+ * xslDbgShellPrintStylesheetsHelper:
+ * @payload :valid xxsltStylesheetPtr
+ * @data : not used
+ * name : not used
+ *
+ * Print out the stylesheet name from the stylesheet given to
+ * us via walkStylesheets
+ */
+void
+ xslDbgShellPrintStylesheetsHelper(void *payload,
+ void *data,
+ xmlChar * name);
+
+
+/**
+ * xslDbgShellPrintStylesheetsHelper2:
+ * @payload :valid xmlNodePtr of included stylesheet
+ * @data : not used
+ * name : not used
+ *
+ * Print out the stylesheet name from the stylesheet given to
+ * us via walkIncludes
+ */
+void
+ xslDbgShellPrintStylesheetsHelper2(void *payload,
+ void *data,
+ xmlChar * name);
+
+
+/**
+ * printTemplateHelper:
+ * @templ: Is valid
+ * @verbose: Either 1 or 0
+ * @templateCount: Is valid
+ * @count: Is valid
+ * @templateName: template name to print and in UTF-8, may be NULL
+ *
+ * This display the templates in the same order as they are in the
+ * stylesheet. If verbose is 1 then print more information
+ * For each template found @templateCount is increased
+ * For each printed template @printCount is increased
+ */
+void printTemplateHelper(xsltTemplatePtr templ, int verbose,
+ int *templateCount, int *count,
+ xmlChar * templateName);
+
+/* -------------------------------------
+ End private functions
+---------------------------------------*/
+
+
+
+/**
+ * printTemplateHelper:
+ * @templ: Is valid
+ * @verbose: Either 1 or 0
+ * @templateCount: Is valid
+ * @count: Is valid
+ * @templateName: template name to print, may be NULL
+ *
+ * This display the templates in the same order as they are in the
+ * stylesheet. If verbose is 1 then print more information
+ * For each template found @templateCount is increased
+ * For each printed template @printCount is increased
+ */
+void
+printTemplateHelper(xsltTemplatePtr templ, int verbose,
+ int *templateCount, int *count, xmlChar * templateName)
+{
+ xmlChar *name, *defaultUrl = (xmlChar *) "<n/a>";
+ const xmlChar *url;
+
+ if (!templ)
+ return;
+
+ *templateCount = *templateCount + 1;
+ printTemplateHelper(templ->next, verbose,
+ templateCount, count, templateName);
+ if (templ->elem && templ->elem->doc && templ->elem->doc->URL) {
+ url = templ->elem->doc->URL;
+ } else {
+ url = defaultUrl;
+ }
+
+ if (templ->match)
+ name = xmlStrdup(templ->match);
+ else
+ name = fullQName(templ->nameURI, templ->name);
+
+ if (name) {
+ if (templateName &&
+ (xmlStrcmp(templateName, name) != 0)) {
+ /* search for template name supplied failed */
+ /* empty */
+ } else {
+ xmlChar *modeTemp = NULL;
+ *count = *count + 1;
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ notifyListQueue(templ);
+ } else {
+ modeTemp = fullQName(templ->modeURI, templ->mode);
+ if (verbose)
+ xsldbgGenericErrorFunc(i18n(" template: \"%1\" mode: \"%2\" in file \"%3\" at line %4\n").arg(xsldbgText(name)).arg(xsldbgText(modeTemp)).arg(xsldbgUrl(url)).arg(xmlGetLineNo(templ->elem)));
+ else
+ xsldbgGenericErrorFunc(QString("\"%s\" ").arg(xsldbgText(name)));
+ if (modeTemp)
+ xmlFree(modeTemp);
+ }
+ }
+
+ xmlFree(name);
+
+ }
+}
+
+
+/**
+ * xslDbgShellPrintTemplateNames:
+ * @styleCtxt: Is valid
+ * @ctxt: Not used
+ * @arg: Not used
+ * @verbose: If 1 then print extra messages about templates found,
+ * otherwise print normal messages only
+ * @allFiles: If 1 then look for all templates in stylsheets found in
+ * @styleCtxt
+ * otherwise look in the stylesheet found by
+ * debugXSLBreak function
+ *
+ * Print out the list of template names found that match critieria
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgShellPrintTemplateNames(xsltTransformContextPtr styleCtxt,
+ xmlShellCtxtPtr ctxt,
+ xmlChar * arg, int verbose, int allFiles)
+{
+ Q_UNUSED(ctxt);
+ int templateCount = 0, printedTemplateCount = 0;
+ int result = 0;
+ xsltStylesheetPtr curStyle;
+ xsltTemplatePtr templ;
+
+ if (xmlStrLen(arg) == 0) {
+ arg = NULL;
+ } else {
+ allFiles = 1; /* make sure we find it if we can */
+ }
+
+ if (!styleCtxt) {
+ xsldbgGenericErrorFunc(i18n("Error: Stylesheet is not valid.\n"));
+ return result;
+ }
+
+ if (allFiles)
+ curStyle = styleCtxt->style;
+ else {
+ /* try to find files in the current stylesheet */
+ /* root copy is set to the stylesheet found by debugXSLBreak */
+ if (debugXSLGetTemplate())
+ curStyle = debugXSLGetTemplate()->style;
+ else
+ curStyle = NULL;
+ }
+
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ notifyListStart(XSLDBG_MSG_TEMPLATE_CHANGED);
+ while (curStyle) {
+ templ = curStyle->templates;
+ /* print them out in the order their in the file */
+ printTemplateHelper(templ, verbose, &templateCount,
+ &printedTemplateCount, arg);
+ if (curStyle->next)
+ curStyle = curStyle->next;
+ else
+ curStyle = curStyle->imports;
+ }
+ notifyListSend();
+ } else {
+ xsltGenericError(xsltGenericErrorContext, "\n");
+ while (curStyle) {
+ templ = curStyle->templates;
+ /* print them out in the order their in the file */
+ printTemplateHelper(templ, verbose, &templateCount,
+ &printedTemplateCount, arg);
+ xsltGenericError(xsltGenericErrorContext, "\n");
+ if (curStyle->next)
+ curStyle = curStyle->next;
+ else
+ curStyle = curStyle->imports;
+ }
+ if (templateCount == 0) {
+ xsldbgGenericErrorFunc(i18n("\tNo XSLT templates found.\n"));
+ } else {
+ xsldbgGenericErrorFunc(i18n("\tTotal of %n XSLT template found", "\tTotal of %n XSLT templates found", templateCount) + QString("\n"));
+ xsldbgGenericErrorFunc(i18n("\tTotal of %n XSLT template printed", "\tTotal of %n XSLT templates printed", printedTemplateCount) + QString("\n"));
+ }
+ }
+
+ result = 1;
+ return result;
+}
+
+
+/**
+ * xslDbgShellPrintStylesheetsHelper:
+ * @payload :valid xsltStylesheetPtr
+ * @data : not used
+ * name : not used
+ *
+ * Print out the stylesheet name from the stylesheet given to
+ * us via walkStylesheets
+ */
+void
+xslDbgShellPrintStylesheetsHelper(void *payload,
+ void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(name);
+ xsltStylesheetPtr style = (xsltStylesheetPtr) payload;
+
+ if (style && style->doc && style->doc->URL) {
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN)
+ notifyListQueue(payload);
+ else
+ /* display the URL of stylesheet */
+ xsldbgGenericErrorFunc(i18n(" Stylesheet %1\n").arg(xsldbgUrl(style->doc->URL)));
+ printCounter++;
+ }
+}
+
+
+/**
+ * xslDbgShellPrintStylesheetsHelper2:
+ * @payload :valid xmlNodePtr of included stylesheet
+ * @data : not used
+ * name : not used
+ *
+ * Print out the stylesheet name from the stylesheet given to
+ * us via walkIncludes
+ */
+void
+xslDbgShellPrintStylesheetsHelper2(void *payload,
+ void *data,
+ xmlChar * name)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(name);
+ xmlNodePtr node = (xmlNodePtr) payload;
+
+ if (node && node->doc && node->doc->URL) {
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN)
+ notifyListQueue(payload);
+ else
+ /* display the URL of stylesheet */
+ xsldbgGenericErrorFunc(i18n(" Stylesheet %1\n").arg(xsldbgUrl(node->doc->URL)));
+ printCounter++;
+ }
+}
+
+
+/**
+ * xslDbgShellPrintStyleSheets:
+ * @arg: The stylesheets of interests and in UTF-8, is NULL for all stylsheets
+ *
+ * Print stylesheets that can be found in loaded stylsheet
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgShellPrintStyleSheets(xmlChar * arg)
+{
+ Q_UNUSED(arg);
+ printCounter = 0;
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ notifyListStart(XSLDBG_MSG_SOURCE_CHANGED);
+ walkStylesheets((xmlHashScanner) xslDbgShellPrintStylesheetsHelper,
+ NULL, filesGetStylesheet());
+ notifyListSend();
+ notifyListStart(XSLDBG_MSG_INCLUDED_SOURCE_CHANGED);
+ walkIncludes((xmlHashScanner) xslDbgShellPrintStylesheetsHelper2,
+ NULL, filesGetStylesheet());
+ notifyListSend();
+ } else {
+ walkStylesheets((xmlHashScanner) xslDbgShellPrintStylesheetsHelper,
+ NULL, filesGetStylesheet());
+ walkIncludes((xmlHashScanner) xslDbgShellPrintStylesheetsHelper2,
+ NULL, filesGetStylesheet());
+ if (printCounter != 0)
+ xsldbgGenericErrorFunc(i18n("\tTotal of %n XSLT stylesheet found.", "\tTotal of %n XSLT stylesheets found.", printCounter) + QString("\n"));
+ else
+ /* strange but possible */
+ xsldbgGenericErrorFunc(i18n("\tNo XSLT stylesheets found.\n"));
+ }
+ return 1; /* always succeed */
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/trace_cmds.cpp b/kxsldbg/kxsldbgpart/libxsldbg/trace_cmds.cpp
new file mode 100644
index 00000000..3893be67
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/trace_cmds.cpp
@@ -0,0 +1,77 @@
+
+/***************************************************************************
+ oc_cmds.c - libxslt parameter 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 "options.h"
+
+
+/* -----------------------------------------
+
+ Tracing related commands
+
+ ------------------------------------------- */
+
+
+/**
+ * xslDbgShellTrace:
+ * @arg: Not used
+ *
+ * Start the tracing of the stylesheet. First need to restart it.
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgShellTrace(xmlChar * arg)
+{
+ Q_UNUSED(arg);
+ xslDebugStatus = DEBUG_RUN_RESTART;
+ optionsSetIntOption(OPTIONS_TRACE, TRACE_ON);
+ return 1;
+}
+
+
+/**
+ * xslDbgShellWalk:
+ * @arg: An interger between 0 and 9 indicate the speed of walk
+ *
+ * Start walking through the stylesheet.
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+xslDbgShellWalk(xmlChar * arg)
+{
+ int result = 0;
+
+ long speed = WALKSPEED_NORMAL;
+
+ if (xmlStrLen(arg)
+ && (!sscanf((char *) arg, "%ld", &speed) || ((speed < 0) || (speed > 9)))) {
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments to command %1.\n").arg("walk"));
+ xsldbgGenericErrorFunc(i18n("Warning: Assuming normal speed.\n"));
+ speed = WALKSPEED_NORMAL;
+ }
+ result = 1;
+ optionsSetIntOption(OPTIONS_WALK_SPEED, speed);
+ xslDebugStatus = DEBUG_WALK;
+
+ return result;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/utils.cpp b/kxsldbg/kxsldbgpart/libxsldbg/utils.cpp
new file mode 100644
index 00000000..c63c07fc
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/utils.cpp
@@ -0,0 +1,187 @@
+
+/**************************************************************************
+ utils.c - misc utils
+
+ -------------------
+ begin : Thur Jan 31 2002
+ 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 "utils.h"
+
+/**
+ * trimString:
+ * @text : A valid string with leading or trailing spaces
+ *
+ * Remove leading and trailing spaces off @text
+ * stores result back into @text
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+trimString(xmlChar * text)
+{
+ int result = 0;
+ xmlChar *start, *end;
+
+ if (text && xmlStrlen(text)) {
+ start = text;
+ end = text + xmlStrLen(text) - 1;
+ while (_IS_BLANK(*start) && (start <= end))
+ start++;
+
+ while (_IS_BLANK(*end) && (end >= start))
+ end--;
+
+ /* copy to @text */
+ while (start <= end) {
+ *text = *start;
+ text++;
+ start++;
+ }
+
+ *text = '\0';
+ result = 1;
+ }
+ return result;
+}
+
+
+/**
+ * splitString:
+ * @textIn: The string to split
+ * @maxStrings: The max number of strings to put into @out
+ * @out: Is valid and at least the size of @maxStrings
+ *
+ * Split string by white space and put into @out
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+int
+splitString(xmlChar * textIn, int maxStrings, xmlChar ** out)
+{
+ int wordCount = 0;
+ int foundQuote = 0;
+
+ if (!textIn || !out)
+ return wordCount;
+
+
+ while ((*textIn != '\0') && (wordCount < maxStrings)) {
+ /*skip the first spaces ? */
+ while (_IS_BLANK(*textIn))
+ textIn++;
+
+ if (*textIn == '\"') {
+ textIn++;
+ foundQuote = 1;
+ }
+ out[wordCount] = textIn;
+
+ /* look for end of word */
+ if (foundQuote == 0) {
+ while (!_IS_BLANK(*textIn) && (*textIn != '\0'))
+ textIn++;
+
+ if (*textIn != '\0') {
+ *textIn = '\0';
+ textIn++;
+ }
+
+ if (xmlStrLen(out[wordCount]) > 0) {
+ wordCount++;
+ }
+ } else {
+ /* look for ending quotation mark */
+ while ((*textIn != '\0') && (*textIn != '\"'))
+ textIn++;
+ if (*textIn == '\0') {
+ xsldbgGenericErrorFunc(i18n("Error: Unmatched quotes in input.\n"));
+ wordCount = 0;
+ break;
+ }
+ *textIn = '\0';
+ textIn++; /* skip the '"' which is now a '\0' */
+ foundQuote = 0;
+ wordCount++;
+ }
+
+ }
+
+ if (*textIn != '\0')
+ wordCount = 0; /* We have not processed all the text givent to us */
+ return wordCount;
+}
+
+
+
+/**
+ * lookupName:
+ * @name : Is valid
+ * @matchList : A NULL terminated list of names to use as lookup table
+ *
+ * Lookup and name in a list
+ *
+ * Returns The id of name found in @matchList,
+ * 0 otherwise
+*/
+int
+lookupName(xmlChar * name, xmlChar ** matchList)
+{
+ int result = -1, nameIndex;
+
+ if (!name || !matchList)
+ return result;
+
+ for (nameIndex = 0; matchList[nameIndex]; nameIndex++) {
+ if (xmlStrEqual(name, matchList[nameIndex])) {
+ result = nameIndex;
+ break;
+ }
+ }
+
+ return result;
+}
+
+/**
+ * fullQName:
+ * @nameURI : QName part of name
+ * @name : Local part of name
+ *
+ * Join nameURI to name
+ *
+ * Returns a copy of "nameURI:name"
+ *
+ */
+
+xmlChar * fullQName(const xmlChar* nameURI, const xmlChar * name)
+{
+ xmlChar *result = NULL;
+ if (!nameURI && !name)
+ result = xmlStrdup((xmlChar*)"");
+ else{
+ if (nameURI == NULL){
+ result = xmlStrdup(name);
+ }else{
+ result = (xmlChar*) xmlMalloc(sizeof(char) * (
+ xmlStrLen(name) +
+ xmlStrLen(nameURI) + 3));
+ if (result)
+ sprintf((char*)result, "%s:%s", (char*)nameURI, (char*)name);
+ }
+ }
+ return result;
+}
+
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/utils.h b/kxsldbg/kxsldbgpart/libxsldbg/utils.h
new file mode 100644
index 00000000..e5cd4bfc
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/utils.h
@@ -0,0 +1,217 @@
+
+/**************************************************************************
+ utils.c - declaration for misc utils this is
+ mixed bag of functions so it is
+ not realy a module hense no need
+ for a utils prefix its functions
+
+ -------------------
+ begin : Thur Jan 31 2002
+ 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. *
+ * *
+ **************************************************************************/
+
+#ifndef XSLDBG_UTILS_H
+#define XSLDBG_UTILS_H
+
+#ifndef BUILD_DOCS
+#include <stdio.h>
+#include <string.h>
+#include <libxml/tree.h>
+#include <libxml/debugXML.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/xsltutils.h>
+#include <libxml/xpath.h>
+#endif
+
+#include "xsldbg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ Make things simpler when working between char* and xmlChar* .
+ By definition a char is the same size as an xmlChar(unsigned char).
+*/
+
+#ifndef BUILD_DOCS
+#define xmlStrLen(text) strlen((char*)(text))
+#define xmlStrCat(a, b) strcat((char*)(a), (char*)(b))
+#define xmlStrCmp(a, b) strcmp((char*)(a), (char*)(b))
+#define xmlStrnCmp(a, b, c) strncmp((char*)(a), (char*)(b), c)
+#define xmlStrCpy(a, b) strcpy((char*)(a), (char*)(b))
+#define xmlStrnCpy(a, b, c) strncpy((char*)(a),(char*)(b), c)
+#define xmlStrChr(a, b) strchr((char*)(a), b)
+#define xmlStrrChr(a, b) strrchr((char*)(a), b)
+#endif
+
+/* what char is use to separate directories in an URI*/
+#define URISEPARATORCHAR '/'
+
+ /* Handle the differences in path and quote character between
+ * win32 and *nix systems */
+#ifdef WIN32
+#define QUOTECHAR ' '
+#define PATHCHAR '\\'
+#else
+#define QUOTECHAR '\"'
+#define PATHCHAR '/'
+#endif
+
+
+/* JRF: Although RISC OS native paths use . as a separator, the arguments
+ to xsldbg are passed in unix or URI form, and thus the above
+ specification is correct. */
+
+
+
+/**
+ * _IS_BLANK:
+ * @c: an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec
+ *
+ * [3] S ::= (#x20 | #x9 | #xD | #xA)+
+ */
+#define _IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) || \
+ ((c) == 0x0D))
+
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * trimString:
+ * @text : A valid string with leading or trailing spaces
+ *
+ * Remove leading and trailing spaces off @text
+ * stores result back into @text
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Remove leading and trailing spaces off @p text
+ * stores result back into @p text
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param text A valid string with leading or trailing spaces
+ */
+#endif
+#endif
+ int trimString(xmlChar * text);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * splitString:
+ * @textIn: The string to split
+ * @maxStrings: The max number of strings to put into @out
+ * @out: Is valid and at least the size of @maxStrings
+ *
+ * Split string by white space and put into @out
+ *
+ * Returns 1 on success,
+ * 0 otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Spit string by white space and put into @p out
+ *
+ * @returns 1 on success,
+ * 0 otherwise
+ *
+ * @param textIn The string to split
+ * @param maxStrings The max number of strings to put into @p out
+ * @param out Is valid and at least the size of @p maxStrings
+ */
+#endif
+#endif
+ int splitString(xmlChar * textIn, int maxStrings, xmlChar ** out);
+
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * lookupName:
+ * @name : Is valid
+ * @matchList : A NULL terminated list of names to use as lookup table
+ *
+ * Lookup and name in a list
+ *
+ * Returns The id of name found in @matchList,
+ * 0 otherwise
+*/
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Lookup and name in a list
+ *
+ *
+ * @returns The id of name found in @p matchList
+ * 0 otherwise
+ *
+ * @param name Is valid
+ * @param matchList A NULL terminated list of names to use as lookup table
+ *
+*/
+#endif
+#endif
+ int lookupName(xmlChar * name, xmlChar ** matchList);
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * fullQName:
+ * @nameURI : QName part of name
+ * @name : Local part of name
+ *
+ * Join nameURI to name
+ *
+ * Returns a copy of "nameURI:name"
+ *
+ */
+
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Join nameURI to name
+ *
+ * @returns a copy of "nameURI:name"
+
+ * fullQName:
+ * @param nameURI : QName part of name
+ * @param name : Local part of name
+ *
+ *
+ */
+#endif
+#endif
+
+ xmlChar * fullQName(const xmlChar* nameURI, const xmlChar * name);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/variable_cmds.cpp b/kxsldbg/kxsldbgpart/libxsldbg/variable_cmds.cpp
new file mode 100644
index 00000000..a00769f4
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/variable_cmds.cpp
@@ -0,0 +1,114 @@
+
+/***************************************************************************
+ variable_cmds.c - description
+ -------------------
+ begin : Sun Dec 30 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 <libxml/xpath.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/variables.h> /* needed for xsltVariablesComp */
+#include <libxml/valid.h> /* needed for xmlSplitQName2 */
+#include "xsldbg.h"
+#include "debugXSL.h"
+#include "search.h"
+
+
+int
+xslDbgShellSetVariable(xsltTransformContextPtr styleCtxt, xmlChar * arg)
+{
+ int result = 0, showUsage = 0;
+ xmlChar *name, *nameURI, *selectExpr, *opts[3];
+
+ if (!styleCtxt) {
+
+ xsldbgGenericErrorFunc(i18n("Error: Stylesheet is not valid.\n"));
+ return result;
+ }
+
+ if (!arg) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Error: NULL argument provided\n");
+#endif
+ return result;
+ }
+
+ if (xmlStrLen(arg) > 1) {
+ if (splitString(arg, 2, opts) == 2) {
+ nameURI = NULL;
+ /* ignore any "$" prefix as user probably didn't mean that
+ "$" is part of variable name*/
+ if (*opts[0] =='$'){
+ opts[0] = opts[0] + 1;
+ }
+ name = xmlSplitQName2(opts[0], &nameURI);
+ if (name == NULL)
+ name = xmlStrdup(opts[0]);
+ selectExpr = xmlStrdup(opts[1]);
+ if (name && selectExpr) {
+ xsltStackElemPtr def = NULL;
+
+ if (styleCtxt->varsNr && styleCtxt->varsTab) {
+ /* try finding varaible in stack */
+ for (int i = styleCtxt->varsNr; i > styleCtxt->varsBase; i--) {
+ xsltStackElemPtr item = styleCtxt->varsTab[i-1];
+ while (item) {
+ if ((xmlStrCmp(name, item->name) == 0) &&
+ (item->nameURI == NULL
+ || (xmlStrCmp(name, item->nameURI) == 0))) {
+ def = item;
+ break;
+ }
+ item = item->next;
+ }
+ }
+ }
+
+ if (def == NULL)
+ def = (xsltStackElemPtr)
+ xmlHashLookup2(styleCtxt->globalVars,
+ name, nameURI);
+ if (def != NULL) {
+ if (def->select) {
+ def->select = xmlDictLookup(styleCtxt->dict, selectExpr, -1);
+ def->tree = NULL; /* maybe a memory leak, but play it safe */
+ def->computed = 1;
+ if (def->comp->comp)
+ xmlXPathFreeCompExpr(def->comp->comp);
+ def->comp->comp = xmlXPathCompile(def->select);
+ if (def->value)
+ xmlXPathFreeObject(def->value);
+ def->value =
+ xmlXPathEval(def->select,
+ styleCtxt->xpathCtxt);
+ result = 1;
+ } else {
+ xmlFree(selectExpr);
+ xsldbgGenericErrorFunc(i18n("Error: Cannot change a variable that does not use the select attribute.\n"));
+ }
+ } else
+ xsldbgGenericErrorFunc(i18n("Error: Variable %1 was not found.\n").arg(xsldbgText(name)));
+ xmlFree(name);
+ } else
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ } else {
+ showUsage = 1;
+ }
+
+ if (showUsage == 1)
+ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments to command %1.\n").arg("set"));
+ }
+ return result;
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/xsldbg.cpp b/kxsldbg/kxsldbgpart/libxsldbg/xsldbg.cpp
new file mode 100644
index 00000000..2afdb828
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/xsldbg.cpp
@@ -0,0 +1,1367 @@
+
+/***************************************************************************
+ xsldbg.c - description
+ -------------------
+ begin : Sun Sep 16 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. *
+ * *
+ ***************************************************************************/
+
+/*
+ * Based on file xsltproc.c
+ *
+ * by Daniel Veillard
+ * daniel@veillard.com
+ *
+ * xsltproc.c is part of libxslt
+ *
+ *
+ */
+
+/* Justin's port version - do not merge into core!!! */
+#define RISCOS_PORT_VERSION "2.01"
+
+#include <kurl.h>
+#include <kdebug.h>
+#include "xsldbg.h"
+#include "debug.h"
+#include "options.h"
+#include "utils.h"
+#include "files.h"
+#include "breakpoint.h"
+#include "debugXSL.h"
+
+#include <libxml/xmlerror.h>
+#include "xsldbgmsg.h"
+#include "xsldbgthread.h" /* for getThreadStatus */
+#ifdef HAVE_READLINE
+# include <readline/readline.h>
+# ifdef HAVE_HISTORY
+# include <readline/history.h>
+# endif
+#endif
+
+/* need to setup catch of SIGINT */
+#include <signal.h>
+
+/* needed by printTemplateNames */
+#include <libxslt/transform.h>
+
+/* standard includes from xsltproc*/
+#include <libxslt/xslt.h>
+#include <libexslt/exslt.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+#include <libxml/xmlmemory.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlerror.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/xmlIO.h>
+#ifdef LIBXML_DOCB_ENABLED
+#include <libxml/DOCBparser.h>
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+#include <libxml/xinclude.h>
+#endif
+
+#include <libxml/catalog.h>
+#include <libxml/parserInternals.h>
+
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
+#include <libxslt/extensions.h>
+#include <libexslt/exsltconfig.h>
+
+#include <kcmdlineargs.h>
+#include <kglobal.h>
+#include <qfile.h>
+
+#ifdef WIN32
+#ifdef _MSC_VER
+#include <winsock2.h>
+#pragma comment(lib, "ws2_32.lib")
+#define gettimeofday(p1,p2)
+#define HAVE_TIME_H
+#include <time.h>
+#define HAVE_STDARG_H
+#include <stdarg.h>
+#endif /* _MS_VER */
+#else /* WIN32 */
+#if defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#elif defined(HAVE_TIME_H)
+#include <time.h>
+#endif
+
+
+#endif /* WIN32 */
+
+#ifndef HAVE_STAT
+# ifdef HAVE__STAT
+
+/* MS C library seems to define stat and _stat. The definition
+ * is identical. Still, mapping them to each other causes a warning. */
+# ifndef _MSC_VER
+# define stat(x,y) _stat(x,y)
+# endif
+# define HAVE_STAT
+# endif
+#endif
+
+#ifdef __riscos
+
+/* Global definition of our program name on invocation.
+ This is required such that we can invoke ourselves for processing
+ search or help messages where our executable does not exist on the
+ current run path */
+char *xsldbgCommand = NULL;
+#endif
+
+xmlSAXHandler mySAXhdlr;
+
+FILE *errorFile = NULL; /* we'll set this just before starting debugger */
+
+xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL,
+ const char *ID,
+ xmlParserCtxtPtr ctxt);
+
+/* -----------------------------------------
+ Private function declarations for xsldbg.c
+ -------------------------------------------*/
+
+/**
+ * xsldbgInit:
+ *
+ * Returns 1 if able to allocate memory needed by xsldbg
+ * 0 otherwise
+ */
+int xsldbgInit(void);
+
+
+/**
+ * xsldbgFree:
+ *
+ * Free memory used by xsldbg
+ */
+void xsldbgFree(void);
+
+
+/**
+ * printTemplates:
+ * @style : valid as parsed my xsldbg
+ * @doc : " " " " "
+ *
+ * print out list of template names
+ */
+void printTemplates(xsltStylesheetPtr style, xmlDocPtr doc);
+
+
+/**
+ * catchSigInt:
+ * @value : not used
+ *
+ * Recover from a signal(SIGINT), exit if needed
+ */
+void catchSigInt(int value);
+
+
+/**
+ * catchSigTerm:
+ * @value : not used
+ *
+ * Clean up and exit
+ */
+void
+ catchSigTerm(int value);
+
+/**
+ * xsldbgGenericErrorFunc:
+ * @ctx: Is Valid
+ * @msg: Is valid
+ * @...: other parameters to use
+ *
+ * Handles print output from xsldbg and passes it to the application if
+ * running as a thread otherwise send to stderr
+ */
+void
+ xsldbgGenericErrorFunc(void *ctx, const char *msg, ...);
+
+xmlEntityPtr (*oldGetEntity)( void * user_data, const xmlChar * name);
+
+static xmlEntityPtr xsldbgGetEntity( void * user_data, const xmlChar * name)
+{
+ xmlEntityPtr ent = NULL;
+ if (oldGetEntity){
+ ent = (oldGetEntity)(user_data, name);
+ if (ent)
+ filesEntityRef(ent, ent->children, ent->last);
+ }
+ return ent;
+}
+
+/* -------------------------------------
+ End private functions
+ ---------------------------------------*/
+
+
+/*
+ * Internal timing routines to remove the necessity to have unix-specific
+ * function calls
+ */
+
+#if defined(HAVE_GETTIMEOFDAY)
+static struct timeval begin, end;
+
+/*
+ * startTimer: call where you want to start timing
+ */
+static void
+startTimer(void)
+{
+ gettimeofday(&begin, NULL);
+}
+
+/*
+ * endTimer: call where you want to stop timing and to print out a
+ * message about the timing performed; format is a printf
+ * type argument
+ */
+static void
+endTimer(const QString& message)
+{
+ long msec;
+
+ gettimeofday(&end, NULL);
+ msec = end.tv_sec - begin.tv_sec;
+ msec *= 1000;
+ msec += (end.tv_usec - begin.tv_usec) / 1000;
+
+#ifndef HAVE_STDARG_H
+#error "endTimer required stdarg functions"
+#endif
+ /* Display the time taken to complete this task */
+ xsldbgGenericErrorFunc(i18n("%1 took %2 ms to complete.\n").arg(message).arg(msec));
+}
+#elif defined(HAVE_TIME_H)
+
+/*
+ * No gettimeofday function, so we have to make do with calling clock.
+ * This is obviously less accurate, but there's little we can do about
+ * that.
+ */
+
+clock_t begin, end;
+static void
+startTimer(void)
+{
+ begin = clock();
+}
+static void
+endTimer(const QString& message)
+{
+ long msec;
+
+ end = clock();
+ msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
+
+#ifndef HAVE_STDARG_H
+#error "endTimer required stdarg functions"
+#endif
+ /* Display the time taken to complete this task */
+ xsldbgGenericErrorFunc(i18n("%1 took %2 ms to complete.\n").arg(message).arg(msec));
+}
+#else
+
+/*
+ * We don't have a gettimeofday or time.h, so we just don't do timing
+ */
+static void
+startTimer(void)
+{
+ /*
+ * Do nothing
+ */
+}
+static void
+endTimer(const QString& message)
+{
+ /*
+ * We can not do anything because we don't have a timing function
+ */
+#ifdef HAVE_STDARG_H
+ /* Display the time taken to complete this task */
+ xsldbgGenericErrorFunc(i18n("%1 took %2 ms to complete.\n"),arg(message).arg(msec));
+#else
+ /* We don't have gettimeofday, time or stdarg.h, what crazy world is
+ * this ?!
+ */
+#endif
+}
+#endif
+
+static void
+xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur)
+{
+
+ xmlDocPtr res;
+ const char *params[8 * 2 + 2];
+ int bytesWritten = -1;
+ int nbparams = 0;
+ int paramIndex;
+ parameterItemPtr paramItem;
+
+ /* Copy the parameters accross for libxslt */
+ for (paramIndex = 0;
+ paramIndex < arrayListCount(optionsGetParamItemList());
+ paramIndex++) {
+ paramItem = (parameterItemPtr)arrayListGet(optionsGetParamItemList(), paramIndex);
+ if (paramItem) {
+ params[nbparams] = (char *) paramItem->name;
+ params[nbparams + 1] = (char *) paramItem->value;
+ nbparams += 2;
+ }
+ }
+
+ params[nbparams] = NULL;
+
+#ifdef LIBXML_XINCLUDE_ENABLED
+ if (optionsGetIntOption(OPTIONS_XINCLUDE)) {
+ if (optionsGetIntOption(OPTIONS_TIMING))
+ startTimer();
+ xmlXIncludeProcess(doc);
+ if (optionsGetIntOption(OPTIONS_TIMING)) {
+ /* Display the time taken to do XInclude processing */
+ endTimer(i18n("XInclude processing %1.").arg((const char*)optionsGetStringOption(OPTIONS_DATA_FILE_NAME)));
+ }
+ }
+#endif
+ if (optionsGetIntOption(OPTIONS_TIMING) ||
+ optionsGetIntOption(OPTIONS_PROFILING))
+ startTimer();
+ if ((optionsGetStringOption(OPTIONS_OUTPUT_FILE_NAME) == NULL) ||
+ optionsGetIntOption(OPTIONS_SHELL)) {
+ if (optionsGetIntOption(OPTIONS_REPEAT)) {
+ int j;
+
+ for (j = 1; j < optionsGetIntOption(OPTIONS_REPEAT); j++) {
+ res = xsltApplyStylesheet(cur, doc, params);
+ xmlFreeDoc(res);
+ doc = xsldbgLoadXmlData();
+ }
+ }
+ if (optionsGetIntOption(OPTIONS_PROFILING)) {
+ if (terminalIO != NULL)
+ res = xsltProfileStylesheet(cur, doc, params, terminalIO);
+ else if ((optionsGetStringOption(OPTIONS_OUTPUT_FILE_NAME) ==
+ NULL) || (getThreadStatus() != XSLDBG_MSG_THREAD_RUN)
+ || (filesTempFileName(1) == NULL))
+ res = xsltProfileStylesheet(cur, doc, params, stderr);
+ else {
+ /* We now have to output to using notify using
+ * temp file #1 */
+ FILE *tempFile = fopen(filesTempFileName(1), "w");
+
+ if (tempFile != NULL) {
+ res =
+ xsltProfileStylesheet(cur, doc, params, tempFile);
+ fclose(tempFile);
+ /* send the data to application */
+ notifyXsldbgApp(XSLDBG_MSG_FILEOUT,
+ filesTempFileName(1));
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to write temporary results to %1.\n").arg(filesTempFileName(1)));
+ res = xsltProfileStylesheet(cur, doc, params, stderr);
+ }
+ }
+ } else {
+ res = xsltApplyStylesheet(cur, doc, params);
+ }
+ if (optionsGetIntOption(OPTIONS_PROFILING)) {
+ if (optionsGetIntOption(OPTIONS_REPEAT))
+ /* Display how long it took to apply stylesheet */
+ endTimer(i18n("Applying stylesheet %n time", "Applying stylesheet %n times", optionsGetIntOption(OPTIONS_REPEAT)));
+ else
+ /* Display how long it took to apply stylesheet */
+ endTimer(i18n("Applying stylesheet"));
+ }
+ if (res == NULL) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext, "Error: Transformation did not complete writing to file %s\n",
+ optionsGetStringOption
+ (OPTIONS_OUTPUT_FILE_NAME));
+#endif
+ return;
+ }
+ if (!optionsGetIntOption(OPTIONS_OUT)) {
+ xmlFreeDoc(res);
+ return;
+ }
+#ifdef LIBXML_DEBUG_ENABLED
+ if (optionsGetIntOption(OPTIONS_DEBUG)) {
+ if (xslDebugStatus != DEBUG_RUN_RESTART){
+ if (terminalIO != NULL)
+ xmlDebugDumpDocument(terminalIO, res);
+ else if ((optionsGetStringOption(OPTIONS_OUTPUT_FILE_NAME) ==
+ NULL) || (getThreadStatus() != XSLDBG_MSG_THREAD_RUN)
+ || (filesTempFileName(1) == NULL))
+ xmlDebugDumpDocument(stdout, res);
+ else {
+ FILE *tempFile = fopen(filesTempFileName(1), "w");
+
+ if (tempFile) {
+ bytesWritten = 0; // flag that we have writen at least zero bytes
+ xmlDebugDumpDocument(tempFile, res);
+ fclose(tempFile);
+ /* send the data to application */
+ notifyXsldbgApp(XSLDBG_MSG_FILEOUT,
+ filesTempFileName(1));
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to write temporary results to %1.\n").arg(filesTempFileName(1)));
+ xmlDebugDumpDocument(stdout, res);
+ }
+
+ }
+ }
+ } else {
+#endif
+ if (xslDebugStatus != DEBUG_RUN_RESTART){
+ if (cur->methodURI == NULL) {
+ if (optionsGetIntOption(OPTIONS_TIMING))
+ startTimer();
+ if (xslDebugStatus != DEBUG_QUIT) {
+ if (terminalIO != NULL)
+ bytesWritten = xsltSaveResultToFile(terminalIO, res, cur);
+ else if (optionsGetStringOption
+ (OPTIONS_OUTPUT_FILE_NAME) == NULL)
+ bytesWritten = xsltSaveResultToFile(stdout, res, cur);
+ else{
+ bytesWritten = xsltSaveResultToFilename((const char *)
+ optionsGetStringOption
+ (OPTIONS_OUTPUT_FILE_NAME),
+ res, cur, 0);
+ }
+ }
+ if (optionsGetIntOption(OPTIONS_TIMING))
+ /* Indicate how long it took to save to file */
+ endTimer(i18n("Saving result"));
+ } else {
+ if (xmlStrEqual(cur->method, (const xmlChar *) "xhtml")) {
+ xsldbgGenericErrorFunc(i18n("Warning: Generating non-standard output XHTML.\n"));
+ if (optionsGetIntOption(OPTIONS_TIMING))
+ startTimer();
+ if (terminalIO != NULL)
+ bytesWritten = xsltSaveResultToFile(terminalIO, res, cur);
+ else if (optionsGetStringOption
+ (OPTIONS_OUTPUT_FILE_NAME) == NULL)
+ bytesWritten = xsltSaveResultToFile(stdout, res, cur);
+ else
+ bytesWritten = xsltSaveResultToFilename((const char *)
+ optionsGetStringOption
+ (OPTIONS_OUTPUT_FILE_NAME),
+ res, cur, 0);
+ if (optionsGetIntOption(OPTIONS_TIMING))
+ /* Indicate how long it took to save to file */
+ endTimer(i18n("Saving result"));
+ } else {
+ xsldbgGenericErrorFunc(i18n("Warning: Unsupported, non-standard output method %1.\n").arg(xsldbgText(cur->method)));
+ }
+ }
+ }
+#ifdef LIBXML_DEBUG_ENABLED
+ }
+#endif
+
+ xmlFreeDoc(res);
+ } else {
+ xsltTransformContextPtr userCtxt = xsltNewTransformContext(cur, doc);
+ if (userCtxt){
+ bytesWritten = xsltRunStylesheetUser(cur, doc, params,
+ (char *)optionsGetStringOption(OPTIONS_OUTPUT_FILE_NAME),
+ NULL, NULL, NULL, userCtxt);
+ if (optionsGetIntOption(OPTIONS_TIMING))
+ endTimer(i18n("Running stylesheet and saving result"));
+ xsltFreeTransformContext(userCtxt);
+ }else{
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ }
+ }
+ if ((xslDebugStatus != DEBUG_RUN_RESTART) && (bytesWritten == -1))
+ xsldbgGenericErrorFunc(i18n("Error: Unable to save results of transformation to file %1.\n").arg(xsldbgText(optionsGetStringOption(OPTIONS_OUTPUT_FILE_NAME))));
+}
+
+int
+xsldbgMain(int argc, char **argv)
+{
+ Q_UNUSED(argc);
+ Q_UNUSED(argv);
+ int i=0, result = 1, noFilesFound = 0;
+ xsltStylesheetPtr cur = NULL;
+ xmlChar *expandedName; /* contains file name with path expansion if any */
+
+ /* in some cases we always want to bring up a command prompt */
+ int showPrompt;
+
+ /* the xml document we're processing */
+ xmlDocPtr doc;
+
+ KCmdLineArgs *args = 0;
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_NOTUSED)
+ args = KCmdLineArgs::parsedArgs();
+
+ errorFile = stderr;
+
+
+ if (args){
+ QString langChoice = args->getOption("lang");
+ if (KGlobal::locale() && !langChoice.isEmpty() && result)
+ KGlobal::locale()->setLanguage(langChoice);
+ }
+
+#ifdef __riscos
+ /* Remember our invocation command such that we may call ourselves */
+ xsldbgCommand = argv[0];
+#endif
+
+ xmlInitMemory();
+
+
+ LIBXML_TEST_VERSION xmlLineNumbersDefault(1);
+
+ if (!xsldbgInit()) {
+ xsldbgGenericErrorFunc(i18n("Fatal error: Aborting debugger due to an unrecoverable error.\n"));
+ xsldbgFree();
+ xsltCleanupGlobals();
+ xmlCleanupParser();
+ xmlMemoryDump();
+ return (1);
+ }
+
+
+ if (args){
+ for (i = 0; i < args->count(); i++) {
+ if (!result)
+ break;
+
+ if (args->arg(i)[0] != '-') {
+ expandedName = filesExpandName((const xmlChar*)args->arg(i));
+ if (!expandedName) {
+ result = 0;
+ break;
+ }
+ switch (noFilesFound) {
+ case 0:
+ optionsSetStringOption(OPTIONS_SOURCE_FILE_NAME,
+ expandedName);
+ noFilesFound++;
+ break;
+ case 1:
+ optionsSetStringOption(OPTIONS_DATA_FILE_NAME,
+ expandedName);
+ noFilesFound++;
+ break;
+
+ default:
+ xsldbgGenericErrorFunc(i18n("Error: Too many file names supplied via command line.\n"));
+ result = 0;
+ }
+ xmlFree(expandedName);
+ continue;
+ }
+ }
+
+
+ // Handle boolean options
+ for (int optionID = OPTIONS_FIRST_BOOL_OPTIONID; optionID < OPTIONS_LAST_BOOL_OPTIONID; optionID++){
+ if (optionsGetOptionName(OptionTypeEnum(optionID))){
+ if (args->isSet((char *)optionsGetOptionName(OptionTypeEnum(optionID))))
+ optionsSetIntOption(OptionTypeEnum
+ (optionID), 1);
+ else
+ optionsSetIntOption(OptionTypeEnum(optionID), 0);
+ }
+ }
+
+ // No extra arguments go straight to the shell?
+ if (args->count() == 0)
+ result = optionsSetIntOption(OPTIONS_SHELL, 1);
+
+ // Disable net access?
+ if (!args->isSet("net")){
+ char noNetCmd[] = {"nonet 1"};
+ xslDbgShellSetOption((xmlChar*)noNetCmd);
+ }
+ }
+
+ if (getThreadStatus() != XSLDBG_MSG_THREAD_NOTUSED){
+ result = optionsSetIntOption(OPTIONS_SHELL, 1);
+ }
+ /* copy the volitile options over to xsldbg */
+ optionsCopyVolitleOptions();
+
+ /*
+ * shell interraction
+ */
+ if (!optionsGetIntOption(OPTIONS_SHELL)) { /* excecute stylesheet (ie no debugging) */
+ xslDebugStatus = DEBUG_NONE;
+ } else {
+ xslDebugStatus = DEBUG_STOP;
+ xsltGenericError(xsltGenericErrorContext, "XSLDBG %s\n", VERSION);
+ }
+
+ if (optionsGetIntOption(OPTIONS_VALID))
+ xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+ else
+ xmlLoadExtDtdDefaultValue = 0;
+
+
+ if (args){
+ if (args->isSet("verbose") && result)
+ xsltSetGenericDebugFunc(stderr, NULL);
+
+ QCString outFile = args->getOption("output");
+ if (!outFile.isEmpty() && result)
+ result = xslDbgShellOutput((const xmlChar *)QFile::encodeName(outFile).data());
+
+ QCString maxDepth = args->getOption("maxdepth");
+ if (!maxDepth.isEmpty() && result){
+ bool OK;
+ int value = maxDepth.toInt(&OK);
+ if (OK && (value> 0))
+ xsltMaxDepth = value;
+ }
+
+ if (args->isSet("repeat") && result){
+ if (optionsGetIntOption(OPTIONS_REPEAT) == 0)
+ optionsSetIntOption(OPTIONS_REPEAT, 20);
+ else
+ optionsSetIntOption(OPTIONS_REPEAT, 100);
+ }
+
+ QCStringList xslParams(args->getOptionList("param"));
+ QCStringList::iterator it;
+ QCString param, paramName, paramValue;
+ int separatorIdx;
+ bool paramOK;
+ for ( it = xslParams.begin(); it != xslParams.end(); ++it){
+ param = (*it);
+ paramOK = true;
+ separatorIdx = param.find(':');
+ if (separatorIdx > 0){
+ paramName = param.left((uint)separatorIdx);
+ paramValue = param.mid((uint)separatorIdx + 1);
+ if (!paramName.isEmpty() && !paramValue.isEmpty()){
+ if (arrayListCount(optionsGetParamItemList()) <= 31) {
+ arrayListAdd(optionsGetParamItemList(), optionsParamItemNew((const xmlChar*)paramName.data(), (const xmlChar*)paramValue.data()));
+ }else{
+ xsldbgGenericErrorFunc(i18n("Warning: Too many libxslt parameters provided via the command line option --param.\n"));
+ }
+ }else{
+ paramOK = false;
+ }
+ }else{
+ paramOK = false;
+ }
+ if (!paramOK)
+ xsldbgGenericErrorFunc(i18n("Error: Argument \"%1\" to --param is not in the format <name>:<value>.\n").arg(param.data()));
+ }
+
+ QCString cdPath = args->getOption("cd");
+ if (!cdPath.isEmpty() && result)
+ result = changeDir((const xmlChar *)QFile::encodeName(cdPath).data());
+
+ }
+
+ if (!result) {
+ KCmdLineArgs::usage();
+ xsldbgFree();
+ return (1);
+ }
+
+
+ /*
+ * * Replace entities with their content.
+ */
+ xmlSubstituteEntitiesDefault(1);
+
+ /*
+ * * Register the EXSLT extensions and the test module
+ */
+ exsltRegisterAll();
+ xsltRegisterTestModule();
+
+
+
+ debugGotControl(0);
+ while (xslDebugStatus != DEBUG_QUIT) {
+ xsldbgReachedFirstTemplate = false;
+ /* don't force xsldbg to show command prompt */
+ showPrompt = 0;
+ cur = NULL;
+ doc = NULL;
+ arrayListEmpty(filesEntityList());
+ xsltSetXIncludeDefault(optionsGetIntOption(OPTIONS_XINCLUDE));
+
+ /* copy the volitile options over to xsldbg */
+ optionsCopyVolitleOptions();
+
+ /* choose where error messages/xsldbg output get sent to */
+ if (optionsGetIntOption(OPTIONS_STDOUT))
+ errorFile = stdout;
+ else
+ errorFile = stderr;
+
+ filesLoadCatalogs();
+
+ if (optionsGetIntOption(OPTIONS_SHELL)) {
+ debugGotControl(0);
+ xsldbgGenericErrorFunc(i18n("\nStarting stylesheet\n\n"));
+ if (optionsGetIntOption(OPTIONS_TRACE) == TRACE_OFF)
+ xslDebugStatus = DEBUG_STOP; /* stop as soon as possible */
+ }
+
+ if ((optionsGetStringOption(OPTIONS_SOURCE_FILE_NAME) == NULL) ||
+ (optionsGetStringOption(OPTIONS_DATA_FILE_NAME) == NULL)) {
+ /* at least on file name has not been set */
+ /*goto a xsldbg command prompt */
+ showPrompt = 1;
+ if (optionsGetStringOption(OPTIONS_SOURCE_FILE_NAME) == NULL)
+ xsldbgGenericErrorFunc(i18n("Error: No XSLT source file supplied.\n"));
+
+ if (optionsGetStringOption(OPTIONS_DATA_FILE_NAME) == NULL) {
+ xsldbgGenericErrorFunc(i18n("Error: No XML data file supplied.\n"));
+ }
+
+ } else {
+ filesLoadXmlFile(NULL, FILES_SOURCEFILE_TYPE);
+ cur = filesGetStylesheet();
+ if ((cur == NULL) || (cur->errors != 0)) {
+ /*goto a xsldbg command prompt */
+ showPrompt = 1;
+ if (xslDebugStatus == DEBUG_NONE) {
+ xslDebugStatus = DEBUG_QUIT; /* panic !! */
+ result = 0;
+ }
+ }
+ }
+
+ if (showPrompt == 0) {
+ filesLoadXmlFile(NULL, FILES_XMLFILE_TYPE);
+ doc = filesGetMainDoc();
+ if (doc == NULL) {
+ if (xslDebugStatus == DEBUG_NONE) {
+ xslDebugStatus = DEBUG_QUIT; /* panic !! */
+ result = 0;
+ } else {
+ /*goto a xsldbg command prompt */
+ showPrompt = 1;
+ }
+ } else {
+ if (xslDebugStatus != DEBUG_QUIT) {
+ xsltProcess(doc, cur);
+ result = 1;
+ }
+ }
+
+ if (optionsGetIntOption(OPTIONS_SHELL) && (showPrompt == 0)) {
+ if ((xslDebugStatus != DEBUG_QUIT)
+ && !debugGotControl(-1)) {
+ xsldbgGenericErrorFunc(i18n("\nDebugger never received control.\n"));
+ /*goto a xsldbg command prompt */
+ showPrompt = 1;
+ xslDebugStatus = DEBUG_STOP;
+ } else {
+ xsldbgGenericErrorFunc(i18n("\nFinished stylesheet\n\032\032\n"));
+ {
+ /* handle trace execution */
+ int trace = optionsGetIntOption(OPTIONS_TRACE);
+
+ switch (trace) {
+ case TRACE_OFF:
+ /* no trace of execution */
+ break;
+
+ case TRACE_ON:
+ /* tell xsldbg to stop tracing next time we get here */
+ optionsSetIntOption(OPTIONS_TRACE,
+ TRACE_RUNNING);
+ xslDebugStatus = DEBUG_TRACE;
+ break;
+
+ case TRACE_RUNNING:
+ /* turn off tracing */
+ xslDebugStatus = DEBUG_CONT;
+ optionsSetIntOption(OPTIONS_TRACE,
+ TRACE_OFF);
+ break;
+ }
+ }
+ if (!optionsGetIntOption(OPTIONS_AUTORESTART) && (xslDebugStatus != DEBUG_RUN_RESTART)){
+ /* pass control to user they won't be able to do much
+ other than add breakpoints, quit, run, continue */
+ debugXSLBreak((xmlNodePtr) cur->doc, (xmlNodePtr) doc,
+ NULL, NULL);
+ }
+ }
+ } else {
+ /* request to execute stylesheet only so we're done */
+ xslDebugStatus = DEBUG_QUIT;
+ }
+ } else {
+ /* Some sort of problem loading source file has occured. Quit? */
+ if (xslDebugStatus == DEBUG_NONE) {
+ xslDebugStatus = DEBUG_QUIT; /* Panic!! */
+ result = 0;
+ } else {
+ /*goto a xsldbg command prompt */
+ showPrompt = 1;
+ }
+ }
+
+ if (showPrompt && optionsGetIntOption(OPTIONS_SHELL)) {
+ xmlDocPtr tempDoc = xmlNewDoc((xmlChar *) "1.0");
+ xmlNodePtr tempNode =
+ xmlNewNode(NULL, (xmlChar *) "xsldbg_default_node");
+ if (!tempDoc || !tempNode) {
+ xsldbgFree();
+ return (1);
+ }
+ xmlAddChild((xmlNodePtr) tempDoc, tempNode);
+
+ xsldbgGenericErrorFunc(i18n("Going to the command shell; not all xsldbg commands will work as not all needed have been loaded.\n"));
+ xslDebugStatus = DEBUG_STOP;
+ if ((cur == NULL) && (doc == NULL)) {
+ /*no doc's loaded */
+ debugXSLBreak(tempNode, tempNode, NULL, NULL);
+ } else if ((cur != NULL) && (doc == NULL)) {
+ /* stylesheet is loaded */
+ debugXSLBreak((xmlNodePtr) cur->doc, tempNode, NULL, NULL);
+ } else if ((cur == NULL) && (doc != NULL)) {
+ /* xml doc is loaded */
+ debugXSLBreak(tempNode, (xmlNodePtr) doc, NULL, NULL);
+ } else {
+ /* unexpected problem, both docs are loaded */
+ debugXSLBreak((xmlNodePtr) cur->doc, (xmlNodePtr) doc,
+ NULL, NULL);
+ }
+ xmlFreeDoc(tempDoc);
+ } else if (showPrompt && !optionsGetIntOption(OPTIONS_SHELL)) {
+ xslDebugStatus = DEBUG_QUIT;
+ result = 0; /* panic */
+ }
+
+ if (optionsGetIntOption(OPTIONS_SHELL)) {
+ /* force a refesh of both stlesheet and xml data */
+ filesFreeXmlFile(FILES_SOURCEFILE_TYPE);
+ filesFreeXmlFile(FILES_XMLFILE_TYPE);
+ }
+ }
+
+ if (!result) {
+ xsldbgGenericErrorFunc(i18n("Fatal error: Aborting debugger due to an unrecoverable error.\n"));
+ }
+ xsldbgFree();
+ xsltCleanupGlobals();
+ xmlCleanupParser();
+ xmlMemoryDump();
+ return !result;
+}
+
+/**
+ * xsldbgLoadStylesheet:
+ *
+ * Load the stylesheet and return it
+ *
+ * Returns The stylesheet after reloading it if successful
+ * NULL otherwise
+ */
+xsltStylesheetPtr
+xsldbgLoadStylesheet()
+{
+ xsltStylesheetPtr cur = NULL;
+ xmlDocPtr style;
+
+ if (optionsGetIntOption(OPTIONS_TIMING))
+ startTimer();
+ style = xmlParseFile((const char *) optionsGetStringOption(OPTIONS_SOURCE_FILE_NAME));
+ if (optionsGetIntOption(OPTIONS_TIMING))
+ endTimer(i18n("Parsing stylesheet %1").arg((const char*)optionsGetStringOption(OPTIONS_SOURCE_FILE_NAME)));
+ if (style == NULL) {
+ xsldbgGenericErrorFunc(i18n("Error: Cannot parse file %1.\n").arg(xsldbgUrl(optionsGetStringOption(OPTIONS_SOURCE_FILE_NAME))));
+ cur = NULL;
+ if (!optionsGetIntOption(OPTIONS_SHELL)) {
+ xsldbgGenericErrorFunc(i18n("Fatal error: Aborting debugger due to an unrecoverable error.\n"));
+ xslDebugStatus = DEBUG_QUIT;
+ } else {
+ xsltGenericError(xsltGenericErrorContext, "\n");
+ xslDebugStatus = DEBUG_STOP;
+ }
+ } else {
+ cur = xsltLoadStylesheetPI(style);
+ if (cur != NULL) {
+ /* it is an embedded stylesheet */
+ xsltProcess(style, cur);
+ xsltFreeStylesheet(cur);
+ } else {
+ cur = xsltParseStylesheetDoc(style);
+ if (cur != NULL) {
+ if (cur->indent == 1)
+ xmlIndentTreeOutput = 1;
+ else
+ xmlIndentTreeOutput = 0;
+ } else {
+ xmlFreeDoc(style);
+ }
+ }
+ }
+ return cur;
+}
+
+
+
+/**
+ * xsldbgLoadXmlData:
+ *
+ * Load the xml data file and return it
+ *
+ * Returns The data file after reloading it if successful
+ * NULL otherwise
+ */
+xmlDocPtr
+xsldbgLoadXmlData(void)
+{
+ xmlDocPtr doc = NULL;
+ xmlSAXHandler mySAXHandler;
+ doc = NULL;
+
+ xmlSAXVersion(&mySAXHandler,2);
+ oldGetEntity = mySAXHandler.getEntity;
+ mySAXHandler.getEntity = xsldbgGetEntity;
+
+ if (optionsGetIntOption(OPTIONS_TIMING))
+ startTimer();
+#ifdef LIBXML_HTML_ENABLED
+ if (optionsGetIntOption(OPTIONS_HTML))
+ doc = htmlParseFile((char *)
+ optionsGetStringOption(OPTIONS_DATA_FILE_NAME),
+ NULL);
+ else
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+ if (optionsGetIntOption(OPTIONS_DOCBOOK))
+ doc = docbParseFile((char *)
+ optionsGetStringOption(OPTIONS_DATA_FILE_NAME),
+ NULL);
+ else
+#endif
+
+#if LIBXML_VERSION >= 20600
+ doc = xmlSAXParseFile(&mySAXHandler,
+ (char *) optionsGetStringOption(OPTIONS_DATA_FILE_NAME), 0);
+#else
+ doc = xmlParseFile((char *) optionsGetStringOption(OPTIONS_DATA_FILE_NAME));
+#endif
+ if (doc == NULL) {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to parse file %1.\n").arg(xsldbgUrl(optionsGetStringOption(OPTIONS_DATA_FILE_NAME))));
+ if (!optionsGetIntOption(OPTIONS_SHELL)) {
+ xsldbgGenericErrorFunc(i18n("Fatal error: Aborting debugger due to an unrecoverable error.\n"));
+ xslDebugStatus = DEBUG_QUIT;
+ } else {
+ xsltGenericError(xsltGenericErrorContext, "\n");
+ xslDebugStatus = DEBUG_STOP;
+ }
+ } else if (optionsGetIntOption(OPTIONS_TIMING))
+ endTimer(QString("Parsing document %1").arg(xsldbgUrl(optionsGetStringOption(OPTIONS_DATA_FILE_NAME))).utf8().data());
+
+ return doc;
+}
+
+
+/**
+ * xsldbgLoadXmlTemporary:
+ * @path: The name of temporary file to load
+ *
+ * Load the temporary data file and return it
+ *
+ * Returns The temporary file after reloading it if successful,
+ * NULL otherwise
+ */
+xmlDocPtr
+xsldbgLoadXmlTemporary(const xmlChar * path)
+{
+ xmlDocPtr doc = NULL;
+ doc = NULL;
+
+ if (optionsGetIntOption(OPTIONS_TIMING))
+ startTimer();
+#ifdef LIBXML_HTML_ENABLED
+ if (optionsGetIntOption(OPTIONS_HTML))
+ doc = htmlParseFile((char *) path, NULL);
+ else
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+ if (optionsGetIntOption(OPTIONS_DOCBOOK))
+ doc = docbParseFile((char *) path, NULL);
+ else
+#endif
+ doc = xmlSAXParseFile(&mySAXhdlr, (char *) path, 0);
+ if (doc == NULL) {
+ xsldbgGenericErrorFunc(i18n("Error: Unable to parse file %1.\n").arg(xsldbgUrl(path)));
+ }
+
+ if (optionsGetIntOption(OPTIONS_TIMING)
+ && (xslDebugStatus != DEBUG_QUIT)) {
+ endTimer(QString("Parsing document %1").arg(xsldbgUrl(path)));
+ }
+ return doc;
+}
+
+/**
+ * printTemplates:
+ * @style : valid as parsed my xsldbg
+ * @doc : " " " " "
+ *
+ * print out list of template names
+ */
+void
+printTemplates(xsltStylesheetPtr style, xmlDocPtr doc)
+{
+ xsltTransformContextPtr ctxt = xsltNewTransformContext(style, doc);
+
+ if (ctxt) {
+ /* don't be verbose when printing out template names */
+ xslDbgShellPrintTemplateNames(ctxt, NULL, NULL, 0, 0);
+ } else {
+ xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n"));
+ }
+}
+
+#ifdef WIN32
+
+/* For the windows world we capture the control event */
+BOOL WINAPI
+handler_routine(DWORD dwCtrlType)
+{
+
+ switch (dwCtrlType) {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ case CTRL_CLOSE_EVENT:
+ catchSigInt(SIGINT);
+ break;
+
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ xsldbgFree();
+ exit(1);
+ break;
+
+ default:
+ printf("Error: Unknown control event\n");
+ break;
+ }
+
+ return (true);
+}
+
+#endif
+
+#if LIBXML_VERSION >= 2006000
+/* libxml/ handlers */
+void xsldbgStructErrorHandler(void * userData, xmlErrorPtr error)
+{
+ if (error && error->message && (error->level >= 0) && (error->level <= 4)){
+ if (getThreadStatus() != XSLDBG_MSG_THREAD_RUN){
+ static const char *msgPrefix[4 + 1] = {"", "warning :", "error:", "fatal:"};
+ if (error->file)
+ xsltGenericError(xsltGenericErrorContext, "%s%s in file \"%s\" line %d", msgPrefix[error->level], error->message, error->file, error->line);
+ else
+ xsltGenericError(xsltGenericErrorContext, "%s%s", msgPrefix[error->level], error->message);
+
+ }else{
+ xsltGenericError(xsltGenericErrorContext,"Struct error handler");
+ notifyXsldbgApp(XSLDBG_MSG_ERROR_MESSAGE, error);
+ }
+ }
+}
+
+void xsldbgSAXErrorHandler(void * ctx, const char * msg, ...)
+{
+ if (ctx)
+ xsldbgStructErrorHandler(0, ((xmlParserCtxtPtr)ctx)->lastError);
+}
+
+void xsldbgSAXWarningHandler(void * ctx, const char * msg, ...)
+{
+ if (ctx)
+ xsldbgStructErrorHandler(0, ((xmlParserCtxtPtr)ctx)->lastError);
+}
+
+#endif
+
+/**
+ * catchSigInt:
+ * @value : not used
+ *
+ * Recover from a signal(SIGINT), exit if needed
+ */
+void
+catchSigInt(int value)
+{
+ Q_UNUSED(value);
+ if ((xslDebugStatus == DEBUG_NONE) || (xsldbgStop == 1) || (xslDebugStatus == DEBUG_STOP)) {
+ xsldbgFree();
+ exit(1);
+ }
+#ifdef __riscos
+ /* re-catch SIGINT - RISC OS resets the handler when the interupt occurs */
+ signal(SIGINT, catchSigInt);
+#endif
+
+ if (xslDebugStatus != DEBUG_STOP) {
+ /* stop running/walking imediately !! */
+ xsldbgStop = 1;
+ }
+}
+
+
+/**
+ * catchSigTerm:
+ * @value : not used
+ *
+ * Clean up and exit
+ */
+void
+catchSigTerm(int value)
+{
+ Q_UNUSED(value);
+ xsldbgFree();
+ exit(1);
+}
+
+
+
+typedef void (*sighandler_t) (int);
+static sighandler_t oldHandler;
+
+static int initialized = 0;
+
+/**
+ * xsldbgInit:
+ *
+ * Returns 1 if able to allocate memory needed by xsldbg
+ * 0 otherwise
+ */
+int
+xsldbgInit()
+{
+ int result = 0;
+ int xmlVer = 0;
+
+ if (!initialized) {
+ sscanf(xmlParserVersion, "%d", &xmlVer);
+ if (!debugInit()) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Fatal error: Init of debug module failed\n");
+#endif
+ return result;
+ }
+ if (!filesInit()) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Fatal error: Init of files module failed\n");
+#endif
+ return result;
+ }
+
+ if (!optionsInit()) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Fatal error: Init of options module failed\n");
+#endif
+ return result;
+ }
+
+ if (!searchInit()) {
+#ifdef WITH_XSLDBG_DEBUG_PROCESS
+ xsltGenericError(xsltGenericErrorContext,
+ "Fatal error: Init of search module failed\n");
+#endif
+ return result;
+ }
+
+
+
+ /* set up the parser */
+ xmlInitParser();
+#if 0
+#if LIBXML_VERSION >= 20600
+ xmlSetGenericErrorFunc(NULL, NULL);
+ xmlSetStructuredErrorFunc(NULL , (xmlStructuredErrorFunc)xsldbgStructErrorHandler);
+#else
+ xmlSetGenericErrorFunc(0, xsldbgGenericErrorFunc);
+ xsltSetGenericErrorFunc(0, xsldbgGenericErrorFunc);
+#endif
+#else
+ xmlSetGenericErrorFunc(0, xsldbgGenericErrorFunc);
+ xsltSetGenericErrorFunc(0, xsldbgGenericErrorFunc);
+#endif
+
+ /*
+ * disable CDATA from being built in the document tree
+ */
+ xmlDefaultSAXHandlerInit();
+ xmlDefaultSAXHandler.cdataBlock = NULL;
+
+ if (getThreadStatus() != XSLDBG_MSG_THREAD_NOTUSED) {
+ initialized = 1;
+ return 1; /* this is all we need to do when running as a thread */
+ }
+#ifndef WIN32
+ /* catch SIGINT */
+ oldHandler = signal(SIGINT, catchSigInt);
+#else
+ if (SetConsoleCtrlHandler(handler_routine, true) != true)
+ return result;
+#endif
+
+#ifndef WIN32
+ /* catch SIGTIN tty input available fro child */
+ signal(SIGTERM, catchSigTerm);
+#endif
+ initialized = 1;
+ }
+ return 1;
+}
+
+/**
+ * xsldbgFree:
+ *
+ * Free memory used by xsldbg
+ */
+void
+xsldbgFree()
+{
+ debugFree();
+ filesFree();
+ optionsFree();
+ searchFree();
+#ifndef WIN32
+ if (oldHandler != SIG_ERR)
+ signal(SIGINT, oldHandler);
+#else
+ SetConsoleCtrlHandler(handler_routine, false);
+#endif
+ initialized = 0;
+
+#ifdef HAVE_READLINE
+ /* rl_free_line_state ();
+ rl_cleanup_after_signal(); */
+# ifdef HAVE_HISTORY
+ clear_history();
+# endif
+#endif
+
+}
+
+
+char msgBuffer[4000];
+
+/**
+ * xsldbgGenericErrorFunc:
+ * @ctx: Is Valid
+ * @msg: Is valid
+ * @...: other parameters to use
+ *
+ * Handles print output from xsldbg and passes it to the application if
+ * running as a thread otherwise send to stderr
+ */
+void
+xsldbgGenericErrorFunc(void *ctx, const char *msg, ...)
+{
+ va_list args;
+ Q_UNUSED(ctx);
+
+ va_start(args, msg);
+ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
+ vsnprintf(msgBuffer, sizeof(msgBuffer), msg, args);
+
+ notifyTextXsldbgApp(XSLDBG_MSG_TEXTOUT, msgBuffer);
+ } else {
+ xmlChar *encodeResult = NULL;
+
+ vsnprintf(msgBuffer, sizeof(msgBuffer), msg, args);
+ encodeResult = filesEncode((xmlChar *) msgBuffer);
+ if (encodeResult) {
+ fprintf(errorFile, "%s", encodeResult);
+ xmlFree(encodeResult);
+ } else
+ fprintf(errorFile, "%s", msgBuffer);
+ }
+ va_end(args);
+}
+
+void xsldbgGenericErrorFunc(QString const &text)
+{
+ xsldbgGenericErrorFunc(0, "%s", text.utf8().data());
+}
+
+
+QString xsldbgUrl(const char *utf8fUrl)
+{
+ QString tempUrl(utf8fUrl);
+ QString fixedURI;
+ KURL url(tempUrl);
+
+ // May be provided with a URL that only has been encoded and has no protocol prefix ie a local file
+ if ( !tempUrl.startsWith("file:/") && !tempUrl.startsWith("http:/") && !tempUrl.startsWith("ftp:/"))
+ fixedURI = KURL::decode_string(tempUrl);
+ else
+ fixedURI = url.prettyURL();
+
+ return fixedURI;
+}
+
+QString xsldbgUrl(const xmlChar *utf8Url)
+{
+ return xsldbgUrl((const char*)(utf8Url));
+}
+
+QString xsldbgText(const char *utf8Text)
+{
+ return QString::fromUtf8(utf8Text);
+
+}
+
+QString xsldbgText(const xmlChar *utf8Text)
+{
+ return QString::fromUtf8((const char *)utf8Text);
+}
+
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/xsldbg.h b/kxsldbg/kxsldbgpart/libxsldbg/xsldbg.h
new file mode 100644
index 00000000..6972fc12
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/xsldbg.h
@@ -0,0 +1,188 @@
+
+/***************************************************************************
+ xsldbg.h - describe the application level functions
+ -------------------
+ begin : Sun Sep 16 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. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef XSLDEBUGGER_H
+#define XSLDEBUGGER_H
+
+#ifdef USE_KDE_DOCS
+
+/**
+ * Provide provide application level services and useful bits and pieces
+ *
+ * @short application functions and useful bits and pieces
+ *
+ * @author Keith Isdale <k_isdale@tpg.com.au>
+ */
+#endif
+
+
+/* We want skip most of these includes when building documentation */
+#ifndef BUILD_DOCS
+#ifndef __riscos
+# ifndef WIN32
+# include "config.h"
+ /* we don't need to use dll declares for *nix based machines */
+# define XSLDBG_SO_API
+# else
+ /* dll declares get defined in xsldbgwin32config.h *nix based machines */
+# include "xsldbgwin32config.h"
+# endif
+#else
+ /* we don't need to use dll declares for risc_os*/
+# define XSLDBG_SO_API
+# include "config_riscos.h"
+# include "libxml/riscos.h"
+#endif
+
+#include <libxslt/xsltconfig.h>
+
+
+#if !defined (FORCE_DEBUGGER) && (LIBXSLT_VERSION > 10019)
+# ifndef WITH_XSLT_DEBUGGER
+# ifndef WITH_DEBUGGER
+# error "WITH_DEBUGGER MACRO not defined in libxslt maybe you've disable debugger in libxslt." \
+ "if your are sure then disable this check by defining WITH_FORCE_DEBUGGER. eg.\n" \
+ "\nmake CFLAGS=\"$CFLAGS -D FORCE_DEBUGGER\""
+# endif
+# endif
+#endif
+
+#ifdef WITH_XSLDBG_DEBUG
+
+#ifndef WITH_XSLDBG_DEBUG_PROCESS
+#define WITH_XSLDBG_DEBUG_PROCESS
+#endif
+
+#ifndef WITH_XSLDBG_DEBUG_BREAKPOINTS
+#define WITH_XSLDBG_DEBUG_BREAKPOINTS
+#endif
+
+#endif /* end of WITH_XSL_DEBUG */
+
+
+#include <libxslt/xslt.h>
+#include <libexslt/exslt.h>
+#include <libxslt/xsltutils.h>
+
+#include <qstring.h>
+#include <klocale.h>
+
+#include "breakpoint.h"
+
+
+#endif /* BUILD_DOCS */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xsldbgLoadStylesheet:
+ *
+ * Load the stylesheet and return it
+ *
+ * Returns the stylesheet after reloading it if successful
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Load the stylesheet and return it
+ *
+ * @returns The stylesheet after reloading it if successful
+ * NULL otherwise
+ */
+#endif
+#endif
+ xsltStylesheetPtr xsldbgLoadStylesheet(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xsldbgLoadXmlData:
+ *
+ * Load the xml data file and return it
+ *
+ * Returns the data file after reloading it if successful
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Load the xml data file and return it
+ *
+ * @returns The stylesheet after reloading it if successful
+ * NULL otherwise
+ */
+#endif
+#endif
+ xmlDocPtr xsldbgLoadXmlData(void);
+
+
+#ifdef USE_GNOME_DOCS
+
+/**
+ * xsldbgLoadXmlTemporary:
+ * @path: The name of temporary file to load
+ *
+ * Load the temporary data file and return it
+ *
+ * Returns The temporary file after reloading it if successful,
+ * NULL otherwise
+ */
+#else
+#ifdef USE_KDE_DOCS
+
+/**
+ * Load the temporary data file and return it
+ *
+ * @returns The temporary file after reloading it if successful,
+ * NULL otherwise
+ * @param path The name of temporary file to loa
+ */
+#endif
+#endif
+ xmlDocPtr xsldbgLoadXmlTemporary(const xmlChar * path);
+
+
+void xsldbgGenericErrorFunc(void *ctx, const char *msg, ...)
+#ifdef __GNUC__
+ __attribute__ ( ( format ( printf, 2, 3 ) ) )
+#endif
+;
+int xsldbgMain(int argc, char **argv);
+
+#ifdef __cplusplus
+}
+#endif
+
+void xsldbgGenericErrorFunc(QString const &text);
+QString xsldbgUrl(const char *utf8Url);
+QString xsldbgUrl(const xmlChar *utf8Url);
+QString xsldbgText(const char *utf8Text);
+QString xsldbgText(const xmlChar *utf8Text);
+
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/xsldbgconfig.h b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgconfig.h
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgconfig.h
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/xsldbgevent.h b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgevent.h
new file mode 100644
index 00000000..85b1827f
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgevent.h
@@ -0,0 +1,302 @@
+
+/***************************************************************************
+ xsldbgevent.h - event to notify app of
+ data from xsldbg
+ -------------------
+ begin : Fri Feb 1 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. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef XSLDBGEVENT_H
+#define XSLDBGEVENT_H
+
+#if defined WIN32
+#include <libxsldbg/xsldbgwin32config.h>
+#endif
+
+#include <qevent.h>
+#include <qptrlist.h>
+
+#include "xsldbgmsg.h"
+
+/* how many columns do we have */
+#define XSLDBGEVENT_COLUMNS 4
+
+class XsldbgDebuggerBase;
+class XsldbgEventData;
+
+class XsldbgEventDataList : public QGList
+{
+public:
+ XsldbgEventDataList(void) {}
+ XsldbgEventDataList( const XsldbgEventDataList &l ) : QGList(l) {}
+ ~XsldbgEventDataList(void) { clear(); }
+ XsldbgEventDataList &operator=(const XsldbgEventDataList &l)
+ { return (XsldbgEventDataList&)QGList::operator=(l); }
+ bool operator==( const XsldbgEventDataList &list ) const
+ { return QGList::operator==( list ); }
+ uint count(void) const { return QGList::count(); }
+ bool isEmpty(void) const { return QGList::count() == 0; }
+ bool insert( uint i, const XsldbgEventData *d){ return QGList::insertAt(i,(QPtrCollection::Item)d); }
+ void inSort( const XsldbgEventData *d ) { QGList::inSort((QPtrCollection::Item)d); }
+ void prepend( const XsldbgEventData *d ) { QGList::insertAt(0,(QPtrCollection::Item)d); }
+ void append( const XsldbgEventData *d ) { QGList::append((QPtrCollection::Item)d); }
+ bool remove( uint i ) { return QGList::removeAt(i); }
+ bool remove(void) { return QGList::remove((QPtrCollection::Item)0); }
+ bool remove( const XsldbgEventData *d ) { return QGList::remove((QPtrCollection::Item)d); }
+ bool removeRef( const XsldbgEventData *d ) { return QGList::removeRef((QPtrCollection::Item)d); }
+ void removeNode( QLNode *n ) { QGList::removeNode(n); }
+ bool removeFirst(void) { return QGList::removeFirst(); }
+ bool removeLast(void) { return QGList::removeLast(); }
+ XsldbgEventData *take( uint i ) { return (XsldbgEventData *)QGList::takeAt(i); }
+ XsldbgEventData *take(void) { return (XsldbgEventData *)QGList::take(); }
+ XsldbgEventData *takeNode( QLNode *n ) { return (XsldbgEventData *)QGList::takeNode(n); }
+ void clear(void) { QGList::clear(); }
+ void sort(void) { QGList::sort(); }
+ int find( const XsldbgEventData *d ) { return QGList::find((QPtrCollection::Item)d); }
+ int findNext( const XsldbgEventData *d ) { return QGList::find((QPtrCollection::Item)d,FALSE); }
+ int findRef( const XsldbgEventData *d ) { return QGList::findRef((QPtrCollection::Item)d); }
+ int findNextRef( const XsldbgEventData *d ){ return QGList::findRef((QPtrCollection::Item)d,FALSE);}
+ uint contains( const XsldbgEventData *d ) const { return QGList::contains((QPtrCollection::Item)d); }
+ uint containsRef( const XsldbgEventData *d ) const
+ { return QGList::containsRef((QPtrCollection::Item)d); }
+ XsldbgEventData *at( uint i ) { return (XsldbgEventData *)QGList::at(i); }
+ int at(void) const { return QGList::at(); }
+ XsldbgEventData *current(void) const { return (XsldbgEventData *)QGList::get(); }
+ QLNode *currentNode(void) const { return QGList::currentNode(); }
+ XsldbgEventData *getFirst(void) const { return (XsldbgEventData *)QGList::cfirst(); }
+ XsldbgEventData *getLast(void) const { return (XsldbgEventData *)QGList::clast(); }
+ XsldbgEventData *first(void) { return (XsldbgEventData *)QGList::first(); }
+ XsldbgEventData *last(void) { return (XsldbgEventData *)QGList::last(); }
+ XsldbgEventData *next(void) { return (XsldbgEventData *)QGList::next(); }
+ XsldbgEventData *prev(void) { return (XsldbgEventData *)QGList::prev(); }
+ void toVector( QGVector *vec )const{ QGList::toVector(vec); }
+private:
+ void deleteItem( QPtrCollection::Item d );
+};
+
+
+
+
+
+
+/**
+ * This class is used to convert a message from xsldbg into a simple data type
+ *
+ * @short convertor of xsldbg message to a data class
+ *
+ * @author Keith Isdale <k_isdale@tpg.com.au>
+ */
+class XsldbgEventData {
+
+ public:
+ XsldbgEventData(void);
+ ~XsldbgEventData(void);
+
+
+ /**
+ * Set the text for the column specified
+ *
+ * @param column 0 =< @p column < XSLDBGEVENT_COLUMNS
+ * @param text The text value to store in column indicated
+ */
+ void setText(int column, QString text);
+
+
+ /**
+ * Get the text from the column specified
+ *
+ * @returns QString::null if invalid column number
+ *
+ * @param column 0 =< @p column < XSLDBGEVENT_COLUMNS
+ *
+ */
+ QString getText(int column);
+
+
+ /**
+ * Set the integer value for the column specified
+ *
+ * @param column 0 =< @p column < XSLDBGEVENT_COLUMNS
+ * @param value The value to store in column indicated
+ */
+ void setInt(int column, int value);
+
+
+ /**
+ * Get the integer value from the column specified
+ *
+ * @returns -1 if invalid column number
+ *
+ * @param column 0 =< @p column < XSLDBGEVENT_COLUMNS
+ *
+ */
+ int getInt(int column);
+
+ private:
+ /** Below are the messages that this class will support
+ Values are mapped left to right ie the first QString value maps
+ to textValues[0], the second mapps to textValues[1]
+ the third maps to textValues[2] etc.. */
+ QString textValues[XSLDBGEVENT_COLUMNS];
+
+ /**
+ Both int and bool values are mapped to intValues in the same manner as
+ stated above */
+ int intValues[XSLDBGEVENT_COLUMNS];
+
+ /** - - - - - - The message/signal types supported - - - - - - */
+ // /** line number and/or file name changed */
+ // void lineNoChanged(QString /* fileName */, int /* lineNumber */, bool /* breakpoint */);
+ // These data items are mapped to attributes of this class with the same name
+
+
+ // /** Show a message in debugger window */
+ // void showMessage(QString /* msg*/);
+ // These data item is mapped to the text attribute
+
+
+ // /** Add breakpoint to view, First parameter is QString::null
+ // to indicate start of breakpoint list notfication */
+ // void breakpointItem(QString /* fileName*/, int /* lineNumber */, QString /*templateName*/,
+ // bool /* enabled */, int /* id */);
+ // These data items are mapped to attributes of this class with the same name
+
+
+ // /** Add global variable to view, First parameter is QString::null
+ // to indicate start of global variable list notfication */
+ // void globalVariableItem(QString /* name */, QString /* fileName */, int /* lineNumber */);
+ // These data items are mapped to attributes of this class with the same name
+
+
+ // /** Add local variable to view, First parameter is QString::null
+ // to indicate start of local variable list notfication */
+ // void localVariableItem(QString /*name */, QString /* templateContext*/,
+ // QString /* fileName */, int /*lineNumber */);
+ // These data items are mapped to attributes of this class with the same name
+
+
+ // /** Add template to view, First parameter is QString::null
+ // to indicate start of template list notfication */
+ // void templateItem(QString /* name*/, QString /*mode*/, QString /* fileName */, int /* lineNumber */);
+
+ // /** Add source to view, First parameter is QString::null
+ // to indicate start of source list notfication */
+ // void sourceItem(QString /* fileName */, QString /* parentFileName */, int /*lineNumber */);
+
+ // /** Add parameter to view, First parameter is QString::null
+ // to indicate start of parameter list notfication */
+ // void parameterItem(QString /* name*/, QString /* value */);
+
+ // /** Add callStack to view, First parameter is QString::null
+ // to indicate start of callstack list notfication */
+ // void callStackItem(QString /* tempalteName*/, QString /* fileName */, int /* lineNumber */);
+
+ // /** Add entity to view, First parameter is QString::null
+ // to indicate start of entity list notfication */
+ // void entityItem(QString /*SystemID*/, QString /*PublicID*/);
+
+ // /* Show the URI for SystemID or PublicID requested */
+ // void resolveItem(QString /*URI*/);
+
+ // /* Display a integer option value First parameter is QString::null
+ // to indicate start of option list notification */
+ // void intOptionItem(QString /* name*/, int /* value */);
+
+ // /* Display a string option value. First parameter is QString::null
+ // to indicate start of option list notification */
+ // void stringOptionItem(QString /* name*/, QString /* value */);
+
+};
+
+
+/**
+ * This class is posted to the applications event queue. When the application
+ * has time to process the event this class then aids in emitting
+ * the relavant signals for the event.
+ *
+ * @short Emit signals to QT application via debugger base class
+ *
+ * @author Keith Isdale <k_isdale@tpg.com.au>
+ */
+class XsldbgEvent : public QEvent {
+
+ public:
+ XsldbgEvent(XsldbgMessageEnum type, const void *data);
+ ~XsldbgEvent(void);
+
+ /** Main control for emitting messages, use this from the application
+ inside its event processing function */
+ void emitMessage(XsldbgDebuggerBase *debugger);
+
+ /** Emit a single message. It uses handleXXX to do the actual emitting
+ of signal from debugger */
+ void emitMessage(XsldbgEventData *eventData);
+
+ private:
+ /** Create the XsldbgEventData for this message. Is used by our constructor
+ it uses handleXXX function to fill in the approriate values in
+ the XsldbgEventData provided */
+ XsldbgEventData * createEventData(XsldbgMessageEnum type, const void *msgData);
+
+ /** The following functions are directly related to the eventual signals that
+ will be emitted ie the signal
+ lineNoChanged(QString, int bool)
+ is mapped to
+ handleLineNoChanged(XsldbgEventData *, void *)
+ */
+ void handleLineNoChanged(XsldbgEventData *eventData, const void *msgData);
+ void handleShowMessage(XsldbgEventData *eventData, const void *msgData);
+ void handleBreakpointItem(XsldbgEventData *eventData, const void *msgData);
+ void handleGlobalVariableItem(XsldbgEventData *eventData, const void *msgData);
+ void handleLocalVariableItem(XsldbgEventData *eventData, const void *msgData);
+ void handleTemplateItem(XsldbgEventData *eventData, const void *msgData);
+ void handleSourceItem(XsldbgEventData *eventData, const void *msgData);
+ void handleIncludedSourceItem(XsldbgEventData *eventData, const void *msgData);
+ void handleParameterItem(XsldbgEventData *eventData, const void *msgData);
+ void handleCallStackItem(XsldbgEventData *eventData, const void *msgData);
+ void handleEntityItem(XsldbgEventData *eventData, const void *msgData);
+ void handleResolveItem(XsldbgEventData *eventData, const void *msgData);
+ void handleIntOptionItem(XsldbgEventData *eventData, const void *msgData);
+ void handleStringOptionItem(XsldbgEventData *eventData, const void *msgData);
+
+
+ private:
+
+ /** What type is the items in list */
+ XsldbgMessageEnum itemType;
+
+ /** A flag that gets set once the list has been filled with approriate
+ XsldbgEventData */
+ bool beenCreated;
+
+ /** This is a volitile value that is only valid for the duration
+ of the constuctor. It will be set to 0L immediately after */
+ const void *data;
+
+ /** This is a volitile value only valid for duration of emitMessage
+ function. It will be set to 0L imedediately after */
+ XsldbgDebuggerBase *debugger;
+
+ /** This is the data associated with this event
+ each data item in the list will be of the type required
+ by the "type" this event
+ */
+ class XsldbgEventDataList list;
+ };
+
+
+
+
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/xsldbgio.h b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgio.h
new file mode 100644
index 00000000..0e164f0e
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgio.h
@@ -0,0 +1,41 @@
+
+/***************************************************************************
+ xsldbgio.h - declare user input functions
+ -------------------
+ begin : Sun Dec 23 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef XSLDBGIO_H
+#define XSLDBGIO_H
+
+#ifndef BUILD_DOCS
+#include <libxml/tree.h> /* needed for definition of xmlChar */
+#endif
+
+/**
+ * xslShellReadline:
+ * @prompt: the prompt value
+ *
+ * Read a string
+ *
+ * Returns a copy of the text inputed or NULL if EOF in stdin found.
+ * The caller is expected to free the returned string.
+ */
+xmlChar *xslDbgShellReadline(xmlChar * prompt);
+
+
+#define DEBUG_BUFFER_SIZE 500 /*used by xslDbgShell */
+
+
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/xsldbgmsg.cpp b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgmsg.cpp
new file mode 100644
index 00000000..9f95d353
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgmsg.cpp
@@ -0,0 +1,119 @@
+
+/***************************************************************************
+ xsldbg.cpp - send message to console or KXSLDbg
+ -------------------
+ begin : Mon April 26 2004
+ 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 <libxslt/xsltutils.h>
+
+#ifdef HAVE_READLINE
+#include <readline/readline.h>
+#ifdef HAVE_HISTORY
+#include <readline/history.h>
+#endif
+#endif
+
+#include "xsldbgmsg.h"
+#include "xsldbgio.h"
+#include "options.h"
+
+static int (*notifyXsldbgAppFuncPtr) (XsldbgMessageEnum type, const void *data) = 0;
+
+static int (*notifyStateXsldbgAppFuncPtr)(XsldbgMessageEnum type, int commandId,
+ XsldbgCommandStateEnum commandState,
+ const char *text) = 0;
+
+static int (*notifyTextXsldbgAppFuncPtr)(XsldbgMessageEnum type, const char *text) = 0;
+static xmlChar * (*xslDbgShellReadlineFuncPtr)(xmlChar * prompt) = 0;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void xsldbgSetAppFunc(int (*notifyXsldbgAppFunc) (XsldbgMessageEnum type, const void *data))
+{
+ notifyXsldbgAppFuncPtr = notifyXsldbgAppFunc;
+}
+
+void xsldbgSetAppStateFunc(int (*notifyStateXsldbgAppFunc)(XsldbgMessageEnum type, int commandId,
+ XsldbgCommandStateEnum commandState,
+ const char *text))
+{
+ notifyStateXsldbgAppFuncPtr = notifyStateXsldbgAppFunc;
+}
+
+
+void xsldbgSetTextFunc(int (*notifyTextXsldbgAppFunc)(XsldbgMessageEnum type, const char *text))
+{
+ notifyTextXsldbgAppFuncPtr = notifyTextXsldbgAppFunc;
+}
+
+void xsldbgSetReadlineFunc(xmlChar * (*xslDbgShellReadlineFunc)(xmlChar * prompt))
+{
+ xslDbgShellReadlineFuncPtr = xslDbgShellReadlineFunc;
+}
+
+int notifyXsldbgApp(XsldbgMessageEnum type, const void *data)
+{
+ if (!notifyXsldbgAppFuncPtr)
+ return 1;
+ else
+ return (notifyXsldbgAppFuncPtr)(type, data);
+}
+
+int notifyStateXsldbgApp(XsldbgMessageEnum type, int commandId,
+ XsldbgCommandStateEnum commandState, const char *text)
+{
+ if (!notifyStateXsldbgAppFuncPtr)
+ return 1;
+ else
+ return (notifyStateXsldbgApp)(type, commandId, commandState, text);
+}
+
+int notifyTextXsldbgApp(XsldbgMessageEnum type, const char *text)
+{
+ if (!notifyTextXsldbgAppFuncPtr)
+ return 1;
+ else
+ return (notifyTextXsldbgAppFuncPtr)(type, text);
+}
+
+
+/* use this function instead of the one that was in debugXSL.c */
+/**
+ * xslShellReadline:
+ * @prompt: the prompt value
+ *
+ * Read a string
+ *
+ * Returns a copy of the text inputed or NULL if EOF in stdin found.
+ * The caller is expected to free the returned string.
+ */
+xmlChar *
+xslDbgShellReadline(xmlChar * prompt)
+{
+
+ if (!xslDbgShellReadlineFuncPtr)
+ return 0;
+ else
+ return (xslDbgShellReadlineFuncPtr)(prompt);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/xsldbgmsg.h b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgmsg.h
new file mode 100644
index 00000000..12b16a3c
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgmsg.h
@@ -0,0 +1,210 @@
+
+/***************************************************************************
+ xsldbgmsg.h - description
+ -------------------
+ begin : Thu Dec 20 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef XSLDBGMSG_H
+#define XSLDBGMSG_H
+
+#ifdef WIN32
+# include <libxsldbg/xsldbgwin32config.h>
+#else
+# ifndef XSLDBG_SO_API
+# define XSLDBG_SO_API
+# endif
+#endif
+
+#ifndef BUILD_DOCS
+#include <libxml/tree.h> /* needed for the definition of xmlChar */
+#include "arraylist.h"
+#endif
+
+typedef enum {
+ /* thread status */
+ XSLDBG_MSG_THREAD_NOTUSED, /* 0: Thread are not to be used */
+ XSLDBG_MSG_THREAD_INIT, /* 1: The xsldbg thread is initializing */
+ XSLDBG_MSG_THREAD_RUN, /* 2: The xsldbg thread is running */
+ XSLDBG_MSG_THREAD_STOP, /* 3: The xsldbg thread is about to die */
+ XSLDBG_MSG_THREAD_DEAD, /* 4: The xsldbg thread died */
+
+ /* input status ( once thread is running) */
+ XSLDBG_MSG_AWAITING_INPUT, /* 5: Waiting for user input */
+ XSLDBG_MSG_READ_INPUT, /* 6: Read user input */
+ XSLDBG_MSG_PROCESSING_INPUT, /* 7: Processing user's request */
+
+ /* provide more informatiom about state of xsldbg (optional) */
+ XSLDBG_MSG_PROCESSING_RESULT, /* 8: An error occured performing command
+ * requested command */
+ XSLDBG_MSG_LINE_CHANGED, /* 9: Changed to new line number
+ * ie a step */
+ XSLDBG_MSG_FILE_CHANGED, /* 10: Loaded source/data file */
+ XSLDBG_MSG_BREAKPOINT_CHANGED, /* 11: Response to a showbreak command */
+ XSLDBG_MSG_PARAMETER_CHANGED, /* 12: Response to showparam command */
+ XSLDBG_MSG_TEXTOUT, /* 13 : Free form text from xsldg */
+ XSLDBG_MSG_FILEOUT, /* 14 : Response to cat commmand, ie
+ * Free form text in file */
+ XSLDBG_MSG_LOCALVAR_CHANGED, /* 15 : Response to locals command ie a
+ * local variable */
+ XSLDBG_MSG_GLOBALVAR_CHANGED, /* 16 : Response to globals command
+ * ie a global variable */
+ XSLDBG_MSG_TEMPLATE_CHANGED, /* 17 : Response to templates commmand
+ * ie template details */
+ XSLDBG_MSG_SOURCE_CHANGED, /* 18 : Response to stylesheets command,
+ * a normal stylesheet */
+ XSLDBG_MSG_INCLUDED_SOURCE_CHANGED, /* 19: Response to stylesheets
+ * command, a xmlNodeptr of
+ * a included stylesheet */
+ XSLDBG_MSG_CALLSTACK_CHANGED, /* 20: Response to where command,
+ * ie a item on the call stack */
+ XSLDBG_MSG_ENTITIY_CHANGED, /* 21: Response to entities
+ * command */
+ XSLDBG_MSG_RESOLVE_CHANGE, /* 22: Response to system or
+ * public command */
+ XSLDBG_MSG_LIST, /* 23 : As list of messages */
+
+ XSLDBG_MSG_INTOPTION_CHANGE, /* 23* Response to options command */
+ XSLDBG_MSG_STRINGOPTION_CHANGE, /* 24* Response to options command */
+ XSLDBG_MSG_ERROR_MESSAGE /* 25: Entercepted error message from libxml2 */
+} XsldbgMessageEnum;
+
+
+typedef enum {
+ XSLDBG_COMMAND_FAILED, /* generic error */
+ XSLDBG_COMMAND_WARNING,
+ XSLDBG_COMMAND_INFO,
+ XSLDBG_COMMAND_NOTUSED
+} XsldbgCommandStateEnum;
+
+
+
+/**
+ * Notify the application that something happened to the xsldbg thread
+ *
+ * @param type : A valid XsldbgMessageEnum
+ *
+ * @param data : The meaning of data can have a different meaning for each value of @type
+ *<pre>
+ * Value of @type Meaning of @data
+ * -------------------------- +++ ---------------------
+ * XSLDBG_MSG_THREAD_NOTUSED, not used
+ * XSLDBG_MSG_THREAD_INIT, not used
+ * XSLDBG_MSG_THREAD_RUN, not used
+ * XSLDBG_MSG_THREAD_STOP, not used
+ * XSLDBG_MSG_THREAD_DEAD, not used
+ * XSLDBG_MSG_AWAITING_INPUT, not used
+ * XSLDBG_MSG_READ_INPUT, A value of the char* for user input
+ * XSLDBG_MSG_PROCESSING_INPUT, not used
+ * XSLDBG_MSG_PROCESSING_RESULT, A value of type xsldbgErrorMsgPtr
+ * XSLDBG_MSG_LINE_CHANGED Is non-NULL if reached breakpoint
+ * otherwise just change in line number
+ * of displayed source/data
+ * XSLDBG_MSG_FILE_CHANGED, not used
+ * XSLDBG_MSG_BREAKPOINT_CHANGED A breakPointPtr of the breakpoint
+ * XSLDBG_MSG_PARAMETER_CHANGED A parameterItemPtr of libxslt pameter.
+ * XSLDBG_MSG_TEXTOUT A char * to buffer for text output
+ * XSLDBG_MSG_FILEOUT A FILE * for text to output
+ * XSLDBG_MSG_LOCALVAR_CHANGED, A local variable of type xsltStackElemPtr
+ * XSLDBG_MSG_GLOBALVAR_CHANGED, A global variable of type xsltStackElemPtr
+ * XSLDBG_MSG_TEMPLATE_CHANGED, A template of type xsltTemplatePtr
+ * XSLDBG_MSG_SOURCE_CHANGED, A xsltStylesheetPtr of a normal stylesheet
+ * XSLDBG_MSG_INCLUDED_SOURCE_CHANGED A xmlNodePtr of a included stylsheet
+ * XSLDBG_MSG_CALLSTACK_CHANGED A callPointPtr of a call stack item
+ * XSLDBG_MSG_ENTITIY_CHANGED A const entityInfoPtr
+ * for the included entity
+ * XSLDBG_MSG_RESOLVE_CHANGE A xmlChar* of URI that
+ * SystemID or PublicID resolves to
+ * XSLDBG_MSG_LIST A notifyMessageListPtr
+ *
+ * XSLDBG_MSG_INTOPTION_CHANGE A paramItemPtr, value is not used
+ * XSLDBG_MSG_STRINGOPTION_CHANGE A paramItemPtr, intValue is not used
+ * XSLDBG_MSG_ERROR_MESSAGE A xmlErrorPtr
+ *
+ *
+ * Legend :
+ * not used :- value may be NULL but must not be used
+ *
+ * All values are to treated as volitile and are only guaranteed
+ * to be valid for the life of the notification messages. ie make a
+ * NEW copy of value if needed for longer than that.
+ * Unless stated otherwise, if reponse can return a value and the value is
+ * NULL then that indicates the start of a list of values
+ *
+ *<pre>
+ * @returns 1 on sucess
+ * 0 otherwise
+*/
+
+typedef struct _xsldbgErrorMsg xsldbgErrorMsg;
+typedef xsldbgErrorMsg *xsldbgErrorMsgPtr;
+struct _xsldbgErrorMsg {
+ XsldbgMessageEnum type;
+ int commandId;
+ XsldbgCommandStateEnum commandState;
+ xmlChar *text;
+ xmlChar *messagefileName; /* used when send large chunks of data */
+};
+
+
+typedef struct _notifyMessageList notifyMessageList;
+typedef notifyMessageList *notifyMessageListPtr;
+struct _notifyMessageList {
+ XsldbgMessageEnum type;
+ arrayListPtr list;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void xsldbgSetAppFunc(int (*notifyXsldbgAppFunc) (XsldbgMessageEnum type, const void *data));
+
+void xsldbgSetAppStateFunc(int (*notifyStateXsldbgAppFunc)(XsldbgMessageEnum type, int commandId,
+ XsldbgCommandStateEnum commandState,
+ const char *text));
+
+void xsldbgSetTextFunc(int (*notifyTextXsldbgAppFunc)(XsldbgMessageEnum type, const char *text));
+
+void xsldbgSetReadlineFunc(xmlChar * (*xslDbgShellReadlineFunc)(xmlChar * prompt));
+
+int notifyXsldbgApp(XsldbgMessageEnum type, const void *data);
+
+int notifyStateXsldbgApp(XsldbgMessageEnum type, int commandId,
+ XsldbgCommandStateEnum commandState,
+ const char *text);
+
+int notifyTextXsldbgApp(XsldbgMessageEnum type, const char *text);
+
+xmlChar * xslDbgShellReadline(xmlChar * prompt);
+
+
+ /* The following functions implemented in xsldbgthread.c */
+ int notifyListStart(XsldbgMessageEnum type);
+
+ /* Data must be valid for until the next notifyListStart.
+ * Memory pointed to by @data will not be freed. Added @data items
+ * queued to list must be of the same data type as required by the
+ * XsldbgMessageEnum used with the matching notifyListSend */
+ int notifyListQueue(const void *data);
+
+ /* The notified application is responsible for free memory used
+ * by the ArrayList and notifyMessageList of notify message */
+ int notifyListSend(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/xsldbgnotifier.h b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgnotifier.h
new file mode 100644
index 00000000..5c5aaeac
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgnotifier.h
@@ -0,0 +1,48 @@
+
+/***************************************************************************
+ xsldbgnotifier.h - description
+ -------------------
+ begin : Thu Dec 20 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef XSLDBGNOTIFIER_H
+#define XSLDBGNOTIFIER_H
+
+#include "xsldbgmsg.h"
+
+#ifndef __cplusplus
+#error "Must only be used with a c++ compiler"
+#endif
+
+
+
+/**
+ *@author keith
+ */
+
+class XsldbgNotifier {
+ public:
+ XsldbgNotifier(void);
+ virtual ~ XsldbgNotifier(void);
+
+ virtual void doNotify(XsldbgMessageEnum type, const void *data);
+};
+
+
+
+/* get the notifer */
+void setNotifier(XsldbgNotifier * notifier);
+
+
+#endif
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/xsldbgthread.cpp b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgthread.cpp
new file mode 100644
index 00000000..ecb94052
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgthread.cpp
@@ -0,0 +1,184 @@
+
+/***************************************************************************
+ xsldbgthread.c - basic thread support
+ -------------------
+ begin : Thu Dec 20 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 "breakpoint.h"
+#include "options.h"
+
+#include "xsldbgmsg.h"
+#include "xsldbgthread.h"
+
+static void (*cleanupFuncPtr)(void) = 0;
+static int threadStatus = XSLDBG_MSG_THREAD_NOTUSED;
+static int inputStatus = XSLDBG_MSG_AWAITING_INPUT;
+
+/* is xsldbg ready for input from the application */
+static int inputReady = 0;
+
+/* Is the application ready for a notification message */
+static int appReady = 0;
+
+static notifyMessageListPtr notifyList;
+
+arrayListPtr msgList = NULL;
+
+int
+getAppReady(void)
+{
+ return appReady;
+}
+
+void
+setAppReady(int ready)
+{
+ appReady = ready;
+}
+
+
+/* the compiler will optimize this function to inline and to keep variable private*/
+int
+getInputStatus(void)
+{
+ return inputStatus;
+}
+
+void
+setInputStatus(XsldbgMessageEnum type)
+{
+ switch (type) {
+ case XSLDBG_MSG_AWAITING_INPUT: /* Waiting for user input */
+ case XSLDBG_MSG_READ_INPUT: /* Read user input */
+ case XSLDBG_MSG_PROCESSING_INPUT: /* Processing user's request */
+ inputStatus = type;
+ break;
+
+ default:
+ printf("Invalid input status %d\n", type);
+ }
+}
+
+
+/* the compiler will optimize this function to inline and to keep variable private*/
+int
+getThreadStatus(void)
+{
+ return threadStatus;
+}
+
+/* reset the status to @p type */
+void
+setThreadStatus(XsldbgMessageEnum type)
+{
+ switch (type) {
+ case XSLDBG_MSG_THREAD_NOTUSED:
+ case XSLDBG_MSG_THREAD_INIT:
+ case XSLDBG_MSG_THREAD_RUN:
+ threadStatus = type;
+ break;
+
+ case XSLDBG_MSG_THREAD_STOP:
+ case XSLDBG_MSG_THREAD_DEAD:
+ xslDebugStatus = DEBUG_QUIT;
+ threadStatus = type;
+ break;
+
+ default:
+ printf("Invalid thread status %d\n", type);
+ }
+}
+
+
+/* Is input ready yet */
+int
+getInputReady(void)
+{
+ return inputReady;
+}
+
+/* set/clear flag that indicates if input is ready*/
+void
+setInputReady(int value)
+{
+ inputReady = value;
+}
+
+
+
+int
+notifyListStart(XsldbgMessageEnum type)
+{
+ int result = 0;
+
+ switch (type) {
+ case XSLDBG_MSG_INTOPTION_CHANGE:
+ case XSLDBG_MSG_STRINGOPTION_CHANGE:
+ msgList =
+ arrayListNew(10, (freeItemFunc) optionsParamItemFree);
+ break;
+
+ default:
+ msgList = arrayListNew(10, NULL);
+ }
+
+ notifyList =
+ (notifyMessageListPtr) xmlMalloc(sizeof(notifyMessageList));
+ if (notifyList && msgList) {
+ notifyList->type = type;
+ notifyList->list = msgList;
+ result = 1;
+ }
+
+ return result;
+}
+
+int
+notifyListQueue(const void *data)
+{
+ int result = 0;
+
+ if (msgList) {
+ arrayListAdd(msgList, (void *) data);
+ result = 1;
+ }
+ return result;
+}
+
+
+int
+notifyListSend(void)
+{
+ int result = 0;
+
+ if (notifyList && msgList) {
+ notifyXsldbgApp(XSLDBG_MSG_LIST, notifyList);
+ result = 1;
+ }
+ return result;
+}
+
+void xsldbgSetThreadCleanupFunc(void (*cleanupFunc)(void))
+{
+ cleanupFuncPtr = cleanupFunc;
+}
+
+void xsldbgThreadCleanup(void)
+{
+ if (cleanupFuncPtr != 0)
+ (cleanupFuncPtr)();
+}
diff --git a/kxsldbg/kxsldbgpart/libxsldbg/xsldbgthread.h b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgthread.h
new file mode 100644
index 00000000..d83e71f3
--- /dev/null
+++ b/kxsldbg/kxsldbgpart/libxsldbg/xsldbgthread.h
@@ -0,0 +1,90 @@
+
+/***************************************************************************
+ xsldbgthread.h - description
+ -------------------
+ begin : Thu Dec 20 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef XSLDBGTHREAD_H
+#define XSLDBGTHREAD_H
+
+#if defined WIN32
+#include <libxsldbg/xsldbgwin32config.h>
+#endif
+
+
+#ifndef BUILD_DOCS
+#include <libxml/xmlmemory.h>
+#include <libxml/tree.h>
+
+#include "xsldbgmsg.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ int getAppReady(void);
+
+ void setAppReady(int ready);
+
+ int getInputStatus(void);
+
+ void setInputStatus(XsldbgMessageEnum type);
+
+ int getThreadStatus(void);
+
+ void setThreadStatus(XsldbgMessageEnum type);
+
+ void *xsldbgThreadMain(void *data);
+
+ int xsldbgMain(int argc, char **argv);
+
+ int xsldbgThreadInit(void);
+
+ void xsldbgThreadFree(void);
+
+ /* thread has died so cleanup after it */
+ void xsldbgThreadCleanup(void);
+ void xsldbgSetThreadCleanupFunc(void (*cleanupFunc)(void));
+
+ const char *getFakeInput(void);
+
+ int fakeInput(const char *text);
+
+ /* Is input ready yet */
+ int getInputReady(void);
+
+ /* set/clear flag that indicates if input is ready */
+ void setInputReady(int value);
+
+ xmlChar *xslDbgShellReadline(xmlChar * prompt);
+
+
+
+ /* This is implemented by xsldbg.c */
+
+/**
+ * xsldbgFree:
+ *
+ * Free memory used by xsldbg
+ */
+ void xsldbgFree(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif