diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | e9ae80694875f869892f13f4fcaf1170a00dea41 (patch) | |
tree | aa2f8d8a217e2d376224c8d46b7397b68d35de2d /kxsldbg | |
download | tdewebdev-e9ae80694875f869892f13f4fcaf1170a00dea41.tar.gz tdewebdev-e9ae80694875f869892f13f4fcaf1170a00dea41.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdewebdev@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kxsldbg')
170 files changed, 30535 insertions, 0 deletions
diff --git a/kxsldbg/Makefile.am b/kxsldbg/Makefile.am new file mode 100644 index 00000000..e70c4127 --- /dev/null +++ b/kxsldbg/Makefile.am @@ -0,0 +1,66 @@ +bin_PROGRAMS = kxsldbg xsldbg + +kxsldbg_SOURCES = kxsldbg.cpp main.cpp kxsldbgif.skel +noinst_HEADERS = kxsldbg.h +kxsldbg_DEPENDENCIES = ./kxsldbgpart/libqtnotfier/libqtnotfier.la ./kxsldbgpart/libkxsldbgcommon.la ./kxsldbgpart/libxsldbg/libxsldbg.la +kxsldbg_LDADD = ./kxsldbgpart/libqtnotfier/libqtnotfier.la ./kxsldbgpart/libkxsldbgcommon.la ./kxsldbgpart/libxsldbg/libxsldbg.la $(LIB_KDEUI) $(LIBXSLT_LIBS) $(LIBXML_LIBS) $(LIB_KPARTS) + +SUBDIRS = kxsldbgpart + +xdg_apps_DATA = kxsldbg.desktop + +# Disable building xsldbg application as documentation for it is not ready +# +xsldbg_SOURCES = xsldbgmain.cpp + +xsldbg_CFLAGS = $(XSLDBG_CFLAGS) $(all_includes) + +xsldbg_DEPENDENCIES = kxsldbgpart/libxsldbg/libxsldbg.la + +# use of configure defined libraries +xsldbg_LDADD = kxsldbgpart/libxsldbg/libxsldbg.la $(LIBXSLT_LIBS) $(LIBXML_LIBS) $(LIB_KDEUI) +# +# the library search path. +xsldbg_LDFLAGS = $(all_libraries) $(XSLDBG_EXTRA_LIBS) + +# These paths are KDE specific. Use them: +# kde_appsdir Where your application's menu entry (.desktop) should go to. +# kde_icondir Where your icon should go to - better use KDE_ICON. +# kde_sounddir Where your sounds should go to. +# kde_htmldir Where your docs should go to. (contains lang subdirs) +# kde_datadir Where you install application data. (Use a subdir) +# kde_locale Where translation files should go to. (contains lang subdirs) +# kde_cgidir Where cgi-bin executables should go to. +# kde_confdir Where config files should go to (system-wide ones with default values). +# kde_mimedir Where mimetypes .desktop files should go to. +# kde_servicesdir Where services .desktop files should go to. +# kde_servicetypesdir Where servicetypes .desktop files should go to. +# kde_toolbardir Where general toolbar icons should go to (deprecated, use KDE_ICON). +# kde_wallpaperdir Where general wallpapers should go to. +# kde_templatesdir Where templates for the "New" menu (Konqueror/KDesktop) should go to. +# kde_bindir Where executables should go to. Use bin_PROGRAMS or bin_SCRIPTS. +# kde_libdir Where shared libraries should go to. Use lib_LTLIBRARIES. +# kde_moduledir Where modules (e.g. parts) should go to. Use kde_module_LTLIBRARIES. +# kde_styledir Where Qt/KDE widget styles should go to (new in KDE 3). +# kde_designerdir Where Qt Designer plugins should go to (new in KDE 3). + +# set the include path for X, qt and KDE +INCLUDES= $(LIBXML_CFLAGS) $(LIBXSLT_CFLAGS) $(all_includes) + +METASOURCES = AUTO + +# the application source, library search path, and link libraries +kxsldbg_LDFLAGS = $(KDE_RPATH) $(all_libraries) + +# this is where the shell's XML-GUI resource file goes +shellrcdir = $(kde_datadir)/kxsldbg +shellrc_DATA = kxsldbg_shell.rc + +messages: rc.cpp + LIST=`find . -name \*.ui -o -name \*.rc`; \ + $(EXTRACTRC) $$LIST >> rc.cpp ;\ + LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \ + if test -n "$$LIST"; then \ + $(XGETTEXT) $$LIST -o $(podir)/kxsldbg.pot; \ + fi + diff --git a/kxsldbg/configure.in.in b/kxsldbg/configure.in.in new file mode 100644 index 00000000..b4f1ef5e --- /dev/null +++ b/kxsldbg/configure.in.in @@ -0,0 +1,176 @@ +LIBXSLT_REQUIRED_VERSION="1.0.18" +AC_SUBST(LIBXSLT_REQUIRED_VERSION) + +dnl +dnl Math detection +dnl + +AC_CHECK_HEADERS(sys/types.h unistd.h string.h) +AC_CHECK_HEADERS(ieeefp.h nan.h math.h fp_class.h float.h ansidecl.h) +AC_CHECK_HEADERS(time.h sys/stat.h stdarg.h) +AC_CHECK_FUNCS(stat _stat) + +AC_CHECK_FUNC(isnan, , AC_CHECK_LIB(m, isnan, + [M_LIBS="-lm"; AC_DEFINE(HAVE_ISNAN)])) + +AC_CHECK_FUNC(isinf, , AC_CHECK_LIB(m, isinf, + [M_LIBS="-lm"; AC_DEFINE(HAVE_ISINF)])) + +AC_CHECK_FUNC(pow, , AC_CHECK_LIB(m, pow, + [M_LIBS="-lm"; AC_DEFINE(HAVE_POW)])) + +AC_CHECK_FUNC(floor, , AC_CHECK_LIB(m, pow, + [M_LIBS="-lm"; AC_DEFINE(HAVE_FLOOR)])) + +AC_CHECK_FUNC(fabs, , AC_CHECK_LIB(m, pow, + [M_LIBS="-lm"; AC_DEFINE(HAVE_FABS)])) +AC_CHECK_FUNCS(gettimeofday) +AC_CHECK_FUNCS(mktime localtime asctime) + +AH_TEMPLATE(USE_DOCS_MACRO) +AH_TEMPLATE(TIMESTAMP) +AH_TEMPLATE(WITH_DEBUG_HELP) +AH_TEMPLATE(WITH_XSLDBG_DEBUG) +AH_TEMPLATE(XSLDBG_BIN) +AH_TEMPLATE(USE_XSLDBG_AS_THREAD) +AH_TEMPLATE(HAVE_INCLUDE_FIX) + +AH_TEMPLATE(_GNU_SOURCE) +AH_TEMPLATE(HAVE_ISINF) +AH_TEMPLATE(HAVE_ISNAN) +AH_TEMPLATE(HAVE_POW) +AH_TEMPLATE(HAVE_FLOOR) +AH_TEMPLATE(HAVE_FABS) +AH_TEMPLATE(HAVE_QT) +AH_TEMPLATE(HAVE_PTHREAD) +AH_TEMPLATE(HAVE_READLINE) +AH_TEMPLATE(HAVE_HISTORY) + +dnl +dnl how are we to invoke xsldbg, or the other stylesheet processor (xsltproc?) +dnl + +AC_DEFINE(XSLDBG_BIN, "xsldbg") + + +dnl +dnl Do we have we fix for included xml files +dnl + +save_LDFLAGS="$LDFLAGS" +save_CFLAGS="$CFLAGS" +LDFLAGS="$LDFLAGS $LIBXML_LIBS" +CFLAGS="$CFLAGS $LIBXML_CFLAGS" + +AC_CHECK_LIB(xml2, xmlSetEntityReferenceFunc, + [AC_DEFINE(HAVE_INCLUDE_FIX)], + [AC_MSG_RESULT( +!!Warning!! The version of libxml2 installed does not support + debugging of files included as entities. Test 10 will be skipped + as it will fail. You will not be able to set breakpoints on external + entities. Try upgrading your libxml2. + See also --enable-includefix) + RUNTEST10="false" + ]) + +LDFLAGS="$save_LDFLAGS" +CFLAGS="$save_CFLAGS" + +AC_ARG_ENABLE([includefix], + [ --enable-includefix Do you want to force the use of include fix (no)], [do_include_fix=$enableval], [do_include_fix="no"]) + +if test "x$do_include_fix" = "xyes"; then + AC_DEFINE(HAVE_INCLUDE_FIX) + AC_MSG_RESULT(Forcing the use if include fix) +fi + + + +XSLDBG_MAJOR_VERSION=3 +XSLDBG_MINOR_VERSION=1 +XSLDBG_MICRO_VERSION=7 +XSLDBG_VERSION=$XSLDBG_MAJOR_VERSION.$XSLDBG_MINOR_VERSION.$XSLDBG_MICRO_VERSION +XSLDBG_VERSION_INFO=`expr $XSLDBG_MAJOR_VERSION + \ +$XSLDBG_MINOR_VERSION`:$XSLDBG_MICRO_VERSION:$XSLDBG_MINOR_VERSION + +XSLDBG_VERSION_NUMBER=`expr $XSLDBG_MAJOR_VERSION \* 10000 + \ +$XSLDBG_MINOR_VERSION \* 100 + $XSLDBG_MICRO_VERSION` +AC_SUBST(XSLDBG_MAJOR_VERSION) +AC_SUBST(XSLDBG_MINOR_VERSION) +AC_SUBST(XSLDBG_MICRO_VERSION) +AC_SUBST(XSLDBG_VERSION) +AC_SUBST(XSLDBG_VERSION_INFO) +AC_SUBST(XSLDBG_VERSION_NUMBER) + + +dnl +dnl We must run xsldbg as a thread +dnl +AC_CHECK_HEADERS(pthread.h, + AC_DEFINE(HAVE_PTHREAD) + AVE_PTHREAD=1 + SE_XSLDBG_AS_THREAD=1 + AC_DEFINE(USE_XSLDBG_AS_THREAD), + AC_MSG_ERROR(PThread library not found) +) +XSLDBG_INCLUDEDIR="`pwd`/kxsldbg/kxsldbgpart" + +dnl Where is the xsldbg documentation stored +dnl +docs_macro=true +AC_ARG_ENABLE(docs_macro, + [ --enable-docs-macro Use a compiler macro to specify where documentation is (PREFIX/doc/xsldbg/)], + [docs_macro=$enableval], [docs_macro="yes"]) + +if test "x$docs_macro" = "xyes"; then + AC_DEFINE(USE_DOCS_MACRO, 1) + if test "x$prefix" != "x" + then + AC_MSG_RESULT(xsldbg will look for installed documentation in ${prefix}/doc/xsldbg) + else + AC_MSG_RESULT(xsldbg will look for installed documentation in ${ac_default_prefix}doc/xsldbg/) + fi + DOCS_PATH="${prefix}/doc/xsldbg" +AC_SUBST(DOCS_PATH) + +else + AC_MSG_RESULT( + + !!Warning!! Using a environment variable for specifiying location of documentation. + On non risc os systems : XSLDBG_DOCS_DIR + On risc os systems : XSLDebugDocs\$Dir + See --enable-docs-macro in ./configure + ) +fi + + +dnl include extra debugging for xsldbg? +AC_ARG_ENABLE([xsldbg-debugging], + [ --enable-xsldbg-debugging Do you want to enable lots of debugging messages in xsldbg (no)], [do_xsldbg_debugging=$enableval], [do_xsldbg_debugging="no"]) + +if test "x$do_xsldbg_debugging" = "xyes"; then + AC_DEFINE(WITH_XSLDBG_DEBUG) + AC_MSG_RESULT(Enabling lots of debug messages in xsldbg) +fi + + + + +AC_MSG_RESULT(Using xsldbg as a part of kxsldbg) + +dnl +dnl Check for readline and history +dnl +XSLDBG_EXTRA_LIBS="" +dnl AC_CHECK_HEADERS(readline/readline.h, [ +dnl AC_DEFINE(HAVE_READLINE) +dnl XSLDBG_EXTRA_LIBS="-lreadline -lncurses"]) +dnl AC_CHECK_HEADER(readline/history.h, [ +dnl AC_DEFINE(HAVE_HISTORY) +dnl XSLDBG_EXTRA_LIBS="$XSLDBG_EXTRA_LIBS -lhistory"]) + +AC_SUBST(XSLDBG_INCLUDEDIR) +AC_SUBST(XSLDBG_EXTRA_LIBS) +XSLDBG_CFLAGS="-I${XSLDBG_INCLUDEDIR} ${LIBXSLT_CFLAGS} " +AC_SUBST(XSLDBG_CFLAGS) +AC_SUBST(XSLDBG_PREFIX) diff --git a/kxsldbg/data/Makefile.am b/kxsldbg/data/Makefile.am new file mode 100644 index 00000000..d6bd3286 --- /dev/null +++ b/kxsldbg/data/Makefile.am @@ -0,0 +1,16 @@ +SUBDIRS = + + +# Provide a example XSLT scripts : testdoc.xsl and empty.xsl +commondata = test1.xml test2.xml test3.xml test4.xml \ + test_import.xsl test_include_bot.xsl test_include_top.xsl \ + testdoc.dtd testdoc.xml testdoc.xsl \ + empty.xsl empty.xml + + +kxsldbgdir = ${kde_datadir}/kxsldbg +kxsldbg_DATA = ${commondata} + + +xsldbgdir = ${kde_datadir}/xsldbg +xsldbg_DATA = ${commondata} diff --git a/kxsldbg/data/empty.xml b/kxsldbg/data/empty.xml new file mode 100644 index 00000000..aa9ac07e --- /dev/null +++ b/kxsldbg/data/empty.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + File : empty.xml + Author: Keith Isdale <k_isdale@tpg.com.au> + Description: empty xml data for getting started + Copyright Reserved Under GPL +--> +<!-- This file does not require translation --> +<!-- NO TRANSLATION --> +<empty> + Empty example data file +</empty> diff --git a/kxsldbg/data/empty.xsl b/kxsldbg/data/empty.xsl new file mode 100644 index 00000000..ab4548ef --- /dev/null +++ b/kxsldbg/data/empty.xsl @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + File : empty.xsl + Author: Keith Isdale <k_isdale@tpg.com.au> + Description: empty stylesheet for getting started + Copyright Reserved Under GPL +--> +<!-- This file does not require translation --> +<!-- NO TRANSLATION --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" +version="1.0"> + + <xsl:output method="text"/> + + <xsl:template match="/"> + <xsl:apply-templates /> + </xsl:template> +</xsl:stylesheet> + diff --git a/kxsldbg/data/test1.xml b/kxsldbg/data/test1.xml new file mode 100644 index 00000000..06c35dde --- /dev/null +++ b/kxsldbg/data/test1.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + File : test1.xml + Author: Keith Isdale <k_isdale@tpg.com.au> + Description: xml data for stylesheet for testing + Copyright Reserved Under GPL +--> +<!-- This file does not require translation --> +<!-- NO TRANSLATION --> +<html> +<head> +</head> +<body> + <h1>test1</h1> + <p>text1</p> +</body> +</html> diff --git a/kxsldbg/data/test2.xml b/kxsldbg/data/test2.xml new file mode 100644 index 00000000..80bf77a7 --- /dev/null +++ b/kxsldbg/data/test2.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + File : test2.xml + Author: Keith Isdale <k_isdale@tpg.com.au> + Description: xml data for stylesheet for testing + Copyright Reserved Under GPL +--> +<!-- This file does not require translation --> +<!-- NO TRANSLATION --> + +<result> + <head name="foo"/> + <data name="fred"/> + <data name="barney"/> + <data name="pebbles"/> + <extra name="wilma"/> +</result> + + + +<!-- initialization code for xemacs --> +<!-- +Local Variables: +mode: sgml +sgml-minimize-attributes:nil +sgml-general-insert-case:lower +sgml-indent-step:0 +sgml-indent-data:nil +End: +--> diff --git a/kxsldbg/data/test3.xml b/kxsldbg/data/test3.xml new file mode 100644 index 00000000..706321e4 --- /dev/null +++ b/kxsldbg/data/test3.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + File : test3.xml + Author: Keith Isdale <k_isdale@tpg.com.au> + Description: xml data for stylesheet for testing + Copyright Reserved Under GPL +--> +<!-- This file does not require translation --> +<!-- NO TRANSLATION --> + +<result> + <data>2</data> + <data>1</data> + <data>3</data> + <extra/> +</result> + + + +<!-- initialization code for xemacs --> +<!-- +Local Variables: +mode: sgml +sgml-minimize-attributes:nil +sgml-general-insert-case:lower +sgml-indent-step:0 +sgml-indent-data:nil +End: +--> diff --git a/kxsldbg/data/test4.xml b/kxsldbg/data/test4.xml new file mode 100644 index 00000000..437ca18e --- /dev/null +++ b/kxsldbg/data/test4.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + File : test4.xml + Author: Keith Isdale <k_isdale@tpg.com.au> + Description: xml data for stylesheet for testing + Copyright Reserved Under GPL +--> +<!-- This file does not require translation --> +<!-- NO TRANSLATION --> + +<result> + <data/> + <extra/> +</result> + + + +<!-- initialization code for xemacs --> +<!-- +Local Variables: +mode: sgml +sgml-minimize-attributes:nil +sgml-general-insert-case:lower +sgml-indent-step:0 +sgml-indent-data:nil +End: +--> diff --git a/kxsldbg/data/test_import.xsl b/kxsldbg/data/test_import.xsl new file mode 100644 index 00000000..e48539eb --- /dev/null +++ b/kxsldbg/data/test_import.xsl @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + File : test_import.xsl + Author: Keith Isdale <k_isdale@tpg.com.au> + Description: stylesheet for testing + Copyright Reserved Under GPL +--> +<!-- This file does not require translation --> +<!-- NO TRANSLATION --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + + <xsl:template match="head"> + <xsl:apply-templates/> + </xsl:template> + +</xsl:stylesheet> diff --git a/kxsldbg/data/test_include_bot.xsl b/kxsldbg/data/test_include_bot.xsl new file mode 100644 index 00000000..6dd6c9aa --- /dev/null +++ b/kxsldbg/data/test_include_bot.xsl @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + File : test_include.xsl + Author: Keith Isdale <k_isdale@tpg.com.au> + Description: stylesheet for include testing + Copyright Reserved Under GPL +--> +<!-- This file does not require translation --> +<!-- NO TRANSLATION --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + + <xsl:template match="include_bot"> + <xsl:apply-templates/> + </xsl:template> + +</xsl:stylesheet> diff --git a/kxsldbg/data/test_include_top.xsl b/kxsldbg/data/test_include_top.xsl new file mode 100644 index 00000000..df7e4967 --- /dev/null +++ b/kxsldbg/data/test_include_top.xsl @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + File : test_include_top.xsl + Author: Keith Isdale <k_isdale@tpg.com.au> + Description: stylesheet for include testing + Copyright Reserved Under GPL +--> +<!-- This file does not require translation --> +<!-- NO TRANSLATION --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + + <xsl:template name="import_top"> + <xsl:apply-templates select="result/head"/> + </xsl:template> + +</xsl:stylesheet> diff --git a/kxsldbg/data/testdoc.dtd b/kxsldbg/data/testdoc.dtd new file mode 100644 index 00000000..08e9108a --- /dev/null +++ b/kxsldbg/data/testdoc.dtd @@ -0,0 +1,6 @@ +<!ELEMENT simple (#PCDATA)> +<!ENTITY mytext "Some text"> +<!ENTITY anotherDoc SYSTEM "test1.xml" > +<!ENTITY anotherDoc2 SYSTEM "test2.xml" > +<!ENTITY anotherDoc3 SYSTEM "test3.xml" > +<!ENTITY anotherDoc4 SYSTEM "test4.xml" >
\ No newline at end of file diff --git a/kxsldbg/data/testdoc.xml b/kxsldbg/data/testdoc.xml new file mode 100644 index 00000000..894fbbfe --- /dev/null +++ b/kxsldbg/data/testdoc.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + File : testdoc.xml + Author: Keith Isdale <k_isdale@tpg.com.au> + Description: xml data for stylesheet for testing + Copyright Reserved Under GPL +--> +<!-- This file does not require translation --> +<!-- NO TRANSLATION --> + +<!DOCTYPE simple SYSTEM "testdoc.dtd"> + +<simple> + &mytext; + &anotherDoc; + &anotherDoc; + &anotherDoc; + &anotherDoc2; + &anotherDoc3; + &anotherDoc4; +</simple> + + +<!-- initialization code for xemacs --> +<!-- +Local Variables: +mode: sgml +sgml-minimize-attributes:nil +sgml-general-insert-case:lower +sgml-indent-step:0 +sgml-indent-data:nil +End: +--> diff --git a/kxsldbg/data/testdoc.xsl b/kxsldbg/data/testdoc.xsl new file mode 100644 index 00000000..da6447f3 --- /dev/null +++ b/kxsldbg/data/testdoc.xsl @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + File : testdoc.xsl + Author: Keith Isdale <k_isdale@tpg.com.au> + Description: stylesheet for testing + Copyright Reserved Under GPL +--> +<!-- This file does not require translation --> +<!-- NO TRANSLATION --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" +version="1.0"> + + <xsl:import href="test_import.xsl"/> + <xsl:include href="test_include_top.xsl"/> + <xsl:strip-space elements="text()"/> + <xsl:decimal-format name="test" decimal-separator="."/> + <xsl:output method="text"/> + <xsl:variable name="globalvariable" select="'foo'"/> + + <xsl:template match="/"> + <xsl:call-template name="test_set_variable"> + <xsl:with-param name="item" select="'1234'"/> + </xsl:call-template> + + <xsl:variable name="localvariable" select="'bar'"/> + <xsl:text>Global variable contains </xsl:text><xsl:value-of select="$globalvariable"/><xsl:text> +</xsl:text> + <xsl:text>Local variable contains </xsl:text><xsl:value-of select="$localvariable"/><xsl:text> +</xsl:text> + + <!-- test import of xsl file --> + <xsl:call-template name="import_top"/> + + <!-- Basic xsl:apply-templates, xsl:call-template usage --> + <!-- Test basic usage of xsl:apply-templates --> + <xsl:apply-templates select="//result/data"/> + <!-- Test basic usage of xsl:call-template --> + <xsl:call-template name="call-template1"/> + + <!-- Test xsl:apply-templates with parameter value. + Test the ability to step into a xsl:with-param child --> + <xsl:apply-templates select="//result/data"> + <xsl:with-param name="item"> + <item/> + </xsl:with-param> + </xsl:apply-templates> + + <!-- Test xsl:call-template with parameter value + Test the ability to step into a xsl:with-param child --> + <xsl:call-template name="call-template2"> + <xsl:with-param name="item"> + <item /> + </xsl:with-param> + </xsl:call-template> + + <!-- Test ability to step into xsl:param from xsl:apply-templates --> + <xsl:apply-templates select="//result/extra" /> + + <!-- Test ability to step into xsl:param from xsl:call-template --> + <xsl:call-template name="call-template3" /> + + <!-- Test ability to step into xsl:sort from xsl:apply-templates --> + <xsl:apply-templates select="//result/data"> + <xsl:sort select="."/> + <xsl:text> +</xsl:text> + </xsl:apply-templates> + + <xsl:apply-imports/> <!-- useless but test that we can step to it --> + + <xsl:apply-templates select="//result/data" mode="verbose" /> + + </xsl:template> + + + <xsl:template match="result"> + <xsl:param name="item" select="'default'"/> + <!-- ignore node content --> + </xsl:template> + + + <xsl:template match="data"> + <!-- ignore node content --> + </xsl:template> + + <xsl:template match="data" mode="verbose"> + <xsl:apply-templates /> + </xsl:template> + + + <xsl:template match="extra"> + <xsl:param name="item"> + <item/> + </xsl:param> + <!-- ignore node content --> + <xsl:text> +</xsl:text> + </xsl:template> + + + <xsl:template name="call-template1"> + <xsl:number value="position()" format="1."/> + <xsl:text> +</xsl:text> + </xsl:template> + + + <xsl:template name="call-template2"> + <!-- ignore any param provided --> + <!-- test message --> + <xsl:message terminate="no">Message here</xsl:message> + <xsl:processing-instruction name="pitest"> + pi text + </xsl:processing-instruction> + <xsl:text> +</xsl:text> + </xsl:template> + + + <xsl:template name="call-template3"> + <xsl:param name="item"> + <item/> + </xsl:param> + <!-- test comments --> + <xsl:comment>A text comment.</xsl:comment> + <!-- test copy and copy-of --> + <xsl:copy>copy text</xsl:copy> + <xsl:copy-of select="'copy-of Text'"/> + <xsl:text> +</xsl:text> + </xsl:template> + + + <xsl:template name="test_set_variable"> + <xsl:param name="item" select="'default-value'"/> + <xsl:value-of select="$item"/> + <xsl:text> +</xsl:text> + </xsl:template> + +</xsl:stylesheet> diff --git a/kxsldbg/kxsldbg.cpp b/kxsldbg/kxsldbg.cpp new file mode 100644 index 00000000..c28325a3 --- /dev/null +++ b/kxsldbg/kxsldbg.cpp @@ -0,0 +1,173 @@ +/* + * kxsldbg.cpp + * + * Copyright (C) 2001 <kurt@granroth.org> + */ +#include "kxsldbg.h" + +#include <kkeydialog.h> +#include <kconfig.h> +#include <klocale.h> + +#include <kedittoolbar.h> + +#include <kaction.h> +#include <kstdaction.h> + +#include <klibloader.h> +#include <kmessagebox.h> +#include <kstatusbar.h> + +KXsldbg::KXsldbg() + : DCOPObject("KXsldbg"), KParts::MainWindow( 0L, "kxsldbg" ) +{ + // set the shell's ui resource file + setXMLFile("kxsldbg_shell.rc"); + + // then, setup our actions + setupActions(); + + // and a status bar + statusBar()->show(); + statusBar()->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); + + // this routine will find and load our Part. it finds the Part by + // name which is a bad idea usually.. but it's alright in this + // case since our Part is made for this Shell + KLibFactory *factory = KLibLoader::self()->factory("libkxsldbgpart"); + if (factory) + { + // now that the Part is loaded, we cast it to a Part to get + // our hands on it + m_part = static_cast<KParts::ReadOnlyPart *>(factory->create(this, + "kxsldbg_part", "KParts::ReadOnlyPart" )); + + if (m_part) + { + // tell the KParts::MainWindow that this is indeed the main widget + setCentralWidget(m_part->widget()); + + // and integrate the part's GUI with the shell's + createGUI(m_part); + + // connect up signals + kapp->dcopClient()->attach(); + connectDCOPSignal(0, 0, "debuggerPositionChanged(QString,int)", "newDebuggerPosition(QString,int)", false ); + connectDCOPSignal(0, 0, "editorPositionChanged(QString,int,int)", "newCursorPosition(QString,int,int)", false ); + } + + } + else + { + // if we couldn't find our Part, we exit since the Shell by + // itself can't do anything useful + KMessageBox::error(this, i18n("Could not find our part.")); + kapp->quit(); + } +} + +KXsldbg::~KXsldbg() +{ + if (m_part) + m_part->closeURL(); + + delete m_part; +} + +void KXsldbg::quit() +{ + closeURL(); + close(); +} + +bool KXsldbg::closeURL() +{ + if (m_part) + m_part->closeURL(); + + return true; +} + +void KXsldbg::setupActions() +{ + KAction *act = KStdAction::quit(kapp, SLOT(quit()), actionCollection()); + connect(act, SIGNAL(activated()), this, SLOT(quit())); + + m_toolbarAction = KStdAction::showToolbar(this, SLOT(optionsShowToolbar()), actionCollection()); + m_statusbarAction = KStdAction::showStatusbar(this, SLOT(optionsShowStatusbar()), actionCollection()); + + KStdAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection()); + KStdAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection()); +} + +void KXsldbg::saveProperties(KConfig* /*config*/) +{ + // the 'config' object points to the session managed + // config file. anything you write here will be available + // later when this app is restored +} + +void KXsldbg::readProperties(KConfig* /*config*/) +{ + // the 'config' object points to the session managed + // config file. this function is automatically called whenever + // the app is being restored. read in here whatever you wrote + // in 'saveProperties' +} + + +void KXsldbg::optionsShowToolbar() +{ + // this is all very cut and paste code for showing/hiding the + // toolbar + if (m_toolbarAction->isChecked()) + toolBar()->show(); + else + toolBar()->hide(); +} + +void KXsldbg::optionsShowStatusbar() +{ + // this is all very cut and paste code for showing/hiding the + // statusbar + if (m_statusbarAction->isChecked()) + statusBar()->show(); + else + statusBar()->hide(); +} + +void KXsldbg::optionsConfigureKeys() +{ + KKeyDialog::configure(actionCollection(), "kxsldbg_shell.rc"); +} + +void KXsldbg::optionsConfigureToolbars() +{ + saveMainWindowSettings(KGlobal::config(), "MainWindow"); + + // use the standard toolbar editor + KEditToolbar dlg(factory()); + connect(&dlg, SIGNAL(newToolbarConfig()), + this, SLOT(applyNewToolbarConfig())); + dlg.exec(); +} + +void KXsldbg::applyNewToolbarConfig() +{ + applyMainWindowSettings(KGlobal::config(), "MainWindow"); +} + + +void KXsldbg::newCursorPosition(const QString &file, int lineNumber, int columnNumber) +{ + statusBar()->clear(); + statusBar()->message( i18n("File: %1 Line: %2 Col: %3").arg(file).arg(lineNumber).arg(columnNumber)); +} + +void KXsldbg::newDebuggerPosition(const QString &file, int lineNumber) +{ + // maybe do something extra here later + newCursorPosition(file, lineNumber); +} + +#include "kxsldbg.moc" diff --git a/kxsldbg/kxsldbg.desktop b/kxsldbg/kxsldbg.desktop new file mode 100644 index 00000000..8ab7ad9e --- /dev/null +++ b/kxsldbg/kxsldbg.desktop @@ -0,0 +1,53 @@ +[Desktop Entry] +Name=KXSLDbg +Name[sv]=Kxsldbg +Name[ta]=KXSLDபிஜி +GenericName=XSLT Debugger +GenericName[bg]=Дебъгер XSLT +GenericName[br]=Dizraener XSLT +GenericName[ca]=Depurador XSLT +GenericName[cs]=XSLT debugger +GenericName[da]=XSLT-Fejlretter +GenericName[de]=XSLT-Debugger +GenericName[el]=Αποσφαλματωτής XSLT +GenericName[es]=Depurador XSLT +GenericName[et]=XSLT silur +GenericName[eu]=XSLT araztailea +GenericName[fa]=اشکالزدای XSLT +GenericName[fi]=XSLT debuggeri +GenericName[fr]=Débogueur XSLT +GenericName[ga]=Dífhabhtóir XSLT +GenericName[gl]=Depurador XSLT +GenericName[hi]=XSLT डिबगर +GenericName[hu]=XSLT-nyomkövető +GenericName[is]=XSLT aflúsari +GenericName[it]=Debugger per XSLT +GenericName[ja]=XSLT デバッガ +GenericName[lt]=XSLT derintuvė +GenericName[ms]=Penyahralat XSLT +GenericName[nds]=XSLT-Fehlersöker +GenericName[ne]=त्रुटिमोचक एक्सएसएलटी +GenericName[nl]=XSLT-debugger +GenericName[pl]=Debuger XSLT +GenericName[pt]=Depuração de XSLT +GenericName[pt_BR]=Debugger para XSLT +GenericName[ro]=Depanator XSLT +GenericName[ru]=Отладчик XSLT +GenericName[sk]=XSLT debuger +GenericName[sl]=Razhroščevalnik XSLT +GenericName[sr]=Исправљач XSLT-а +GenericName[sr@Latn]=Ispravljač XSLT-a +GenericName[sv]=XSLT-felsökare +GenericName[ta]=XSLT வழுநீக்குபவர் +GenericName[tg]=Ғалатёби XSLT +GenericName[tr]=XSLT Hata Ayıklayıcısı +GenericName[uk]=Зневаджувач XSLT +GenericName[zh_CN]=XSLT 调试器 +GenericName[zh_HK]=XSLT 除錯器 +GenericName[zh_TW]=XSLT 除錯器 +Exec=kxsldbg %i %m -caption "%c" +Icon=kxsldbg +Type=Application +DocPath=kxsldbg/index.html +Terminal=false +Categories=Qt;KDE;Development;WebDevelopment; diff --git a/kxsldbg/kxsldbg.h b/kxsldbg/kxsldbg.h new file mode 100644 index 00000000..7c75629a --- /dev/null +++ b/kxsldbg/kxsldbg.h @@ -0,0 +1,84 @@ +#ifndef KXSLDBG_H +#define KXSLDBG_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kapplication.h> +#include <kparts/mainwindow.h> +#include <dcopobject.h> +#include <dcopclient.h> +#include "kxsldbgif.h" + +class KToggleAction; + +/** + * This is the application "Shell". It has a menubar, toolbar, and + * statusbar but relies on the "Part" to do all the real work. + * + * @short Application Shell + * @author Keith Isdale <k_isdale@tpg.com.au> + * @version 0.4 + */ +class KXsldbg : public KParts::MainWindow, public KXsldbgIf +{ + Q_OBJECT + +public: + /** + * Default Constructor + */ + KXsldbg(); + + /** + * Default Destructor + */ + virtual ~KXsldbg(); + + /** + KxsldbgIf implementation + */ + void newCursorPosition(const QString &file, int lineNumber, int columnNumber=0); + void newDebuggerPosition(const QString & file, int lineNumber); + +protected: + /** + * This method is called when it is time for the app to save its + * properties for session management purposes. + */ + void saveProperties(KConfig *); + + /** + * This method is called when this app is restored. The KConfig + * object points to the session management config file that was saved + * with @ref saveProperties + */ + void readProperties(KConfig *); + + virtual bool closeURL(); + +public slots: + void quit(); + +private slots: + void optionsShowToolbar(); + void optionsShowStatusbar(); + void optionsConfigureKeys(); + void optionsConfigureToolbars(); + + void applyNewToolbarConfig(); + + +private: + void setupAccel(); + void setupActions(); + +private: + KParts::ReadOnlyPart *m_part; + + KToggleAction *m_toolbarAction; + KToggleAction *m_statusbarAction; +}; + +#endif // KXSLDBG_H diff --git a/kxsldbg/kxsldbg_shell.rc b/kxsldbg/kxsldbg_shell.rc new file mode 100644 index 00000000..d3e2fc86 --- /dev/null +++ b/kxsldbg/kxsldbg_shell.rc @@ -0,0 +1,29 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="kxsldbg_shell" version="1"> +<MenuBar> + <Menu noMerge="1" name="file"><text>&File</text> + <Merge/> + <Separator/> + <Action name="file_quit"/> + </Menu> + <Menu name="debug"><text>Debug</text> + </Menu> + <Menu noMerge="1" name="settings"><text>&Settings</text> + <Action name="options_show_toolbar"/> + <Action name="options_show_statusbar"/> + <Merge name="show_merge"/> + <Separator/> + <Action name="options_configure_keybinding"/> + <Action name="options_configure_toolbars"/> + <Action name="options_configure"/> + <Action name="configureEditorCmd"/> + <Merge name="configure_merge"/> + <Separator/> + <Merge/> + </Menu> +</MenuBar> +<ToolBar noMerge="1" name="mainToolBar"><text>Main Toolbar</text> + <Merge/> + <Action name="help"/> +</ToolBar> +</kpartgui> diff --git a/kxsldbg/kxsldbgif.h b/kxsldbg/kxsldbgif.h new file mode 100644 index 00000000..a9942bfc --- /dev/null +++ b/kxsldbg/kxsldbgif.h @@ -0,0 +1,17 @@ +#ifndef KXSLDBGIF_H +#define KXSLDBGIF_H + +#include <dcopobject.h> + +class KXsldbgIf : virtual public DCOPObject +{ + K_DCOP + k_dcop: + + virtual void newCursorPosition(const QString & file, int lineNumber, int columnNumber=0) = 0; + virtual void newDebuggerPosition(const QString & file, int lineNumber) = 0; + +}; + +#endif + diff --git a/kxsldbg/kxsldbgpart/Makefile.am b/kxsldbg/kxsldbgpart/Makefile.am new file mode 100644 index 00000000..ee5e1e9a --- /dev/null +++ b/kxsldbg/kxsldbgpart/Makefile.am @@ -0,0 +1,31 @@ +noinst_LTLIBRARIES = libkxsldbgcommon.la +libkxsldbgcommon_la_SOURCES = xsldbgwalkspeedimpl.cpp xsldbgtemplatesimpl.cpp xsldbgtemplatelistitem.cpp xsldbgsourcesimpl.cpp xsldbgoutputview.cpp xsldbglocalvariablesimpl.cpp xsldbglocallistitem.cpp xsldbglistitem.cpp xsldbginspector.cpp xsldbgglobalvariablesimpl.cpp xsldbggloballistitem.cpp xsldbgentitiesimpl.cpp xsldbgdoc.cpp xsldbgdialogbase.cpp xsldbgdebugger.cpp xsldbgconfigimpl.cpp xsldbgcallstackimpl.cpp xsldbgbreakpointsimpl.cpp xsldbgbreakpointlistitem.cpp qxsldbgdoc.cpp kxsldbg_part.cpp kxsldbg_partif.skel xsldbgwalkspeed.ui xsldbgtemplates.ui xsldbgsources.ui xsldbgmsgdialog.ui xsldbglocalvariables.ui xsldbgglobalvariables.ui xsldbgentities.ui xsldbgconfig.ui xsldbgcallstack.ui xsldbgbreakpoints.ui +libkxsldbgcommon_la_METASOURCES = AUTO +libkxsldbgcommon_la_LDFLAGS = $(all_libraries) +libkxsldbgcommon_la_LIBADD = libxsldbg/libxsldbg.la libqtnotfier/libqtnotfier.la + +noinst_HEADERS = kxsldbg_part.h qxsldbgdoc.h xsldbgbreakpointlistitem.h xsldbgbreakpointsimpl.h xsldbgcallstackimpl.h xsldbgconfigimpl.h xsldbgdebugger.h xsldbgdialogbase.h xsldbgdoc.h xsldbgdocmap.h xsldbgentitiesimpl.h xsldbggloballistitem.h xsldbgglobalvariablesimpl.h xsldbginspector.h xsldbglistitem.h xsldbglocallistitem.h xsldbglocalvariablesimpl.h xsldbgmsgdialogimpl.h xsldbgoutputview.h xsldbgsourcesimpl.h xsldbgtemplatelistitem.h xsldbgtemplatesimpl.h xsldbgwalkspeedimpl.h + +kde_module_LTLIBRARIES = libkxsldbgpart.la + +libkxsldbgpart_la_SOURCES = dummy.cpp + +SUBDIRS = libqtnotfier libxsldbg + +INCLUDES = $(XSLDBG_CFLAGS) -I.. $(all_includes) + + +libkxsldbgpart_la_LDFLAGS = -module $(KDE_PLUGIN) -lkatepartinterfaces $(all_libraries) $(XSLDBG_EXTRA_LIBS) +libkxsldbgpart_la_LIBADD = libkxsldbgcommon.la $(LIB_KPARTS) + + +# this is where the desktop file will go +partdesktopdir = $(kde_servicesdir) +partdesktop_DATA = kxsldbg_part.desktop + +# this is where the part's XML-GUI resource file goes +partrcdir = $(kde_datadir)/kxsldbgpart +partrc_DATA = kxsldbg_part.rc + +KDE_ICON = AUTO + diff --git a/kxsldbg/kxsldbgpart/dummy.cpp b/kxsldbg/kxsldbgpart/dummy.cpp new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/kxsldbg/kxsldbgpart/dummy.cpp diff --git a/kxsldbg/kxsldbgpart/hi16-action-1downarrow.png b/kxsldbg/kxsldbgpart/hi16-action-1downarrow.png Binary files differnew file mode 100644 index 00000000..f545e039 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-1downarrow.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-configure.png b/kxsldbg/kxsldbgpart/hi16-action-configure.png Binary files differnew file mode 100644 index 00000000..95bd319c --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-configure.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-exit.png b/kxsldbg/kxsldbgpart/hi16-action-exit.png Binary files differnew file mode 100644 index 00000000..3ce53009 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-exit.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-hash.png b/kxsldbg/kxsldbgpart/hi16-action-hash.png Binary files differnew file mode 100644 index 00000000..dd8c43ce --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-hash.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-mark.png b/kxsldbg/kxsldbgpart/hi16-action-mark.png Binary files differnew file mode 100644 index 00000000..8ab861a1 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-mark.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-next.png b/kxsldbg/kxsldbgpart/hi16-action-next.png Binary files differnew file mode 100644 index 00000000..a9300537 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-next.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-run.png b/kxsldbg/kxsldbgpart/hi16-action-run.png Binary files differnew file mode 100644 index 00000000..215fc6aa --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-run.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-step.png b/kxsldbg/kxsldbgpart/hi16-action-step.png Binary files differnew file mode 100644 index 00000000..56f1baf6 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-step.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-xsldbg_break.png b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_break.png Binary files differnew file mode 100644 index 00000000..543710fb --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_break.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-xsldbg_data.png b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_data.png Binary files differnew file mode 100644 index 00000000..6f359b41 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_data.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-xsldbg_delete.png b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_delete.png Binary files differnew file mode 100644 index 00000000..6d0d29d7 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_delete.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-xsldbg_enable.png b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_enable.png Binary files differnew file mode 100644 index 00000000..59522882 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_enable.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-xsldbg_output.png b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_output.png Binary files differnew file mode 100644 index 00000000..0d826bbf --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_output.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-xsldbg_refresh.png b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_refresh.png Binary files differnew file mode 100644 index 00000000..5c6a26dd --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_refresh.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-xsldbg_source.png b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_source.png Binary files differnew file mode 100644 index 00000000..4e1c214c --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_source.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-xsldbg_stepdown.png b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_stepdown.png Binary files differnew file mode 100644 index 00000000..4eec6e5a --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_stepdown.png diff --git a/kxsldbg/kxsldbgpart/hi16-action-xsldbg_stepup.png b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_stepup.png Binary files differnew file mode 100644 index 00000000..22220d87 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi16-action-xsldbg_stepup.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-1downarrow.png b/kxsldbg/kxsldbgpart/hi22-action-1downarrow.png Binary files differnew file mode 100644 index 00000000..6dce81ca --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-1downarrow.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-configure.png b/kxsldbg/kxsldbgpart/hi22-action-configure.png Binary files differnew file mode 100644 index 00000000..96ba4338 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-configure.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-exit.png b/kxsldbg/kxsldbgpart/hi22-action-exit.png Binary files differnew file mode 100644 index 00000000..119e5ef7 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-exit.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-next.png b/kxsldbg/kxsldbgpart/hi22-action-next.png Binary files differnew file mode 100644 index 00000000..cfab7cfb --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-next.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-run.png b/kxsldbg/kxsldbgpart/hi22-action-run.png Binary files differnew file mode 100644 index 00000000..b5c89495 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-run.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-step.png b/kxsldbg/kxsldbgpart/hi22-action-step.png Binary files differnew file mode 100644 index 00000000..a0e64fc0 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-step.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-xsldbg_break.png b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_break.png Binary files differnew file mode 100644 index 00000000..31c064ba --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_break.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-xsldbg_data.png b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_data.png Binary files differnew file mode 100644 index 00000000..bcd6c2f5 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_data.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-xsldbg_delete.png b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_delete.png Binary files differnew file mode 100644 index 00000000..6fb193f0 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_delete.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-xsldbg_enable.png b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_enable.png Binary files differnew file mode 100644 index 00000000..aa6ed24c --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_enable.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-xsldbg_output.png b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_output.png Binary files differnew file mode 100644 index 00000000..bb4a9447 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_output.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-xsldbg_refresh.png b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_refresh.png Binary files differnew file mode 100644 index 00000000..3fa8db76 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_refresh.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-xsldbg_source.png b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_source.png Binary files differnew file mode 100644 index 00000000..1f9c87bb --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_source.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-xsldbg_stepdown.png b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_stepdown.png Binary files differnew file mode 100644 index 00000000..384f0c32 --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_stepdown.png diff --git a/kxsldbg/kxsldbgpart/hi22-action-xsldbg_stepup.png b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_stepup.png Binary files differnew file mode 100644 index 00000000..fffef2ec --- /dev/null +++ b/kxsldbg/kxsldbgpart/hi22-action-xsldbg_stepup.png diff --git a/kxsldbg/kxsldbgpart/kxsldbg_part.cpp b/kxsldbg/kxsldbgpart/kxsldbg_part.cpp new file mode 100644 index 00000000..5c4742ab --- /dev/null +++ b/kxsldbg/kxsldbgpart/kxsldbg_part.cpp @@ -0,0 +1,875 @@ +#include "kxsldbg_part.h" +#include "libxsldbg/files.h" +#include "libxsldbg/xsldbg.h" + +#include <kinstance.h> +#include <kaction.h> +#include <kstdaction.h> +#include <kfiledialog.h> +#include <kparts/genericfactory.h> +#include <ktexteditor/markinterface.h> +#include <ktexteditor/editinterface.h> +#include <ktexteditor/viewcursorinterface.h> +#include <ktexteditor/configinterface.h> +#include <kate/view.h> + +#include <qfile.h> +#include <qtextstream.h> + +#include "../kxsldbg.h" +#include <kaction.h> +#include <kcmdlineargs.h> +#include <kinstance.h> +#include <kiconloader.h> +#include <qmessagebox.h> +#include <klocale.h> +#include <kdeversion.h> +#if KDE_IS_VERSION(3,1,90) +#include <kinputdialog.h> +#else +#include <klineeditdlg.h> +#endif + +// Qxsldbg specific includes +#include "qxsldbgdoc.h" +#include <qvariant.h> +#include <qfile.h> +#include <qstatusbar.h> +#include <qsplitter.h> +#include <qvbox.h> + + +#include <qmime.h> +#include <qdragobject.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qaction.h> +#include <qmenubar.h> +#include <qpopupmenu.h> +#include <qtoolbar.h> +#include <qimage.h> +#include <qpixmap.h> +#include <qtextstream.h> +#include <qtextbrowser.h> +#include <qmessagebox.h> +#include <qlineedit.h> +#include <qdockwindow.h> +#include <qpushbutton.h> +#include <qinputdialog.h> +#include <qobjectlist.h> +#include <qwidgetstack.h> +#include "xsldbgoutputview.h" +#include "xsldbgconfigimpl.h" +#include <kdebug.h> +#include "xsldbgdebugger.h" + +typedef KParts::GenericFactory<KXsldbgPart> KXsldbgPartFactory; +K_EXPORT_COMPONENT_FACTORY( libkxsldbgpart, KXsldbgPartFactory ) + +KXsldbgPart::KXsldbgPart( QWidget *parentWidget, const char * /*widgetName*/, + QObject *parent, const char *name, + const QStringList & /*args*/ ) + : DCOPObject("KXsldbgPart"), KParts::ReadOnlyPart(parent, name) +{ + currentLineNo = 0; + currentColumnNo = 0; + inspector = 0L; + debugger = 0L; + configWidget = 0L; + currentDoc = 0L; + + // we need an instance + setInstance( KXsldbgPartFactory::instance() ); + QVBox *frame = new QVBox(parentWidget); + QHBox *h = new QHBox(frame); + newXPath = new QLineEdit(h); + xPathBtn = new QPushButton(i18n("Goto XPath"), h); +/* Disable searching as searching documentation is not ready + h = new QHBox(frame); + newSearch = new QLineEdit(h); + searchBtn = new QPushButton(i18n("Search"), h); +*/ + h = new QHBox(frame); + newEvaluate = new QLineEdit(h); + evaluateBtn = new QPushButton(i18n("Evaluate"), h); + + QSplitter *splitter = new QSplitter(QSplitter::Vertical, frame); + mainView = new QWidgetStack(splitter); + mainView->setMinimumHeight(400); //## TODO don't use a magic number + outputview = new XsldbgOutputView(splitter); + setWidget(frame); + docDictionary.setAutoDelete(true); + + // create our actions + KStdAction::open(this, SLOT(fileOpen()), actionCollection()); + + // set our XML-UI resource file + setXMLFile("kxsldbg_part.rc"); + (void) new KAction( i18n("Configure Editor..."), + "configure", 0, + this, SLOT(configureEditorCmd_activated()), + actionCollection(), "configureEditorCmd" ); + (void) new KAction( i18n("Configure..."), + "configure", Key_C, + this, SLOT(configureCmd_activated()), + actionCollection(), "configureCmd" ); + + (void) new KAction( i18n("Inspect..."), + "find", Key_I, + this, SLOT(inspectorCmd_activated()), + actionCollection(), "inspectCmd" ); + + + // Motions commands + (void) new KAction( i18n("Run"), + "run", Key_F5, + this, SLOT(runCmd_activated()), + actionCollection(), "runCmd" ); + + (void) new KAction( i18n("Continue"), + "1downarrow", Key_F4, + this, SLOT(continueCmd_activated()), + actionCollection(), "continueCmd" ); + + (void) new KAction( i18n("Step"), + "step", Key_F8, + this, SLOT(stepCmd_activated()), + actionCollection(), "stepCmd" ); + + (void) new KAction( i18n("Next"), + "next", Key_F10, + this, SLOT(nextCmd_activated()), + actionCollection(), "nextCmd" ); + + (void) new KAction( i18n("Step Up"), + "xsldbg_stepup", Key_F6, + this, SLOT(stepupCmd_activated()), + actionCollection(), "stepupCmd" ); + + (void) new KAction( i18n("Step Down"), + "xsldbg_stepdown", Key_F7, + this, SLOT(stepCmd_activated()), + actionCollection(), "stepdownCmd" ); + + // Breakpoint commands + (void) new KAction( i18n("Break"), + "xsldbg_break", Key_F2, + this, SLOT(breakCmd_activated()), + actionCollection(), "breakCmd" ); + + (void) new KAction( i18n("Enable/Disable"), + "xsldbg_enable", Key_F3, + this, SLOT(enableCmd_activated()), + actionCollection(), "enableCmd" ); + + (void) new KAction( i18n("Delete"), + "xsldbg_delete", Key_Delete, + this, SLOT(deleteCmd_activated()), + actionCollection(), "deleteCmd" ); + + (void) new KAction( i18n("&Source"), + "xsldbg_source", Key_S, + this, SLOT(sourceCmd_activated()), + actionCollection(), "sourceCmd" ); + + (void) new KAction( i18n("&Data"), + "xsldbg_data", Key_D, + this, SLOT(dataCmd_activated()), + actionCollection(), "dataCmd" ); + + (void) new KAction( i18n("&Output"), + "xsldbg_output", Key_O, + this, SLOT(outputCmd_activated()), + actionCollection(), "outputCmd" ); + + (void) new KAction( i18n("Reload Current File From Disk"), + "xsldbg_refresh", CTRL + Key_F5, + this, SLOT(refreshCmd_activated()), + actionCollection(), "refreshCmd" ); + + /* tracing and walking */ + (void) new KAction( i18n("Walk Through Stylesheet..."), + Key_W, + this, SLOT(walkCmd_activated()), + actionCollection(), "walkCmd" ); + (void) new KAction( i18n("Stop Wal&king Through Stylesheet"), + Key_K, + this, SLOT(walkStopCmd_activated()), + actionCollection(), "walkStopCmd" ); + (void) new KAction( i18n("Tr&ace Execution of Stylesheet"), + Key_A, + this, SLOT(traceCmd_activated()), + actionCollection(), "traceCmd" ); + (void) new KAction( i18n("Stop Tracing of Stylesheet"), + Key_K, + this, SLOT(traceStopCmd_activated()), + actionCollection(), "traceStopCmd" ); + + (void) new KAction( i18n("&Evaluate Expression..."), + Key_E, + this, SLOT(evaluateCmd_activated()), + actionCollection(), "evaluateCmd" ); + + (void) new KAction( i18n("Goto &XPath..."), + Key_X, + this, SLOT(gotoXPathCmd_activated()), + actionCollection(), "gotoXPathCmd" ); + + (void) new KAction( i18n("Lookup SystemID..."), + 0, + this, SLOT(slotLookupSystemID()), + actionCollection(), "lookupSystemID" ); + + (void) new KAction( i18n("Lookup PublicID..."), + 0, + this, SLOT(slotLookupPublicID()), + actionCollection(), "lookupPublicID" ); + + (void) new KAction( i18n("Quit"), + 0, CTRL + Key_Q, + this, SLOT(quit()), + actionCollection(), "file_quit" ); + + /* + (void) new KAction( i18n("Exit KXsldbg"), + "xsldbg_output", CTRL + Key_Q, + this, SLOT(exitCmd_activated()), + actionCollection(), "exitCmd" ); + */ + connect( xPathBtn, SIGNAL( clicked() ), + this, SLOT( slotGotoXPath() ) ); + connect( evaluateBtn, SIGNAL( clicked() ), + this, SLOT( slotEvaluate() ) ); +/* + + connect( searchBtn, SIGNAL( clicked() ), + this, SLOT( slotSearch() ) ); +*/ +/* We must have a valid debugger and inspector */ + createInspector(); + if (checkDebugger()){ + configWidget = new XsldbgConfigImpl( debugger, 0L ); + Q_CHECK_PTR( configWidget ); + debugger->start(); + }else{ + openURL(""); + } +} + +KXsldbgPart::~KXsldbgPart() +{ + docDictionary.clear(); +} + +void KXsldbgPart::quit() +{ + qWarning("Custom void KXsldbgPart::quit()"); + closeURL(); +} + + +KAboutData *KXsldbgPart::createAboutData() +{ + // the non-i18n name here must be the same as the directory in + // which the part's rc file is installed ('partrcdir' in the + // Makefile) + KAboutData *aboutData = new KAboutData("kxsldbgpart", I18N_NOOP("KXsldbgPart"), "0.1"); + aboutData->addAuthor("Keith Isdale", 0L, "k_isdale@tpg.com.au"); + return aboutData; +} + + +bool KXsldbgPart::openURL(const KURL &url) +{ + bool result = fetchURL(url); + if (result){ + QXsldbgDoc *docPtr = docDictionary[url.prettyURL()]; + if (docPtr && docPtr->kateView()){ + if (docPtr != currentDoc){ + currentDoc = docPtr; + currentFileName = url.prettyURL(); + mainView->raiseWidget(currentDoc->kateView()); + emit setWindowCaption(currentDoc->url().prettyURL()); + } + } else{ + result = false; + } + } + + return result; +} + + +/* Don't show the content of URL just loaded it into our data structures */ +bool KXsldbgPart::fetchURL(const KURL &url) +{ + QString docID = url.prettyURL(); + QXsldbgDoc *docPtr = docDictionary[docID]; + if (!docPtr){ + docPtr = new QXsldbgDoc(mainView, url); + docDictionary.insert(docID, docPtr); + if (docPtr->kateView()){ + mainView->addWidget(docPtr->kateView()); + Kate::View *v = Kate::view((docPtr->kateView())); + connect(v, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChanged())); + } + } + + return true; +} + +bool KXsldbgPart::openFile() +{ + qWarning("bool KXsldbgPart::openFile() called"); + return false; +} + +bool KXsldbgPart::closeURL() +{ + docDictionary.clear(); + return true; +} + +void KXsldbgPart::fileOpen() +{ + // this slot is called whenever the File->Open menu is selected, + // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar + // button is clicked + QString file_name = KFileDialog::getOpenFileName(); + + if (file_name.isEmpty() == false) + openURL(KURL( file_name )); +} + +void KXsldbgPart::configureEditorCmd_activated() +{ + if (currentDoc){ + KTextEditor::ConfigInterface *configIf = KTextEditor::configInterface(currentDoc->kateDoc()); + if (configIf) + configIf->configDialog(); + } +} + +bool KXsldbgPart::checkDebugger() +{ + bool result = debugger != 0L; + if (!result){ + QMessageBox::information(0L, i18n("Debugger Not Ready"), + i18n("Configure and start the debugger first."), + QMessageBox::Ok); + } + + return result; +} + + +void KXsldbgPart::lookupSystemID( QString systemID) +{ + bool ok = false; + if (!checkDebugger()) + return; + + if (systemID.isEmpty()){ +#if KDE_IS_VERSION(3, 1, 90) + systemID = KInputDialog::getText( + i18n( "Lookup SystemID" ), + i18n( "Please enter SystemID to find:" ), + QString::null, &ok, + mainView); +#else + systemID = QInputDialog::getText( + i18n( "Lookup SystemID" ), + i18n( "Please enter SystemID to find:" ), + QLineEdit::Normal, QString::null, &ok, + mainView); +#endif + }else{ + ok = true; + } + if ( ok && !systemID.isEmpty() ){ + // user entered something and pressed ok + QString msg(QString("system %1").arg(systemID)); // noTr + debugger->fakeInput(msg, true); + } + +} + + +void KXsldbgPart::lookupPublicID(QString publicID) +{ + bool ok = false; + if (!checkDebugger()) + return; + + if (publicID.isEmpty()){ +#if KDE_IS_VERSION(3, 1, 90) + publicID = KInputDialog::getText( + i18n( "Lookup PublicID" ), + i18n( "Please enter PublicID to find:" ), + QString::null, &ok, mainView ); +#else + publicID = QInputDialog::getText( + i18n( "Lookup PublicID" ), + i18n( "Please enter PublicID to find:" ), + QLineEdit::Normal, QString::null, &ok, mainView ); +#endif + }else{ + ok = true; + } + if ( ok && !publicID.isEmpty()){ + // user entered something and pressed ok + QString msg(QString("public %1").arg(publicID)); // noTr + debugger->fakeInput(msg, true); + } +} + + +void KXsldbgPart::slotLookupSystemID() +{ + lookupSystemID(""); +} + +void KXsldbgPart::slotLookupPublicID() +{ + lookupPublicID(""); +} + +void KXsldbgPart::configureCmd_activated() +{ + if (!checkDebugger()) + return; + + if (configWidget != 0L){ + configWidget->refresh(); + configWidget->show(); + } +} + +void +KXsldbgPart::runCmd_activated() +{ + if ( checkDebugger() ) + debugger->slotRunCmd(); +} + +void KXsldbgPart::inspectorCmd_activated() +{ + if (inspector == 0L) + createInspector(); + + if (checkDebugger() && (inspector != 0L)){ + inspector->show(); + } +} + + +void KXsldbgPart::createInspector() +{ + if ( inspector == 0L ) { + debugger = new XsldbgDebugger(); + Q_CHECK_PTR( debugger ); + if ( debugger != 0L ) { + connect(debugger, SIGNAL( debuggerReady()), + this, SLOT(debuggerStarted())); + if (outputview){ + connect(debugger, + SIGNAL( showMessage(QString /* msg*/)), + outputview, + SLOT(slotProcShowMessage(QString /* msg*/))); + } + inspector = new XsldbgInspector( debugger ); + Q_CHECK_PTR( inspector ); + debugger->setInspector( inspector ); + if (inspector != 0L){ + /*process line number and/or file name changed */ + connect(debugger, + SIGNAL(lineNoChanged + (QString /* fileName */ , + int /* lineNumber */ , + bool /* breakpoint */ ) ), + this, + SLOT(lineNoChanged + ( QString /* fileName */ , + int /* lineNumber */ , + bool /* breakpoint */ ) ) ); + connect(debugger, + SIGNAL(breakpointItem(QString /* fileName*/, + int /* lineNumber */, + QString /*templateName*/, + QString /* modeName */, + bool /* enabled */, + int /* id */)), + this, + SLOT( breakpointItem(QString /* fileName*/, + int /* lineNumber */, + QString /*templateName*/, + QString /* modeName */, + bool /* enabled */, + int /* id */))); + connect(debugger, SIGNAL(resolveItem(QString /*URI*/)), + this, SLOT(slotProcResolveItem(QString /*URI*/))); + } + } + } +} + +void KXsldbgPart::emitOpenFile(QString file, int line, int row) +{ + QByteArray params; + QDataStream stream(params, IO_WriteOnly); + stream << file << line << row; + emitDCOPSignal("openFile(QString,int,int)", params); +} +void KXsldbgPart::continueCmd_activated() +{ + if ( checkDebugger() ) + debugger->slotContinueCmd(); + +} + +void KXsldbgPart::stepCmd_activated() +{ + if ( checkDebugger() ) + debugger->slotStepCmd(); +} + +void KXsldbgPart::nextCmd_activated() +{ + if ( checkDebugger() ) + debugger->fakeInput("next", true); // noTr +} + + +void KXsldbgPart::stepupCmd_activated() +{ + if ( checkDebugger() ) + debugger->fakeInput("stepup", true); // noTr +} + + +void KXsldbgPart::stepdownCmd_activated() +{ + if ( checkDebugger() ) + debugger->fakeInput("stepdown", true); // noTr +} + + +void KXsldbgPart::dataCmd_activated() +{ + if ( checkDebugger() ) + debugger->slotDataCmd(); +} + +void +KXsldbgPart::sourceCmd_activated() +{ + if ( checkDebugger() ) + debugger->slotSourceCmd(); +} + +void +KXsldbgPart::outputCmd_activated() +{ + if ( ( inspector != 0L ) && checkDebugger() && ( configWidget != 0L ) ){ + debugger->setOutputFileActive(true); + lineNoChanged( configWidget->getOutputFile(), 1, false ); + refreshCmd_activated(); + } +} + +void KXsldbgPart::refreshCmd_activated() +{ + + if ( !currentFileName.isEmpty() ){ + QDictIterator<QXsldbgDoc> it(docDictionary); + QXsldbgDoc *docPtr; + while (it.current()){ + docPtr = it.current(); + docPtr->refresh(); + ++it; + } + if ( checkDebugger() ){ + debugger->fakeInput("showbreak", true); // noTr + } + } +} + +void KXsldbgPart::enableCmd_activated() +{ + if ( checkDebugger() ){ + debugger->slotEnableCmd( currentFileName, currentLineNo); + } +} + +void KXsldbgPart::deleteCmd_activated() +{ + if ( checkDebugger() ){ + debugger->slotDeleteCmd( currentFileName, currentLineNo); + } +} + +void KXsldbgPart::breakCmd_activated() +{ + if ( checkDebugger() ){ + debugger->slotBreakCmd( currentFileName, currentLineNo); + } +} + +void KXsldbgPart::evaluateCmd_activated() +{ +#if KDE_IS_VERSION(3,1,90) + QString expression = KInputDialog::getText(i18n("Evalute Expression"), i18n("XPath:")); +#else + QString expression = KLineEditDlg::getText(i18n("Evalute Expression"), i18n("XPath:")); +#endif + if (checkDebugger() && (expression.length() > 0)){ + debugger->slotCatCmd( expression); + } +} + +void KXsldbgPart::gotoXPathCmd_activated() +{ +#if KDE_IS_VERSION(3,1,90) + QString xpath = KInputDialog::getText(i18n("Goto XPath"), i18n("XPath:")); +#else + QString xpath = KLineEditDlg::getText(i18n("Goto XPath"), i18n("XPath:")); +#endif + if (checkDebugger() && xpath.length() > 0){ + debugger->slotCdCmd( xpath ); + } +} + +void +KXsldbgPart::lineNoChanged(QString fileName, int lineNumber, bool breakpoint) +{ + if ( fileName.isEmpty() ) { + kdDebug() << "Empty file Name" << endl; // noTr + return; + } + + openURL(fileName); + + QXsldbgDoc *docPtr; + QDictIterator<QXsldbgDoc> it(docDictionary); + while (it.current()){ + docPtr = it.current(); + // cause all Execution and BreakpointReached marks to be cleared + docPtr->clearMarks(false); + ++it; + } + /* Did we stop at a breakpoint if so move the marker */ + if (currentDoc) { + currentDoc->selectBreakPoint(lineNumber -1, breakpoint); + QByteArray params; + QDataStream stream(params, IO_WriteOnly); + stream << currentFileName << lineNumber; + emitDCOPSignal("debuggerPositionChanged(QString,int)", params); + }else { + qWarning("Unable to retrieve document from internal cache"); + } + + + /* Move cursor and update status bar */ + if (currentDoc && currentDoc->kateView()){ + KTextEditor::ViewCursorInterface *cursorIf = KTextEditor::viewCursorInterface(currentDoc->kateView()); + if (cursorIf){ + cursorIf->setCursorPositionReal(lineNumber - 1, 0); + currentLineNo = lineNumber; + } + } +} + +void KXsldbgPart::cursorPositionChanged() +{ + if (currentDoc && currentDoc->kateView()){ + KTextEditor::ViewCursorInterface *viewCurIf = KTextEditor::viewCursorInterface(currentDoc->kateView()); + if (viewCurIf){ + viewCurIf->cursorPosition(¤tLineNo, ¤tColumnNo); + currentLineNo++; + currentColumnNo++; + QByteArray params; + QDataStream stream(params, IO_WriteOnly); + stream << currentFileName << currentLineNo << currentColumnNo; + emitDCOPSignal("editorPositionChanged(QString,int,int)", params); + } + } +} + +void KXsldbgPart::docChanged() +{ + if (!currentDoc || currentDoc->kateDoc() || currentDoc->kateView()) + return; +} + +void KXsldbgPart::debuggerStarted() +{ + if (configWidget != 0L){ + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if (args){ + int i=0, result=1, noFilesFound = 0; + QString expandedName; /* contains file name with path expansion if any */ + + for (i = 0; i < args->count(); i++) { + if (!result) + break; + + if (args->arg(i)[0] != '-') { + expandedName = QString::fromUtf8((const char*)filesExpandName((const xmlChar*)args->arg(i))); + if (expandedName.isEmpty()) { + result = 0; + break; + } + switch (noFilesFound) { + case 0: + configWidget->slotSourceFile(expandedName); + noFilesFound++; + break; + case 1: + configWidget->slotDataFile(expandedName); + noFilesFound++; + break; + case 2: + configWidget->slotOutputFile(expandedName); + noFilesFound++; + break; + + default: + xsldbgGenericErrorFunc(i18n("Error: Too many file names supplied via command line.\n")); + result = 0; + } + continue; + } + } + configWidget->refresh(); + configWidget->show(); + } + } +} + +void KXsldbgPart::addBreakPoint(int lineNumber) +{ + if ( checkDebugger() ){ + debugger->slotBreakCmd( currentFileName, lineNumber); + } +} + +void KXsldbgPart::enableBreakPoint(int lineNumber) +{ + if ( checkDebugger() ){ + debugger->slotEnableCmd( currentFileName, lineNumber); + } +} + + +void KXsldbgPart::deleteBreakPoint(int lineNumber) +{ + if ( checkDebugger() ){ + debugger->slotDeleteCmd( currentFileName, lineNumber); + } +} + + + +void KXsldbgPart::slotSearch() +{ + if ((newSearch != 0L) && checkDebugger() ) { + QString msg(QString("search \"%1\"").arg(newSearch->text())); // noTr + debugger->fakeInput(msg, false); + } +} + + +void KXsldbgPart::slotEvaluate() +{ + if ((newEvaluate != 0L) && checkDebugger() ){ + debugger->slotCatCmd( newEvaluate->text() ); + } +} + +void KXsldbgPart::slotGotoXPath() +{ + if ((newXPath != 0L) && checkDebugger() ){ + debugger->slotCdCmd( newXPath->text() ); + } +} + + + +void KXsldbgPart::slotProcResolveItem(QString URI) +{ + if (!URI.isEmpty()){ + QMessageBox::information(mainView, i18n("SystemID or PublicID Resolution Result"), + i18n("SystemID or PublicID has been resolved to\n.%1").arg(URI), + QMessageBox::Ok); + } +} + +void KXsldbgPart::breakpointItem(QString fileName, int lineNumber , + QString /*templateName*/, QString /* modeName */, + bool enabled , int /* id */) +{ + + if (fileName == 0L){ + /* Go through all documents and remove all breakpoints */ + QDictIterator<QXsldbgDoc> it(docDictionary); + QXsldbgDoc *docPtr; + while (it.current()){ + docPtr = it.current(); + docPtr->clearMarks(true); + ++it; + } + }else{ +/* + if (!fileName.contains("://")){ + // relative path ? must handle this special case + KURL url; + url.setFileName(fileName); + fetchURL(url); + }else{ + fetchURL(fileName); + } +*/ + fileName = XsldbgDebugger::fixLocalPaths(fileName); + KURL temp(fileName); + fileName = temp.prettyURL(); + fetchURL(fileName); + QXsldbgDoc *docPtr = docDictionary[fileName] ; + if (docPtr){ + docPtr->addBreakPoint(lineNumber - 1, enabled); + }else { + qWarning("Unable to get doc %s from docDictionary", fileName.local8Bit().data()); + } + } +} + + + +void KXsldbgPart::walkCmd_activated() +{ + if (checkDebugger()){ + debugger->slotWalkCmd(); + } +} + +void KXsldbgPart::walkStopCmd_activated() +{ + if (checkDebugger()){ + debugger->slotWalkStopCmd(); + } +} + +void KXsldbgPart::traceCmd_activated() +{ + if (checkDebugger()){ + debugger->slotTraceCmd(); + } +} + +void KXsldbgPart::traceStopCmd_activated() +{ + walkStopCmd_activated(); +} + + +#include "kxsldbg_part.moc" diff --git a/kxsldbg/kxsldbgpart/kxsldbg_part.desktop b/kxsldbg/kxsldbgpart/kxsldbg_part.desktop new file mode 100644 index 00000000..229c6cad --- /dev/null +++ b/kxsldbg/kxsldbgpart/kxsldbg_part.desktop @@ -0,0 +1,15 @@ +[Desktop Entry] +Name=KXsldbgPart +Name[de]=KXsldbg-Komponente +Name[fr]=Module externe KXsldbg +Name[ja]=KXsldbgPort +Name[nds]=KXsldbg-Komponent +Name[pl]=Osadzalny program KPart KXsldbg +Name[pt_BR]=KXSsldbgPart +Name[sv]=Kxsldbg-delprogram +Name[ta]=KXsldbg பகுதி +Name[tg]=Қисми KXsldbg +MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++; +ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=libkxsldbgpart +Type=Service diff --git a/kxsldbg/kxsldbgpart/kxsldbg_part.h b/kxsldbg/kxsldbgpart/kxsldbg_part.h new file mode 100644 index 00000000..1da5ceb8 --- /dev/null +++ b/kxsldbg/kxsldbgpart/kxsldbg_part.h @@ -0,0 +1,170 @@ +#ifndef KXSLDBGKPART_H +#define KXSLDBGKPART_H + +#include <kparts/part.h> +#include <qvariant.h> +#include <qdict.h> +#include <qmainwindow.h> +#include "xsldbgdebugger.h" +#include "xsldbginspector.h" +#include <dcopclient.h> +#include "kxsldbg_partif.h" +#include <ktexteditor/document.h> +#include <ktexteditor/view.h> + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QAction; +class QActionGroup; +class QToolBar; +class QPopupMenu; +class QTextBrowser; +class QLineEdit; +class QDockWindow; +class QWidgetStack; + +class XsldbgBrkStatusView; +class QXsldbgDoc; +class XsldbgOutputView; +class XsldbgConfigImpl; + +class QWidget; +class QPainter; +class KURL; +class QMultiLineEdit; +class KAboutData; + +typedef QDict<QXsldbgDoc> XsldbgDocDict; + +/** + * This is a "Part". It that does all the real work in a KPart + * application. + * + * @short Main Part + * @author Keith Isdale <k_isdale@tpg.com.au> + * @version 0.1 + */ +class KXsldbgPart : public KParts::ReadOnlyPart, public KXsldbgPartIf +{ + Q_OBJECT + +public: + /** + * Default constructor + */ + KXsldbgPart(QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name, const QStringList &args); + + /** + * Destructor + */ + virtual ~KXsldbgPart(); + + static KAboutData *createAboutData(); + + + /** Checks the debugger, if it is not ready then + * display a error in a message box + * + * @returns TRUE if debugger is ready, otherwise FALSE + */ + bool checkDebugger(); + void lookupSystemID(QString systemID); + void lookupPublicID(QString publicID); + void createInspector(); + +public slots: + virtual bool openURL(const KURL &url); + virtual bool closeURL(); + void quit(); + void emitOpenFile(QString file, int line, int row); + void slotLookupSystemID(); + void slotLookupPublicID(); + void walkCmd_activated(); + void walkStopCmd_activated(); + void traceCmd_activated(); + void traceStopCmd_activated(); + void configureEditorCmd_activated(); + + //Tool bar commands + void configureCmd_activated(); + void inspectorCmd_activated(); + void runCmd_activated(); + void stepCmd_activated(); + void nextCmd_activated(); + void continueCmd_activated(); + void stepupCmd_activated(); + void stepdownCmd_activated(); + void sourceCmd_activated(); + void dataCmd_activated(); + void outputCmd_activated(); + void refreshCmd_activated(); + void enableCmd_activated(); + void breakCmd_activated(); + void deleteCmd_activated(); + + /** Evaluate expression entered */ + void evaluateCmd_activated(); + + /** Goto/display file XPath entered */ + void gotoXPathCmd_activated(); + + virtual void lineNoChanged( QString fileName, int lineNumber, + bool breakpoint ); + + void addBreakPoint(int lineNumber); + void enableBreakPoint(int lineNumber); + void deleteBreakPoint(int lineNumber); + + /** Evaluate expression entered in expressionEdit */ + void slotEvaluate(); + + /** Goto/display file that matches XPath specified in xPathEdit */ + void slotGotoXPath(); + + /** Run search on data base , see search.dtd for DTD of search database */ + void slotSearch(); + + /* Process the the URI for SystemID or PublicID requested */ + void slotProcResolveItem(QString URI); + + /* used to get breakpoint list notfication */ + void breakpointItem(QString fileName, int lineNumber , + QString /*templateName*/, QString /* modeName */, + bool enabled , int /* id */); + + void cursorPositionChanged(); + void docChanged(); + + void debuggerStarted(); + +protected: + /** + * This must be implemented by each part + */ + virtual bool openFile(); + bool fetchURL(const KURL &url); + +protected slots: + void fileOpen(); + +private: + QXsldbgDoc *currentDoc; + QWidgetStack *mainView; + + QPushButton *xPathBtn, *searchBtn, *evaluateBtn; + QLineEdit *newXPath, *newSearch, *newEvaluate; + QGridLayout* qxsldbgLayout; + + uint currentLineNo, currentColumnNo; + XsldbgDocDict docDictionary; + XsldbgInspector *inspector; + XsldbgDebugger *debugger; + XsldbgConfigImpl *configWidget; + QString currentFileName; + + XsldbgOutputView *outputview; +}; + +#endif // KXSLDBGPART_H diff --git a/kxsldbg/kxsldbgpart/kxsldbg_part.rc b/kxsldbg/kxsldbgpart/kxsldbg_part.rc new file mode 100644 index 00000000..b8daea6e --- /dev/null +++ b/kxsldbg/kxsldbgpart/kxsldbg_part.rc @@ -0,0 +1,61 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="kxsldbg_part" version="1"> +<MenuBar> + <Menu name="debug"><text>Debug</text> + <Action name="configureCmd"/> + <Action name="inspectCmd"/> + <Action name="runCmd"/> + <Action name="continueCmd"/> + <Action name="stepCmd"/> + <Action name="nextCmd"/> + <Separator/> + <Action name="stepupCmd"/> + <Action name="stepdownCmd"/> + <Separator/> + <Action name="breakCmd"/> + <Action name="deleteCmd"/> + <Action name="enableCmd"/> + <Separator/> + <Action name="sourceCmd"/> + <Action name="dataCmd"/> + <Action name="outputCmd"/> + <Action name="refreshCmd"/> + <Separator/> + <Action name="walkCmd"/> + <Action name="walkStopCmd"/> + <Action name="traceCmd"/> + <Action name="traceStopCmd"/> + <Separator/> + <Action name="evaluateCmd"/> + <Action name="gotoXPathCmd"/> + <Action name="lookupSystemID"/> + <Action name="lookupPublicID"/> + </Menu> + <Menu name="settings"><text>&Settings</text> + <Action name="configureEditorCmd"/> + </Menu> + +</MenuBar> + +<ToolBar name="debugToolBar"> + <Action name="configureCmd"/> + <Action name="inspectCmd"/> + <Action name="runCmd"/> + <Action name="continueCmd"/> + <Action name="stepCmd"/> + <Action name="nextCmd"/> + <Separator/> + <Action name="stepupCmd"/> + <Action name="stepdownCmd"/> + <Separator/> + <Action name="breakCmd"/> + <Action name="deleteCmd"/> + <Action name="enableCmd"/> + <Separator/> + <Action name="sourceCmd"/> + <Action name="dataCmd"/> + <Action name="outputCmd"/> + <Action name="refreshCmd"/> + <Separator/> + </ToolBar> +</kpartgui> diff --git a/kxsldbg/kxsldbgpart/kxsldbg_partif.h b/kxsldbg/kxsldbgpart/kxsldbg_partif.h new file mode 100644 index 00000000..bd537cec --- /dev/null +++ b/kxsldbg/kxsldbgpart/kxsldbg_partif.h @@ -0,0 +1,14 @@ +#ifndef KXSLDBG_PARTIF_H +#define KXSLDBG_PARTIF_H + +#include <dcopobject.h> + +class KXsldbgPartIf : virtual public DCOPObject +{ + K_DCOP + k_dcop: + + /* reserved for future expansion*/ +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/libqtnotfier/Makefile.am b/kxsldbg/kxsldbgpart/libqtnotfier/Makefile.am new file mode 100644 index 00000000..82902c19 --- /dev/null +++ b/kxsldbg/kxsldbgpart/libqtnotfier/Makefile.am @@ -0,0 +1,8 @@ +noinst_LTLIBRARIES = libqtnotfier.la + +libqtnotfier_la_LIBADD = $(LIBXSLT_LIBS) +libqtnotfier_la_METASOURCES = AUTO + +libqtnotfier_la_SOURCES = xsldbgthread.cpp xsldbgnotifier.cpp xsldbgevent.cpp xsldbgdebuggerbase.cpp qtnotifier2.cpp + +INCLUDES = $(XSLDBG_CFLAGS) $(all_includes) diff --git a/kxsldbg/kxsldbgpart/libqtnotfier/qtnotifier2.cpp b/kxsldbg/kxsldbgpart/libqtnotfier/qtnotifier2.cpp new file mode 100644 index 00000000..6d4b7fcb --- /dev/null +++ b/kxsldbg/kxsldbgpart/libqtnotfier/qtnotifier2.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** + qtnotifier2.cpp - description + ------------------- + begin : Sun Dec 23 2001 + copyright : (C) 2001 by keith + 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 <qapplication.h> + +#include "../libxsldbg/xsldbgevent.h" +#include "../libxsldbg/qtnotifier2.h" +#include "xsldbgdebuggerbase.h" +#include "../libxsldbg/xsldbgthread.h" + +XsldbgDebuggerBase *_debugger = 0L; + +int qtNotifyXsldbgApp(XsldbgMessageEnum type, const void *data) +{ + int result = 0; + if (::getThreadStatus() == XSLDBG_MSG_THREAD_NOTUSED){ + return 1; + } + + /* clear the input ready flag as quickly as possible*/ + if ( ::getInputStatus() == XSLDBG_MSG_READ_INPUT) + ::setInputReady(0); + + /* state of the thread */ + if (_debugger != 0L){ + XsldbgEvent *e = new XsldbgEvent(type, data); + if (e != 0L) { + /* The application will now have this event in its event queue + that all that is needed from here*/ + QApplication::postEvent(_debugger, e); + } + } + + if (::getThreadStatus() == XSLDBG_MSG_THREAD_STOP) + ::xsldbgThreadCleanup(); /* thread has died so cleanup after it */ + + result++; /* at the moment this function will always work */ + + return result; +} + + + +void connectNotifier(XsldbgDebuggerBase *debugger){ + _debugger = debugger; +} + + diff --git a/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgdebuggerbase.cpp b/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgdebuggerbase.cpp new file mode 100644 index 00000000..930be808 --- /dev/null +++ b/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgdebuggerbase.cpp @@ -0,0 +1,93 @@ +/*************************************************************************** + xsldbgdebuggerbase.cpp - The base class from + which a debugger + could be built + + ------------------- + 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 <qapplication.h> +#include <qglobal.h> +#include <qstringlist.h> +#include <kurl.h> + +#include "xsldbgdebuggerbase.h" + +XsldbgDebuggerBase::XsldbgDebuggerBase() + : QObject(0L, "XsldbgDebuggerBase") +{ + initialized = false; + updateTimerID = -1; +} + + +XsldbgDebuggerBase::~XsldbgDebuggerBase() +{ + /* empty*/ +} + + + +QString XsldbgDebuggerBase::fromUTF8(const char *text) +{ + QString result; + if (text != 0L) + result = (const char*)text; + return result; +} + + +QString XsldbgDebuggerBase::fromUTF8(const xmlChar *text) +{ + QString result; + if (text != 0L) + result = QString::fromUtf8((const char*)text); + return result; +} + + +QString XsldbgDebuggerBase::fromUTF8FileName(const char *text) +{ + QString result; + if (text != 0L){ + KURL url(((const char*)text)); + if (url.isLocalFile()) + result = QString("file:") + url.path(); + else + result = url.prettyURL(); + } + return result; +} + + +QString XsldbgDebuggerBase::fromUTF8FileName(const xmlChar *text) +{ + QString result; + if (text != 0L){ + KURL url(QString::fromUtf8((const char*)text)); + if (url.isLocalFile()) + result = QString("file:") + url.path(); + else + result = url.prettyURL(); + } + return result; +} + + +void XsldbgDebuggerBase::queueMessage(const QString &text) +{ + updateText += text; +} +#include "xsldbgdebuggerbase.moc" diff --git a/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgdebuggerbase.h b/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgdebuggerbase.h new file mode 100644 index 00000000..ff830495 --- /dev/null +++ b/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgdebuggerbase.h @@ -0,0 +1,147 @@ +/*************************************************************************** + xsldbgdebuggerbase.h - The base class from + which a debugger + could be built + + ------------------- + 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 XSLDBGDEBUGGERBASE_H +#define XSLDBGDEBUGGERBASE_H + +#if defined WIN32 +# include <libxsldbg/xsldbgwin32config.h> +#else +# ifndef XSLDBG_SO_API +# define XSLDBG_SO_API +# endif +#endif + +#include <qobject.h> +#include <qstringlist.h> +#include <libxml/tree.h> + +class XsldbgEvent; +class QApplication; +class QStringList; + +/** + We delegate the task of emitting our signals to XsldbgEvent , so + Xsldbg must become our friend +*/ +class XsldbgDebuggerBase : public QObject +{ + Q_OBJECT + + friend class XsldbgEvent; + + public: + XsldbgDebuggerBase(void); + ~XsldbgDebuggerBase(void); + + void setInitialized(bool state) {initialized = state; }; + bool getInitialized(void) {return initialized ;}; + + void setUpdateTimerID(int ID) { updateTimerID = ID;}; + int getUpdateTimerID(void) {return updateTimerID ;}; + + + /** Convert from libxslt UTF8 to a QString */ + static QString fromUTF8(const char *text); + static QString fromUTF8FileName(const char *text); + + /** Convert from libxslt UTF8 to a QString */ + static QString fromUTF8(const xmlChar *text); + static QString fromUTF8FileName(const xmlChar *text); + + /* list of command yet to be processed */ + QStringList commandQueue(void) {return _commandQueue ;}; + + void queueMessage(const QString &text); + +protected: + QString updateText; + + private: + bool initialized; + int updateTimerID; + QStringList _commandQueue; + + signals: // Signals + /** line number and/or file name changed */ + void lineNoChanged(QString /* fileName */, int /* lineNumber */, bool /* breakpoint */); + + /** Show a message in debugger window */ + void showMessage(QString /* msg*/); + + /** Add breakpoint to view, First parameter is QString::null + to indicate start of breakpoint list notfication */ + void breakpointItem(QString /* fileName*/, int /* lineNumber */, + QString /*templateName*/, QString /* modeName */, + bool /* enabled */, int /* id */); + + /** 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 */); + + /** 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 */); + + /** Add a variable to view, First parameter is QString::null + to indicate start of local variable list notfication */ + void variableItem(QString /*name */, QString /* templateContext*/, + QString /* fileName */, int /*lineNumber */, + QString /* select XPath */, int /* is it a local variable */); + + /** 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 */); + + /* Cause the names for source, data and output files to be reload from xsldbg */ + void fileDetailsChanged(); + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgevent.cpp b/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgevent.cpp new file mode 100644 index 00000000..a424eaba --- /dev/null +++ b/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgevent.cpp @@ -0,0 +1,857 @@ + +/*************************************************************************** + xsldbgevent.c - 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. * + * * + ***************************************************************************/ + +#include <qapplication.h> +#include <qtimer.h> +#include <qfile.h> +#include <kurl.h> +#include <qtextstream.h> + +#include <libxslt/xsltInternals.h> + +#include "../libxsldbg/xsldbgevent.h" +#include "xsldbgdebuggerbase.h" +#include "../libxsldbg/arraylist.h" +#include "../libxsldbg/breakpoint.h" +#include "../libxsldbg/xsldbgmsg.h" +#include "../libxsldbg/xsldbgthread.h" +#include "../libxsldbg/options.h" +#include "../libxsldbg/files.h" + +QString updateText; + +XsldbgEventData::XsldbgEventData() +{ + int column; + + for (column = 0; column < XSLDBGEVENT_COLUMNS; column++){ + textValues[column] = QString::null; + } + + for (column = 0; column < XSLDBGEVENT_COLUMNS; column++){ + intValues[column] = -1; + } + +} + +XsldbgEventData::~XsldbgEventData() +{ +} + +void XsldbgEventData::setText(int column, QString text) +{ + if ((column >= 0) && (column < XSLDBGEVENT_COLUMNS)) + textValues[column] = text; +} + + +QString XsldbgEventData::getText(int column) +{ + if ((column >= 0) && (column < XSLDBGEVENT_COLUMNS)) + return textValues[column]; + else + return QString::null; +} + + +void XsldbgEventData::setInt(int column, int value) +{ + if ((column >= 0) && (column < XSLDBGEVENT_COLUMNS)) + intValues[column] = value; +} + + +int XsldbgEventData::getInt(int column) +{ + if ((column >= 0) && (column < XSLDBGEVENT_COLUMNS)) + return intValues[column]; + else + return -1; +} + + +XsldbgEvent::XsldbgEvent(XsldbgMessageEnum type, const void *data) + : QEvent(QEvent::User) +{ + XsldbgEventData *eventData; + this->data = data; + debugger = 0L; + beenCreated = false; + + if (type == XSLDBG_MSG_LIST){ /* 23 : As list of messages */ + notifyMessageListPtr msgList = (notifyMessageListPtr)data; + void *msgData; + /* If this is an included source message, which just continues a source message, + we don't need to add an empty XsldbgEventData */ + if (msgList->type != XSLDBG_MSG_INCLUDED_SOURCE_CHANGED){ + /* add an empty event data item which indicates the start of a list */ + eventData = new XsldbgEventData(); + if (eventData != 0L) + list.append(eventData); + } + for (int index = 0; index < arrayListCount(msgList->list); index++){ + msgData = ::arrayListGet(msgList->list, index); + eventData = createEventData(msgList->type, msgData); + if (eventData != 0L) + list.append(eventData); + } + ::arrayListFree(msgList->list); + msgList->list = 0L; + itemType = msgList->type; + }else{ + eventData = createEventData(type, data); + if (eventData != 0L) + list.append(eventData); + itemType = type; + } + + beenCreated = true; + /* remove any knowledge of orginal data */ + this->data = 0L; +} + + +XsldbgEvent::~XsldbgEvent() +{ +} + + +XsldbgEventData *XsldbgEvent::createEventData(XsldbgMessageEnum type, const void *msgData) +{ + XsldbgEventData *result = new XsldbgEventData(); + + if (result == 0L) + return result; + + switch (type){ + + case XSLDBG_MSG_THREAD_NOTUSED: /* 0: Thread are not to be used */ + case XSLDBG_MSG_THREAD_INIT: /* 1: The xsldbg thread is initializing */ + case XSLDBG_MSG_THREAD_RUN: /* 2: The xsldbg thread is running */ + case XSLDBG_MSG_THREAD_STOP: /* 3: The xsldbg thread is about to die */ + case XSLDBG_MSG_THREAD_DEAD: /* 4: The xsldbg thread died */ + /* we don't need to do anything extra with this message */ + break; + + /* input status ( once thread is running) */ + case XSLDBG_MSG_AWAITING_INPUT: /* 5: Waiting for user input */ + /* we don't need to do anything extra with this message */ + break; + + case XSLDBG_MSG_READ_INPUT: /* 6: Read user input */ + /* we don't need to do anything extra with this message */ + break; + + case XSLDBG_MSG_PROCESSING_INPUT: /* 7: Processing user's request */ + /* we don't need to do anything extra with this message */ + break; + + /* provide more informatiom about state of xsldbg (optional) */ + case XSLDBG_MSG_PROCESSING_RESULT: /* 8: An error occured performing command + * requested command */ + if (msgData != 0L){ + xsldbgErrorMsgPtr msg = (xsldbgErrorMsgPtr)msgData; + if (msg->text) + result->setText(0, XsldbgDebuggerBase::fromUTF8(msg->text)); + } + break; + + case XSLDBG_MSG_LINE_CHANGED: /* 9: Changed to new line number + * ie a step */ + handleLineNoChanged(result, msgData); + break; + + case XSLDBG_MSG_FILE_CHANGED: /* 10: Changed selection for source/data/output file */ + // not used + break; + + case XSLDBG_MSG_BREAKPOINT_CHANGED: /* 11: Response to a showbreak command */ + handleBreakpointItem(result, msgData); + break; + + case XSLDBG_MSG_PARAMETER_CHANGED: /* 12: Response to showparam command */ + handleParameterItem(result, msgData); + break; + + case XSLDBG_MSG_TEXTOUT: /* 13 : Free form text from xsldg */ + /* this is going to be most common and its so simple we can handle + it here */ + result->setText(0, XsldbgDebuggerBase::fromUTF8((xmlChar*)msgData)); + break; + + case XSLDBG_MSG_FILEOUT: /* 14 : Response to cat commmand, ie + * Free form text in file */ + /* this is actualy the file to load */ + { + KURL url(XsldbgDebuggerBase::fromUTF8FileName((xmlChar*)msgData)); + if (!url.isLocalFile()){ + qDebug("Remote path to temp file %s unsupported, unable to read message from xsldbg", url.prettyURL().local8Bit().data()); + break; + } + + QString fileName = url.path(); + QString outputText; + if (!fileName.isNull()){ + QFile file (fileName); + if (file.open(IO_ReadOnly)){ + QTextStream textFile(&file); + QString textIn = ""; + textFile.setEncoding(QTextStream::UnicodeUTF8); + while (1){ + textIn = textFile.readLine(); + if (textIn.isNull()) + break; + outputText.append(textIn).append("\n"); + } + file.close(); + } + outputText.append("\n"); + result->setText(0, outputText); + } + } + break; + + case XSLDBG_MSG_LOCALVAR_CHANGED: /* 15 : Response to locals command ie a + * local variable */ + handleLocalVariableItem(result, msgData); + break; + + case XSLDBG_MSG_GLOBALVAR_CHANGED: /* 16 : Response to globals command + * ie a global variable */ + handleGlobalVariableItem(result, msgData); + break; + + case XSLDBG_MSG_TEMPLATE_CHANGED: /* 17 : Response to templates commmand + * ie template details */ + handleTemplateItem(result, msgData); + break; + + case XSLDBG_MSG_SOURCE_CHANGED: /* 18 : Response to stylesheets command, + * a normal stylesheet */ + handleSourceItem(result, msgData); + break; + + case XSLDBG_MSG_INCLUDED_SOURCE_CHANGED: /* 19: Response to stylesheets + * command, a xmlNodeptr of + * a included stylesheet */ + handleIncludedSourceItem(result, msgData); + break; + + case XSLDBG_MSG_CALLSTACK_CHANGED: /* 20: Response to where command, + * ie a item on the call stack */ + handleCallStackItem(result, msgData); + break; + + case XSLDBG_MSG_ENTITIY_CHANGED: /* 21: Response to entities + * command */ + handleEntityItem(result, msgData); + break; + + case XSLDBG_MSG_RESOLVE_CHANGE: /* 22: Response to system or + * public command */ + handleResolveItem(result, msgData); + break; + + default: + qDebug("Unhandled type in createEventData %d", type); + + } + return result; +} + +void XsldbgEvent::emitMessage(XsldbgDebuggerBase *debugger) +{ + XsldbgEventData *eventData; + + this->debugger = debugger; + + for (eventData = list.first(); eventData != 0L; eventData = list.next()){ + emitMessage(eventData); + } + + /* make sure that we only temporarily set the value for debugger*/ + this->debugger = 0L; +} + + +void XsldbgEvent::emitMessage(XsldbgEventData *eventData) +{ + + if ((eventData == 0L) || (debugger == 0L)){ + qDebug("emitMessage failed"); + if (eventData == 0L) + qDebug("Event data == NULL"); + if (debugger == 0L) + qDebug("Debugger == NULL"); + return; + } + + /* + Method use will end up like + + emit debugger->lineNoChanged("", 1, false); + + */ + + switch (itemType){ + + case XSLDBG_MSG_THREAD_NOTUSED: /* 0: Thread are not to be used */ + case XSLDBG_MSG_THREAD_INIT: /* 1: The xsldbg thread is initializing */ + case XSLDBG_MSG_THREAD_RUN: /* 2: The xsldbg thread is running */ + /* we don't need to do anything extra with this message */ + break; + + case XSLDBG_MSG_THREAD_STOP: /* 3: The xsldbg thread is about to die */ + case XSLDBG_MSG_THREAD_DEAD: /* 4: The xsldbg thread died */ + /* the debugger has stopped is about to stop */ + debugger->setInitialized(false); + break; + + /* input status ( once thread is running) */ + case XSLDBG_MSG_AWAITING_INPUT: /* 5: Waiting for user input */ + if ((getInputReady() == 0) && (debugger->commandQueue().count() > 0)){ + qDebug("Command queue not empty"); + QTimerEvent *e = new QTimerEvent(debugger->getUpdateTimerID()); + QApplication::postEvent(debugger, e); + } + if (!updateText.isEmpty()){ + debugger->queueMessage(updateText); + updateText = ""; + } + break; + + case XSLDBG_MSG_READ_INPUT: /* 6: Read user input */ + /* we don't need to do anything extra with this message */ + break; + + case XSLDBG_MSG_PROCESSING_INPUT: /* 7: Processing user's request */ + /* we don't need to do anything extra with this message */ + break; + + /* provide more informatiom about state of xsldbg (optional) */ + case XSLDBG_MSG_PROCESSING_RESULT: /* 8: An error occured performing command + * requested command */ + if (!eventData->getText(0).isNull()) + updateText.append(eventData->getText(0)); + break; + + case XSLDBG_MSG_LINE_CHANGED: /* 9: Changed to new line number + * ie a step */ + handleLineNoChanged(eventData, 0L); + break; + + case XSLDBG_MSG_FILE_CHANGED: /* 10: Loaded source/data file */ + if (beenCreated == false){ + /* Empty data */ + }else{ + emit debugger->fileDetailsChanged(); + } + break; + + case XSLDBG_MSG_BREAKPOINT_CHANGED: /* 11: Response to a showbreak command */ + handleBreakpointItem(eventData, 0L); + break; + + case XSLDBG_MSG_PARAMETER_CHANGED: /* 12: Response to showparam command */ + handleParameterItem(eventData, 0L); + break; + + case XSLDBG_MSG_TEXTOUT: /* 13 : Free form text from xsldg */ + /* this is going to be most common and its so simple we can handle + it here */ + /* + emit debugger->showMessage(eventData->getText(0)); + */ + if (!eventData->getText(0).isNull()) + updateText.append(eventData->getText(0)); + break; + + case XSLDBG_MSG_FILEOUT: /* 14 : Response to cat commmand */ + if (!eventData->getText(0).isNull()) + updateText.append(eventData->getText(0)); + break; + + case XSLDBG_MSG_LOCALVAR_CHANGED: /* 15 : Response to locals command ie a + * local variable */ + handleLocalVariableItem(eventData, 0L); + break; + + case XSLDBG_MSG_GLOBALVAR_CHANGED: /* 16 : Response to globals command + * ie a global variable */ + handleGlobalVariableItem(eventData, 0L); + break; + + case XSLDBG_MSG_TEMPLATE_CHANGED: /* 17 : Response to templates commmand + * ie template details */ + handleTemplateItem(eventData, 0L); + break; + + case XSLDBG_MSG_SOURCE_CHANGED: /* 18 : Response to stylesheets command, + * a normal stylesheet */ + handleSourceItem(eventData, 0L); + break; + + case XSLDBG_MSG_INCLUDED_SOURCE_CHANGED: /* 19: Response to stylesheets + * command, a xmlNodeptr of + * a included stylesheet */ + handleIncludedSourceItem(eventData, 0L); + break; + + case XSLDBG_MSG_CALLSTACK_CHANGED: /* 20: Response to where command, + * ie a item on the call stack */ + handleCallStackItem(eventData, 0L); + break; + + case XSLDBG_MSG_ENTITIY_CHANGED: /* 21: Response to entities + * command */ + handleEntityItem(eventData, 0L); + break; + + case XSLDBG_MSG_RESOLVE_CHANGE: /* 22: Response to system or + * public command */ + handleResolveItem(eventData, 0L); + break; + + default: + qDebug("Unhandled type in emitMessage %d", itemType); + } +} + + +void XsldbgEvent::handleLineNoChanged(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (xsldbgUrl() != 0L){ + eventData->setText(0, XsldbgDebuggerBase::fromUTF8FileName(xsldbgUrl())); + eventData->setInt(0, xsldbgLineNo()); + eventData->setInt(1, msgData != 0L); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->lineNoChanged(eventData->getText(0), eventData->getInt(0), + eventData->getInt(1)); + } + } +} + + +void XsldbgEvent::handleShowMessage(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + eventData->setText(0, XsldbgDebuggerBase::fromUTF8((xmlChar*)msgData)); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->showMessage(eventData->getText(0)); + } + } +} + + +void XsldbgEvent::handleBreakpointItem(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + breakPointPtr breakItem = (breakPointPtr)msgData; + /* set the file name*/ + eventData->setText(0, XsldbgDebuggerBase::fromUTF8FileName(breakItem->url)); + /* line number*/ + eventData->setInt(0, (int)breakItem->lineNo); + + /* templateName */ + eventData->setText(1, XsldbgDebuggerBase::fromUTF8(breakItem->templateName)); + + /* modeName */ + eventData->setText(2, XsldbgDebuggerBase::fromUTF8(breakItem->modeName)); + /* enabled state */ + eventData->setInt(1, (int)(breakItem->flags & BREAKPOINT_ENABLED)); + + /* id value */ + eventData->setInt(2, (int)breakItem->id); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->breakpointItem(eventData->getText(0), /* file name*/ + eventData->getInt(0), /* line number*/ + eventData->getText(1), /* template name */ + eventData->getText(2), /* mode name */ + eventData->getInt(1), /* enabled state*/ + eventData->getInt(2) /* id*/); + } + } +} + + +void XsldbgEvent::handleGlobalVariableItem(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + xsltStackElemPtr item = (xsltStackElemPtr)msgData; + QString name, fileName, selectXPath; + int lineNumber = -1; + + /* variable name*/ + if (item->nameURI) + name = (XsldbgDebuggerBase::fromUTF8FileName(item->nameURI)).append(":"); + name.append(XsldbgDebuggerBase::fromUTF8(item->name)); + + + + if (item->computed && item->comp && item->comp->inst && item->comp->inst->doc){ + fileName = XsldbgDebuggerBase::fromUTF8FileName(item->comp->inst->doc->URL); + lineNumber= xmlGetLineNo(item->comp->inst); + } + + if (item->select) + selectXPath = XsldbgDebuggerBase::fromUTF8(item->select); + + eventData->setText(0, name); + eventData->setText(1, ""); + eventData->setText(2, fileName); + eventData->setText(3, selectXPath); + eventData->setInt(0, lineNumber); + eventData->setInt(1, 0); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->variableItem(eventData->getText(0), /* variable name*/ + eventData->getText(1), /* templatecontext*/ + eventData->getText(2), /* file name */ + eventData->getInt(0), /* line number */ + eventData->getText(3), /* select XPath */ + eventData->getInt(1) /* Is this a local variable */ ); + } + } +} + + +void XsldbgEvent::handleLocalVariableItem(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + xsltStackElemPtr item = (xsltStackElemPtr)msgData; + QString name, templateContext, fileName, selectXPath; + int lineNumber = -1; + xmlNodePtr varXmlNode; + + /* variable name */ + if (item->nameURI) + name = (XsldbgDebuggerBase::fromUTF8FileName(item->nameURI)).append(":"); + name.append(XsldbgDebuggerBase::fromUTF8(item->name)); + + if (item->computed && item->comp && item->comp->inst){ + varXmlNode = item->comp->inst; + + /* try to find out what template this variable belongs to */ + if (varXmlNode->parent && IS_XSLT_NAME(varXmlNode->parent, "template")) { + xmlChar* value = xmlGetProp(varXmlNode->parent, (xmlChar *) "name"); + if (value) { + templateContext = XsldbgDebuggerBase::fromUTF8(value); + xmlFree(value); + }else{ + value = xmlGetProp(varXmlNode->parent, (xmlChar *) "match"); + if (value) { + templateContext = XsldbgDebuggerBase::fromUTF8(value); + xmlFree(value); + } + } + } + + if (varXmlNode->doc) { + fileName = XsldbgDebuggerBase::fromUTF8FileName(varXmlNode->doc->URL); + lineNumber = xmlGetLineNo(varXmlNode); + } + + if (item->select) + selectXPath = XsldbgDebuggerBase::fromUTF8(item->select); + + eventData->setText(0, name); + eventData->setText(1, templateContext); + eventData->setText(2, fileName); + eventData->setText(3, selectXPath); + eventData->setInt(0, lineNumber); + eventData->setInt(1, 1); + } + } + }else{ + /* emit the event data via debugger*/ + emit debugger->variableItem(eventData->getText(0), /* variable name*/ + eventData->getText(1), /* templatecontext*/ + eventData->getText(2), /* file name */ + eventData->getInt(0), /* line number */ + eventData->getText(3), /* select XPath */ + eventData->getInt(1) /* Is this a local variable */ ); + } + } +} + + +void XsldbgEvent::handleTemplateItem(XsldbgEventData *eventData, const void *msgData) +{ +if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if(msgData != 0L){ + xsltTemplatePtr item = (xsltTemplatePtr)msgData; + QString name, mode, fileName; + int lineNumber = -1; + + if (item->nameURI) + name.append(XsldbgDebuggerBase::fromUTF8FileName(item->nameURI)).append(":"); + + if (item->name) + name.append(XsldbgDebuggerBase::fromUTF8(item->name)); + else if (item->match) + name.append(XsldbgDebuggerBase::fromUTF8(item->match)); + + mode = XsldbgDebuggerBase::fromUTF8(item->mode); + + if (item->elem && item->elem->doc){ + fileName = XsldbgDebuggerBase::fromUTF8FileName(item->elem->doc->URL); + lineNumber = xmlGetLineNo(item->elem); + } + eventData->setText(0, name); + eventData->setText(1, mode); + eventData->setText(2, fileName); + eventData->setInt(0, lineNumber); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->templateItem(eventData->getText(0), /* tempalte name*/ + eventData->getText(1), /* mode*/ + eventData->getText(2), /* file name*/ + eventData->getInt(0) /* line number*/); + } + } + +} + + +void XsldbgEvent::handleIncludedSourceItem(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + xmlNodePtr item = (xmlNodePtr)msgData; + QString name, fileName; + int lineNumber = -1; + + if (item->doc) + name = XsldbgDebuggerBase::fromUTF8FileName(item->doc->URL); + + if (item->parent && item->parent->doc){ + fileName = XsldbgDebuggerBase::fromUTF8FileName(item->parent->doc->URL); + lineNumber = xmlGetLineNo((xmlNodePtr)item->parent->doc); + } + eventData->setText(0, name); + eventData->setText(1, fileName); + eventData->setInt(0, lineNumber); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->sourceItem(eventData->getText(0), /* file name*/ + eventData->getText(1), /* parent file name*/ + eventData->getInt(0) /* parent line number*/); + } + } +} + +void XsldbgEvent::handleSourceItem(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + xsltStylesheetPtr item = (xsltStylesheetPtr)msgData; + QString name, fileName; + int lineNumber = -1; + + if (item->doc) + name = XsldbgDebuggerBase::fromUTF8FileName(item->doc->URL); + + if (item->parent && item->parent->doc){ + fileName = XsldbgDebuggerBase::fromUTF8FileName(item->parent->doc->URL); + lineNumber = xmlGetLineNo((xmlNodePtr)item->parent->doc); + } + + eventData->setText(0, name); + eventData->setText(1, fileName); + eventData->setInt(0, lineNumber); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->sourceItem(eventData->getText(0), /* name*/ + eventData->getText(1), /* parent file name*/ + eventData->getInt(0) /* parent line number*/); + } + } +} + +void XsldbgEvent::handleParameterItem(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + parameterItemPtr paramItem = (parameterItemPtr)msgData; + QString name, value; + + name = XsldbgDebuggerBase::fromUTF8(paramItem->name); + value = XsldbgDebuggerBase::fromUTF8(paramItem->value); + + eventData->setText(0, name); + eventData->setText(1, value); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->parameterItem(eventData->getText(0), /* param name*/ + eventData->getText(1) /* param value*/); + } + } +} + + +void XsldbgEvent::handleCallStackItem(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + callPointPtr item = (callPointPtr)msgData; + QString templateName, fileName; + int lineNumber = -1; + + /* template name */ + if (item->info){ + templateName = XsldbgDebuggerBase::fromUTF8(item->info->templateName); + fileName = XsldbgDebuggerBase::fromUTF8FileName(item->info->url); + lineNumber = item->lineNo; + } + + eventData->setText(0, templateName); + eventData->setText(1, fileName); + eventData->setInt(0, lineNumber); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->callStackItem(eventData->getText(0), /* template name*/ + eventData->getText(1), /* fileName */ + eventData->getInt(0) /* line number*/); + } + } +} + + +void XsldbgEvent::handleEntityItem(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + QString SystemID, PublicID; + + entityInfoPtr info = (entityInfoPtr)msgData; + SystemID = XsldbgDebuggerBase::fromUTF8FileName(info->SystemID); + PublicID = XsldbgDebuggerBase::fromUTF8(info->PublicID); + + eventData->setText(0, SystemID); + eventData->setText(1, PublicID); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->entityItem(eventData->getText(0), /* SystemID*/ + eventData->getText(1) /* PublicID*/); + } + } +} + + +void XsldbgEvent::handleResolveItem(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + QString URI = XsldbgDebuggerBase::fromUTF8FileName((const xmlChar*)msgData); + + eventData->setText(0, URI); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->resolveItem(eventData->getText(0) /* URI */); + } + } +} + + +void XsldbgEvent::handleIntOptionItem(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + parameterItemPtr paramItem = (parameterItemPtr)msgData; + eventData->setText(0, XsldbgDebuggerBase::fromUTF8(paramItem->name)); + eventData->setInt(0, paramItem->intValue); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->intOptionItem(eventData->getText(0), /* option name*/ + eventData->getInt(0) /* value*/); + } + } +} + + +void XsldbgEvent::handleStringOptionItem(XsldbgEventData *eventData, const void *msgData) +{ + if (eventData != 0L){ + if (beenCreated == false){ + /* add our specific data to eventData*/ + if (msgData != 0L){ + parameterItemPtr paramItem = (parameterItemPtr)msgData; + eventData->setText(0, XsldbgDebuggerBase::fromUTF8(paramItem->name)); + eventData->setText(1, XsldbgDebuggerBase::fromUTF8(paramItem->value)); + } + }else{ + /* emit the event data via debugger*/ + emit debugger->stringOptionItem(eventData->getText(0), /* option name*/ + eventData->getText(1) /* value*/); + } + } +} + + + +void XsldbgEventDataList::deleteItem( QPtrCollection::Item d ) +{ + if ( del_item ) delete (XsldbgEventData *)d; +} diff --git a/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgnotifier.cpp b/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgnotifier.cpp new file mode 100644 index 00000000..d76c6678 --- /dev/null +++ b/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgnotifier.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + xsldbgnotifier.cpp - description + ------------------- + begin : Thu Dec 20 2001 + copyright : (C) 2001 by keith + email : keith@linux + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "../libxsldbg/xsldbgnotifier.h" + +XsldbgNotifier::XsldbgNotifier(void) +{ +} + + +XsldbgNotifier::~XsldbgNotifier(void) +{ +} + + +void XsldbgNotifier::doNotify(XsldbgMessageEnum /*type*/, const void * /*data*/) +{ +} + diff --git a/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgthread.cpp b/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgthread.cpp new file mode 100644 index 00000000..1f428bb5 --- /dev/null +++ b/kxsldbg/kxsldbgpart/libqtnotfier/xsldbgthread.cpp @@ -0,0 +1,360 @@ +/*************************************************************************** + xsldbgthread.cpp - description + ------------------- + begin : Thu Dec 20 2001 + copyright : (C) 2001 by keith + email : keith@linux + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "config.h" +#include <pthread.h> /* need to create/work with process thread */ +#include <errno.h> /* need for EAGAIN */ +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <stdarg.h> + +#include <libxml/xmlerror.h> + +#include "../libxsldbg/breakpoint.h" +#include "../libxsldbg/xsldbgmsg.h" +#include "../libxsldbg/xsldbgthread.h" +#include "../libxsldbg/qtnotifier2.h" + +#ifdef HAVE_READLINE +#include <readline/readline.h> +#ifdef HAVE_HISTORY +#include <readline/history.h> +#endif +#endif + +#define DEBUG_BUFFER_SIZE 500 + +static char inputBuffer[DEBUG_BUFFER_SIZE]; +static char outputBuffer[DEBUG_BUFFER_SIZE]; + +/*the major structure to hold information about the process thread */ +pthread_t mythread; + +/* The reader for stdout */ +pthread_t stdoutReaderThread; + +FILE *stdoutIO = NULL; + + +/* ----------------------------------------------- + private functions + ---------------------------------------------------*/ + +extern "C" { + +/** + * xsldbgGenericErrorFunc: + * @ctx: Is Valid + * @msg: Is valid + * @...: other parameters to use + * + * Handles print output from xsldbg and passes it to the application + */ +void +xsldbgGenericErrorFunc(void *ctx, const char *msg, ...); +xmlChar * qtXslDbgShellReadline(xmlChar * prompt); + +} + +/* ----------------------------------------------- + end functions + ---------------------------------------------------*/ + +/* setup all application wide items */ +int +xsldbgThreadInit(void) +{ + int result = 0; + fprintf(stderr, "mainInit()\n"); + xsltSetGenericErrorFunc(0, xsldbgGenericErrorFunc); + setThreadStatus(XSLDBG_MSG_THREAD_INIT); + xsldbgSetAppFunc(qtNotifyXsldbgApp); + xsldbgSetAppStateFunc(qtNotifyStateXsldbgApp); + xsldbgSetTextFunc(qtNotifyTextXsldbgApp); + xsldbgSetReadlineFunc(qtXslDbgShellReadline); + + + /* create the thread */ + if (pthread_create(&mythread, NULL, xsldbgThreadMain, NULL) != EAGAIN) { + int counter; + for (counter = 0; counter < 11; counter++){ + if (getThreadStatus() != XSLDBG_MSG_THREAD_INIT) + break; + usleep(250000); /*guess that it will take at most 2.5 seconds to startup */ + } + /* xsldbg should have started by now if it can */ + if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN){ + fprintf(stderr, "Created thread\n"); + result++; + }else + fprintf(stderr, "Thread did not start\n"); + } else { + fprintf(stderr, "Failed to create thread\n"); + } + + return result; +} + + +/* tell the thread to stop and free that memory !*/ +void +xsldbgThreadFree(void) +{ + fprintf(stderr, "xsldbgThreadFree()\n"); + if (getThreadStatus() != XSLDBG_MSG_THREAD_DEAD) + { + int counter; + fprintf(stderr, "Killing xsldbg thread\n"); + setThreadStatus(XSLDBG_MSG_THREAD_STOP); + for (counter = 0; counter < 11; counter++){ + if (getThreadStatus() == XSLDBG_MSG_THREAD_DEAD) + break; + usleep(250000); /*guess that it will take at most 2.5 seconds to stop */ + } + } + +} + +const char *getFakeInput() +{ + return inputBuffer; +} + + +/* put text into standard input just like we had typed it */ +int +fakeInput(const char *text) +{ + int result = 0; + + if (!text || (getInputReady() == 1) || (getThreadStatus() != XSLDBG_MSG_THREAD_RUN)) + return result; + + // fprintf(stderr, "\nFaking input of \"%s\"\n", text); + strncpy(inputBuffer, text, sizeof(inputBuffer)); + setInputReady(1); + result++; + return result; +} + + +/* use this function instead of the one that was in debugXSL.c */ +/** + * qtXslDbgShellReadline: + * @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 * +qtXslDbgShellReadline(xmlChar * prompt) +{ + + const char *inputReadBuff; + + static char last_read[DEBUG_BUFFER_SIZE] = { '\0' }; + + if (getThreadStatus() != XSLDBG_MSG_THREAD_RUN) + { +#ifdef HAVE_READLINE + xmlChar *line_read; + + /* Get a line from the user. */ + line_read = (xmlChar *) readline((char *) prompt); + + /* If the line has any text in it, save it on the history. */ + if (line_read && *line_read) { + add_history((char *) line_read); + strncpy((char*)last_read, (char*)line_read, DEBUG_BUFFER_SIZE - 1); + } else { + /* if only <Enter>is pressed then try last saved command line */ + line_read = (xmlChar *) xmlMemStrdup(last_read); + } + return (line_read); +#else + char line_read[DEBUG_BUFFER_SIZE]; + + if (prompt != NULL) + xsltGenericError(xsltGenericErrorContext, "%s", prompt); + if (!fgets(line_read, DEBUG_BUFFER_SIZE - 1, stdin)) + return (NULL); + line_read[DEBUG_BUFFER_SIZE - 1] = 0; + /* if only <Enter>is pressed then try last saved command line */ + if ((strlen(line_read) == 0) || (line_read[0] == '\n')) { + strcpy(line_read, last_read); + } else { + strcpy(last_read, line_read); + } + return (xmlChar *) xmlMemStrdup(line_read); +#endif + + } + else{ + + setInputStatus(XSLDBG_MSG_AWAITING_INPUT); + notifyXsldbgApp(XSLDBG_MSG_AWAITING_INPUT, NULL); + + while (getInputReady() == 0){ + usleep(10000); + /* have we been told to die */ + if (getThreadStatus() == XSLDBG_MSG_THREAD_STOP){ + fprintf(stderr, "About to stop thread\n"); + xslDebugStatus = DEBUG_QUIT; + return NULL; + } + } + + setInputStatus(XSLDBG_MSG_READ_INPUT); + inputReadBuff = getFakeInput(); + if(inputReadBuff){ + notifyXsldbgApp(XSLDBG_MSG_READ_INPUT, inputReadBuff); + return (xmlChar*)xmlMemStrdup(inputReadBuff); + }else{ + return NULL; + } + } +} + + +xsldbgErrorMsg msg; +xsldbgErrorMsgPtr msgPtr = &msg; +xmlChar *msgText = NULL; + +int qtNotifyStateXsldbgApp(XsldbgMessageEnum type, int commandId, + XsldbgCommandStateEnum commandState, const char *text) +{ + int result = 0; + msg.type = type; + msg.commandId = commandId; + msg.commandState = commandState; + if (text != NULL) + { + msg.text = (xmlChar*)xmlMemStrdup(text); + if (msg.text == NULL) + return result; /* out of memory */ + } + else + msg.text = NULL; + + notifyXsldbgApp(XSLDBG_MSG_PROCESSING_RESULT, msgPtr); + if (msg.text != NULL) + { + xmlFree(msg.text); + msg.text = NULL; + } + + result = 1; + return result; +} + + +int qtNotifyTextXsldbgApp(XsldbgMessageEnum type, const char *text) +{ + return qtNotifyStateXsldbgApp(type, -1, XSLDBG_COMMAND_NOTUSED, text); +} + +char mainBuffer[DEBUG_BUFFER_SIZE]; +static void xsldbgThreadCleanupQt(void); + + +/* this is where the thread get to do all its work */ +void * +xsldbgThreadMain(void *) +{ + // int defaultArgc = 2; + // char *defaultArgv[2]; + // int i; + + if (getThreadStatus() != XSLDBG_MSG_THREAD_INIT){ + fprintf(stderr, "xsldbg thread is not ready to be started. Or one is already running.\n"); + return NULL; /* we can't start more than one thread of xsldbg */ + } + +// defaultArgv[0] = xmlMemStrdup("xsldbg"); +// defaultArgv[1] = xmlMemStrdup("--shell"); + /* + defaultArgv[2] = xmlMemStrdup("xsldoc.xsl"); + defaultArgv[3] = xmlMemStrdup("xsldoc.xml"); + */ +/* for (i = 0; i < defaultArgc; i++){ + if (defaultArgv[i] == NULL){ + fprintf(stderr, "Start thread failed. Unable to create xsldbg arguments\n"); + return NULL; + } + } +*/ + xsldbgSetThreadCleanupFunc(xsldbgThreadCleanupQt); + setThreadStatus(XSLDBG_MSG_THREAD_RUN); + setInputStatus(XSLDBG_MSG_AWAITING_INPUT); + fprintf(stderr, "Starting thread\n"); + + /* call the "main of xsldbg" found in debugXSL.c */ +// xsldbgMain(defaultArgc, defaultArgv); + xsldbgMain(0,0); + fprintf(stderr, "Stopping thread\n"); +/* + for (i = 0; i < defaultArgc; i++){ + xmlFree(defaultArgv[i]); + } +*/ + + setThreadStatus(XSLDBG_MSG_THREAD_DEAD); + setInputStatus(XSLDBG_MSG_PROCESSING_INPUT); + notifyXsldbgApp(XSLDBG_MSG_THREAD_DEAD, NULL); + return NULL; +} + + + +/* thread has died so cleanup after it not called directly but via + notifyXsldbgApp*/ +void +xsldbgThreadCleanupQt(void) +{ + fprintf(stderr, "Thread has finished\n"); + if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) + { + xsldbgThreadFree(); + } + /* its safe to modify threadStatus as the thread is now dead */ + setThreadStatus(XSLDBG_MSG_THREAD_DEAD); +} + + + +void * +xsldbgThreadStdoutReader(void *data) +{ + if (!stdoutIO) + return data; + + while (getThreadStatus() == XSLDBG_MSG_THREAD_RUN){ + if (fgets(outputBuffer, sizeof(outputBuffer -1), stdoutIO)){ + usleep(10000); + strcat(outputBuffer, "\n"); + notifyTextXsldbgApp(XSLDBG_MSG_TEXTOUT, outputBuffer); + }else{ + fprintf(stderr, "Unable to read from stdout from xsldbg\n"); + break; + } + } + return data; +} 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(©->url, ©->lineNo); + } else { + result = validateData(©->url, ©->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, ©, (xsltTransformContextPtr)data); + }else{ + result = validateBreakPoint(breakPtr, ©); + } + }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", ¶mId)) { + 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 diff --git a/kxsldbg/kxsldbgpart/qxsldbgdoc.cpp b/kxsldbg/kxsldbgpart/qxsldbgdoc.cpp new file mode 100644 index 00000000..69105338 --- /dev/null +++ b/kxsldbg/kxsldbgpart/qxsldbgdoc.cpp @@ -0,0 +1,162 @@ +/** + File : qxsldbgdoc.cpp + Author : Keith Isdale + Date : 19th April 2002 + Description : The document to handle source and breakpoints + */ + +#include "qxsldbgdoc.h" +#include <ktexteditor/markinterface.h> +#include <ktexteditor/editorchooser.h> +#include <qfile.h> +#include <qdir.h> +#include <qtextstream.h> +#include <qptrlist.h> + + +QXsldbgDoc::QXsldbgDoc(QWidget *parent, KURL url) + : QObject(0L, "QXsldbgDoc"), kDoc(0L),kView(0L), locked(false) +{ + kDoc = KTextEditor::createDocument("libkatepart", 0L,"KTextEditor::Document"); + connect(kDoc, SIGNAL(started(KIO::Job *)), this, SLOT(lockDoc())); + connect(kDoc, SIGNAL(completed()), this, SLOT(unlockDoc())); + if (kDoc){ + kView = kDoc->createView(parent, "QXsldbgDocView"); + KURL cleanUrl; + // convert paths relative to PWD into a absolute path + QString relUrl = url.prettyURL(); + if (!relUrl.contains(":/")){ + if (!(relUrl.left(1) == "/")) + relUrl.prepend(QDir::currentDirPath() + "/"); + cleanUrl.setFileName(relUrl); + }else{ + cleanUrl = url; + } + kDoc->openURL(cleanUrl); + } +} + + +QXsldbgDoc::~QXsldbgDoc() +{ + if (kDoc){ + if (kDoc->views().count() == 1){ + kDoc->closeURL(false); + delete kDoc; + } + } +} + +void QXsldbgDoc::slotResult( KIO::Job *job ) +{ + if ( job->error() != 0 ){ + }else{ + } + emit docChanged(); +} + +KURL QXsldbgDoc::url() const +{ + if (kDoc) + return kDoc->url(); + else + return KURL(); +} + +void QXsldbgDoc::refresh() +{ + if (kDoc){ + KURL lastUrl = kDoc->url(); + kDoc->closeURL(false); + kDoc->openURL(lastUrl); + } +} + + +void QXsldbgDoc::enableBreakPoint(uint lineNumber, bool state) +{ + if (locked) + return; + + KTextEditor::MarkInterface *markIf = KTextEditor::markInterface(kDoc); + if (markIf){ + if (state){ + markIf->setMark(lineNumber, KTextEditor::MarkInterface::BreakpointActive); + }else{ + markIf->removeMark(lineNumber, KTextEditor::MarkInterface::BreakpointDisabled); + } + } +} + +void QXsldbgDoc::addBreakPoint(uint lineNumber, bool enabled) +{ + if (locked) + return; + + KTextEditor::MarkInterface *markIf = KTextEditor::markInterface(kDoc); + if (markIf){ + if (enabled) + markIf->setMark(lineNumber, KTextEditor::MarkInterface::BreakpointActive); + else + markIf->setMark(lineNumber, KTextEditor::MarkInterface::BreakpointDisabled); + } +} + +void QXsldbgDoc::deleteBreakPoint(uint lineNumber) +{ + if (locked) + return; + + KTextEditor::MarkInterface *markIf = KTextEditor::markInterface(kDoc); + if (markIf) + markIf->clearMark(lineNumber); +} + + +void QXsldbgDoc::clearMarks(bool allMarkTypes) +{ + if (locked) + return; + + KTextEditor::MarkInterface *markIf = KTextEditor::markInterface(kDoc); + if (markIf){ + if (!allMarkTypes){ + QPtrList<KTextEditor::Mark> marks = markIf->marks(); + while ( marks.current()) { + markIf->removeMark(marks.current()->line, KTextEditor::MarkInterface::Execution); + markIf->removeMark(marks.current()->line, KTextEditor::MarkInterface::BreakpointReached); + marks.next(); + } + }else { + markIf->clearMarks(); + } + } + +} + +void QXsldbgDoc::selectBreakPoint(uint lineNumber, bool reachedBreakPoint) +{ + if (locked) + return; + + clearMarks(false); + KTextEditor::MarkInterface *markIf = KTextEditor::markInterface(kDoc); + if (markIf){ + if (reachedBreakPoint){ + //markIf->setMark(lineNumber, KTextEditor::MarkInterface::BreakpointReached); + }else{ + markIf->setMark(lineNumber, KTextEditor::MarkInterface::Execution); + } + } +} + +void QXsldbgDoc::lockDoc() +{ + locked = true; +} + +void QXsldbgDoc::unlockDoc() +{ + locked = false; +} +#include "qxsldbgdoc.moc" diff --git a/kxsldbg/kxsldbgpart/qxsldbgdoc.h b/kxsldbg/kxsldbgpart/qxsldbgdoc.h new file mode 100644 index 00000000..ec126aa6 --- /dev/null +++ b/kxsldbg/kxsldbgpart/qxsldbgdoc.h @@ -0,0 +1,56 @@ +/** + File : qxsldbgdoc.h + Author : Keith Isdale + Date : 19th April 2002 + Description : The document to handle source and breakpoints + */ + + +#ifndef QXSLDBGDOC_H +#define QXSLDBGDOC_H + +#include <kio/job.h> +#include <qptrlist.h> +#include <qstring.h> +#include <qguardedptr.h> +#include <ktexteditor/document.h> +#include <ktexteditor/view.h> + +class QXsldbgDoc : public QObject { + +Q_OBJECT + + public: + QXsldbgDoc(QWidget *parent=0, KURL url=QString::null); + ~QXsldbgDoc(); + + void enableBreakPoint(uint lineNumber, bool state); + void addBreakPoint(uint lineNumber, bool enabled); + void deleteBreakPoint(uint lineNumber); + void selectBreakPoint(uint lineNumberbool, bool reachedBreakPoint); + bool isSelected(uint lineNumberbool); + void clearMarks(bool allMarkTypes); + + KURL url() const; + KTextEditor::Document *kateDoc() {return kDoc;}; + KTextEditor::View *kateView() {return kView;}; + + + bool isLocked() {return locked;}; + void refresh(); + +signals: + void docChanged(); + +private slots: + void slotResult( KIO::Job *job ); + void lockDoc(); + void unlockDoc(); + + private: + QGuardedPtr<KTextEditor::Document> kDoc; + QGuardedPtr<KTextEditor::View> kView; + bool locked; +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgbreakpointlistitem.cpp b/kxsldbg/kxsldbgpart/xsldbgbreakpointlistitem.cpp new file mode 100644 index 00000000..9e0c7130 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgbreakpointlistitem.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** + xsldbgbreakpointlistitem.cpp - description + ------------------- + begin : Sun Jan 6 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 <klocale.h> +#include "xsldbgbreakpointlistitem.h" + +XsldbgBreakpointListItem::XsldbgBreakpointListItem(QListView *parent, + QString fileName, int lineNumber, + QString templateName, QString modeName, + bool enabled, int id) + : XsldbgListItem(parent, 3, fileName, lineNumber) +{ + this->id = id; + setText(0, QString::number(id)); + + this->templateName = templateName; + setText(1, templateName); + + this->modeName = modeName; + setText(2, modeName); + + __enabled = enabled; + if (enabled == true) + setText(5, i18n("Enabled")); + else + setText(5, i18n("Disabled")); +} + +XsldbgBreakpointListItem::~XsldbgBreakpointListItem() +{ +} + diff --git a/kxsldbg/kxsldbgpart/xsldbgbreakpointlistitem.h b/kxsldbg/kxsldbgpart/xsldbgbreakpointlistitem.h new file mode 100644 index 00000000..3c25395e --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgbreakpointlistitem.h @@ -0,0 +1,51 @@ +/*************************************************************************** + xsldbgbreakpointlistitem.h - description + ------------------- + begin : Sun Jan 6 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGBREAKPOINTLISTITEM_H +#define XSLDBGBREAKPOINTLISTITEM_H + +/** + *@author Keith Isdale + */ + +#include "xsldbglistitem.h" + +class XsldbgBreakpointListItem : public XsldbgListItem { +public: + XsldbgBreakpointListItem(QListView *parent, + QString fileName, int lineNumber, + QString templateName, QString modeName, + bool enabled, int id); + ~XsldbgBreakpointListItem(); + + /** returns true if this breakpoint is enabled */ + bool getEnabled() {return __enabled; }; + + /** Returns the name of template for this breakpoiint */ + QString getTemplateName() { return templateName;}; + QString getModeName() {return modeName;}; + + /** Return the breakpoint's id */ + int getId() { return id;}; + +private: + QString templateName, modeName; + bool __enabled; /*make sure the name does not clash with QT */ + int id; +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgbreakpoints.ui b/kxsldbg/kxsldbgpart/xsldbgbreakpoints.ui new file mode 100644 index 00000000..a5af9c36 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgbreakpoints.ui @@ -0,0 +1,582 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>XsldbgBreakpoints</class> +<author>Keith Isdale <k_isdale@tpg.com.au></author> +<widget class="QWidget"> + <property name="name"> + <cstring>XsldbgBreakpoints</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>498</width> + <height>563</height> + </rect> + </property> + <property name="caption"> + <string>Xsldbg Breakpoints</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView"> + <column> + <property name="text"> + <string>ID</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Mode</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>File Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Line Number</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Enabled</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>breakpointListView</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip" stdset="0"> + <string>Click breakpoint in list to modify or delete it</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout6</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>idLabel</cstring> + </property> + <property name="text"> + <string>ID:</string> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>lineNumberLabel</cstring> + </property> + <property name="text"> + <string>Line number:</string> + </property> + </widget> + <widget class="QLineEdit" row="3" column="1"> + <property name="name"> + <cstring>sourceFileEdit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>You don't need to specify directory for file name</string> + </property> + </widget> + <widget class="QLineEdit" row="1" column="1"> + <property name="name"> + <cstring>templateNameEdit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Template name or match name to look for</string> + </property> + </widget> + <widget class="QLayoutWidget" row="4" column="1"> + <property name="name"> + <cstring>Layout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLineEdit"> + <property name="name"> + <cstring>lineNumberEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>60</width> + <height>32767</height> + </size> + </property> + <property name="toolTip" stdset="0"> + <string>Must be positive</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer10_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget" row="0" column="1"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLineEdit"> + <property name="name"> + <cstring>idEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>60</width> + <height>32767</height> + </size> + </property> + <property name="toolTip" stdset="0"> + <string>Must be positive</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer10</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLineEdit" row="2" column="1"> + <property name="name"> + <cstring>modeNameEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>TextLabel1_2</cstring> + </property> + <property name="text"> + <string>Mode:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Name:</string> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>sourceFileLabel</cstring> + </property> + <property name="text"> + <string>File name:</string> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer9</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>81</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer> + <property name="name"> + <cstring>Spacer7</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer8_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout18</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>deleteButton</cstring> + </property> + <property name="text"> + <string>Delete</string> + </property> + <property name="toolTip" stdset="0"> + <string>Delete breakpoint using ID</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>PushButton5</cstring> + </property> + <property name="text"> + <string>Clear</string> + </property> + <property name="toolTip" stdset="0"> + <string>Clear entered text</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="0"> + <property name="name"> + <cstring>addAllButton</cstring> + </property> + <property name="text"> + <string>Add All</string> + </property> + <property name="toolTip" stdset="0"> + <string>Add breakpoint on all templates found</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>deleteAllButton</cstring> + </property> + <property name="text"> + <string>Delete All</string> + </property> + <property name="toolTip" stdset="0"> + <string>Delete all breakpoints</string> + </property> + </widget> + <widget class="QPushButton" row="0" column="2"> + <property name="name"> + <cstring>enableButton</cstring> + </property> + <property name="text"> + <string>Enable</string> + </property> + <property name="toolTip" stdset="0"> + <string>Enable breakpoint using ID</string> + </property> + </widget> + <widget class="QPushButton" row="0" column="0"> + <property name="name"> + <cstring>addButton</cstring> + </property> + <property name="text"> + <string>Add</string> + </property> + <property name="toolTip" stdset="0"> + <string>Add breakpoint using file name with line number or a template name</string> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer8_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>refreshBtn</cstring> + </property> + <property name="text"> + <string>Refresh</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>breakpointListView</sender> + <signal>selectionChanged(QListViewItem*)</signal> + <receiver>XsldbgBreakpoints</receiver> + <slot>selectionChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>addButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgBreakpoints</receiver> + <slot>slotAddBreakpoint()</slot> + </connection> + <connection> + <sender>deleteButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgBreakpoints</receiver> + <slot>slotDeleteBreakpoint()</slot> + </connection> + <connection> + <sender>enableButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgBreakpoints</receiver> + <slot>slotEnableBreakpoint()</slot> + </connection> + <connection> + <sender>refreshBtn</sender> + <signal>clicked()</signal> + <receiver>XsldbgBreakpoints</receiver> + <slot>refresh()</slot> + </connection> + <connection> + <sender>PushButton5</sender> + <signal>clicked()</signal> + <receiver>XsldbgBreakpoints</receiver> + <slot>slotClear()</slot> + </connection> + <connection> + <sender>addAllButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgBreakpoints</receiver> + <slot>slotAddAllTemplateBreakpoints()</slot> + </connection> + <connection> + <sender>deleteAllButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgBreakpoints</receiver> + <slot>slotDeleteAllBreakpoints()</slot> + </connection> +</connections> +<tabstops> + <tabstop>breakpointListView</tabstop> + <tabstop>idEdit</tabstop> + <tabstop>sourceFileEdit</tabstop> + <tabstop>lineNumberEdit</tabstop> + <tabstop>addButton</tabstop> + <tabstop>deleteButton</tabstop> + <tabstop>enableButton</tabstop> +</tabstops> +<slots> + <slot>slotClear()</slot> + <slot>refresh()</slot> + <slot>selectionChanged(QListViewItem*)</slot> + <slot>slotAddBreakpoint()</slot> + <slot>slotDeleteBreakpoint()</slot> + <slot>slotEnableBreakpoint()</slot> + <slot>slotAddAllTemplateBreakpoints()</slot> + <slot>slotDeleteAllBreakpoints()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kxsldbg/kxsldbgpart/xsldbgbreakpointsimpl.cpp b/kxsldbg/kxsldbgpart/xsldbgbreakpointsimpl.cpp new file mode 100644 index 00000000..81e83142 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgbreakpointsimpl.cpp @@ -0,0 +1,202 @@ +/*************************************************************************** + xsldbgbreakpointsimpl.cpp - description + ------------------- + begin : Fri Jan 4 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 <klocale.h> +#include <qlistview.h> +#include <qlineedit.h> +#include <qmessagebox.h> +#include "xsldbgdebugger.h" +#include "xsldbgbreakpointsimpl.h" +#include "xsldbgbreakpointlistitem.h" +#include <kdebug.h> + + +XsldbgBreakpointsImpl::XsldbgBreakpointsImpl(XsldbgDebugger *debugger, + QWidget *parent /*=0*/, const char *name /*=0*/) + : XsldbgBreakpoints(parent, name), XsldbgDialogBase() +{ + this->debugger = debugger; + connect(debugger, SIGNAL(breakpointItem(QString /* file*/, + int /*line number */, QString /*templateName*/, + QString /* modeName*/, + bool /* enabled */, int /* id */)), + this, SLOT(slotProcBreakpointItem(QString /* file*/, + int /*line number */, QString /*templateName*/, + QString /* modeName */, + bool /* enabled */, int /* id */))); + connect( breakpointListView, SIGNAL(selectionChanged(QListViewItem *)), + this, SLOT(selectionChanged(QListViewItem*))); + show(); + refresh(); +} + +XsldbgBreakpointsImpl::~XsldbgBreakpointsImpl() +{ + debugger = 0L; +} + +int XsldbgBreakpointsImpl::getLineNumber() +{ + bool isOk = false; + int lineNo = lineNumberEdit->text().toInt(&isOk); + if (isOk == false){ + lineNo = -1; + kdDebug() << "Invalid line number" << endl; + } + + return lineNo; +} + +int XsldbgBreakpointsImpl::getId() +{ + bool isOk = false; + int id = idEdit->text().toInt(&isOk); + if (isOk == false){ + id = -1; + kdDebug() << "Invalid line number" << endl; + } + + return id; +} + +void XsldbgBreakpointsImpl::slotAddBreakpoint() +{ + int lineNo = getLineNumber(); + if (lineNo != -1) { + if (!sourceFileEdit->text().isEmpty()){ + debugger->slotBreakCmd(sourceFileEdit->text(), lineNo); + }else { + QMessageBox::information(this, i18n("Operation Failed"), + i18n("A line number was provided without a file name."), + QMessageBox::Ok); + } + }else if (!templateNameEdit->text().isEmpty() || + !modeNameEdit->text().isEmpty()){ + debugger->slotBreakCmd(templateNameEdit->text(), + modeNameEdit->text()); + }else{ + QMessageBox::information(this, i18n("Operation Failed"), + i18n("No details provided or an invalid line number was supplied."), + QMessageBox::Ok); + } +} + +void XsldbgBreakpointsImpl::slotAddAllTemplateBreakpoints() +{ + if (debugger != 0L){ + debugger->fakeInput("break *", true); + debugger->fakeInput("show", true); + } +} + +void XsldbgBreakpointsImpl::slotDeleteBreakpoint() +{ + int lineNo = getLineNumber(), id = getId(); + if (id != -1){ + debugger->slotDeleteCmd(id); + }else if (lineNo != -1) { + if (!sourceFileEdit->text().isEmpty()){ + debugger->slotDeleteCmd(sourceFileEdit->text(), lineNo); + }else { + QMessageBox::information(this, i18n("Operation Failed"), + i18n("A line number was provided without a file name."), + QMessageBox::Ok); + } + }else { + QMessageBox::information(this, i18n("Operation Failed"), + i18n("No details provided or an invalid line or ID was supplied."), + QMessageBox::Ok); + } +} + +void XsldbgBreakpointsImpl::slotDeleteAllBreakpoints() +{ + if (debugger != 0L){ + debugger->fakeInput("delete *", true); + debugger->fakeInput("show", true); + } +} + +void XsldbgBreakpointsImpl::slotEnableBreakpoint() +{ + int lineNo = getLineNumber(), id = getId(); + if (id != -1){ + debugger->slotEnableCmd(id); + }else if (lineNo != -1){ + if (!sourceFileEdit->text().isEmpty()){ + debugger->slotEnableCmd(sourceFileEdit->text(), lineNo); + }else { + QMessageBox::information(this, i18n("Operation Failed"), + i18n("A line number was provided without a file name."), + QMessageBox::Ok); + } + }else { + QMessageBox::information(this, i18n("Operation Failed"), + i18n("No details provided."), + QMessageBox::Ok); + } +} + +void XsldbgBreakpointsImpl::selectionChanged(QListViewItem *item) +{ + XsldbgBreakpointListItem *breakItem = + dynamic_cast<XsldbgBreakpointListItem*>(item); + if (breakItem){ + idEdit->setText(QString::number(breakItem->getId())); + templateNameEdit->setText(breakItem->getTemplateName()); + modeNameEdit->setText(breakItem->getModeName()); + sourceFileEdit->setText(breakItem->getFileName()); + lineNumberEdit->setText(QString::number(breakItem->getLineNumber())); } +} + + +void XsldbgBreakpointsImpl::refresh() +{ + /* get xsldbg to tell what breakpoints are set, + we'll get the notification back via slotProcBreakpointItem */ + debugger->fakeInput("showbreak", true); +} + + +void XsldbgBreakpointsImpl::slotClear() +{ + idEdit->setText(""); + templateNameEdit->setText(""); + modeNameEdit->setText(""); + sourceFileEdit->setText(""); + lineNumberEdit->setText(""); +} + +void XsldbgBreakpointsImpl::slotProcBreakpointItem(QString fileName, + int lineNumber , + QString templateName, + QString modeName, + bool enabled, int id ) +{ + if (fileName.isNull()) + breakpointListView->clear(); + else{ + breakpointListView->insertItem( + new XsldbgBreakpointListItem(breakpointListView, + fileName, lineNumber,templateName, modeName, enabled, id)); + } +} + + + + +#include "xsldbgbreakpointsimpl.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbgbreakpointsimpl.h b/kxsldbg/kxsldbgpart/xsldbgbreakpointsimpl.h new file mode 100644 index 00000000..2dad57ca --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgbreakpointsimpl.h @@ -0,0 +1,71 @@ +/*************************************************************************** + xsldbgbreakpointsimpl.h - description + ------------------- + begin : Fri Jan 4 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGBREAKPOINTSIMPL_H +#define XSLDBGBREAKPOINTSIMPL_H + +/** + *@author Keith Isdale + */ + +#include "xsldbgbreakpoints.h" +#include "xsldbgdialogbase.h" + +class XsldbgDebugger; + + +class XsldbgBreakpointsImpl : public XsldbgBreakpoints, public XsldbgDialogBase { + Q_OBJECT + +public: + XsldbgBreakpointsImpl(XsldbgDebugger *debugger, QWidget *parent=0, const char *name=0); + ~XsldbgBreakpointsImpl(); + + /* Return >= 0 if line number entered is valid */ + int getLineNumber(); + + /* Return >= 0 if breakpoint id entered is valid */ + int getId(); + + +public slots: + + void slotAddBreakpoint(); + void slotAddAllTemplateBreakpoints(); + void slotDeleteBreakpoint(); + void slotDeleteAllBreakpoints(); + void slotEnableBreakpoint(); + void selectionChanged(QListViewItem *item); + + /** Recieve notification about breakpoint to add to view, First parameter is QString::null + to indicate start of breakpoint list notfication */ + void slotProcBreakpointItem(QString file, int lineNumber, + QString templateName, QString modeName, + bool enabled, int id ); + + /** refresh data from source */ + void refresh(); + + /**Clear data from all fields */ + void slotClear(); + +private: + XsldbgDebugger *debugger; + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgcallstack.ui b/kxsldbg/kxsldbgpart/xsldbgcallstack.ui new file mode 100644 index 00000000..6203e764 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgcallstack.ui @@ -0,0 +1,157 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>XsldbgCallStack</class> +<author>Keith Isdale <k_isdale@tpg.com.au></author> +<widget class="QWidget"> + <property name="name"> + <cstring>XsldbgCallStack</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>520</width> + <height>391</height> + </rect> + </property> + <property name="caption"> + <string>Xsldbg Callstack</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QListView" row="0" column="0"> + <column> + <property name="text"> + <string>Frame# Template Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Source File Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Line Number</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>callStackListView</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip" stdset="0"> + <string>Oldest Frame # is 0, Frame # has been added to the first column</string> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>refreshBtn</cstring> + </property> + <property name="text"> + <string>Refresh</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>callStackListView</sender> + <signal>selectionChanged(QListViewItem*)</signal> + <receiver>XsldbgCallStack</receiver> + <slot>selectionChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>refreshBtn</sender> + <signal>clicked()</signal> + <receiver>XsldbgCallStack</receiver> + <slot>refresh()</slot> + </connection> +</connections> +<slots> + <slot>refresh()</slot> + <slot>selectionChanged(QListViewItem*)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kxsldbg/kxsldbgpart/xsldbgcallstackimpl.cpp b/kxsldbg/kxsldbgpart/xsldbgcallstackimpl.cpp new file mode 100644 index 00000000..5592e4e6 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgcallstackimpl.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + xsldbgcallstackimpl.cpp - description + ------------------- + begin : Wed Jan 16 2002 + copyright : (C) 2002 by Keith lsdale + 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 <qlistview.h> +#include <qlineedit.h> + +#include "xsldbgdebugger.h" +#include "xsldbgcallstackimpl.h" +#include "xsldbggloballistitem.h" /* reuse global list item variable as a template list item */ + +XsldbgCallStackImpl::XsldbgCallStackImpl(XsldbgDebugger *debugger, + QWidget *parent /*=0*/, const char *name /*=0*/) + : XsldbgCallStack(parent, name), XsldbgDialogBase() +{ + this->debugger = debugger; + + connect(debugger, SIGNAL(callStackItem(QString /* templateName*/, QString /* fileName */, int /* lineNumber */)), + this, SLOT(slotProcCallStackItem(QString /* templateName*/, QString /* fileName */, int /* lineNumber */))); + connect( callStackListView, SIGNAL(selectionChanged(QListViewItem *)), + this, SLOT(selectionChanged(QListViewItem*))); + + show(); + refresh(); +} + +XsldbgCallStackImpl::~XsldbgCallStackImpl(){ + debugger = 0L; +} + +void XsldbgCallStackImpl::slotProcCallStackItem(QString templateName, QString fileName , int lineNumber ) +{ + static int frameNo =0; + if (templateName.isNull()){ + callStackListView->clear(); + frameNo = 0; + }else{ + /* each stack entry will have a FRAME# prefix */ + callStackListView->insertItem(new XsldbgGlobalListItem(callStackListView, + fileName, lineNumber, templateName.prepend(QString::number(frameNo++)+ "# "))); + } +} + + +void XsldbgCallStackImpl::selectionChanged(QListViewItem *item) +{ + XsldbgGlobalListItem *callStackItem = dynamic_cast<XsldbgGlobalListItem*>(item); + if (callStackItem){ + debugger->gotoLine(callStackItem->getFileName(), callStackItem->getLineNumber()); + } +} + +void XsldbgCallStackImpl::refresh() +{ + debugger->fakeInput("where", true) ; +} + + +#include "xsldbgcallstackimpl.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbgcallstackimpl.h b/kxsldbg/kxsldbgpart/xsldbgcallstackimpl.h new file mode 100644 index 00000000..61200fe8 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgcallstackimpl.h @@ -0,0 +1,53 @@ +/*************************************************************************** + xsldbgcallstackimpl.h - description + ------------------- + begin : Wed Jan 16 2002 + copyright : (C) 2002 by Keith lsdale + 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 XSLDBGCALLSTACKIMPL_H +#define XSLDBGCALLSTACKIMPL_H + +/** + *@author Keith lsdale + */ + +#include "xsldbgcallstack.h" +#include "xsldbgdialogbase.h" + +class XsldbgDebugger; + +class XsldbgCallStackImpl : public XsldbgCallStack, public XsldbgDialogBase { + Q_OBJECT + +public: + XsldbgCallStackImpl(XsldbgDebugger *debugger, QWidget *parent=0, const char *name=0); + ~XsldbgCallStackImpl(); + +public slots: + void selectionChanged(QListViewItem *item); + + /** Process request to add callstack to view, First parameter is QString::null + to indicate start of callstack list notfication */ + void slotProcCallStackItem(QString templateName, QString fileName , int lineNumber ); + + /** refresh data from source */ + void refresh(); + + +private: + XsldbgDebugger *debugger; + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgconfig.ui b/kxsldbg/kxsldbgpart/xsldbgconfig.ui new file mode 100644 index 00000000..660d9890 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgconfig.ui @@ -0,0 +1,817 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>XsldbgConfig</class> +<author>Keith Isdale <k_isdale@tpg.com.au></author> +<widget class="QWidget"> + <property name="name"> + <cstring>XsldbgConfig</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>501</width> + <height>542</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>450</height> + </size> + </property> + <property name="caption"> + <string>KXsldbg Configuration</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="3" column="0"> + <property name="name"> + <cstring>Spacer12</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="QGroupBox" row="4" column="0"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>LibXSLT Parameters</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout12</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>Layout10_2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>paramValueLabel</cstring> + </property> + <property name="text"> + <string>Parameter value:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>parameterValueEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxLength"> + <number>100</number> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>Layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>paramNameLabel</cstring> + </property> + <property name="text"> + <string>Parameter name:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>parameterNameEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxLength"> + <number>100</number> + </property> + </widget> + </hbox> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout12</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton" row="1" column="0"> + <property name="name"> + <cstring>prevButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Prev</string> + </property> + </widget> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>deleteButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Delete</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>nextButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Next</string> + </property> + </widget> + <widget class="QPushButton" row="0" column="0"> + <property name="name"> + <cstring>addButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Add</string> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> + </widget> + <spacer row="5" column="0"> + <property name="name"> + <cstring>Spacer61</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget" row="6" column="0"> + <property name="name"> + <cstring>Layout18</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer23</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton13</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>110</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>&Apply</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton14</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>110</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer24</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>Spacer12_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>Layout11</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget" row="4" column="0"> + <property name="name"> + <cstring>Layout8</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>outputFileLabel</cstring> + </property> + <property name="text"> + <string>Output file:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>outputFileEdit</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>outputFileButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="2" column="0"> + <property name="name"> + <cstring>Layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>xmlSourceLabel</cstring> + </property> + <property name="text"> + <string>XML data:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>xmlDataEdit</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>xmlDataButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>Layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>xslSourceLabel</cstring> + </property> + <property name="text"> + <string>XSL source:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>xslSourceEdit</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>xslSourceButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </hbox> + </widget> + </grid> + </widget> + <widget class="QButtonGroup" row="2" column="0"> + <property name="name"> + <cstring>ButtonGroup1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Options</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>catalogsChkBox</cstring> + </property> + <property name="text"> + <string>catalogs</string> + </property> + <property name="toolTip" stdset="0"> + <string>use catalogs from $SGML_CATALOGS_FILES</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="2"> + <property name="name"> + <cstring>novalidChkBox</cstring> + </property> + <property name="text"> + <string>novalid</string> + </property> + <property name="toolTip" stdset="0"> + <string>skip the DTD loading phase</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="1"> + <property name="name"> + <cstring>htmlChkBox</cstring> + </property> + <property name="text"> + <string>html</string> + </property> + <property name="toolTip" stdset="0"> + <string>the input document is(are) an HTML file(s)</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="2"> + <property name="name"> + <cstring>docbookChkBox</cstring> + </property> + <property name="text"> + <string>docbook</string> + </property> + <property name="toolTip" stdset="0"> + <string>the input document is SGML docbook</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>debugChkBox</cstring> + </property> + <property name="text"> + <string>debug</string> + </property> + <property name="toolTip" stdset="0"> + <string>dump the tree of the result instead</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>nooutChkBox</cstring> + </property> + <property name="text"> + <string>noout</string> + </property> + <property name="toolTip" stdset="0"> + <string>do not dump the result</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="1"> + <property name="name"> + <cstring>profileChkBox</cstring> + </property> + <property name="text"> + <string>profile</string> + </property> + <property name="toolTip" stdset="0"> + <string>print profiling information</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="2"> + <property name="name"> + <cstring>timingChkBox</cstring> + </property> + <property name="text"> + <string>timing</string> + </property> + <property name="toolTip" stdset="0"> + <string>display the time used</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="1"> + <property name="name"> + <cstring>nonetChkBox</cstring> + </property> + <property name="text"> + <string>nonet</string> + </property> + <property name="toolTip" stdset="0"> + <string>refuse to fetch DTDs or entities over network</string> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>xslSourceButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgConfig</receiver> + <slot>slotChooseSourceFile()</slot> + </connection> + <connection> + <sender>xmlDataButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgConfig</receiver> + <slot>slotChooseDataFile()</slot> + </connection> + <connection> + <sender>outputFileButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgConfig</receiver> + <slot>slotChooseOutputFile()</slot> + </connection> + <connection> + <sender>addButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgConfig</receiver> + <slot>slotAddParam()</slot> + </connection> + <connection> + <sender>deleteButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgConfig</receiver> + <slot>slotDeleteParam()</slot> + </connection> + <connection> + <sender>nextButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgConfig</receiver> + <slot>slotNextParam()</slot> + </connection> + <connection> + <sender>prevButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgConfig</receiver> + <slot>slotPrevParam()</slot> + </connection> + <connection> + <sender>PushButton13</sender> + <signal>clicked()</signal> + <receiver>XsldbgConfig</receiver> + <slot>slotApply()</slot> + </connection> + <connection> + <sender>PushButton14</sender> + <signal>clicked()</signal> + <receiver>XsldbgConfig</receiver> + <slot>slotCancel()</slot> + </connection> +</connections> +<tabstops> + <tabstop>parameterNameEdit</tabstop> + <tabstop>parameterValueEdit</tabstop> + <tabstop>addButton</tabstop> + <tabstop>deleteButton</tabstop> + <tabstop>prevButton</tabstop> + <tabstop>nextButton</tabstop> + <tabstop>PushButton13</tabstop> + <tabstop>PushButton14</tabstop> + <tabstop>xslSourceButton</tabstop> + <tabstop>xmlDataButton</tabstop> + <tabstop>outputFileButton</tabstop> + <tabstop>catalogsChkBox</tabstop> + <tabstop>debugChkBox</tabstop> + <tabstop>nooutChkBox</tabstop> + <tabstop>htmlChkBox</tabstop> + <tabstop>nonetChkBox</tabstop> + <tabstop>profileChkBox</tabstop> + <tabstop>docbookChkBox</tabstop> + <tabstop>novalidChkBox</tabstop> + <tabstop>timingChkBox</tabstop> + <tabstop>outputFileEdit</tabstop> + <tabstop>xmlDataEdit</tabstop> + <tabstop>xslSourceEdit</tabstop> +</tabstops> +<slots> + <slot>slotCancel()</slot> + <slot>slotAddParam()</slot> + <slot>slotApply()</slot> + <slot>slotChooseDataFile()</slot> + <slot>slotChooseOutputFile()</slot> + <slot>slotChooseSourceFile()</slot> + <slot>slotDatafile(QString)</slot> + <slot>slotDeleteParam()</slot> + <slot>slotNextParam()</slot> + <slot>slotPrevParam()</slot> + <slot>slotSourcefile(QString)</slot> + <slot>slotoutputfile(QString)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kxsldbg/kxsldbgpart/xsldbgconfigimpl.cpp b/kxsldbg/kxsldbgpart/xsldbgconfigimpl.cpp new file mode 100644 index 00000000..dd62b1ec --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgconfigimpl.cpp @@ -0,0 +1,499 @@ +/*************************************************************************** + xsldbgconfigimpl.cpp - description + ------------------- + begin : Fri Jan 4 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 <klocale.h> +#include <kfiledialog.h> + +#include <qdialog.h> +#include <qlineedit.h> +#include <qcheckbox.h> +#include <qmessagebox.h> + +#include "xsldbgconfigimpl.h" +#include "xsldbgdebugger.h" +#include <kdebug.h> + +LibxsltParam::LibxsltParam(const QString &name, const QString &value) + : QObject(0L, 0L) +{ + _name = name; + _value = value; +} + + +LibxsltParam::~LibxsltParam() +{ +} + + +QString LibxsltParam::getName() const +{ + return _name; +} + +void LibxsltParam::setName(const QString &name) +{ + _name = name; +} + + +QString LibxsltParam::getValue() const +{ + return _value; +} + + +void LibxsltParam::setValue(const QString & value) +{ + _value = value; +} + + +bool LibxsltParam::isValid() const +{ + bool result = true; + if ((_name.length() > 0) && ( _value.length() == 0)) + result = false; + + return result; +} + + +XsldbgConfigImpl::XsldbgConfigImpl(XsldbgDebugger *debugger, + QWidget *parent /*=0*/, const char *name /*=0*/) + : XsldbgConfig(parent, name) +{ + this->debugger = debugger; + connect(debugger, SIGNAL(parameterItem(QString /* name*/, QString /* value */)), + this, SLOT(slotProcParameterItem(QString /* name*/, QString /* value */))); + connect(debugger, SIGNAL(fileDetailsChanged()), + this, SLOT(slotReloadFileNames())); + paramIndex= 0; + catalogs = false; + debug = false; + html = false; + nonet = false; + docbook = false; +} + +XsldbgConfigImpl::~XsldbgConfigImpl() +{ + debugger = 0L; +} + + +QString XsldbgConfigImpl::getSourceFile() +{ + if (xslSourceEdit != 0L) + return xslSourceEdit->text(); + else + return QString(); +} + + +QString XsldbgConfigImpl::getDataFile() +{ + if (xmlDataEdit != 0L) + return xmlDataEdit->text(); + else + return QString(); +} + + +QString XsldbgConfigImpl::getOutputFile() +{ + if (outputFileEdit != 0L) + return outputFileEdit->text(); + else + return QString(); +} + + +LibxsltParam *XsldbgConfigImpl::getParam(int paramNumber) +{ + return paramList.at(paramNumber); +} + +LibxsltParam *XsldbgConfigImpl::getParam(QString name) +{ + LibxsltParam *param = 0L; + for (param = paramList.first(); param != 0L; param = paramList.next()) + { + if (param->getName() == name) + break; + } + + return param; +} + + +int XsldbgConfigImpl::getParamCount() +{ + return paramList.count(); +} + + +void XsldbgConfigImpl::addParam(QString name, QString value) +{ + LibxsltParam *param; + if ((name.length() == 0) || (value.length() == 0)) + return; + + param = getParam(name); + if (param == 0L) + { + param = new LibxsltParam(name, value); + if (param != 0L) + paramList.append(param); + + }else + param->setValue(value); +} + + +void XsldbgConfigImpl::deleteParam(QString name) +{ + bool isOk = false; + LibxsltParam *param; + if (name.length() == 0) + return; + + param = getParam(name); + if (param != 0L) + isOk = paramList.remove(param); + + if (isOk == false) + kdDebug() << QString(" Param %1 dosn't exist").arg(name) << endl; + else + kdDebug() << "Deleted param " << name << endl; +} + + +bool XsldbgConfigImpl::isValid(QString &errorMsg) +{ + bool isOK = true; + errorMsg = ""; + if (xslSourceEdit->text().isEmpty()) + errorMsg.append( i18n("\t\"XSL source\" \n")); + if (xmlDataEdit->text().isEmpty()) + errorMsg.append(i18n("\t\"XML data\" \n")); + if (outputFileEdit->text().isEmpty()) + errorMsg.append(i18n("\t\"Output file\" \n")); + if (!errorMsg.isEmpty()){ + errorMsg.prepend(i18n("Missing values for \n")); + isOK = false; + }else if (( xslSourceEdit->text() == outputFileEdit->text()) || + (xmlDataEdit->text() == outputFileEdit->text())){ + errorMsg.append(i18n("Output file is the same as either XSL Source or " + "XML Data file\n")); + isOK = false; + } + + // make it a warning when parameters are invalid + LibxsltParam *param; + QString emptyParams = ""; + for (param = paramList.first(); param != 0L; param = paramList.next()) + { + if (!param->isValid()){ + if (emptyParams.isEmpty()) + emptyParams = param->getName(); + else + emptyParams.append(", "). append(param->getName()); + } + } + + if (!emptyParams.isEmpty()){ + errorMsg.append(i18n("The following libxslt parameters are empty\n\t")); + errorMsg.append(emptyParams); + } + + return isOK; +} + + +/*we previously said that isValid() == true so we must commit our changes */ +void XsldbgConfigImpl::update() +{ + QString msg; + if (debugger == 0L) + return; + + /* update source, data, output file name if needed */ + slotSourceFile(xslSourceEdit->text()); + slotDataFile(xmlDataEdit->text()); + slotOutputFile(outputFileEdit->text()); + + /* ensure entered param are updated */ + slotAddParam(); + + if (debugger->start() == false) + return ; /* User has killed xsldbg and we can't restart it */ + + /* always update the libxslt parameters */ + debugger->fakeInput("delparam", true); + + + + LibxsltParam *param; + for (param = paramList.first(); param != 0L; param = paramList.next()) + { + if (debugger->start() == false) + return ; /* User has killed xsldbg and we can't restart it */ + if (param->isValid()){ + msg = "addparam "; + msg.append(param->getName()).append(" ").append(param->getValue()); + debugger->fakeInput(msg, true); + } + } + + /* now set the xsldbg options*/ + if (catalogsChkBox->isChecked() != catalogs){ + catalogs = catalogsChkBox->isChecked(); + debugger->setOption("catalogs", catalogs); + } + if (debugChkBox->isChecked() != debug){ + debug= debugChkBox->isChecked(); + debugger->setOption("debug", debug); + } + if (htmlChkBox->isChecked() != html){ + html = htmlChkBox->isChecked(); + debugger->setOption("html", html); + } + if (docbookChkBox->isChecked() != docbook){ + docbook = docbookChkBox->isChecked(); + debugger->setOption("docbook", docbook); + } + if (nonetChkBox->isChecked() != nonet){ + nonet = nonetChkBox->isChecked(); + debugger->setOption("nonet", nonet); + } + if (novalidChkBox->isChecked() != novalid){ + novalid = novalidChkBox->isChecked(); + debugger->setOption("novalid", novalid); + } + if (nooutChkBox->isChecked() != noout){ + noout = nooutChkBox->isChecked(); + debugger->setOption("noout", noout); + } + if (timingChkBox->isChecked() != timing){ + timing = timingChkBox->isChecked(); + debugger->setOption("timing", timing); + } + if (profileChkBox->isChecked() != profile){ + profile = profileChkBox->isChecked(); + debugger->setOption("profile", profile); + } + + debugger->setOption("preferhtml", true); + debugger->setOption("utf8input", true); + debugger->slotRunCmd(); + hide(); +} + + +void XsldbgConfigImpl::refresh() +{ + paramIndex = 0; + repaintParam(); + xslSourceEdit->setText(debugger->sourceFileName()); + xmlDataEdit->setText(debugger->dataFileName()); + outputFileEdit->setText(debugger->outputFileName()); + /* + if (debugger->start() == false) + return ; + + qDebug("XsldbgConfigImpl::refresh"); + */ + /* we'll get the list of parameters via paramItem(..) in this class */ + /* debugger->fakeInput("showparam", true); + */ + +} + + +void XsldbgConfigImpl::slotSourceFile(QString xslFile) +{ + if (debugger->start() == false) + return ; /* User has killed xsldbg and we can't restart it */ + + if (debugger->sourceFileName() == xslFile) + return; + + QString msg("source "); + msg.append(XsldbgDebugger::fixLocalPaths(xslFile)); + debugger->fakeInput(msg, true); +} + +void XsldbgConfigImpl::slotDataFile(QString xmlFile) +{ + if (debugger->start() == false) + return ; /* User has killed xsldbg and we can't restart it */ + + if (debugger->dataFileName() == xmlFile) + return; + + QString msg("data "); + msg.append(XsldbgDebugger::fixLocalPaths(xmlFile)); + debugger->fakeInput(msg, true); +} + +void XsldbgConfigImpl::slotOutputFile(QString outputFile) +{ + if (debugger->start() == false) + return ; /* User has killed xsldbg and we can't restart it */ + + if (debugger->outputFileName() == outputFile) + return; + + QString msg("output "); + msg.append(XsldbgDebugger::fixLocalPaths(outputFile)); + debugger->fakeInput(msg, true); +} + +void XsldbgConfigImpl::slotChooseSourceFile() +{ + KURL url = KFileDialog::getOpenURL(QString::null, "*.xsl; *.XSL; *.Xsl ; *.xslt; *.XSLT; *.Xslt \n *.*", this, + i18n("Choose XSL Source to Debug")); + QString fileName = url.prettyURL(); + + if ((!fileName.isNull()) && (fileName.length() > 0)){ + xslSourceEdit->setText(XsldbgDebugger::fixLocalPaths(fileName)); + } +} + + +void XsldbgConfigImpl::slotChooseDataFile() +{ + KURL url = KFileDialog::getOpenURL(QString::null, "*.xml; *.XML; *.Xml \n*.docbook \n *.html;*.HTML; *.htm ; *HTM \n *.*", this, + i18n("Choose XML Data to Debug")); + QString fileName = url.prettyURL(); + + if ((!fileName.isNull()) && (fileName.length() > 0)) + xmlDataEdit->setText(XsldbgDebugger::fixLocalPaths(fileName)); +} + + +void XsldbgConfigImpl::slotChooseOutputFile() +{ + KURL url = KFileDialog::getSaveURL(QString::null, "*.xml; *.XML; *.Xml \n*.docbook \n *.txt; *.TXT \n *.htm;*.HTM;*.htm;*.HTML \n*.*", this, + i18n("Choose Output File for XSL Transformation")); + QString fileName; + + if (url.isLocalFile()){ + fileName = url.prettyURL(); + if ((!fileName.isNull()) && (fileName.length() > 0)) + outputFileEdit->setText(XsldbgDebugger::fixLocalPaths(fileName)); + } +} + +void XsldbgConfigImpl::slotReloadFileNames() +{ + if (debugger != 0){ + xslSourceEdit->setText(debugger->sourceFileName()); + xmlDataEdit->setText(debugger->dataFileName()); + outputFileEdit->setText(debugger->outputFileName()); + } +} + + +void XsldbgConfigImpl::repaintParam() +{ + if (paramIndex < getParamCount()){ + LibxsltParam *param = getParam(paramIndex); + parameterNameEdit->setText(param->getName()); + parameterValueEdit->setText(param->getValue()); + }else{ + parameterNameEdit->setText(""); + parameterValueEdit->setText(""); + } +} + +void XsldbgConfigImpl::slotAddParam() +{ + addParam(parameterNameEdit->text(), parameterValueEdit->text()); + if (paramIndex < getParamCount()) + paramIndex++; + + repaintParam(); +} + +void XsldbgConfigImpl::slotDeleteParam() +{ + deleteParam(parameterNameEdit->text()); + repaintParam(); +} + + +void XsldbgConfigImpl::slotNextParam() +{ + addParam(parameterNameEdit->text(), parameterValueEdit->text()); + if (paramIndex < getParamCount()) + paramIndex++; + + repaintParam(); +} + +void XsldbgConfigImpl::slotPrevParam() +{ + addParam(parameterNameEdit->text(), parameterValueEdit->text()); + if (paramIndex > 0) + paramIndex--; + + repaintParam(); +} + +void XsldbgConfigImpl::slotProcParameterItem(QString name, QString value) +{ + if (name.isNull()){ + paramList.clear(); + paramIndex = 0; + parameterNameEdit->setText(""); + parameterValueEdit->setText(""); + }else{ + addParam(name, value); + if(paramList.count() == 1){ + parameterNameEdit->setText(name); + parameterValueEdit->setText(value); + } + } +} + + + +void XsldbgConfigImpl::slotApply() +{ + + // Validate the users choices before applying it + QString msg; + if (isValid(msg)){ + if (!msg.isEmpty()) + QMessageBox::information(this, i18n("Suspect Configuration"), + msg, QMessageBox::Ok); + update(); + }else{ + QMessageBox::information(this, i18n("Incomplete or Invalid Configuration"), + msg, QMessageBox::Ok); + } +} + + +void XsldbgConfigImpl::slotCancel() +{ + hide(); +} + +#include "xsldbgconfigimpl.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbgconfigimpl.h b/kxsldbg/kxsldbgpart/xsldbgconfigimpl.h new file mode 100644 index 00000000..ad207d7a --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgconfigimpl.h @@ -0,0 +1,151 @@ +/*************************************************************************** + xsldbgconfigimpl.h - description + ------------------- + begin : Fri Jan 4 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGCONFIGIMPL_H +#define XSLDBGCONFIGIMPL_H + +/** + *@author Keith Isdale + */ + +#include "xsldbgconfig.h" +#include "xsldbgdialogbase.h" + +#include <qptrlist.h> + + +class LibxsltParam : public QObject +{ + public: + LibxsltParam(const QString & name, const QString &value); + ~LibxsltParam(); + + QString getName() const; + void setName(const QString &name); + QString getValue() const; + void setValue(const QString &value); + bool isValid() const; + +private: + QString _name; + QString _value; +}; + + +class XsldbgDebugger; + +class XsldbgConfigImpl : public XsldbgConfig, public XsldbgDialogBase { + Q_OBJECT + +public: + XsldbgConfigImpl(XsldbgDebugger *debugger, QWidget *parent=0, const char *name=0); + ~XsldbgConfigImpl(); + + LibxsltParam *getParam(int paramNumber); + LibxsltParam *getParam(QString name); + int getParamCount(); + void addParam(QString name, QString value); + void deleteParam(QString name); + void repaintParam(); + + QString getSourceFile(); + QString getDataFile(); + QString getOutputFile(); + bool debugEnabled() const {return debug; }; + bool catalogsEnabled() const {return catalogs; }; + bool htmlEnabled() const {return html; }; + bool docbookEnabled() const {return docbook; }; + bool nonetEnabled() const {return nonet; }; + bool novalidEnabled() const {return novalid; }; + bool nooutEnabled() const {return noout; }; + bool timingEnabled() const {return timing; }; + bool profileEnabled() const {return profile; }; + + + /** return true if all data ok */ + bool isValid(QString &errorMsg); + + /** Update changes to xsldbg*/ + void update(); + + /** refresh data from source */ + void refresh(); + + +public slots: + + /** Set xsl source file*/ + void slotSourceFile(QString); + + /** Set xml data file*/ + void slotDataFile(QString); + + /** Set file name for the default output of transformed data*/ + void slotOutputFile(QString); + + /**Choose the XSL source file */ + void slotChooseSourceFile(); + + /**Choose the XML data file */ + void slotChooseDataFile(); + + + /**Choose the output file */ + void slotChooseOutputFile(); + + /* Update the gui with the new values for source, data and output files */ + void slotReloadFileNames(); + + /** Configure dialog has request that a param be added */ + void slotAddParam(); + + /** Configure dialog has request that a param be deleted */ + void slotDeleteParam(); + + /** Configure dialog has request that a next param be shown */ + void slotNextParam(); + + /** Configure dialog has request that a prev param be shown */ + void slotPrevParam(); + + /** Apply the changes */ + void slotApply(); + + /** Ignore any changes and hide dialog */ + void slotCancel(); + + /** Process notification of add parameter to view, First parameter + is QString::null to indicate start of parameter list notfication */ + void slotProcParameterItem(QString name, QString value); + + +private: + int paramIndex; + QPtrList<LibxsltParam> paramList; + + XsldbgDebugger *debugger; + + bool catalogs; + bool debug; + bool html; + bool docbook; + bool nonet; + bool novalid; + bool noout; + bool timing; + bool profile; +}; +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgdebugger.cpp b/kxsldbg/kxsldbgpart/xsldbgdebugger.cpp new file mode 100644 index 00000000..69fcaeec --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgdebugger.cpp @@ -0,0 +1,474 @@ +/*************************************************************************** + xsldbgdebugger.cpp - description + ------------------- + begin : Tue Jan 1 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 <klocale.h> +#include <kurl.h> + +#include <libxml/tree.h> +#include <libxslt/xsltInternals.h> +#include "xsldbgdebugger.h" + +#include <libxsldbg/xsldbgthread.h> +#include <libxsldbg/xsldbgevent.h> +#include <libxsldbg/qtnotifier2.h> +#include <libxsldbg/options.h> +#include <libxsldbg/files.h> + +extern int xsldbgStop; + +#include "xsldbgwalkspeedimpl.h" +#include <qmessagebox.h> +#include <kdebug.h> + +XsldbgDebugger::XsldbgDebugger() +{ + initialized = false; + inspector = 0L; + walkDialog = 0L; + outputFileActive = false; + + updateText = ""; + lastType = XSLDBG_MSG_AWAITING_INPUT; + readMsg = false; + procMsg = false; + /* set a slow occurance of timer events to check for xsldbg commands from user */ + updateTimerID = startTimer(100); + + connectNotifier(this); +} + + +XsldbgDebugger::~XsldbgDebugger(){ + if (initialized == true) + xsldbgThreadFree(); + + if (walkDialog != 0L) + walkDialog->close(true); + +} + + +void XsldbgDebugger::setInspector(XsldbgInspector *inspector) +{ + this->inspector = inspector; +} + +bool XsldbgDebugger::event(QEvent *e) +{ + if (e == 0L) + return false; + + if (e->type() != QEvent::User) + return QObject::event(e); + else{ + static bool waitingFirstmessage = true; + if (waitingFirstmessage){ + waitingFirstmessage = false; + emit debuggerReady(); + } + + /* we now have a notify message from xsldbg */ + XsldbgEvent *event = dynamic_cast<XsldbgEvent*>(e); + /* send to this debugger the messages in event */ + event->emitMessage(this); + } + return true; + +} + + +void XsldbgDebugger::timerEvent(QTimerEvent *e) +{ + /* This function runs in the application's thread */ + + if (e == 0L || (e->timerId() != updateTimerID)) + return; + + if ((getInputReady() == 0) && (getInputStatus() == XSLDBG_MSG_AWAITING_INPUT) && + (commandQue.count() > 0)){ + QString msg = commandQue.first(); + commandQue.remove(msg); + ::fakeInput((const char*)msg.utf8()); + } + + if ((!updateText.isEmpty()) && (getInputStatus() == XSLDBG_MSG_AWAITING_INPUT)){ + /* flush remainding text to message window */ + QString msgCopy = updateText; + updateText = ""; + emit showMessage(msgCopy); + lastType = XSLDBG_MSG_AWAITING_INPUT; + } + +} + + +QString XsldbgDebugger::fixLocalPaths(QString & file) +{ + QString result = file; + + if (file.left(6) == "file:/"){ + xmlChar * tempResult = filesExpandName((xmlChar *)file.utf8().data()); + result = QString::fromUtf8((char*)tempResult); + xmlFree(tempResult); + } + + return result; +} + + +QString XsldbgDebugger::sourceFileName() +{ + QString fileName; + + if (optionsGetStringOption(OPTIONS_SOURCE_FILE_NAME) != 0L) + fileName = QString::fromUtf8((const char*)optionsGetStringOption(OPTIONS_SOURCE_FILE_NAME)); + + return fileName; +} + +QString XsldbgDebugger::dataFileName() +{ + QString fileName; + + if (optionsGetStringOption(OPTIONS_DATA_FILE_NAME) != 0L) + fileName = QString::fromUtf8((const char*)optionsGetStringOption(OPTIONS_DATA_FILE_NAME)); + + return fileName; +} + +QString XsldbgDebugger::outputFileName() +{ + QString fileName; + + if (optionsGetStringOption(OPTIONS_OUTPUT_FILE_NAME) != 0L) + fileName = QString::fromUtf8((const char*)optionsGetStringOption(OPTIONS_OUTPUT_FILE_NAME)); + + return fileName; +} + +void XsldbgDebugger::gotoLine(QString fileName, int lineNo, bool breakpoint /*= false*/) +{ + emit lineNoChanged(fileName, lineNo, breakpoint); +} + + +void XsldbgDebugger::setOption(const char* name, bool value) +{ + QString msg = "setoption "; + msg.append(name).append(" ").append(QString::number(value)); + fakeInput(msg, true); +} + +void XsldbgDebugger::fakeInput(QString text, bool wait) +{ + Q_UNUSED(wait); + commandQue.append(text); +} + + +bool XsldbgDebugger::start() +{ + bool result = false; + if ((initialized == false) && !xsldbgThreadInit()) + { + xsldbgThreadFree(); + kdDebug() << "Init of thread failed" << endl; + } + else + { + initialized = true; + result = true; + } + return result; +} + +bool XsldbgDebugger::stop() +{ + if (initialized == true){ + setThreadStatus(XSLDBG_MSG_THREAD_STOP); + } + + /* it always succeeds at the moment */ + return true; +} + +void XsldbgDebugger::slotConfigure() +{ + if (start() == false) + return; + + if(inspector == 0L ){ + inspector = new XsldbgInspector(this); + connect(inspector, SIGNAL(closedWindow()), this, SLOT(slotConfigClosed())); + } +} + + +void XsldbgDebugger::slotConfigClosed() +{ + inspector = 0L; +} + +void XsldbgDebugger::slotStepCmd() +{ + if (start()) + fakeInput("step", true); + if (inspector != 0L) + inspector->refreshVariables(); +} + +void XsldbgDebugger::slotContinueCmd() +{ + if (start()) + /*this can take a while so don't wait for xsldbg to finish */ + fakeInput("continue", false); + if (inspector != 0L) + inspector->refreshVariables(); + +} + +void XsldbgDebugger::slotRunCmd() +{ + if (start()) + /*this can take a while so don't wait for xsldbg to finish */ + fakeInput("run", false); + + if (inspector != 0L) + inspector->refresh(); +} + + +void XsldbgDebugger::slotWalkSpeed(int speed) +{ + if ((speed >= 0) && (speed <= 9)){ + if (start()){ + if (optionsGetIntOption(OPTIONS_WALK_SPEED) == WALKSPEED_STOP){ + // start walking at speed requested + QString msg("walk "); + msg.append(QString::number(speed)); + fakeInput(msg, true); + } else + // This will take effect imediately + optionsSetIntOption(OPTIONS_WALK_SPEED, speed); + } + }else + kdDebug() << "Invalid walk speed " << speed << endl; +} + +void XsldbgDebugger::slotWalkCmd() +{ + if (walkDialog == 0L ) + walkDialog = new XsldbgWalkSpeedImpl (this); + + if (walkDialog != 0L) + /* if the user changes the speed the dialog will call back slotWalkSpeed(int) */ + walkDialog->show(); +} + +void XsldbgDebugger::slotWalkStopCmd() +{ + xsldbgStop = 1; +} + +void XsldbgDebugger::slotTraceCmd() +{ + if (start()) + /*this can take a while so don't wait for xsldbg to finish */ + fakeInput("trace", false); +} + +void XsldbgDebugger::slotBreakCmd(QString fileName, int lineNumber) +{ + if (outputFileActive == true){ + QMessageBox::information(0L, i18n("Operation Failed"), + i18n("Cannot set/edit breakpoints on the output file."), + QMessageBox::Ok); + return ; + } + + QString msg("break -l \""); + msg.append(XsldbgDebugger::fixLocalPaths(fileName)).append("\" ").append(QString::number(lineNumber)); + + if (start()) + fakeInput(msg, true); + + if (inspector != 0L) + inspector->refreshBreakpoints(); +} + +void XsldbgDebugger::slotBreakCmd(QString templateName, QString modeName) +{ + + if (outputFileActive == true){ + QMessageBox::information(0L, i18n("Operation Failed"), + i18n("Cannot set/edit breakpoints on the output file."), + QMessageBox::Ok); + return ; + } + QString msg("break \""); + msg.append(templateName).append("\" \"").append(modeName).append("\""); + if (start()) + fakeInput(msg, true); + + if (inspector != 0L) + inspector->refreshBreakpoints(); +} + +void XsldbgDebugger::slotEnableCmd(QString fileName, int lineNumber) +{ + + if (outputFileActive == true){ + QMessageBox::information(0L, i18n("Operation Failed"), + i18n("Cannot set/edit breakpoints on the output file."), + QMessageBox::Ok); + return ; + } + + QString msg("enable -l \""); + msg.append(XsldbgDebugger::fixLocalPaths(fileName)).append("\" ").append(QString::number(lineNumber)); + if (start()) + fakeInput(msg, true); + + if (inspector != 0L) + inspector->refreshBreakpoints(); +} + + +void XsldbgDebugger::slotEnableCmd(int id) +{ + + if (outputFileActive == true){ + QMessageBox::information(0L, i18n("Operation Failed"), + i18n("Cannot set/edit breakpoints on the output file."), + QMessageBox::Ok); + return ; + } + + QString msg("enable "); + msg.append(QString::number(id)); + if (start()) + fakeInput(msg, true); + + if (inspector != 0L) + inspector->refreshBreakpoints(); +} + + +void XsldbgDebugger::slotDeleteCmd(QString fileName, int lineNumber) +{ + + if (outputFileActive == true){ + QMessageBox::information(0L, i18n("Operation Failed"), + i18n("Cannot set/edit breakpoints on the output file."), + QMessageBox::Ok); + return ; + } + + QString msg("delete -l \""); + msg.append(XsldbgDebugger::fixLocalPaths(fileName)).append("\" ").append(QString::number(lineNumber)); + if (start()) + fakeInput(msg, true); + if (inspector != 0L) + inspector->refreshBreakpoints(); +} + + +void XsldbgDebugger::slotDeleteCmd(int id) +{ + + if (outputFileActive == true){ + QMessageBox::information(0L, i18n("Operation Failed"), + i18n("Cannot set/edit breakpoints on the output file."), + QMessageBox::Ok); + return ; + } + QString msg("delete "); + msg.append(QString::number(id)); + if (start()) + fakeInput(msg, true); + if (inspector != 0L) + inspector->refreshBreakpoints(); +} + + +void XsldbgDebugger::slotSourceCmd() +{ + if (start()){ + outputFileActive = false; + fakeInput("source", true); + } +} + + +void XsldbgDebugger::slotDataCmd() +{ + if (start()){ + outputFileActive = false; + fakeInput("data", true); + } +} + +void XsldbgDebugger::slotShowDocument() +{ + + if (outputFileName().length() > 0){ + outputFileActive = true; + gotoLine(outputFileName(), 1); + } +} + + +void XsldbgDebugger::slotExitCmd() +{ + /* showMessage("\nExit command disabled in Quanta for the moment\n");*/ + stop(); +} + + +void XsldbgDebugger::slotCatCmd(QString xPathExpression){ + QString msg("cat "); + msg.append(xPathExpression); + + if (start()) + /*this can take a while so don't wait for xsldbg to finish */ + fakeInput(msg, false); + +} + +void XsldbgDebugger::slotCdCmd(QString xPathExpression){ + QString msg("cd "); + msg.append(xPathExpression); + + if (start()) + fakeInput(msg, true); +} +void XsldbgDebugger::slotSetVariableCmd(QString variableName, QString xPathExpression) +{ + if (!variableName.isEmpty() && !xPathExpression.isEmpty()){ + QString msg("set "); + msg.append(variableName); + msg.append(" \""); + msg.append(xPathExpression); + msg.append("\""); + + if (start()) + fakeInput(msg, true); + } +} + + +#include "xsldbgdebugger.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbgdebugger.h b/kxsldbg/kxsldbgpart/xsldbgdebugger.h new file mode 100644 index 00000000..3e9c267f --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgdebugger.h @@ -0,0 +1,176 @@ +/*************************************************************************** + xsldbgdebugger.h - description + ------------------- + begin : Tue Jan 1 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGDEBUGGER_H +#define XSLDBGDEBUGGER_H + +#include <qevent.h> +#include "libxsldbg/xsldbgmsg.h" /* needed for XsldbgMessageEnum */ +#include "libqtnotfier/xsldbgdebuggerbase.h" + +#include "xsldbginspector.h" + + +/** + *@author Keith Isdale + */ + +class QStringList; + +class XsldbgWalkSpeedImpl; + +class XsldbgDebugger : public XsldbgDebuggerBase { + Q_OBJECT + +public: + XsldbgDebugger(); + ~XsldbgDebugger(); + + /** */ + void setInspector(XsldbgInspector *inspector); + + /** Get the name of source file from xsldbg*/ + QString sourceFileName(); + + /** Get the name of data file from xsldbg*/ + QString dataFileName(); + + /** Get the name of output file from xsldbg*/ + QString outputFileName(); + + /** Tell quanta to move its cursor to file and line number supplied */ + void gotoLine(QString fileName, int lineNo, bool breakpoint = false); + + /** Set a xsldbg option */ + void setOption(const char *name, bool value); + + bool event(QEvent *e); + void timerEvent(QTimerEvent *e); + + void setOutputFileActive(bool b) {outputFileActive = b;}; + + /* helper function to handle differences between URI's in Qt/KDE and libxml2 */ + static QString fixLocalPaths(QString & file); + +private: + /** */ + bool outputFileActive; + +public slots: + /** start xsldbg */ + bool start(); + + /** stop xsldbg */ + bool stop(); + + /** send text to xsldbg, if wait is true then wait for the reply */ + void fakeInput(QString text, bool wait); + + /** Display configure dialog */ + void slotConfigure(); + + /** Config window closed */ + void slotConfigClosed(); + + /** Step to next instruction */ + void slotStepCmd(); + + /** Continue to next break point */ + void slotContinueCmd(); + + /** Restart xsldbg with selected xsl/xml file */ + void slotRunCmd(); + + /** Walk throught shtylesheet at a fixed speed + @param speed : Must be a value of 0 to 9, where 1 mean fast, 9 means slow, and 0 means stop + */ + void slotWalkSpeed(int speed); + + /** Present a dialog for use to choose walk speed */ + void slotWalkCmd(); + + /** Stop walking imediately */ + void slotWalkStopCmd(); + + /** + Start xslbg's trace mode, where output will be sent to to message window. + Can only be be stopped by using "exit" tool button and killing xsldbg */ + void slotTraceCmd(); + + /** Add breakpoint at given file and line number */ + void slotBreakCmd(QString fileName, int lineNumber); + + /** Add breakpoint at given template name*/ + void slotBreakCmd(QString templateName, QString modeName); + + /** Toggle the enabling of break point at given file and line number */ + void slotEnableCmd(QString fileName, int lineNumber); + + /** Enable break point for given breakpoint id */ + void slotEnableCmd(int id); + + /** Delete break point at given file and line number */ + void slotDeleteCmd(QString fileName, int lineNumber); + + /** Delete break point for given breakpoint id */ + void slotDeleteCmd(int id); + + /** Switch to view of XSL source */ + void slotSourceCmd(); + + /* switch to the output document */ + void slotShowDocument(); + + /** Switch to view of XML data */ + void slotDataCmd(); + + /** Stop xsldg, must use start after this command */ + void slotExitCmd(); + + /** Print the result of evaluating xPathExpression to the message window */ + void slotCatCmd(QString xPathExpression); + + /** Move to line specified by xPathExpression */ + void slotCdCmd(QString xPathExpression); + + /** Set a libxslt variable to xPathExpression */ + void slotSetVariableCmd(QString variableName, QString xPathExpression); +signals: // Signals + // generated after first message is received from xsldbg + void debuggerReady(); + +private: + bool initialized; + + /* xsldbg config and inspection dialog */ + XsldbgInspector *inspector; + + /**Walk speed dialog */ + XsldbgWalkSpeedImpl *walkDialog; + bool readMsg; + bool procMsg; + + /* copy text to output only if no furher output us requested */ + XsldbgMessageEnum lastType; + int updateTimerID; + bool addMsg; + + QStringList commandQue; + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgdialogbase.cpp b/kxsldbg/kxsldbgpart/xsldbgdialogbase.cpp new file mode 100644 index 00000000..6170e185 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgdialogbase.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** + xsldbgdialogbase.cpp - description + ------------------- + begin : Sun Jan 6 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 "xsldbgdialogbase.h" + +XsldbgDialogBase::XsldbgDialogBase(){ +} + +XsldbgDialogBase::~XsldbgDialogBase(){ +} + + +bool XsldbgDialogBase::isValid() +{ + return true; +} + +void XsldbgDialogBase::update() +{ +} + +void XsldbgDialogBase::refresh() +{ +} + diff --git a/kxsldbg/kxsldbgpart/xsldbgdialogbase.h b/kxsldbg/kxsldbgpart/xsldbgdialogbase.h new file mode 100644 index 00000000..4582ef3f --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgdialogbase.h @@ -0,0 +1,46 @@ +/*************************************************************************** + xsldbgdialogbase.h - description + ------------------- + begin : Sun Jan 6 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGDIALOGBASE_H +#define XSLDBGDIALOGBASE_H + + +/** + *@author Keith Isdale + */ + +#include <qfiledialog.h> + +class XsldbgDialogBase { + +public: + XsldbgDialogBase(); + virtual ~XsldbgDialogBase(); + +public : + /** return true if all data ok */ + virtual bool isValid(); + + /** Update changes to xsldbg*/ + virtual void update(); + + /** refresh data from source */ + virtual void refresh(); + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgdoc.cpp b/kxsldbg/kxsldbgpart/xsldbgdoc.cpp new file mode 100644 index 00000000..51b27dcb --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgdoc.cpp @@ -0,0 +1,61 @@ +/* + Handle our documents + */ + +#include "xsldbgdoc.h" + +XsldbgDoc::XsldbgDoc() +{ + fileName = QString(); + text = QString(); + row = 0; + column = 0; +} + + +XsldbgDoc::XsldbgDoc(const QString &fileName, const QString &text) +{ + this->fileName = fileName; + this->text = text; + row = 0; + column = 0; +} + + +XsldbgDoc::~XsldbgDoc() +{ + /* Empty */ +} + + +QString XsldbgDoc::getText() const +{ + return text; +} + + +QString XsldbgDoc::getFileName() const +{ + return fileName; +} + +void XsldbgDoc::setRow(int row) +{ + this->row = row; +} + +int XsldbgDoc::getRow() +{ + return row; +} + +void XsldbgDoc::setColumn(int column) +{ + this->column = column; +} + + +int XsldbgDoc::getColumn() +{ + return column; +} diff --git a/kxsldbg/kxsldbgpart/xsldbgdoc.h b/kxsldbg/kxsldbgpart/xsldbgdoc.h new file mode 100644 index 00000000..26e4482a --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgdoc.h @@ -0,0 +1,28 @@ + +#ifndef XSLDBGDOC +#define XSLDBGDOC + +#include <qstring.h> + +class XsldbgDoc { + public: + XsldbgDoc(); + XsldbgDoc(const QString &fileName, const QString &text); + ~XsldbgDoc(); + + QString getText() const; + QString getFileName() const; + + void setRow(int row); + int getRow(); + void setColumn(int column); + int getColumn(); + + private: + QString text; + QString fileName; + int row, column; + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgdocmap.h b/kxsldbg/kxsldbgpart/xsldbgdocmap.h new file mode 100644 index 00000000..189ddc1c --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgdocmap.h @@ -0,0 +1,5 @@ + +#include <qmap.h> +#include "qxsldbgdoc.h" + +typedef QMap<QString, QXsldbgDoc> XsldbgDocMap; diff --git a/kxsldbg/kxsldbgpart/xsldbgentities.ui b/kxsldbg/kxsldbgpart/xsldbgentities.ui new file mode 100644 index 00000000..3f3d1339 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgentities.ui @@ -0,0 +1,161 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>XsldbgEntities</class> +<author>Keith Isdale <k_isdale@tpg.com.au></author> +<widget class="QWidget"> + <property name="name"> + <cstring>XsldbgEntities</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>610</width> + <height>464</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Xsldbg Entities</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QListView" row="0" column="0"> + <column> + <property name="text"> + <string>PublicID</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>SystemID</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>entitiesListView</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <spacer row="3" column="0"> + <property name="name"> + <cstring>Spacer3_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget" row="4" column="0"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>refreshBtn</cstring> + </property> + <property name="text"> + <string>Refresh</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>refreshBtn</sender> + <signal>clicked()</signal> + <receiver>XsldbgEntities</receiver> + <slot>refresh()</slot> + </connection> +</connections> +<slots> + <slot>refresh()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kxsldbg/kxsldbgpart/xsldbgentitiesimpl.cpp b/kxsldbg/kxsldbgpart/xsldbgentitiesimpl.cpp new file mode 100644 index 00000000..f24e694f --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgentitiesimpl.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** + xsldbgentitiesimplimpl.cpp - description + ------------------- + begin : Sun Jan20 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 <qlistview.h> +#include <qlineedit.h> + +#include "xsldbgentitiesimpl.h" +#include "xsldbgdebugger.h" +#include "xsldbggloballistitem.h" + + +XsldbgEntitiesImpl::XsldbgEntitiesImpl(XsldbgDebugger *debugger, + QWidget *parent /*=0*/, const char *name /*=0*/) + : XsldbgEntities(parent, name), XsldbgDialogBase() +{ + this->debugger = debugger; + connect(debugger, + SIGNAL(entityItem(QString /*SystemID*/, + QString /*PublicID*/)), + this, + SLOT(slotProcEntityItem(QString /*SystemID*/, + QString /*PublicID*/))); + + connect( entitiesListView, + SIGNAL(selectionChanged(QListViewItem *)), + this, SLOT(selectionChanged(QListViewItem*))); + show(); +} + + +XsldbgEntitiesImpl::~XsldbgEntitiesImpl(){ +} + + +void XsldbgEntitiesImpl::slotProcEntityItem(QString SystemID, QString PublicID) +{ + if (SystemID.isNull()) + entitiesListView->clear(); + else{ + entitiesListView->insertItem( + new XsldbgGlobalListItem(entitiesListView, + SystemID, -1, PublicID)); + } + +} + + +void XsldbgEntitiesImpl::selectionChanged(QListViewItem *item) +{ + XsldbgGlobalListItem *globalItem = dynamic_cast<XsldbgGlobalListItem*>(item); + if (globalItem){ + debugger->gotoLine(globalItem->getFileName(), 1); + } +} + +void XsldbgEntitiesImpl::refresh() +{ + debugger->fakeInput("entities", true) ; +} + + + + + +#include "xsldbgentitiesimpl.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbgentitiesimpl.h b/kxsldbg/kxsldbgpart/xsldbgentitiesimpl.h new file mode 100644 index 00000000..2c744001 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgentitiesimpl.h @@ -0,0 +1,53 @@ +/*************************************************************************** + xsldbgentitiesimpl.h - description + ------------------- + begin : Sun Jan 20 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGENTITIESIMPL_H +#define XSLDBGENTITIESIMPL_H + +/** + *@author Keith Isdale + */ + +#include "xsldbgentities.h" +#include "xsldbgdialogbase.h" + +class XsldbgDebugger; + +class XsldbgEntitiesImpl : public XsldbgEntities, public XsldbgDialogBase { + Q_OBJECT + +public: + XsldbgEntitiesImpl(XsldbgDebugger *debugger, QWidget *parent=0, const char *name=0); + ~XsldbgEntitiesImpl(); + +public slots: + /** Process request to add entity to view, First parameter is QString::null + to indicate start of entity list notfication */ + void slotProcEntityItem(QString SystemID, QString PublicID); + + void selectionChanged(QListViewItem *item); + + /** refresh data from source */ + void refresh(); + + +private: + XsldbgDebugger *debugger; + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbggloballistitem.cpp b/kxsldbg/kxsldbgpart/xsldbggloballistitem.cpp new file mode 100644 index 00000000..b1fa76d9 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbggloballistitem.cpp @@ -0,0 +1,38 @@ +/*************************************************************************** + xsldbggloballistitem.cpp - description + ------------------- + begin : Sun Jan 13 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 "xsldbggloballistitem.h" + +XsldbgGlobalListItem::XsldbgGlobalListItem(QListView *parent, + QString fileName, int lineNumber, QString globalName) + : XsldbgListItem(parent, 1, fileName, lineNumber) +{ + varName = globalName; + setText(0, globalName); +} + + +XsldbgGlobalListItem::~XsldbgGlobalListItem() +{ +} + + +QString XsldbgGlobalListItem::getVarName() +{ + return varName; +} + diff --git a/kxsldbg/kxsldbgpart/xsldbggloballistitem.h b/kxsldbg/kxsldbgpart/xsldbggloballistitem.h new file mode 100644 index 00000000..325df028 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbggloballistitem.h @@ -0,0 +1,41 @@ +/*************************************************************************** + xsldbggloballistitem.h - description + ------------------- + begin : Sun Jan 13 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGGLOBALLISTITEM_H +#define XSLDBGGLOBALLISTITEM_H + +/** + *@author Keith Isdale + */ + +#include "xsldbglistitem.h" + + +class XsldbgGlobalListItem : public XsldbgListItem { +public: + XsldbgGlobalListItem(QListView *parent, + QString fileName, int lineNumber, QString globalName); + ~XsldbgGlobalListItem(); + + /** return the name of this variable */ + QString getVarName(); + +private: + QString varName; +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgglobalvariables.ui b/kxsldbg/kxsldbgpart/xsldbgglobalvariables.ui new file mode 100644 index 00000000..513e3079 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgglobalvariables.ui @@ -0,0 +1,272 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>XsldbgGlobalVariables</class> +<author>Keith Isdale <k_isdale@tpg.com.au></author> +<widget class="QWidget"> + <property name="name"> + <cstring>XsldbgGlobalVariables</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>639</width> + <height>342</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Xsldbg Global Variables</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QListView" row="2" column="0"> + <column> + <property name="text"> + <string>Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Source File</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Source Line Number</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>varsListView</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Expression:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>expressionEdit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Enter a valid XPath expression</string> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>expressionButton</cstring> + </property> + <property name="text"> + <string>Evaluate</string> + </property> + <property name="toolTip" stdset="0"> + <string>Result of evaluation will appear in message window</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>refreshBtn</cstring> + </property> + <property name="text"> + <string>Refresh</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>expressionButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgGlobalVariables</receiver> + <slot>slotEvaluate()</slot> + </connection> + <connection> + <sender>refreshBtn</sender> + <signal>clicked()</signal> + <receiver>XsldbgGlobalVariables</receiver> + <slot>refresh()</slot> + </connection> +</connections> +<slots> + <slot>refresh()</slot> + <slot>slotEvaluate()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kxsldbg/kxsldbgpart/xsldbgglobalvariablesimpl.cpp b/kxsldbg/kxsldbgpart/xsldbgglobalvariablesimpl.cpp new file mode 100644 index 00000000..37083068 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgglobalvariablesimpl.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** + xsldbgglobalvariablesimpl.cpp - description + ------------------- + begin : Sat Jan 5 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 <qlistview.h> +#include <qlineedit.h> + +#include "xsldbgglobalvariablesimpl.h" +#include "xsldbgdebugger.h" +#include "xsldbggloballistitem.h" + + +XsldbgGlobalVariablesImpl::XsldbgGlobalVariablesImpl(XsldbgDebugger *debugger, + QWidget *parent /*=0*/, const char *name /*=0*/) + : XsldbgGlobalVariables(parent, name), XsldbgDialogBase() +{ + this->debugger = debugger; + connect(debugger, SIGNAL(globalVariableItem(QString /*name */, QString /* fileName */, int /*lineNumber */)), + this, SLOT(slotProcGlobalVariableItem(QString /*name */, QString /* fileName */, int /*lineNumber */))); + connect( varsListView, SIGNAL(selectionChanged(QListViewItem *)), + this, SLOT(selectionChanged(QListViewItem*))); + show(); +} + + +XsldbgGlobalVariablesImpl::~XsldbgGlobalVariablesImpl(){ + debugger = 0L; +} + +void XsldbgGlobalVariablesImpl::slotProcGlobalVariableItem(QString name , QString fileName, int lineNumber) +{ + if (name.isNull()) + varsListView->clear(); + else{ + varsListView->insertItem(new XsldbgGlobalListItem(varsListView, + fileName, lineNumber, name)); + } + +} + + +void XsldbgGlobalVariablesImpl::selectionChanged(QListViewItem *item) +{ + XsldbgGlobalListItem *globalItem = dynamic_cast<XsldbgGlobalListItem*>(item); + if (globalItem != 0 && debugger != 0) { + debugger->gotoLine(globalItem->getFileName(), globalItem->getLineNumber()); + } +} + +void XsldbgGlobalVariablesImpl::refresh() +{ + if (debugger != 0) + debugger->fakeInput("globals -q", true) ; +} + +void XsldbgGlobalVariablesImpl::slotEvaluate() +{ + if (debugger != 0L) + debugger->slotCatCmd( expressionEdit->text() ); +} + + + +#include "xsldbgglobalvariablesimpl.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbgglobalvariablesimpl.h b/kxsldbg/kxsldbgpart/xsldbgglobalvariablesimpl.h new file mode 100644 index 00000000..57d0c922 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgglobalvariablesimpl.h @@ -0,0 +1,55 @@ +/*************************************************************************** + xsldbgglobalvariablesimpl.h - description + ------------------- + begin : Sat Jan 5 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGGLOBALVARIABLESIMPL_H +#define XSLDBGGLOBALVARIABLESIMPL_H + +/** + *@author Keith Isdale + */ + +#include "xsldbgglobalvariables.h" +#include "xsldbgdialogbase.h" + +class XsldbgDebugger; + +class XsldbgGlobalVariablesImpl : public XsldbgGlobalVariables, public XsldbgDialogBase { + Q_OBJECT + +public: + XsldbgGlobalVariablesImpl(XsldbgDebugger *debugger, QWidget *parent=0, const char *name=0); + ~XsldbgGlobalVariablesImpl(); + +public slots: + /** Process request to add global variable to view, First parameter is QString::null + to indicate start of global variable list notfication */ + void slotProcGlobalVariableItem(QString name , QString fileName, int lineNumber); + + void selectionChanged(QListViewItem *item); + + /** refresh data from source */ + void refresh(); + + void slotEvaluate(); + + +private: + XsldbgDebugger *debugger; + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbginspector.cpp b/kxsldbg/kxsldbgpart/xsldbginspector.cpp new file mode 100644 index 00000000..c36130c7 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbginspector.cpp @@ -0,0 +1,210 @@ +/** + File : xsldbginspector.cpp + Author : Keith Isdale + Date : 30th March 2002 + Description : Dialog to inspect stylesheet using xsldbg. Based on + file created by uic + */ + +#include "xsldbginspector.h" + +#include <klocale.h> + +#include <qvariant.h> +#include <qlistbox.h> +#include <qpushbutton.h> +#include <qtabwidget.h> +#include <qwidget.h> +#include <qmime.h> +#include <qdragobject.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qimage.h> +#include <qpixmap.h> +#include <qiconset.h> + +#include <kpushbutton.h> +#include <kstdguiitem.h> +#include "xsldbgdebugger.h" +#include "xsldbgbreakpointsimpl.h" +#include "xsldbglocalvariablesimpl.h" +#include "xsldbgcallstackimpl.h" +#include "xsldbgtemplatesimpl.h" +#include "xsldbgsourcesimpl.h" +#include "xsldbgentitiesimpl.h" + +static QPixmap uic_load_pixmap_XsldbgInspector( const QString &name ) +{ + const QMimeSource *m = QMimeSourceFactory::defaultFactory()->data( name ); + if ( !m ) + return QPixmap(); + QPixmap pix; + QImageDrag::decode( m, pix ); + return pix; +} +/* + * Constructs a XsldbgInspector which is a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * true to construct a modal dialog. + */ +XsldbgInspector::XsldbgInspector( XsldbgDebugger *debugger, QWidget* parent, + const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + Q_CHECK_PTR(debugger); + this->debugger = debugger; + breakpointWidget = 0L; + localWidget = 0L; + callStackWidget = 0L; + templateWidget = 0L; + sourceWidget = 0L; + entityWidget = 0L; + if ( !name ) + setName( "XsldbgInspector" ); + resize( 597, 364 ); + setCaption( i18n( "Xsldbg Inspector" ) ); + setSizeGripEnabled( true ); + XsldbgInspectorLayout = new QGridLayout( this, 1, 1, 11, 6, + "XsldbgInspectorLayout"); + + tabWidget = new QTabWidget( this, "tabWidget" ); + Q_CHECK_PTR( tabWidget ); + breakpointWidget = new XsldbgBreakpointsImpl( debugger, tabWidget ); + Q_CHECK_PTR( breakpointWidget ); + tabWidget->insertTab( breakpointWidget, i18n( "Breakpoints" ) ); + + localWidget = new XsldbgLocalVariablesImpl( debugger, tabWidget ); + Q_CHECK_PTR( localWidget ); + tabWidget->insertTab( localWidget, + QIconSet( uic_load_pixmap_XsldbgInspector( "xsldbg_source.png" ) ), + i18n( "Variables" ) ); + + callStackWidget = new XsldbgCallStackImpl( debugger, tabWidget ); + Q_CHECK_PTR( callStackWidget ); + tabWidget->insertTab( callStackWidget, + QIconSet( uic_load_pixmap_XsldbgInspector( "xsldbg_source.png" ) ), + i18n( "CallStack" )); + + templateWidget = new XsldbgTemplatesImpl( debugger, tabWidget ); + Q_CHECK_PTR( templateWidget ); + tabWidget->insertTab( templateWidget, + QIconSet( uic_load_pixmap_XsldbgInspector( "xsldbg_source.png" ) ), + i18n( "Templates" )); + + sourceWidget = new XsldbgSourcesImpl( debugger, tabWidget ); + Q_CHECK_PTR( sourceWidget ); + tabWidget->insertTab( sourceWidget, + QIconSet( uic_load_pixmap_XsldbgInspector( "xsldbg_source.png" ) ), + i18n( "Sources" )); + + entityWidget = new XsldbgEntitiesImpl( debugger, tabWidget ); + Q_CHECK_PTR( entityWidget ); + tabWidget->insertTab( entityWidget, + QIconSet( uic_load_pixmap_XsldbgInspector( "xsldbg_data.png" ) ), + i18n( "Entities" )); + + XsldbgInspectorLayout->addWidget( tabWidget, 0, 1 ); + Layout1 = new QHBoxLayout( 0, 0, 6, "Layout1"); + + buttonHelp = new KPushButton( KStdGuiItem::help(), this, "buttonHelp" ); + buttonHelp->setAccel( 4144 ); + buttonHelp->setAutoDefault( true ); + Layout1->addWidget( buttonHelp ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + Layout1->addItem( spacer ); + + buttonOk = new KPushButton( KStdGuiItem::ok(), this, "buttonOk" ); + buttonOk->setAccel( 0 ); + buttonOk->setAutoDefault( true ); + buttonOk->setDefault( true ); + Layout1->addWidget( buttonOk ); + + buttonApply = new KPushButton( KStdGuiItem::apply(), this, "buttonApply" ); + QToolTip::add(buttonApply, i18n("Apply changes to xsldbg after restarting execution")); + buttonApply->setAccel( 0 ); + buttonApply->setAutoDefault( true ); + buttonApply->setDefault( true ); + Layout1->addWidget( buttonApply ); + + buttonRefresh = new QPushButton( this, "buttonRefresh" ); + buttonRefresh->setText( i18n( "&Refresh" ) ); + QToolTip::add(buttonRefresh, i18n("Refresh values in inspectors from xsldbg")); + buttonRefresh->setAccel( 0 ); + buttonRefresh->setAutoDefault( true ); + buttonRefresh->setDefault( true ); + Layout1->addWidget( buttonRefresh ); + + buttonCancel = new KPushButton( KStdGuiItem::cancel(), this, "buttonCancel" ); + buttonCancel->setAccel( 0 ); + buttonCancel->setAutoDefault( true ); + Layout1->addWidget( buttonCancel ); + + XsldbgInspectorLayout->addMultiCellLayout( Layout1, 1, 1, 0, 1 ); + + // signals and slots connections + connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( buttonApply, SIGNAL ( clicked() ), this, SLOT ( update() ) ); + connect( buttonRefresh, SIGNAL ( clicked() ), this, SLOT ( refresh() ) ); + connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); + + hide(); +} + +/* + * Destroys the object and frees any allocated resources + */ +XsldbgInspector::~XsldbgInspector() +{ + debugger = 0L; + // no need to delete child widgets, Qt does it all for us +} + + +void XsldbgInspector::accept() +{ + QDialog::accept(); +} + +void XsldbgInspector::reject() +{ + QDialog::reject(); +} + + +void XsldbgInspector::refresh() +{ + + refreshBreakpoints(); + refreshVariables(); + + if ( templateWidget != 0L) + templateWidget->refresh(); + + if ( sourceWidget != 0L) + sourceWidget->refresh(); + + if ( entityWidget != 0L) + entityWidget->refresh(); + +} + +void XsldbgInspector::refreshBreakpoints() +{ + if ( breakpointWidget != 0L ) + breakpointWidget->refresh(); +} + + +void XsldbgInspector::refreshVariables() +{ + if ( localWidget != 0L ) + localWidget->refresh(); + + if (callStackWidget != 0L) + callStackWidget->refresh(); +} + +#include "xsldbginspector.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbginspector.h b/kxsldbg/kxsldbgpart/xsldbginspector.h new file mode 100644 index 00000000..c879af58 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbginspector.h @@ -0,0 +1,67 @@ +/** + File : xsldbginspector.h + Author : Keith Isdale + Date : 30th March 2002 + Description : Dialog to inspect stylesheet using xsldbg. Based on + file created by uic +*/ +#ifndef XSLDBGINSPECTOR_H +#define XSLDBGINSPECTOR_H + +#include <qvariant.h> +#include <qdialog.h> +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QListBox; +class QListBoxItem; +class QPushButton; +class QTabWidget; +class QWidget; +class KPushButton; + +class XsldbgDebugger; +class XsldbgBreakpointsImpl; +class XsldbgLocalVariablesImpl; +class XsldbgCallStackImpl; +class XsldbgTemplatesImpl; +class XsldbgSourcesImpl; +class XsldbgEntitiesImpl; + +class XsldbgInspector : public QDialog +{ + Q_OBJECT + +public: + XsldbgInspector( XsldbgDebugger *debugger, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~XsldbgInspector(); + + QTabWidget* tabWidget; + KPushButton* buttonHelp; + KPushButton* buttonOk; + KPushButton* buttonApply; + QPushButton* buttonRefresh; + KPushButton* buttonCancel; + + +public slots: + void accept(); + void reject(); + void refresh(); + void refreshBreakpoints(); + void refreshVariables(); + + +protected: + QGridLayout* XsldbgInspectorLayout; + QHBoxLayout* Layout1; + XsldbgDebugger *debugger; + XsldbgBreakpointsImpl *breakpointWidget; + XsldbgLocalVariablesImpl *localWidget; + XsldbgCallStackImpl *callStackWidget; + XsldbgTemplatesImpl *templateWidget; + XsldbgSourcesImpl *sourceWidget; + XsldbgEntitiesImpl *entityWidget; +}; + +#endif // XSLDBGINPECTOR_H diff --git a/kxsldbg/kxsldbgpart/xsldbglistitem.cpp b/kxsldbg/kxsldbgpart/xsldbglistitem.cpp new file mode 100644 index 00000000..9242994f --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbglistitem.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** + xsldbglistitem.cpp - description + ------------------- + begin : Sun Jan 6 2002 + copyright : (C) 2002 by Andras Mantia + email : amantia@kde.org + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "xsldbglistitem.h" + +XsldbgListItem::XsldbgListItem(QListView *parent, int columnOffset, + const QString & fileName, int lineNumber) + : QListViewItem(parent) +{ + this->fileName = fileName; + this->lineNumber = lineNumber; + setText(columnOffset, fileName); + /* we may not have a line number column so skip it if needed */ + if ((listView()->columns() >= columnOffset + 1) && (lineNumber != -1)) + setText(columnOffset + 1, QString::number(lineNumber)); +} + +XsldbgListItem::~XsldbgListItem() +{ +} + + +QString XsldbgListItem::getFileName() const +{ + return fileName; +} + +int XsldbgListItem::getLineNumber() const +{ + return lineNumber; +} + diff --git a/kxsldbg/kxsldbgpart/xsldbglistitem.h b/kxsldbg/kxsldbgpart/xsldbglistitem.h new file mode 100644 index 00000000..35ad39c7 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbglistitem.h @@ -0,0 +1,45 @@ +/*************************************************************************** + xsldbglistitem.h - description + + ------------------- + begin : Sun Jan 6 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. * + * * + ***************************************************************************/ + +#ifndef XSLDBGLISTITEM_H +#define XSLDBGLISTITEM_H + +/** + *@author Keith Isdale + */ + + +#include <qlistview.h> + +class XsldbgListItem : public QListViewItem { +public: + /** column offset is the index of the fileName column */ + XsldbgListItem(QListView *parent, int columnOffset, + const QString &fileName, int lineNumber); + ~XsldbgListItem(); + + + QString getFileName() const; + int getLineNumber() const; + +private: + QString fileName; + int lineNumber; +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbglocallistitem.cpp b/kxsldbg/kxsldbgpart/xsldbglocallistitem.cpp new file mode 100644 index 00000000..ccade6ac --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbglocallistitem.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** + xsldbglocallistitem.cpp - description + ------------------- + begin : Sun Jan 13 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 "xsldbglocallistitem.h" +#include <klocale.h> + +XsldbgLocalListItem::XsldbgLocalListItem(QListView *parent, QString fileName, int lineNumber, + QString localName, QString templateContext, QString selectXPath, bool localVariable) +: XsldbgListItem(parent, 3, fileName, lineNumber) +{ + varName = localName; + contextName = templateContext; + XPath = selectXPath; + + setText(0, localName); + setText(1, templateContext); + if (localVariable) + setText(2, i18n("Local")); + else + setText(2, i18n("Global")); +} + +XsldbgLocalListItem::~XsldbgLocalListItem() +{ +} + +QString XsldbgLocalListItem::getVarName() +{ + return varName; +} + +QString XsldbgLocalListItem::getContextName() +{ + return contextName; +} + +QString XsldbgLocalListItem::getXPath() +{ + return XPath; +} + +bool XsldbgLocalListItem::isLocalVariable() +{ + return localVar; +} diff --git a/kxsldbg/kxsldbgpart/xsldbglocallistitem.h b/kxsldbg/kxsldbgpart/xsldbglocallistitem.h new file mode 100644 index 00000000..ee72ab1a --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbglocallistitem.h @@ -0,0 +1,51 @@ +/*************************************************************************** + xsldbglocallistitem.h - description + ------------------- + begin : Sun Jan 13 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGLOCALLISTITEM_H +#define XSLDBGLOCALLISTITEM_H + +/** + *@author Keith Isdale + */ + +#include "xsldbglistitem.h" + +class XsldbgLocalListItem : public XsldbgListItem { +public: + XsldbgLocalListItem(QListView *parent, QString fileName, int lineNumber, + QString localName, QString templateContext, QString selectXPath, bool localVariable); + ~XsldbgLocalListItem(); + + /** return the name of this variable */ + QString getVarName(); + + /** return the template context for this variable */ + QString getContextName(); + + /** return the XPath for this variable */ + QString getXPath(); + + bool isLocalVariable(); + +private: + QString varName; + QString contextName; + QString XPath; + bool localVar; +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbglocalvariables.ui b/kxsldbg/kxsldbgpart/xsldbglocalvariables.ui new file mode 100644 index 00000000..2d31320c --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbglocalvariables.ui @@ -0,0 +1,374 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>XsldbgLocalVariables</class> +<author>Keith Isdale <k_isdale@tpg.com.au></author> +<widget class="QWidget"> + <property name="name"> + <cstring>XsldbgLocalVaraibles</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>690</width> + <height>473</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Xsldbg Local Variables</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Expression:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>expressionEdit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Enter a valid XPath expression</string> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>expressionButton</cstring> + </property> + <property name="text"> + <string>Evaluate</string> + </property> + <property name="toolTip" stdset="0"> + <string>Result of evaluation will appear in message window</string> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QListView"> + <column> + <property name="text"> + <string>Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Template Context</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Type</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Source File</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Source Line Number</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>varsListView</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout6</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>Variable expression:</string> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>variableName</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>variableType</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Variable type:</string> + </property> + </widget> + <widget class="QLayoutWidget" row="2" column="1"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLineEdit"> + <property name="name"> + <cstring>xPathEdit</cstring> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>setExpressionButton</cstring> + </property> + <property name="text"> + <string>Set Expression</string> + </property> + <property name="toolTip" stdset="0"> + <string>Set the selection for variable </string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string>Variable name:</string> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>refreshBtn</cstring> + </property> + <property name="text"> + <string>Refresh</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>expressionButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgLocalVaraibles</receiver> + <slot>slotEvaluate()</slot> + </connection> + <connection> + <sender>refreshBtn</sender> + <signal>clicked()</signal> + <receiver>XsldbgLocalVaraibles</receiver> + <slot>refresh()</slot> + </connection> + <connection> + <sender>setExpressionButton</sender> + <signal>clicked()</signal> + <receiver>XsldbgLocalVaraibles</receiver> + <slot>slotSetExpression()</slot> + </connection> +</connections> +<slots> + <slot>refresh()</slot> + <slot>slotEvaluate()</slot> + <slot>slotSetExpression()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kxsldbg/kxsldbgpart/xsldbglocalvariablesimpl.cpp b/kxsldbg/kxsldbgpart/xsldbglocalvariablesimpl.cpp new file mode 100644 index 00000000..bd39fcc8 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbglocalvariablesimpl.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** + xsldbglocalvariablesimpl.cpp - description + ------------------- + begin : Sat Jan 5 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 <qlistview.h> +#include <qlineedit.h> +#include <qlabel.h> +#include <qpushbutton.h> + +#include "xsldbglocalvariablesimpl.h" +#include "xsldbglocallistitem.h" +#include "xsldbgdebugger.h" +#include <klocale.h> + + +XsldbgLocalVariablesImpl::XsldbgLocalVariablesImpl(XsldbgDebugger *debugger, + QWidget *parent /*=0*/, const char *name /*=0*/) + : XsldbgLocalVariables(parent, name), XsldbgDialogBase() +{ + this->debugger = debugger; + connect(debugger, SIGNAL(variableItem(QString /*name */, QString /* templateContext*/, + QString /* fileName */, int /*lineNumber */, + QString /* select XPath */, int /* is it a local variable */)), + this, SLOT(slotProcVariableItem(QString /*name */, QString /* templateContext*/, + QString /* fileName */, int /*lineNumber */, + QString /* select XPath */, int /* is it a local variable */))); + connect(varsListView, SIGNAL(selectionChanged(QListViewItem *)), + this, SLOT(selectionChanged(QListViewItem*))); + show(); +} + + +XsldbgLocalVariablesImpl::~XsldbgLocalVariablesImpl() +{ + debugger = 0L; +} + +void XsldbgLocalVariablesImpl::slotProcVariableItem(QString name , QString templateContext, + QString fileName, int lineNumber, + QString selectXPath, int localVariable) +{ + + if (!name.isNull()){ + varsListView->insertItem(new XsldbgLocalListItem(varsListView, + fileName, lineNumber, name, templateContext, selectXPath, localVariable != 0)); + } + +} + +void XsldbgLocalVariablesImpl::selectionChanged(QListViewItem *item) +{ + XsldbgLocalListItem *localItem = dynamic_cast<XsldbgLocalListItem*>(item); + if (localItem){ + variableName->setText(localItem->getVarName()); + xPathEdit->setText(localItem->getXPath()); + + if (localItem->isLocalVariable()) + variableType->setText(i18n("Local")); + else + variableType->setText(i18n("Global")); + + setExpressionButton->setEnabled(!localItem->getXPath().isEmpty()); + xPathEdit->setEnabled(!localItem->getXPath().isEmpty()); + debugger->gotoLine(localItem->getFileName(), localItem->getLineNumber()); + }else{ + // "clear" values in variable editing widgets + variableName->setText(""); + xPathEdit->setText(""); + variableType->setText(""); + setExpressionButton->setEnabled(false); + xPathEdit->setEnabled(false); + } + +} + +void XsldbgLocalVariablesImpl::refresh() +{ + if (varsListView){ + varsListView->clear(); + debugger->fakeInput("locals -q", true) ; + // "clear" values in variable editing widgets + variableName->setText(""); + xPathEdit->setText(""); + variableType->setText(""); + setExpressionButton->setEnabled(false); + xPathEdit->setEnabled(false); + } +} + +void XsldbgLocalVariablesImpl::slotEvaluate() +{ + if (debugger != 0L) + debugger->slotCatCmd( expressionEdit->text() ); +} + +void XsldbgLocalVariablesImpl::slotSetExpression() +{ + if (debugger != 0L){ + debugger->slotSetVariableCmd( variableName->text(), xPathEdit->text() ); + refresh(); + } +} + + + + + +#include "xsldbglocalvariablesimpl.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbglocalvariablesimpl.h b/kxsldbg/kxsldbgpart/xsldbglocalvariablesimpl.h new file mode 100644 index 00000000..0f05b0ef --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbglocalvariablesimpl.h @@ -0,0 +1,60 @@ +/*************************************************************************** + xsldbglocalvariablesimpl.h - description + ------------------- + begin : Sat Jan 5 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. * + * * + ***************************************************************************/ + +#ifndef XSLDBGLOCALVARIABLESIMPL_H +#define XSLDBGLOCALVARIABLESIMPL_H + +/** + *@author Keith Isdale + */ + +#include "xsldbglocalvariables.h" +#include "xsldbgdialogbase.h" + +class XsldbgDebugger; + +class XsldbgLocalVariablesImpl : public XsldbgLocalVariables, public XsldbgDialogBase { + Q_OBJECT + +public: + XsldbgLocalVariablesImpl(XsldbgDebugger *debugger, QWidget *parent=0, const char *name=0); + ~XsldbgLocalVariablesImpl(); + +public slots: + /** Process request to add local varaible to view, First parameter is QString::null + to indicate start of local variable list notfication */ + + void slotProcVariableItem(QString /*name */, QString /* templateContext*/, + QString /* fileName */, int /*lineNumber */, + QString /* select XPath */, int /* is it a local variable */); + + void selectionChanged(QListViewItem *item); + + /** refresh data from source */ + void refresh(); + + void slotEvaluate(); + + void slotSetExpression(); + + +private: + XsldbgDebugger *debugger; + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgmsgdialog.ui b/kxsldbg/kxsldbgpart/xsldbgmsgdialog.ui new file mode 100644 index 00000000..8ba1cac3 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgmsgdialog.ui @@ -0,0 +1,175 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>XsldbgMsgDialog</class> +<comment>Used with QT3 or greater</comment> +<author>Keith Isdale <k_isdale@tpg.com.au></author> +<widget class="QDialog"> + <property name="name"> + <cstring>XsldbgMsgDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>456</width> + <height>211</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>qxsldbg Message</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>iconLbl</cstring> + </property> + <property name="text"> + <string>TextLabel1</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QTextEdit"> + <property name="name"> + <cstring>msgTextEdit</cstring> + </property> + <property name="resizePolicy"> + <enum>AutoOneFit</enum> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton1</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>PushButton1</sender> + <signal>clicked()</signal> + <receiver>XsldbgMsgDialog</receiver> + <slot>accept()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kxsldbg/kxsldbgpart/xsldbgmsgdialogimpl.h b/kxsldbg/kxsldbgpart/xsldbgmsgdialogimpl.h new file mode 100644 index 00000000..a801d49b --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgmsgdialogimpl.h @@ -0,0 +1,30 @@ +/*********************************************************************************** + * * + * 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 XSLDBMSGDIALOGIMPL_H +#define XSLDBMSGDIALOGIMPL_H + +/** + *@author Keith Isdale + */ + +#include "xsldbgmsgdialog.h" +#include <qtextedit.h> + +class XsldbgMsgDialogImpl : public XsldbgMsgDialog { + +public: + + XsldbgMsgDialogImpl(QWidget *parent, + QMessageBox::Icon icon, + const QString & title, const QString &msg); + + void append(const QString &text); +}; +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgoutputview.cpp b/kxsldbg/kxsldbgpart/xsldbgoutputview.cpp new file mode 100644 index 00000000..6284ddec --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgoutputview.cpp @@ -0,0 +1,156 @@ +/*************************************************************************** + xsldbgoutputview.cpp - Display raw output from xsldbg + ------------------- + begin : Sat July 27 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. * + * * + ************************************************************************************/ + +/** + *@author Keith Isdale + */ + +#include <klocale.h> + +#include <qlayout.h> +#include <qmessagebox.h> +#include <qdialog.h> +#include <qpushbutton.h> +#include <qlabel.h> + +#if QT_VERSION >= 300 +#include "xsldbgmsgdialogimpl.h" +#else +#include "xsldbgmsgdialogimpl2.h" +#endif + + +XsldbgMsgDialogImpl::XsldbgMsgDialogImpl(QWidget *parent, + QMessageBox::Icon icon, + const QString &title, const QString &msg) +#if QT_VERSION >= 300 + : XsldbgMsgDialog(parent, "XsldbgMsgDialogImpl" , TRUE ) +#else + : XsldbgMsgDialog2(parent, "XsldbgMsgDialogImpl" , TRUE ) +#endif +{ + setCaption(title); + + QMessageBox tmpMsg; + tmpMsg.setIcon(icon); + msgTextEdit->setText(msg); + iconLbl->setPixmap(*tmpMsg.iconPixmap()); +} + +void XsldbgMsgDialogImpl::append(const QString &text) +{ + msgTextEdit->append(text); +} + + + +#if QT_VERSION >= 300 + +#include "xsldbgoutputview.h" + +XsldbgOutputView::XsldbgOutputView(QWidget * parent) + : QTextEdit(parent, "outputview") +{ + new QBoxLayout(this, QBoxLayout::TopToBottom); + setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); + setMinimumSize(QSize(500, 80)); + setCaption(i18n("xsldbg Output")); + setText(i18n("\t\txsldbg output capture ready\n\n")); + dlg = 0L; + show(); + setReadOnly(TRUE); +} + +#else + +#include "xsldbgoutputview2.h" + +XsldbgOutputView::XsldbgOutputView(QWidget * parent) + : QTextView(parent, "outputview") +{ + new QBoxLayout(this, QBoxLayout::TopToBottom); + setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); + setMinimumSize(QSize(500,80)); + setCaption(i18n("xsldbg Output")); + setText(i18n("\t\txsldbg output capture ready\n\n")); + dlg = 0L; + show(); +} +#endif // QT_VERSION + +void XsldbgOutputView::slotProcShowMessage(QString msg) +{ + bool processed = FALSE; + // Is this a result of an evaluate command + if ((msg[0] == QChar('=')) && (msg[1] == QChar(' '))){ + int endPosition = msg.find(QChar('\n')); + if (endPosition >= 0){ + processed = TRUE; + showDialog(QMessageBox::Information, i18n("Result of evaluation"), + msg.mid(endPosition + 1)); + } + }else /* Is there some sort of error message in msg */ + if ((msg.find("Error:") != -1) || + (msg.find("Warning:") != -1) || + (msg.find("Request to xsldbg failed") != -1) || + /* the following errors are libxml or libxslt generated */ + (msg.find("error:") != -1) || + (msg.find("xmlXPathEval:") != -1) || + (msg.find("runtime error") != -1)) { + /* OK we've found an error but ingore any errors about + data or source files */ + if ((msg.find("Error: No XSL source file supplied") == -1) && + (msg.find("Error: No XML data file supplied") == -1) && + (msg.find("Load of source deferred") == -1) && + (msg.find("Load of data deferred") == -1) ) + showDialog(QMessageBox::Warning, i18n("Request Failed "), + msg); + processed = TRUE; + } + if (processed == FALSE){ + if (isVisible() == FALSE) + show(); + append(msg); + } +} + + +void XsldbgOutputView::slotClearView() +{ +} + +void XsldbgOutputView::showDialog(QMessageBox::Icon icon, QString title, + QString msg) +{ + + if ( dlg ){ + // not pretty, add this text to the open dialog when multiple + // calls to showDialog are made + dlg->append(msg); + }else{ + dlg = new XsldbgMsgDialogImpl(this, icon, title, msg); + if ( dlg ){ + dlg->exec(); + delete dlg; + dlg = 0L; + } + } +} + + + +#include "xsldbgoutputview.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbgoutputview.h b/kxsldbg/kxsldbgpart/xsldbgoutputview.h new file mode 100644 index 00000000..547ca907 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgoutputview.h @@ -0,0 +1,51 @@ +/*************************************************************************** + xsldbgoutputview.h - Display raw output from xsldbg + ------------------- + begin : Sat July 27 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGOUTPUTVIEW_H +#define XSLDBGOUTPUTVIEW_H + +/** + *@author Keith Isdale + */ +#include <qtextedit.h> +#include <qmessagebox.h> + +class QDialog; +class XsldbgMsgDialogImpl; + +class XsldbgOutputView : public QTextEdit { + Q_OBJECT + +public : + XsldbgOutputView(QWidget *parent = 0); + + void showDialog(QMessageBox::Icon icon, QString title, QString msg); + +public slots: + /** Process a copy of mesage sent to message window */ + void slotProcShowMessage(QString msg); + + /** Clear message view window of its text */ + void slotClearView(); + + private: + + XsldbgMsgDialogImpl *dlg; + +}; + +#endif /* XSLDBGOUTPUTVIEW_H */ diff --git a/kxsldbg/kxsldbgpart/xsldbgsources.ui b/kxsldbg/kxsldbgpart/xsldbgsources.ui new file mode 100644 index 00000000..b6073eb6 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgsources.ui @@ -0,0 +1,154 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>XsldbgSources</class> +<author>Keith Isdale <k_isdale@tpg.com.au></author> +<widget class="QWidget"> + <property name="name"> + <cstring>XsldbgSources</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>536</width> + <height>365</height> + </rect> + </property> + <property name="caption"> + <string>Xsldbg Source Files</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QListView" row="0" column="0"> + <column> + <property name="text"> + <string>Source File</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Parent File</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Parent Line Number</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>sourceListView</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>refreshBtn</cstring> + </property> + <property name="text"> + <string>Refresh</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>sourceListView</sender> + <signal>selectionChanged(QListViewItem*)</signal> + <receiver>XsldbgSources</receiver> + <slot>selectionChanged(QListViewItem*)</slot> + </connection> + <connection> + <sender>refreshBtn</sender> + <signal>clicked()</signal> + <receiver>XsldbgSources</receiver> + <slot>refresh()</slot> + </connection> +</connections> +<slots> + <slot>refresh()</slot> + <slot>selectionChanged(QListViewItem*)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kxsldbg/kxsldbgpart/xsldbgsourcesimpl.cpp b/kxsldbg/kxsldbgpart/xsldbgsourcesimpl.cpp new file mode 100644 index 00000000..1c0528f0 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgsourcesimpl.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** + xsldbgsourcesimpl.cpp - description + ------------------- + begin : Fri Jan 4 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 <qlistview.h> +#include <qlineedit.h> + +#include "xsldbgsourcesimpl.h" +#include "xsldbgdebugger.h" +#include "xsldbggloballistitem.h" + + +XsldbgSourcesImpl::XsldbgSourcesImpl(XsldbgDebugger *debugger, + QWidget *parent /*=0*/, const char *name /*=0*/) + : XsldbgSources(parent, name), XsldbgDialogBase() +{ + this->debugger = debugger; + connect(debugger, SIGNAL(sourceItem(QString /* fileName */, QString /* parentFileName */, int /*lineNumber */)), + this, SLOT(slotProcSourceItem(QString /* fileName */, QString /* parentFileName */, int /*lineNumber */))); + + connect( sourceListView, SIGNAL(selectionChanged(QListViewItem *)), + this, SLOT(selectionChanged(QListViewItem*))); + + show(); + refresh(); +} + +XsldbgSourcesImpl::~XsldbgSourcesImpl(){ + debugger = 0L; +} + +void XsldbgSourcesImpl::slotProcSourceItem(QString fileName , QString parentFileName , int lineNumber ) +{ + if (fileName.isNull()){ + sourceListView->clear(); + }else{ + sourceListView->insertItem(new XsldbgGlobalListItem(sourceListView, + parentFileName, lineNumber, fileName)); + } +} + + +void XsldbgSourcesImpl::selectionChanged(QListViewItem *item) +{ + XsldbgGlobalListItem *sourceItem = dynamic_cast<XsldbgGlobalListItem*>(item); + if (sourceItem){ + debugger->gotoLine(sourceItem->getVarName(), 1); + } +} + +void XsldbgSourcesImpl::refresh() +{ + debugger->fakeInput("stylesheets", true) ; +} + + + + + +#include "xsldbgsourcesimpl.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbgsourcesimpl.h b/kxsldbg/kxsldbgpart/xsldbgsourcesimpl.h new file mode 100644 index 00000000..b8afe34e --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgsourcesimpl.h @@ -0,0 +1,53 @@ +/*************************************************************************** + xsldbgsourcesimpl.h - description + ------------------- + begin : Fri Jan 4 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. * + * * + ***************************************************************************/ + +#ifndef XSLDBGSOURCESIMPL_H +#define XSLDBGSOURCESIMPL_H + +/** + *@author Keith Isdale + */ + +#include "xsldbgsources.h" +#include "xsldbgdialogbase.h" + +class XsldbgDebugger; + +class XsldbgSourcesImpl : public XsldbgSources, public XsldbgDialogBase { + Q_OBJECT + +public: + XsldbgSourcesImpl(XsldbgDebugger *debugger, QWidget *parent=0, const char *name=0); + ~XsldbgSourcesImpl(); + +public slots: + void selectionChanged(QListViewItem *item); + + /** Process request to add source to view, First parameter is QString::null + to indicate start of source list notfication */ + void slotProcSourceItem(QString fileName , QString parentFileName , int lineNumber ); + + /** refresh data from source */ + void refresh(); + + +private: + XsldbgDebugger *debugger; + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgtemplatelistitem.cpp b/kxsldbg/kxsldbgpart/xsldbgtemplatelistitem.cpp new file mode 100644 index 00000000..8c58b9fc --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgtemplatelistitem.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** + xsldbgtemplatelistitem.cpp - description + ------------------- + begin : Mon Jan 21 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 "xsldbgtemplatelistitem.h" + +XsldbgTemplateListItem::XsldbgTemplateListItem(QListView *parent, + QString fileName, int lineNumber, QString templateName, QString modeName) + : XsldbgListItem(parent, 2, fileName, lineNumber) +{ + this->templateName = templateName; + setText(0, templateName); + this->modeName = modeName; + setText(1, modeName); +} + +XsldbgTemplateListItem::~XsldbgTemplateListItem() +{ +} diff --git a/kxsldbg/kxsldbgpart/xsldbgtemplatelistitem.h b/kxsldbg/kxsldbgpart/xsldbgtemplatelistitem.h new file mode 100644 index 00000000..5a10a6ff --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgtemplatelistitem.h @@ -0,0 +1,44 @@ +/*************************************************************************** + xsldbgtemplatelistitem.h - description + ------------------- + begin : Mon Jan 21 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGTEMPLATELISTITEM_H +#define XSLDBGTEMPLATELISTITEM_H + +/** + *@author Keith Isdale + */ +#include "xsldbglistitem.h" + +class XsldbgTemplateListItem : public XsldbgListItem { +public: + XsldbgTemplateListItem(QListView *parent, + QString fileName, int lineNumber, QString templateName, QString modeName); + ~XsldbgTemplateListItem(); + + /** return the name of this template */ + QString getTemplateName(); + + /** return the mode of this template */ + QString getModeName(); + +private: + QString templateName; + QString modeName; + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgtemplates.ui b/kxsldbg/kxsldbgpart/xsldbgtemplates.ui new file mode 100644 index 00000000..9804bcef --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgtemplates.ui @@ -0,0 +1,100 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>XsldbgTemplates</class> +<author>Keith Isdale <k_isdale@tpg.com.au></author> +<widget class="QWidget"> + <property name="name"> + <cstring>XsldbgTemplates</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>491</width> + <height>232</height> + </rect> + </property> + <property name="caption"> + <string>Xsldbg Templates</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QListView" row="0" column="0"> + <column> + <property name="text"> + <string>Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Mode</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Source File Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Line Number</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>templatesListView</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>templatesListView</sender> + <signal>selectionChanged(QListViewItem*)</signal> + <receiver>XsldbgTemplates</receiver> + <slot>selectionChanged(QListViewItem*)</slot> + </connection> +</connections> +<slots> + <slot>selectionChanged(QListViewItem*)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kxsldbg/kxsldbgpart/xsldbgtemplatesimpl.cpp b/kxsldbg/kxsldbgpart/xsldbgtemplatesimpl.cpp new file mode 100644 index 00000000..ebc25bee --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgtemplatesimpl.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** + xsldbgtemplatesimpl.cpp - description + ------------------- + begin : Fri Jan 4 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 <qlistview.h> +#include <qlineedit.h> + +#include "xsldbgdebugger.h" +#include "xsldbgtemplatesimpl.h" +#include "xsldbgtemplatelistitem.h" + +XsldbgTemplatesImpl::XsldbgTemplatesImpl(XsldbgDebugger *debugger, + QWidget *parent /*=0*/, const char *name /*=0*/) + : XsldbgTemplates(parent, name), XsldbgDialogBase() +{ + this->debugger = debugger; + + connect(debugger, SIGNAL(templateItem(QString /* name*/, QString /*mode*/, QString /* fileName */, int /* lineNumber */)), + this, SLOT(slotProcTemplateItem(QString /* name*/, QString /*mode*/, QString /* fileName */, int /* lineNumber */))); + connect( templatesListView, SIGNAL(selectionChanged(QListViewItem *)), + this, SLOT(selectionChanged(QListViewItem*))); + + show(); +} + +XsldbgTemplatesImpl::~XsldbgTemplatesImpl(){ + debugger = 0L; +} + + +void XsldbgTemplatesImpl::slotProcTemplateItem(QString name, QString mode, QString fileName , int lineNumber ) +{ + if (name.isNull()) + templatesListView->clear(); + else + templatesListView->insertItem(new XsldbgTemplateListItem(templatesListView, + fileName, lineNumber, name, mode)); +} + + +void XsldbgTemplatesImpl::selectionChanged(QListViewItem *item) +{ + XsldbgTemplateListItem *templateItem = dynamic_cast<XsldbgTemplateListItem*>(item); + if (templateItem){ + debugger->gotoLine(templateItem->getFileName(), templateItem->getLineNumber()); + } +} + +void XsldbgTemplatesImpl::refresh() +{ + debugger->fakeInput("templates", true) ; +} + + + +#include "xsldbgtemplatesimpl.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbgtemplatesimpl.h b/kxsldbg/kxsldbgpart/xsldbgtemplatesimpl.h new file mode 100644 index 00000000..1a9705fe --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgtemplatesimpl.h @@ -0,0 +1,55 @@ +/*************************************************************************** + xsldbgtemplatesimpl.h - description + ------------------- + begin : Fri Jan 4 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. * + * * + ***************************************************************************/ + +#ifndef XSLDBGTEMPLATESIMPL_H +#define XSLDBGTEMPLATESIMPL_H + + +/** + *@author Keith Isdale + */ + + +#include "xsldbgtemplates.h" +#include "xsldbgdialogbase.h" + +class XsldbgDebugger; + +class XsldbgTemplatesImpl : public XsldbgTemplates, public XsldbgDialogBase { + Q_OBJECT + +public: + XsldbgTemplatesImpl(XsldbgDebugger *debugger, QWidget *parent=0, const char *name=0); + ~XsldbgTemplatesImpl(); + +public slots: + void selectionChanged(QListViewItem *item); + + /** Process request to add template to view, First parameter is QString::null + to indicate start of template list notfication */ + void slotProcTemplateItem(QString name, QString mode, QString fileName , int lineNumber ); + + /** refresh data from source */ + void refresh(); + + +private: + XsldbgDebugger *debugger; + +}; + +#endif diff --git a/kxsldbg/kxsldbgpart/xsldbgwalkspeed.ui b/kxsldbg/kxsldbgpart/xsldbgwalkspeed.ui new file mode 100644 index 00000000..2088d97f --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgwalkspeed.ui @@ -0,0 +1,239 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>XsldbgWalkSpeed</class> +<author>Keith Isdale <k_isdale@tpg.com.au></author> +<widget class="QDialog"> + <property name="name"> + <cstring>XsldbgWalkSpeed</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>382</width> + <height>292</height> + </rect> + </property> + <property name="caption"> + <string>Configure xsldbg's Walk Speed</string> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>4</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>60</height> + </size> + </property> + <property name="text"> + <string>Change the speed at which xsldbg walks through execution of the stylesheet.</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter|AlignLeft</set> + </property> + <property name="wordwrap" stdset="0"> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>51</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Slow</string> + </property> + </widget> + <widget class="QSlider"> + <property name="name"> + <cstring>walkSpeedSlider</cstring> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="maxValue"> + <number>9</number> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Fast</string> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>51</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton1</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>PushButton2</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>PushButton1</sender> + <signal>clicked()</signal> + <receiver>XsldbgWalkSpeed</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>PushButton2</sender> + <signal>clicked()</signal> + <receiver>XsldbgWalkSpeed</receiver> + <slot>reject()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kxsldbg/kxsldbgpart/xsldbgwalkspeedimpl.cpp b/kxsldbg/kxsldbgpart/xsldbgwalkspeedimpl.cpp new file mode 100644 index 00000000..376fbfb7 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgwalkspeedimpl.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** + xsldbgwalkspeedimpl.cpp - description + ------------------- + begin : Fri Jan 25 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 <qslider.h> + +#include "xsldbgdebugger.h" +#include "xsldbgwalkspeedimpl.h" + +XsldbgWalkSpeedImpl::XsldbgWalkSpeedImpl(XsldbgDebugger *debugger, + QWidget *parent /*=0 */, const char *name /*=0*/ ) + : XsldbgWalkSpeed(parent, name, false) +{ + this->debugger = debugger; +} + +XsldbgWalkSpeedImpl::~XsldbgWalkSpeedImpl() +{ +} + +void XsldbgWalkSpeedImpl::accept() +{ + /* For xsldbg 1 means fast speed 9 means slow so invert the slider value to suit + ie : a slider value of 1 results in walk speed of 9 */ + debugger->slotWalkSpeed(10 - walkSpeedSlider->value()); + hide(); +} + +void XsldbgWalkSpeedImpl::reject() +{ + hide(); +} + + + +#include "xsldbgwalkspeedimpl.moc" diff --git a/kxsldbg/kxsldbgpart/xsldbgwalkspeedimpl.h b/kxsldbg/kxsldbgpart/xsldbgwalkspeedimpl.h new file mode 100644 index 00000000..dafe86d7 --- /dev/null +++ b/kxsldbg/kxsldbgpart/xsldbgwalkspeedimpl.h @@ -0,0 +1,45 @@ +/*************************************************************************** + xsldbgwalkspeedimpl.h - description + ------------------- + begin : Fri Jan 25 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. * + * * + ************************************************************************************/ + +#ifndef XSLDBGWALKSPEEDIMPL_H +#define XSLDBGWALKSPEEDIMPL_H + +/** + *@author Keith Isdale + */ + +#include "xsldbgwalkspeed.h" + +class XsldbgDebugger; + +class XsldbgWalkSpeedImpl : public XsldbgWalkSpeed { + Q_OBJECT + +public: + XsldbgWalkSpeedImpl(XsldbgDebugger *debugger, QWidget *parent=0, const char *name=0); + ~XsldbgWalkSpeedImpl(); + +public slots: + void accept() ; + void reject(); + +private: + XsldbgDebugger *debugger; + +}; + +#endif diff --git a/kxsldbg/lo16-app-kxsldbg.png b/kxsldbg/lo16-app-kxsldbg.png Binary files differnew file mode 100644 index 00000000..0985586b --- /dev/null +++ b/kxsldbg/lo16-app-kxsldbg.png diff --git a/kxsldbg/lo32-app-kxsldbg.png b/kxsldbg/lo32-app-kxsldbg.png Binary files differnew file mode 100644 index 00000000..12542c8a --- /dev/null +++ b/kxsldbg/lo32-app-kxsldbg.png diff --git a/kxsldbg/main.cpp b/kxsldbg/main.cpp new file mode 100644 index 00000000..ca7b18b3 --- /dev/null +++ b/kxsldbg/main.cpp @@ -0,0 +1,38 @@ +#include "kxsldbg.h" +#include <kapplication.h> +#include <kaboutdata.h> +#include <kcmdlineargs.h> +#include <klocale.h> +#include <kdebug.h> + +static const char *description = + I18N_NOOP("A KDE KPart Application for xsldbg, an XSLT debugger"); + +static const char *version = VERSION; +static const KCmdLineOptions options[] = +{ + { "+XSLSource", I18N_NOOP("XSL script to run"), 0}, + { "+XMLData", I18N_NOOP("XML data to be transformed"), 0}, + { "+OutputFile", I18N_NOOP("File to save results to"), 0}, + KCmdLineLastOption // End of options. +}; + +int main(int argc, char **argv) +{ + KAboutData about("kxsldbg", I18N_NOOP("KXSLDbg"), version, description, KAboutData::License_GPL, "(C) 2003 Keith Isdale", 0, 0, "k_isdale@tpg.com.au"); + about.addAuthor( "Keith Isdale", 0, "k_isdale@tpg.com.au" ); + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions( options ); + KApplication app; + + // see if we are starting with session management + if (app.isRestored()) + RESTORE(KXsldbg) + else + { + KXsldbg *widget = new KXsldbg; + widget->show(); + } + + return app.exec(); +} diff --git a/kxsldbg/output.txt b/kxsldbg/output.txt new file mode 100644 index 00000000..0d7db4bb --- /dev/null +++ b/kxsldbg/output.txt @@ -0,0 +1,50 @@ + + xsldbg version 0.5.9 + ==================== + + xsldbg help + ___________ + +xsldbg is similar to gdb. It has three major modes of execution of stylesheets. + Run the whole stylesheet + Step to next xsl instruction + Continue until next break point is found, or stylesheet has restarted + +On systems with readline library available you can use the back/forward keys to navigate the history of entered commands. On all systems the last entered command can be repeated by just pressing the <ENTER> key. + + TEMPLATENAME : a valid template name + FILENAME : a valid URL for a stylesheet + LINENO : a valid line number in associated FILENAME + NUMBER_OF_FRAMES : a valid line number frames to change position by + BREAKPOINT_ID : a valid break point number + SPEED: speed to walk through code at, between 0 to 9 + (Comment): a comment about command meaning or usage + { opt1 | opt2 | opt2 .. etc} : Choose one of the opt's + XPATH : a xpath selection of node(s) + PARAM_ID : a valid parameter number as indicated by showparam command + PATH : a path to change working directory to + TEXT : free form text (no restrictions) + COMMAND : a valid command for the xsdbg + QNAME : a valid variable/parameter name + SOURCE : the stylesheet being/to be executed + DATA : the xml data(document) being/to be processed by the stylesheet + DEVICE_PATH : is a valid terminal on the operating system + TTY_LEVEL : is a valid level of input/output to use + + + Help related :help + Running related : {bye|exit|quit},step,stepup,stepdown,continue,run,trace + Libxslt parameter related :addparam,delparam,showparam + Template related :templates,where,frame + Break point related :break,showbreak,delete,enable + Expression viewing(xpath) :cat + Node viewing :ls,dir,du,cat,pwd + Variable viewing :globals,locals,cat + Node selection :source,data,cd + Searching :search + Operating system related :chdir,shell,tty + File related :validate,load,save,write,free + +nb: At the moment the file related commands as disabled because they are not completed. + + Help document version 0.5 diff --git a/kxsldbg/simpleio.c b/kxsldbg/simpleio.c new file mode 100644 index 00000000..900a698a --- /dev/null +++ b/kxsldbg/simpleio.c @@ -0,0 +1,144 @@ + +/*************************************************************************** + simpleio.c - use console io only + ------------------- + 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. * + * * + ***************************************************************************/ + +#include "kxsldbgpart/libxsldbg/xsldbg.h" + +#include <libxslt/xsltutils.h> + +#ifdef HAVE_READLINE +#include <readline/readline.h> +#ifdef HAVE_HISTORY +#include <readline/history.h> +#endif +#endif + +#include <string.h> + +#include "kxsldbgpart/libxsldbg/xsldbgmsg.h" +#include "kxsldbgpart/libxsldbg/xsldbgio.h" +#include "kxsldbgpart/libxsldbg/options.h" + + +int notifyXsldbgApp(XsldbgMessageEnum type, const void *data) +{ + return 1; +} + +int notifyStateXsldbgApp(XsldbgMessageEnum type, int commandId, + XsldbgCommandStateEnum commandState, const char *text) +{ + return 1; +} + +int notifyTextXsldbgApp(XsldbgMessageEnum type, const char *text) +{ + return 1; +} + + +/* 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) +{ + + static char last_read[DEBUG_BUFFER_SIZE] = { '\0' }; + +#ifdef HAVE_READLINE + + xmlChar *line_read; + + if (optionsGetIntOption(OPTIONS_STDOUT) == 0){ + /* Get a line from the user. */ + line_read = (xmlChar *) readline((char *) prompt); + + /* If the line has any text in it, save it on the history. */ + if (line_read && *line_read) { + char *temp = (char*)line_read; + add_history((char *) line_read); + strncpy((char*)last_read, (char*)line_read, DEBUG_BUFFER_SIZE - 1); + /* we must ensure that the data is free properly */ + line_read = xmlStrdup((xmlChar*)line_read); + free(temp); + } else { + free(line_read); + /* if only <Enter>is pressed then try last saved command line */ + line_read = xmlStrdup((xmlChar*)last_read); + } + }else{ + /* readline library will/may echo its output which is not wanted + when running in gdb mode.*/ + char line_buffer[DEBUG_BUFFER_SIZE]; + + if (prompt != NULL) + xsltGenericError(xsltGenericErrorContext, "%s", prompt); + if (!fgets(line_buffer, sizeof(line_buffer) - 1, stdin)){ + line_read = NULL; + }else{ + line_buffer[DEBUG_BUFFER_SIZE - 1] = 0; + if ((strlen(line_buffer) == 0) || (line_buffer[0] == '\n')){ + line_read = xmlStrdup((xmlChar*)last_read); + }else{ + add_history((char *) line_buffer); + line_read = xmlStrdup((xmlChar*)line_buffer); + strncpy((char*)last_read, (char*)line_read, sizeof(last_read) - 1); } + } + + } + return (line_read); + +#else + char line_read[DEBUG_BUFFER_SIZE]; + + if (prompt != NULL) + xsltGenericError(xsltGenericErrorContext, "%s", prompt); + fflush(stderr); + if (!fgets(line_read, DEBUG_BUFFER_SIZE - 1, stdin)) + return (NULL); + line_read[DEBUG_BUFFER_SIZE - 1] = 0; + /* Repeat of last command when gdb mode is disabled */ + if (optionsGetIntOption(OPTIONS_GDB) == 0){ + /* if only <Enter>is pressed then try last saved command line */ + if ((strlen(line_read) == 0) || (line_read[0] == '\n')) { + strncpy(line_read, last_read, sizeof(line_read) - 1); + } else { + strcpy(last_read, line_read); + } + } + return xmlStrdup((xmlChar*)line_read); +#endif + + } + +void xsldbgThreadCleanup(void); + +/* thread has died so cleanup after it not called directly but via + notifyXsldbgApp*/ +void +xsldbgThreadCleanup(void) +{ + +} diff --git a/kxsldbg/xsldbgmain.cpp b/kxsldbg/xsldbgmain.cpp new file mode 100644 index 00000000..23f6bb0b --- /dev/null +++ b/kxsldbg/xsldbgmain.cpp @@ -0,0 +1,256 @@ + +/*************************************************************************** + main.c - main fiule for xsldbg + ------------------- + begin : Sat Dec 22 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 "kxsldbgpart/libxsldbg/xsldbg.h" + +#include <libxslt/xsltutils.h> + +#ifdef HAVE_READLINE +#include <readline/readline.h> +#ifdef HAVE_HISTORY +#include <readline/history.h> +#endif +#endif + +#include <string.h> +#include "kxsldbgpart/libxsldbg/xsldbgmsg.h" +#include "kxsldbgpart/libxsldbg/xsldbgio.h" +#include "kxsldbgpart/libxsldbg/xsldbg.h" +#include "kxsldbgpart/libxsldbg/options.h" + +#include <libxslt/xsltutils.h> +#include <kapplication.h> +#include <kaboutdata.h> +#include <kcmdlineargs.h> +#include <klocale.h> +#include <kglobal.h> +#include <kdebug.h> +/* Forward delare private functions */ +static int notifyXsldbgAppSimple(XsldbgMessageEnum type, const void *data); +static int notifyStateXsldbgAppSimple(XsldbgMessageEnum type, int commandId, + XsldbgCommandStateEnum commandState, const char *text); +static int notifyTextXsldbgAppSimple(XsldbgMessageEnum type, const char *text); +static xmlChar * xslDbgShellReadlineSimple(xmlChar * prompt); + + +static const char *description = I18N_NOOP("A KDE console application for xsldbg, an XSLT debugger"); + +static const char *version = VERSION; + +static const KCmdLineOptions options[] = +{ + { "shell", I18N_NOOP("Start a shell"), 0}, + { "cd <path>", I18N_NOOP("Path to change into before loading files"), 0}, + { "param <name>:<value>",I18N_NOOP("Add a parameter named <name> and value <value> to XSL environment"), 0}, + { "lang <LANG>", I18N_NOOP("Use ISO 639 language code specified; for example en_US"), 0}, { "output file", I18N_NOOP("Save to a given file. See output command documentation"), 0}, + { "version", I18N_NOOP("Show the version of libxml and libxslt used"), 0}, + { "verbose", I18N_NOOP("Show logs of what is happening"), 0}, + { "timing", I18N_NOOP("Display the time used"), 0}, + { "repeat", I18N_NOOP("Run the transformation 20 times"), 0}, +#ifdef LIBXML_DEBUG_ENABLED + { "debug", I18N_NOOP("Dump the tree of the result instead"), 0}, +#endif + { "novalid", I18N_NOOP("Disable the DTD loading phase"), 0}, + { "noout", I18N_NOOP("Disable the output of the result"), 0}, + { "maxdepth val", I18N_NOOP("Increase the maximum depth"), 0}, + +#ifdef LIBXML_HTML_ENABLED + { "html", I18N_NOOP("The input document is(are) an HTML file(s)"), 0}, +#endif + +#ifdef LIBXML_DOCB_ENABLED + { "docbook", I18N_NOOP("The input document is SGML docbook"), 0}, +#endif + + { "nonet", I18N_NOOP("Disable the fetching DTDs or entities over network"), 0}, + +#ifdef LIBXML_CATALOG_ENABLED + { "catalogs", I18N_NOOP("Use the catalogs from $SGML_CATALOG_FILES"), 0}, +#endif + +#ifdef LIBXML_XINCLUDE_ENABLED + { "noxinclude", I18N_NOOP("Disable XInclude processing on document input"), 0}, +#endif + + { "profile", I18N_NOOP("Print profiling informations"), 0}, + { "nogdb", I18N_NOOP("Do not run gdb compatability mode and print less information"), 0}, + { "autoencode", I18N_NOOP("Detect and use encodings in the stylesheet"), 0}, + { "utf8input", I18N_NOOP("Treat command line input as encoded in UTF-8"), 0}, + { "preferhtml", I18N_NOOP("Use HTML output when generating search reports"), 0}, + { "stdout", I18N_NOOP("Print all error messages to stdout, normally error messages go to stderr"), 0}, + { "noautorestart", I18N_NOOP("Disable the automatic restarting of execution when current processing pass is complete"), 0}, + { "+XSLSource", I18N_NOOP("XSL script to run"), 0}, + { "+XMLData", I18N_NOOP("XML data to be transformed"), 0}, + KCmdLineLastOption // End of options. +}; + +class XsldbgApp : public KApplication +{ + public: + XsldbgApp() + :KApplication(false, false) + { + xsldbgSetAppFunc(notifyXsldbgAppSimple); + xsldbgSetAppStateFunc(notifyStateXsldbgAppSimple); + xsldbgSetTextFunc(notifyTextXsldbgAppSimple); + xsldbgSetReadlineFunc(xslDbgShellReadlineSimple); + } + + int exec(){ + return xsldbgMain(0, 0); + } + +}; + +int main(int argc, char **argv) +{ + KLocale::setMainCatalogue("kxsldbg"); // Translations come from KXSLDbg's catalog + + QString xsldbgRunTimeInfo(i18n("Using libxml %1, libxslt %2 and libexslt %3\n").arg(xmlParserVersion).arg(xsltEngineVersion).arg(exsltLibraryVersion)); + QString libxmlCompileTimeInfo(i18n("xsldbg was compiled against libxml %1, libxslt %2 and libexslt %3\n").arg(LIBXML_VERSION).arg(LIBXSLT_VERSION).arg(LIBEXSLT_VERSION)); + QString libxsltCompileTimeInfo(i18n("libxslt %1 was compiled against libxml %2\n").arg(xsltLibxsltVersion).arg(xsltLibxmlVersion)); + QString libexsltCompileTimeInfo(i18n("libexslt %1 was compiled against libxml %2\n").arg(exsltLibexsltVersion).arg(exsltLibxmlVersion)); + QString freeFormText = xsldbgRunTimeInfo + libxmlCompileTimeInfo + libxsltCompileTimeInfo + libexsltCompileTimeInfo; + + KAboutData about("xsldbg", I18N_NOOP("Xsldbg"), version, description, KAboutData::License_GPL, "(C) 2003 Keith Isdale", freeFormText, 0, "k_isdale@tpg.com.au"); + about.addAuthor( "Keith Isdale", 0, "k_isdale@tpg.com.au" ); + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions( options ); + XsldbgApp app; + + return app.exec();; +} + +/* Private implmentation of messaging functions */ +int notifyXsldbgAppSimple(XsldbgMessageEnum type, const void *data) +{ + Q_UNUSED(type); + Q_UNUSED(data); + return 1; +} + +int notifyStateXsldbgAppSimple(XsldbgMessageEnum type, int commandId, + XsldbgCommandStateEnum commandState, const char *text) +{ + Q_UNUSED(type); + Q_UNUSED(commandId); + Q_UNUSED(commandState); + Q_UNUSED(text); + return 1; +} + +int notifyTextXsldbgAppSimple(XsldbgMessageEnum type, const char *text) +{ + Q_UNUSED(type); + Q_UNUSED(text); + return 1; +} + + +/* 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 * +xslDbgShellReadlineSimple(xmlChar * prompt) +{ + + static char last_read[DEBUG_BUFFER_SIZE] = { '\0' }; + +#ifdef HAVE_READLINE + + xmlChar *line_read; + + if (optionsGetIntOption(OPTIONS_STDOUT) == 0){ + /* Get a line from the user. */ + line_read = (xmlChar *) readline((char *) prompt); + + /* If the line has any text in it, save it on the history. */ + if (line_read && *line_read) { + char *temp = (char*)line_read; + add_history((char *) line_read); + strncpy((char*)last_read, (char*)line_read, DEBUG_BUFFER_SIZE - 1); + /* we must ensure that the data is free properly */ + line_read = xmlStrdup((xmlChar*)line_read); + free(temp); + } else { + free(line_read); + /* if only <Enter>is pressed then try last saved command line */ + line_read = xmlStrdup((xmlChar*)last_read); + } + }else{ + /* readline library will/may echo its output which is not wanted + when running in gdb mode.*/ + char line_buffer[DEBUG_BUFFER_SIZE]; + + if (prompt != NULL) + xsltGenericError(xsltGenericErrorContext, "%s", prompt); + if (!fgets(line_buffer, sizeof(line_buffer) - 1, stdin)){ + line_read = NULL; + }else{ + line_buffer[DEBUG_BUFFER_SIZE - 1] = 0; + if ((strlen(line_buffer) == 0) || (line_buffer[0] == '\n')){ + line_read = xmlStrdup((xmlChar*)last_read); + }else{ + add_history((char *) line_buffer); + line_read = xmlStrdup((xmlChar*)line_buffer); + strncpy((char*)last_read, (char*)line_read, sizeof(last_read) - 1); } + } + + } + return (line_read); + +#else + char line_read[DEBUG_BUFFER_SIZE]; + + if (prompt != NULL) + xsltGenericError(xsltGenericErrorContext, "%s", prompt); + fflush(stderr); + if (!fgets(line_read, DEBUG_BUFFER_SIZE - 1, stdin)) + return (NULL); + line_read[DEBUG_BUFFER_SIZE - 1] = 0; + /* if only <Enter>is pressed then try last saved command line */ + if ((strlen(line_read) == 0) || (line_read[0] == '\n')) { + strncpy(line_read, last_read, sizeof(line_read) - 1); + } else { + strcpy(last_read, line_read); + } + return xmlStrdup((xmlChar*)line_read); +#endif + + } +/* +void xsldbgThreadCleanup(void); +*/ +/* thread has died so cleanup after it not called directly but via + notifyXsldbgApp*/ +/* +void +xsldbgThreadCleanup(void) +{ + +} +*/ + + |