summaryrefslogtreecommitdiffstats
path: root/kdbg
diff options
context:
space:
mode:
authorSlávek Banko <slavek.banko@axis.cz>2013-07-03 01:47:30 +0200
committerSlávek Banko <slavek.banko@axis.cz>2013-07-03 01:47:30 +0200
commit239e873a38fa91a3fbd27e134bda015922abbabd (patch)
treed7c79f740bce93768ee78b6b787c83a2115b047f /kdbg
downloadkdbg-239e873a38fa91a3fbd27e134bda015922abbabd.tar.gz
kdbg-239e873a38fa91a3fbd27e134bda015922abbabd.zip
Initial import
Diffstat (limited to 'kdbg')
-rw-r--r--kdbg/Makefile.am98
-rw-r--r--kdbg/Makefile.in1288
-rw-r--r--kdbg/brkpt.cpp513
-rw-r--r--kdbg/brkpt.h75
-rw-r--r--kdbg/commandids.h14
-rw-r--r--kdbg/dbgdriver.cpp527
-rw-r--r--kdbg/dbgdriver.h622
-rw-r--r--kdbg/dbgmainwnd.cpp876
-rw-r--r--kdbg/dbgmainwnd.h113
-rw-r--r--kdbg/debugger.cpp2210
-rw-r--r--kdbg/debugger.h556
-rw-r--r--kdbg/doc/Makefile.am3
-rw-r--r--kdbg/doc/Makefile.in721
-rw-r--r--kdbg/doc/de/Makefile.am27
-rw-r--r--kdbg/doc/de/Makefile.in609
-rw-r--r--kdbg/doc/de/argspwdenv.html50
-rw-r--r--kdbg/doc/de/breakptlist.html82
-rw-r--r--kdbg/doc/de/globaloptions.html72
-rw-r--r--kdbg/doc/de/howdoi.html83
-rw-r--r--kdbg/doc/de/index.html190
-rw-r--r--kdbg/doc/de/localvars.html25
-rw-r--r--kdbg/doc/de/memory.html29
-rw-r--r--kdbg/doc/de/pgmoutput.html52
-rw-r--r--kdbg/doc/de/pgmsettings.html83
-rw-r--r--kdbg/doc/de/registers.html37
-rw-r--r--kdbg/doc/de/sourcecode.html30
-rw-r--r--kdbg/doc/de/stack.html25
-rw-r--r--kdbg/doc/de/threads.html44
-rw-r--r--kdbg/doc/de/tips.html45
-rw-r--r--kdbg/doc/de/watches.html27
-rw-r--r--kdbg/doc/en/Makefile.am23
-rw-r--r--kdbg/doc/en/Makefile.in604
-rw-r--r--kdbg/doc/en/argspwdenv.html42
-rw-r--r--kdbg/doc/en/breakptlist.html93
-rw-r--r--kdbg/doc/en/globaloptions.html78
-rw-r--r--kdbg/doc/en/howdoi.html76
-rw-r--r--kdbg/doc/en/index.html185
-rw-r--r--kdbg/doc/en/invocation.html34
-rw-r--r--kdbg/doc/en/localvars.html28
-rw-r--r--kdbg/doc/en/memory.html26
-rw-r--r--kdbg/doc/en/pgmoutput.html46
-rw-r--r--kdbg/doc/en/pgmsettings.html81
-rw-r--r--kdbg/doc/en/registers.html35
-rw-r--r--kdbg/doc/en/sourcecode.html28
-rw-r--r--kdbg/doc/en/stack.html23
-rw-r--r--kdbg/doc/en/threads.html42
-rw-r--r--kdbg/doc/en/tips.html47
-rw-r--r--kdbg/doc/en/types.html183
-rw-r--r--kdbg/doc/en/watches.html28
-rw-r--r--kdbg/doc/en/xslt.html24
-rw-r--r--kdbg/doc/ru/Makefile.am27
-rw-r--r--kdbg/doc/ru/Makefile.in609
-rw-r--r--kdbg/doc/ru/argspwdenv.html43
-rw-r--r--kdbg/doc/ru/breakptlist.html68
-rw-r--r--kdbg/doc/ru/globaloptions.html72
-rw-r--r--kdbg/doc/ru/howdoi.html78
-rw-r--r--kdbg/doc/ru/index.html177
-rw-r--r--kdbg/doc/ru/localvars.html19
-rw-r--r--kdbg/doc/ru/memory.html26
-rw-r--r--kdbg/doc/ru/pgmoutput.html43
-rw-r--r--kdbg/doc/ru/pgmsettings.html73
-rw-r--r--kdbg/doc/ru/registers.html31
-rw-r--r--kdbg/doc/ru/sourcecode.html31
-rw-r--r--kdbg/doc/ru/stack.html23
-rw-r--r--kdbg/doc/ru/threads.html38
-rw-r--r--kdbg/doc/ru/tips.html43
-rw-r--r--kdbg/doc/ru/types.html126
-rw-r--r--kdbg/doc/ru/watches.html20
-rw-r--r--kdbg/envvar.h24
-rw-r--r--kdbg/exprwnd.cpp831
-rw-r--r--kdbg/exprwnd.h180
-rw-r--r--kdbg/gdbdriver.cpp2572
-rw-r--r--kdbg/gdbdriver.h92
-rw-r--r--kdbg/kdbg.desktop42
-rw-r--r--kdbg/kdbgrc50
-rw-r--r--kdbg/kdbgui.rc88
-rw-r--r--kdbg/main.cpp139
-rw-r--r--kdbg/mainwndbase.cpp637
-rw-r--r--kdbg/mainwndbase.h153
-rw-r--r--kdbg/memwindow.cpp316
-rw-r--r--kdbg/memwindow.h55
-rw-r--r--kdbg/mydebug.h25
-rw-r--r--kdbg/pgmargs.cpp246
-rw-r--r--kdbg/pgmargs.h51
-rw-r--r--kdbg/pgmargsbase.cpp237
-rw-r--r--kdbg/pgmargsbase.ui571
-rw-r--r--kdbg/pgmsettings.cpp115
-rw-r--r--kdbg/pgmsettings.h53
-rw-r--r--kdbg/pics/Makefile.am56
-rw-r--r--kdbg/pics/Makefile.in698
-rw-r--r--kdbg/pics/brkcond.xpm20
-rw-r--r--kdbg/pics/brkdis.xpm21
-rw-r--r--kdbg/pics/brkena.xpm21
-rw-r--r--kdbg/pics/brkorph.xpm19
-rw-r--r--kdbg/pics/brktmp.xpm20
-rwxr-xr-xkdbg/pics/genanim.sh9
-rw-r--r--kdbg/pics/hi16-action-brkpt.pngbin0 -> 389 bytes
-rw-r--r--kdbg/pics/hi16-action-execopen.pngbin0 -> 684 bytes
-rw-r--r--kdbg/pics/hi16-action-pgmfinish.pngbin0 -> 441 bytes
-rw-r--r--kdbg/pics/hi16-action-pgmnext.pngbin0 -> 482 bytes
-rw-r--r--kdbg/pics/hi16-action-pgmnexti.pngbin0 -> 491 bytes
-rw-r--r--kdbg/pics/hi16-action-pgmrun.pngbin0 -> 477 bytes
-rw-r--r--kdbg/pics/hi16-action-pgmstep.pngbin0 -> 433 bytes
-rw-r--r--kdbg/pics/hi16-action-pgmstepi.pngbin0 -> 443 bytes
-rw-r--r--kdbg/pics/hi16-app-kdbg.pngbin0 -> 454 bytes
-rw-r--r--kdbg/pics/hi22-action-brkpt.pngbin0 -> 298 bytes
-rw-r--r--kdbg/pics/hi22-action-execopen.pngbin0 -> 1104 bytes
-rw-r--r--kdbg/pics/hi22-action-pgmfinish.pngbin0 -> 381 bytes
-rw-r--r--kdbg/pics/hi22-action-pgmnext.pngbin0 -> 359 bytes
-rw-r--r--kdbg/pics/hi22-action-pgmnexti.pngbin0 -> 383 bytes
-rw-r--r--kdbg/pics/hi22-action-pgmrun.pngbin0 -> 636 bytes
-rw-r--r--kdbg/pics/hi22-action-pgmstep.pngbin0 -> 367 bytes
-rw-r--r--kdbg/pics/hi22-action-pgmstepi.pngbin0 -> 390 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse.pngbin0 -> 5528 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse.xml259
-rw-r--r--kdbg/pics/hi22-action-pulse000000.pngbin0 -> 507 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000001.pngbin0 -> 508 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000002.pngbin0 -> 509 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000003.pngbin0 -> 508 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000004.pngbin0 -> 511 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000005.pngbin0 -> 513 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000006.pngbin0 -> 512 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000007.pngbin0 -> 520 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000008.pngbin0 -> 519 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000009.pngbin0 -> 527 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000010.pngbin0 -> 521 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000011.pngbin0 -> 521 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000012.pngbin0 -> 551 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000013.pngbin0 -> 549 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000014.pngbin0 -> 536 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000015.pngbin0 -> 525 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000016.pngbin0 -> 525 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000017.pngbin0 -> 543 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000018.pngbin0 -> 533 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000019.pngbin0 -> 529 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000020.pngbin0 -> 523 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000021.pngbin0 -> 517 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000022.pngbin0 -> 525 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000023.pngbin0 -> 529 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000024.pngbin0 -> 509 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000025.pngbin0 -> 517 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000026.pngbin0 -> 518 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000027.pngbin0 -> 512 bytes
-rw-r--r--kdbg/pics/hi22-action-pulse000028.pngbin0 -> 506 bytes
-rw-r--r--kdbg/pics/hi32-app-kdbg.pngbin0 -> 1233 bytes
-rw-r--r--kdbg/pics/hi48-app-kdbg.pngbin0 -> 1954 bytes
-rw-r--r--kdbg/pics/lo16-app-kdbg.pngbin0 -> 434 bytes
-rw-r--r--kdbg/pics/lo32-app-kdbg.pngbin0 -> 798 bytes
-rw-r--r--kdbg/pics/pcinner.xpm14
-rw-r--r--kdbg/pics/pcup.xpm14
-rw-r--r--kdbg/pics/pointer.xpm18
-rw-r--r--kdbg/pics/regs.xpm26
-rw-r--r--kdbg/pics/watch.xpm24
-rw-r--r--kdbg/pics/watchcoded.xpm26
-rw-r--r--kdbg/pics/watchdis.xpm22
-rw-r--r--kdbg/pics/watchena.xpm22
-rw-r--r--kdbg/prefdebugger.cpp48
-rw-r--r--kdbg/prefdebugger.h43
-rw-r--r--kdbg/prefmisc.cpp85
-rw-r--r--kdbg/prefmisc.h51
-rw-r--r--kdbg/procattach.cpp308
-rw-r--r--kdbg/procattach.h81
-rw-r--r--kdbg/procattachbase.cpp137
-rw-r--r--kdbg/procattachbase.ui276
-rw-r--r--kdbg/programconfig.cpp147
-rw-r--r--kdbg/programconfig.h37
-rw-r--r--kdbg/regwnd.cpp613
-rw-r--r--kdbg/regwnd.h44
-rw-r--r--kdbg/sourcewnd.cpp967
-rw-r--r--kdbg/sourcewnd.h124
-rw-r--r--kdbg/testprogs/Makefile.am62
-rw-r--r--kdbg/testprogs/Makefile.in885
-rw-r--r--kdbg/testprogs/anonstruct.cpp32
-rw-r--r--kdbg/testprogs/locals.cpp26
-rw-r--r--kdbg/testprogs/maths.cpp30
-rw-r--r--kdbg/testprogs/nestedclass.cpp31
-rw-r--r--kdbg/testprogs/qt.cpp41
-rw-r--r--kdbg/testprogs/repeats.cpp41
-rw-r--r--kdbg/testprogs/std.cpp58
-rw-r--r--kdbg/testprogs/templates.cpp117
-rw-r--r--kdbg/testprogs/test1.xml15
-rw-r--r--kdbg/testprogs/test1.xsl113
-rw-r--r--kdbg/testprogs/testfile.cpp202
-rw-r--r--kdbg/testprogs/widechar.cpp31
-rw-r--r--kdbg/testprogs/xsldoc.xml667
-rw-r--r--kdbg/testprogs/xsldoc.xsl114
-rw-r--r--kdbg/threadlist.cpp128
-rw-r--r--kdbg/threadlist.h39
-rw-r--r--kdbg/ttywnd.cpp239
-rw-r--r--kdbg/ttywnd.h69
-rw-r--r--kdbg/typetable.cpp409
-rw-r--r--kdbg/typetable.h193
-rw-r--r--kdbg/typetables/Makefile.am16
-rw-r--r--kdbg/typetables/Makefile.in600
-rw-r--r--kdbg/typetables/X11.kdbgtt9
-rw-r--r--kdbg/typetables/glib.kdbgtt7
-rw-r--r--kdbg/typetables/gtk+.kdbgtt7
-rw-r--r--kdbg/typetables/kdecore.kdbgtt7
-rw-r--r--kdbg/typetables/kdecore3.kdbgtt7
-rw-r--r--kdbg/typetables/qt.kdbgtt23
-rw-r--r--kdbg/typetables/qt2.kdbgtt28
-rw-r--r--kdbg/typetables/qt3.kdbgtt65
-rw-r--r--kdbg/typetables/qt4core.kdbgtt9
-rw-r--r--kdbg/typetables/stdc++.kdbgtt7
-rw-r--r--kdbg/typetables/stdc++6.kdbgtt45
-rw-r--r--kdbg/winstack.cpp449
-rw-r--r--kdbg/winstack.h147
-rw-r--r--kdbg/xsldbgdriver.cpp1452
-rw-r--r--kdbg/xsldbgdriver.h106
209 files changed, 29652 insertions, 0 deletions
diff --git a/kdbg/Makefile.am b/kdbg/Makefile.am
new file mode 100644
index 0000000..ce9790b
--- /dev/null
+++ b/kdbg/Makefile.am
@@ -0,0 +1,98 @@
+# set the include path for X, qt and KDE
+INCLUDES= $(all_includes)
+
+# claim, which subdirectories you want to install
+SUBDIRS = doc pics typetables testprogs
+
+####### This part is very kdbg specific
+# you can add here more. This one gets installed
+bin_PROGRAMS = kdbg
+
+# Which sources should be compiled for kdbg.
+kdbg_SOURCES = \
+ pgmargs.cpp \
+ pgmargsbase.ui \
+ procattach.cpp \
+ procattachbase.ui \
+ debugger.cpp \
+ programconfig.cpp \
+ dbgdriver.cpp \
+ gdbdriver.cpp \
+ xsldbgdriver.cpp \
+ brkpt.cpp \
+ exprwnd.cpp \
+ regwnd.cpp \
+ memwindow.cpp \
+ threadlist.cpp \
+ sourcewnd.cpp \
+ winstack.cpp \
+ ttywnd.cpp \
+ typetable.cpp \
+ prefdebugger.cpp \
+ prefmisc.cpp \
+ pgmsettings.cpp \
+ mainwndbase.cpp \
+ dbgmainwnd.cpp \
+ main.cpp
+
+# the library search path
+kdbg_LDFLAGS = \
+ $(all_libraries) $(KDE_RPATH)
+
+# the libraries to link against.
+kdbg_LDADD = $(LIB_KIO)
+
+# this option you can leave out. Just, if you use "make dist", you need it
+noinst_HEADERS = \
+ pgmargs.h \
+ procattach.h \
+ debugger.h \
+ programconfig.h \
+ dbgdriver.h \
+ gdbdriver.h \
+ xsldbgdriver.h \
+ brkpt.h \
+ exprwnd.h \
+ regwnd.h \
+ memwindow.h \
+ threadlist.h \
+ sourcewnd.h \
+ winstack.h \
+ ttywnd.h \
+ typetable.h \
+ prefdebugger.h \
+ prefmisc.h \
+ pgmsettings.h \
+ mainwndbase.h \
+ dbgmainwnd.h \
+ envvar.h \
+ commandids.h \
+ mydebug.h
+
+kdbg_METASOURCES = AUTO
+
+# if you "make clean", this files get removed. If you want to remove
+# them while "make distclean", use DISTCLEANFILES
+CLEANFILES = $(kdbg_METASOURCES)
+
+xdg_apps_DATA = kdbg.desktop
+
+configdir = $(kde_confdir)
+config_DATA = kdbgrc
+
+rcdir = $(kde_datadir)/kdbg
+rc_DATA = kdbgui.rc
+
+# Make messages.po and move it to $(top_srcdir)/po. "make merge" there.
+# the -x is for skipping messages already translated in kdelibs
+# Messages are generated in the source directory so that file names
+# mentioned in the .pot file are not prefixed by $(srcdir).
+messages:
+ cd $(srcdir) && \
+ extractrc *.rc *.ui > rc.cpp && \
+ LIST=`find . -name \*.h -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.C` && \
+ $(XGETTEXT) -C -ki18n -kI18N_NOOP -x $(includedir)/kde.pot \
+ $$LIST && mv messages.po $(top_srcdir)/po/kdbg.pot; \
+ rm -f rc.cpp
+
+EXTRA_DIST = kdbg.desktop kdbgrc
diff --git a/kdbg/Makefile.in b/kdbg/Makefile.in
new file mode 100644
index 0000000..e0f7b0d
--- /dev/null
+++ b/kdbg/Makefile.in
@@ -0,0 +1,1288 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 483858 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+bin_PROGRAMS = kdbg$(EXEEXT)
+subdir = kdbg
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(configdir)" \
+ "$(DESTDIR)$(rcdir)" "$(DESTDIR)$(xdg_appsdir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_kdbg_OBJECTS = pgmargs.$(OBJEXT) procattach.$(OBJEXT) \
+ debugger.$(OBJEXT) programconfig.$(OBJEXT) dbgdriver.$(OBJEXT) \
+ gdbdriver.$(OBJEXT) xsldbgdriver.$(OBJEXT) brkpt.$(OBJEXT) \
+ exprwnd.$(OBJEXT) regwnd.$(OBJEXT) memwindow.$(OBJEXT) \
+ threadlist.$(OBJEXT) sourcewnd.$(OBJEXT) winstack.$(OBJEXT) \
+ ttywnd.$(OBJEXT) typetable.$(OBJEXT) prefdebugger.$(OBJEXT) \
+ prefmisc.$(OBJEXT) pgmsettings.$(OBJEXT) mainwndbase.$(OBJEXT) \
+ dbgmainwnd.$(OBJEXT) main.$(OBJEXT)
+#>- kdbg_OBJECTS = $(am_kdbg_OBJECTS)
+#>+ 12
+kdbg_final_OBJECTS = kdbg.all_cpp.o
+kdbg_nofinal_OBJECTS = pgmargs.$(OBJEXT) procattach.$(OBJEXT) \
+ debugger.$(OBJEXT) programconfig.$(OBJEXT) dbgdriver.$(OBJEXT) \
+ gdbdriver.$(OBJEXT) xsldbgdriver.$(OBJEXT) brkpt.$(OBJEXT) \
+ exprwnd.$(OBJEXT) regwnd.$(OBJEXT) memwindow.$(OBJEXT) \
+ threadlist.$(OBJEXT) sourcewnd.$(OBJEXT) winstack.$(OBJEXT) \
+ ttywnd.$(OBJEXT) typetable.$(OBJEXT) prefdebugger.$(OBJEXT) \
+ prefmisc.$(OBJEXT) pgmsettings.$(OBJEXT) mainwndbase.$(OBJEXT) \
+ dbgmainwnd.$(OBJEXT) main.$(OBJEXT) pgmargsbase.$(OBJEXT) procattachbase.$(OBJEXT)\
+procattach.moc.o
+@KDE_USE_FINAL_FALSE@kdbg_OBJECTS = $(kdbg_nofinal_OBJECTS)
+@KDE_USE_FINAL_TRUE@kdbg_OBJECTS = $(kdbg_final_OBJECTS)
+am__DEPENDENCIES_1 =
+kdbg_DEPENDENCIES = $(am__DEPENDENCIES_1)
+#>- kdbg_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
+#>- $(kdbg_LDFLAGS) $(LDFLAGS) -o $@
+#>+ 3
+kdbg_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
+ $(kdbg_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
+am__depfiles_maybe = depfiles
+#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 2
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+#>- LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 3
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+CXXLD = $(CXX)
+#>- CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+#>- $(LDFLAGS) -o $@
+#>+ 3
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(kdbg_SOURCES)
+DIST_SOURCES = $(kdbg_SOURCES)
+#>- RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+#>- html-recursive info-recursive install-data-recursive \
+#>- install-dvi-recursive install-exec-recursive \
+#>- install-html-recursive install-info-recursive \
+#>- install-pdf-recursive install-ps-recursive install-recursive \
+#>- installcheck-recursive installdirs-recursive pdf-recursive \
+#>- ps-recursive uninstall-recursive
+#>+ 7
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive nmcheck-recursive bcheck-recursive
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+configDATA_INSTALL = $(INSTALL_DATA)
+rcDATA_INSTALL = $(INSTALL_DATA)
+xdg_appsDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(config_DATA) $(rc_DATA) $(xdg_apps_DATA)
+HEADERS = $(noinst_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARTSCCONFIG = @ARTSCCONFIG@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOPIDLNG = @DCOPIDLNG@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
+KCONFIG_COMPILER = @KCONFIG_COMPILER@
+KDECONFIG = @KDECONFIG@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
+KDE_MT_LIBS = @KDE_MT_LIBS@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_FPIE = @KDE_USE_FPIE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+KDE_USE_PIE = @KDE_USE_PIE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPTHREAD = @LIBPTHREAD@
+LIBRESOLV = @LIBRESOLV@
+LIBS = @LIBS@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBZ = @LIBZ@
+LIB_KAB = @LIB_KAB@
+LIB_KABC = @LIB_KABC@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDED = @LIB_KDED@
+LIB_KDEPIM = @LIB_KDEPIM@
+LIB_KDEPRINT = @LIB_KDEPRINT@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KDNSSD = @LIB_KDNSSD@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMPROXY = @LIB_KIMPROXY@
+LIB_KIO = @LIB_KIO@
+LIB_KJS = @LIB_KJS@
+LIB_KNEWSTUFF = @LIB_KNEWSTUFF@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KUNITTEST = @LIB_KUNITTEST@
+LIB_KUTILS = @LIB_KUTILS@
+LIB_POLL = @LIB_POLL@
+LIB_QPE = @LIB_QPE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_X11 = @LIB_X11@
+LIB_XEXT = @LIB_XEXT@
+LIB_XRENDER = @LIB_XRENDER@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKEKDEWIDGETS = @MAKEKDEWIDGETS@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MKDIR_P = @MKDIR_P@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PS_COMMAND = @PS_COMMAND@
+QTE_NORTTI = @QTE_NORTTI@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+UIC_TR = @UIC_TR@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+XGETTEXT = @XGETTEXT@
+XMKMF = @XMKMF@
+XMLLINT = @XMLLINT@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+X_RPATH = @X_RPATH@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_kcfgdir = @kde_kcfgdir@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_qtver = @kde_qtver@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_styledir = @kde_styledir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+kde_widgetdir = @kde_widgetdir@
+kdeinitdir = @kdeinitdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+xdg_appsdir = @xdg_appsdir@
+xdg_directorydir = @xdg_directorydir@
+xdg_menudir = @xdg_menudir@
+
+# set the include path for X, qt and KDE
+INCLUDES = $(all_includes)
+
+# claim, which subdirectories you want to install
+SUBDIRS = doc pics typetables testprogs
+
+# Which sources should be compiled for kdbg.
+#>- kdbg_SOURCES = \
+#>- pgmargs.cpp \
+#>- pgmargsbase.ui \
+#>- procattach.cpp \
+#>- procattachbase.ui \
+#>- debugger.cpp \
+#>- programconfig.cpp \
+#>- dbgdriver.cpp \
+#>- gdbdriver.cpp \
+#>- xsldbgdriver.cpp \
+#>- brkpt.cpp \
+#>- exprwnd.cpp \
+#>- regwnd.cpp \
+#>- memwindow.cpp \
+#>- threadlist.cpp \
+#>- sourcewnd.cpp \
+#>- winstack.cpp \
+#>- ttywnd.cpp \
+#>- typetable.cpp \
+#>- prefdebugger.cpp \
+#>- prefmisc.cpp \
+#>- pgmsettings.cpp \
+#>- mainwndbase.cpp \
+#>- dbgmainwnd.cpp \
+#>- main.cpp
+#>+ 25
+kdbg_SOURCES=\
+ pgmargs.cpp \
+ \
+ procattach.cpp \
+ \
+ debugger.cpp \
+ programconfig.cpp \
+ dbgdriver.cpp \
+ gdbdriver.cpp \
+ xsldbgdriver.cpp \
+ brkpt.cpp \
+ exprwnd.cpp \
+ regwnd.cpp \
+ memwindow.cpp \
+ threadlist.cpp \
+ sourcewnd.cpp \
+ winstack.cpp \
+ ttywnd.cpp \
+ typetable.cpp \
+ prefdebugger.cpp \
+ prefmisc.cpp \
+ pgmsettings.cpp \
+ mainwndbase.cpp \
+ dbgmainwnd.cpp \
+ main.cpp pgmargsbase.cpp procattachbase.cpp
+
+
+# the library search path
+kdbg_LDFLAGS = \
+ $(all_libraries) $(KDE_RPATH)
+
+
+# the libraries to link against.
+kdbg_LDADD = $(LIB_KIO)
+
+# this option you can leave out. Just, if you use "make dist", you need it
+noinst_HEADERS = \
+ pgmargs.h \
+ procattach.h \
+ debugger.h \
+ programconfig.h \
+ dbgdriver.h \
+ gdbdriver.h \
+ xsldbgdriver.h \
+ brkpt.h \
+ exprwnd.h \
+ regwnd.h \
+ memwindow.h \
+ threadlist.h \
+ sourcewnd.h \
+ winstack.h \
+ ttywnd.h \
+ typetable.h \
+ prefdebugger.h \
+ prefmisc.h \
+ pgmsettings.h \
+ mainwndbase.h \
+ dbgmainwnd.h \
+ envvar.h \
+ commandids.h \
+ mydebug.h
+
+#>- kdbg_METASOURCES = AUTO
+
+# if you "make clean", this files get removed. If you want to remove
+# them while "make distclean", use DISTCLEANFILES
+CLEANFILES = $(kdbg_METASOURCES)
+xdg_apps_DATA = kdbg.desktop
+configdir = $(kde_confdir)
+config_DATA = kdbgrc
+rcdir = $(kde_datadir)/kdbg
+rc_DATA = kdbgui.rc
+EXTRA_DIST = kdbg.desktop kdbgrc
+#>- all: all-recursive
+#>+ 1
+all: docs-am all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu kdbg/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+kdbg$(EXEEXT): $(kdbg_OBJECTS) $(kdbg_DEPENDENCIES)
+ @rm -f kdbg$(EXEEXT)
+ $(kdbg_LINK) $(kdbg_OBJECTS) $(kdbg_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brkpt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbgdriver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbgmainwnd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debugger.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exprwnd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdbdriver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mainwndbase.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memwindow.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pgmargs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pgmsettings.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prefdebugger.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prefmisc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/procattach.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/programconfig.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regwnd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sourcewnd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threadlist.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttywnd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/typetable.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/winstack.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsldbgdriver.Po@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-configDATA: $(config_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(configdir)" || $(MKDIR_P) "$(DESTDIR)$(configdir)"
+ @list='$(config_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(configDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(configdir)/$$f'"; \
+ $(configDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(configdir)/$$f"; \
+ done
+
+uninstall-configDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(config_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(configdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(configdir)/$$f"; \
+ done
+install-rcDATA: $(rc_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(rcdir)" || $(MKDIR_P) "$(DESTDIR)$(rcdir)"
+ @list='$(rc_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(rcDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(rcdir)/$$f'"; \
+ $(rcDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(rcdir)/$$f"; \
+ done
+
+uninstall-rcDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(rc_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(rcdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(rcdir)/$$f"; \
+ done
+install-xdg_appsDATA: $(xdg_apps_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(xdg_appsdir)" || $(MKDIR_P) "$(DESTDIR)$(xdg_appsdir)"
+ @list='$(xdg_apps_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(xdg_appsDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(xdg_appsdir)/$$f'"; \
+ $(xdg_appsDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(xdg_appsdir)/$$f"; \
+ done
+
+uninstall-xdg_appsDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(xdg_apps_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(xdg_appsdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(xdg_appsdir)/$$f"; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(PROGRAMS) $(DATA) $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(configdir)" "$(DESTDIR)$(rcdir)" "$(DESTDIR)$(xdg_appsdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-recursive
+#>+ 1
+clean: kde-rpo-clean clean-recursive
+
+#>- clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+#>+ 1
+clean-am: clean-metasources clean-ui clean-bcheck clean-final clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-configDATA install-rcDATA \
+ install-xdg_appsDATA
+
+install-dvi: install-dvi-recursive
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-recursive
+
+install-info: install-info-recursive
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-ps: install-ps-recursive
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-configDATA \
+ uninstall-rcDATA uninstall-xdg_appsDATA
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
+ install-strip
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libtool ctags ctags-recursive distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-binPROGRAMS install-configDATA \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-rcDATA \
+ install-strip install-xdg_appsDATA installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am \
+ uninstall-binPROGRAMS uninstall-configDATA uninstall-rcDATA \
+ uninstall-xdg_appsDATA
+
+
+# Make messages.po and move it to $(top_srcdir)/po. "make merge" there.
+# the -x is for skipping messages already translated in kdelibs
+# Messages are generated in the source directory so that file names
+# mentioned in the .pot file are not prefixed by $(srcdir).
+messages:
+ cd $(srcdir) && \
+ extractrc *.rc *.ui > rc.cpp && \
+ LIST=`find . -name \*.h -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.C` && \
+ $(XGETTEXT) -C -ki18n -kI18N_NOOP -x $(includedir)/kde.pot \
+ $$LIST && mv messages.po $(top_srcdir)/po/kdbg.pot; \
+ rm -f rc.cpp
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+
+#>+ 3
+ttywnd.moc: $(srcdir)/ttywnd.h
+ $(MOC) $(srcdir)/ttywnd.h -o ttywnd.moc
+
+#>+ 2
+mocs: ttywnd.moc
+
+#>+ 3
+memwindow.moc: $(srcdir)/memwindow.h
+ $(MOC) $(srcdir)/memwindow.h -o memwindow.moc
+
+#>+ 2
+mocs: memwindow.moc
+
+#>+ 3
+brkpt.moc: $(srcdir)/brkpt.h
+ $(MOC) $(srcdir)/brkpt.h -o brkpt.moc
+
+#>+ 2
+mocs: brkpt.moc
+
+#>+ 3
+mainwndbase.moc: $(srcdir)/mainwndbase.h
+ $(MOC) $(srcdir)/mainwndbase.h -o mainwndbase.moc
+
+#>+ 2
+mocs: mainwndbase.moc
+
+#>+ 3
+sourcewnd.moc: $(srcdir)/sourcewnd.h
+ $(MOC) $(srcdir)/sourcewnd.h -o sourcewnd.moc
+
+#>+ 2
+mocs: sourcewnd.moc
+
+#>+ 3
+gdbdriver.moc: $(srcdir)/gdbdriver.h
+ $(MOC) $(srcdir)/gdbdriver.h -o gdbdriver.moc
+
+#>+ 2
+mocs: gdbdriver.moc
+
+#>+ 3
+pgmargs.moc: $(srcdir)/pgmargs.h
+ $(MOC) $(srcdir)/pgmargs.h -o pgmargs.moc
+
+#>+ 2
+mocs: pgmargs.moc
+
+#>+ 3
+threadlist.moc: $(srcdir)/threadlist.h
+ $(MOC) $(srcdir)/threadlist.h -o threadlist.moc
+
+#>+ 2
+mocs: threadlist.moc
+
+#>+ 3
+exprwnd.moc: $(srcdir)/exprwnd.h
+ $(MOC) $(srcdir)/exprwnd.h -o exprwnd.moc
+
+#>+ 2
+mocs: exprwnd.moc
+
+#>+ 3
+dbgmainwnd.moc: $(srcdir)/dbgmainwnd.h
+ $(MOC) $(srcdir)/dbgmainwnd.h -o dbgmainwnd.moc
+
+#>+ 2
+mocs: dbgmainwnd.moc
+
+#>+ 3
+debugger.moc: $(srcdir)/debugger.h
+ $(MOC) $(srcdir)/debugger.h -o debugger.moc
+
+#>+ 2
+mocs: debugger.moc
+
+#>+ 3
+procattach.moc.cpp: $(srcdir)/procattach.h
+ $(MOC) $(srcdir)/procattach.h -o procattach.moc.cpp
+
+#>+ 2
+mocs: procattach.moc.cpp
+
+#>+ 3
+xsldbgdriver.moc: $(srcdir)/xsldbgdriver.h
+ $(MOC) $(srcdir)/xsldbgdriver.h -o xsldbgdriver.moc
+
+#>+ 2
+mocs: xsldbgdriver.moc
+
+#>+ 3
+pgmsettings.moc: $(srcdir)/pgmsettings.h
+ $(MOC) $(srcdir)/pgmsettings.h -o pgmsettings.moc
+
+#>+ 2
+mocs: pgmsettings.moc
+
+#>+ 3
+dbgdriver.moc: $(srcdir)/dbgdriver.h
+ $(MOC) $(srcdir)/dbgdriver.h -o dbgdriver.moc
+
+#>+ 2
+mocs: dbgdriver.moc
+
+#>+ 3
+regwnd.moc: $(srcdir)/regwnd.h
+ $(MOC) $(srcdir)/regwnd.h -o regwnd.moc
+
+#>+ 2
+mocs: regwnd.moc
+
+#>+ 3
+winstack.moc: $(srcdir)/winstack.h
+ $(MOC) $(srcdir)/winstack.h -o winstack.moc
+
+#>+ 2
+mocs: winstack.moc
+
+#>+ 3
+clean-metasources:
+ -rm -f ttywnd.moc memwindow.moc brkpt.moc mainwndbase.moc sourcewnd.moc gdbdriver.moc pgmargs.moc threadlist.moc exprwnd.moc dbgmainwnd.moc debugger.moc procattach.moc.cpp xsldbgdriver.moc pgmsettings.moc dbgdriver.moc regwnd.moc winstack.moc
+
+#>+ 2
+KDE_DIST=pgmargsbase.ui procattachbase.ui Makefile.in Makefile.am kdbgui.rc
+
+#>+ 5
+clean-ui:
+ -rm -f \
+ pgmargsbase.cpp pgmargsbase.h pgmargsbase.moc \
+ procattachbase.cpp procattachbase.h procattachbase.moc
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-recursive
+
+bcheck-am:
+ @for i in ; do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXXCOMPILE) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 11
+kdbg.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/pgmargs.cpp $(srcdir)/procattach.cpp $(srcdir)/debugger.cpp $(srcdir)/programconfig.cpp $(srcdir)/dbgdriver.cpp $(srcdir)/gdbdriver.cpp $(srcdir)/xsldbgdriver.cpp $(srcdir)/brkpt.cpp $(srcdir)/exprwnd.cpp $(srcdir)/regwnd.cpp $(srcdir)/memwindow.cpp $(srcdir)/threadlist.cpp $(srcdir)/sourcewnd.cpp $(srcdir)/winstack.cpp $(srcdir)/ttywnd.cpp $(srcdir)/typetable.cpp $(srcdir)/prefdebugger.cpp $(srcdir)/prefmisc.cpp $(srcdir)/pgmsettings.cpp $(srcdir)/mainwndbase.cpp $(srcdir)/dbgmainwnd.cpp $(srcdir)/main.cpp $(srcdir)/pgmargsbase.cpp $(srcdir)/procattachbase.cpp procattach.moc.cpp ttywnd.moc brkpt.moc memwindow.moc mainwndbase.moc sourcewnd.moc gdbdriver.moc pgmargs.moc threadlist.moc pgmargsbase.moc exprwnd.moc dbgmainwnd.moc debugger.moc xsldbgdriver.moc pgmsettings.moc regwnd.moc dbgdriver.moc procattachbase.moc winstack.moc
+ @echo 'creating kdbg.all_cpp.cpp ...'; \
+ rm -f kdbg.all_cpp.files kdbg.all_cpp.final; \
+ echo "#define KDE_USE_FINAL 1" >> kdbg.all_cpp.final; \
+ for file in pgmargs.cpp procattach.cpp debugger.cpp programconfig.cpp dbgdriver.cpp gdbdriver.cpp xsldbgdriver.cpp brkpt.cpp exprwnd.cpp regwnd.cpp memwindow.cpp threadlist.cpp sourcewnd.cpp winstack.cpp ttywnd.cpp typetable.cpp prefdebugger.cpp prefmisc.cpp pgmsettings.cpp mainwndbase.cpp dbgmainwnd.cpp main.cpp pgmargsbase.cpp procattachbase.cpp procattach.moc.cpp ; do \
+ echo "#include \"$$file\"" >> kdbg.all_cpp.files; \
+ test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> kdbg.all_cpp.final; \
+ done; \
+ cat kdbg.all_cpp.final kdbg.all_cpp.files > kdbg.all_cpp.cpp; \
+ rm -f kdbg.all_cpp.final kdbg.all_cpp.files
+
+#>+ 3
+clean-final:
+ -rm -f kdbg.all_cpp.cpp
+
+#>+ 3
+final:
+ $(MAKE) kdbg_OBJECTS="$(kdbg_final_OBJECTS)" all-am
+
+#>+ 3
+final-install:
+ $(MAKE) kdbg_OBJECTS="$(kdbg_final_OBJECTS)" install-am
+
+#>+ 3
+no-final:
+ $(MAKE) kdbg_OBJECTS="$(kdbg_nofinal_OBJECTS)" all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) kdbg_OBJECTS="$(kdbg_nofinal_OBJECTS)" install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 57
+ttywnd.lo: ttywnd.moc
+$(srcdir)/typetable.cpp: pgmargsbase.h procattachbase.h
+gdbdriver.o: gdbdriver.moc
+$(srcdir)/threadlist.cpp: pgmargsbase.h procattachbase.h
+$(srcdir)/main.cpp: pgmargsbase.h procattachbase.h
+$(srcdir)/dbgdriver.cpp: pgmargsbase.h procattachbase.h
+dbgmainwnd.lo: dbgmainwnd.moc
+dbgdriver.o: dbgdriver.moc
+$(srcdir)/pgmargs.cpp: pgmargsbase.h procattachbase.h
+$(srcdir)/xsldbgdriver.cpp: pgmargsbase.h procattachbase.h
+$(srcdir)/programconfig.cpp: pgmargsbase.h procattachbase.h
+threadlist.o: threadlist.moc
+gdbdriver.lo: gdbdriver.moc
+pgmargs.lo: pgmargs.moc
+$(srcdir)/dbgmainwnd.cpp: pgmargsbase.h procattachbase.h
+pgmargs.o: pgmargs.moc
+nmcheck-am: nmcheck
+$(srcdir)/ttywnd.cpp: pgmargsbase.h procattachbase.h
+memwindow.o: memwindow.moc
+exprwnd.o: exprwnd.moc
+regwnd.o: regwnd.moc
+ttywnd.o: ttywnd.moc
+debugger.lo: debugger.moc
+$(srcdir)/prefmisc.cpp: pgmargsbase.h procattachbase.h
+sourcewnd.o: sourcewnd.moc
+$(srcdir)/procattach.cpp: pgmargsbase.h procattachbase.h
+pgmsettings.o: pgmsettings.moc
+$(srcdir)/pgmsettings.cpp: pgmargsbase.h procattachbase.h
+$(srcdir)/mainwndbase.cpp: pgmargsbase.h procattachbase.h
+$(srcdir)/prefdebugger.cpp: pgmargsbase.h procattachbase.h
+brkpt.o: brkpt.moc
+$(srcdir)/exprwnd.cpp: pgmargsbase.h procattachbase.h
+$(srcdir)/brkpt.cpp: pgmargsbase.h procattachbase.h
+mainwndbase.o: mainwndbase.moc
+$(srcdir)/sourcewnd.cpp: pgmargsbase.h procattachbase.h
+dbgmainwnd.o: dbgmainwnd.moc
+xsldbgdriver.o: xsldbgdriver.moc
+debugger.o: debugger.moc
+pgmsettings.lo: pgmsettings.moc
+$(srcdir)/winstack.cpp: pgmargsbase.h procattachbase.h
+nmcheck:
+xsldbgdriver.lo: xsldbgdriver.moc
+$(srcdir)/gdbdriver.cpp: pgmargsbase.h procattachbase.h
+$(srcdir)/memwindow.cpp: pgmargsbase.h procattachbase.h
+sourcewnd.lo: sourcewnd.moc
+regwnd.lo: regwnd.moc
+threadlist.lo: threadlist.moc
+dbgdriver.lo: dbgdriver.moc
+winstack.lo: winstack.moc
+mainwndbase.lo: mainwndbase.moc
+winstack.o: winstack.moc
+$(srcdir)/debugger.cpp: pgmargsbase.h procattachbase.h
+memwindow.lo: memwindow.moc
+exprwnd.lo: exprwnd.moc
+$(srcdir)/regwnd.cpp: pgmargsbase.h procattachbase.h
+brkpt.lo: brkpt.moc
+
+#>+ 30
+pgmargsbase.cpp: $(srcdir)/pgmargsbase.ui pgmargsbase.h pgmargsbase.moc
+ rm -f pgmargsbase.cpp
+ echo '#include <kdialog.h>' > pgmargsbase.cpp
+ echo '#include <klocale.h>' >> pgmargsbase.cpp
+ $(UIC) -tr ${UIC_TR} -i pgmargsbase.h $(srcdir)/pgmargsbase.ui > pgmargsbase.cpp.temp ; ret=$$?; \
+ $(PERL) -pe "s,${UIC_TR}( \"\" ),QString::null,g" pgmargsbase.cpp.temp | $(PERL) -pe "s,${UIC_TR}( \"\"\, \"\" ),QString::null,g" | $(PERL) -pe "s,image([0-9][0-9]*)_data,img\$$1_pgmargsbase,g" | $(PERL) -pe "s,: QWizard\(,: KWizard(,g" >> pgmargsbase.cpp ;\
+ rm -f pgmargsbase.cpp.temp ;\
+ if test "$$ret" = 0; then echo '#include "pgmargsbase.moc"' >> pgmargsbase.cpp; else rm -f pgmargsbase.cpp ; exit $$ret ; fi
+
+pgmargsbase.h: $(srcdir)/pgmargsbase.ui
+ rm -rf pgmargsbase.h;
+ $(UIC) $(srcdir)/pgmargsbase.ui | $(PERL) -pi -e "s,public QWizard,public KWizard,g; s,#include <qwizard.h>,#include <kwizard.h>,g" >> pgmargsbase.h ;
+pgmargsbase.moc: pgmargsbase.h
+ $(MOC) pgmargsbase.h -o pgmargsbase.moc
+
+procattachbase.cpp: $(srcdir)/procattachbase.ui procattachbase.h procattachbase.moc
+ rm -f procattachbase.cpp
+ echo '#include <kdialog.h>' > procattachbase.cpp
+ echo '#include <klocale.h>' >> procattachbase.cpp
+ $(UIC) -tr ${UIC_TR} -i procattachbase.h $(srcdir)/procattachbase.ui > procattachbase.cpp.temp ; ret=$$?; \
+ $(PERL) -pe "s,${UIC_TR}( \"\" ),QString::null,g" procattachbase.cpp.temp | $(PERL) -pe "s,${UIC_TR}( \"\"\, \"\" ),QString::null,g" | $(PERL) -pe "s,image([0-9][0-9]*)_data,img\$$1_procattachbase,g" | $(PERL) -pe "s,: QWizard\(,: KWizard(,g" >> procattachbase.cpp ;\
+ rm -f procattachbase.cpp.temp ;\
+ if test "$$ret" = 0; then echo '#include "procattachbase.moc"' >> procattachbase.cpp; else rm -f procattachbase.cpp ; exit $$ret ; fi
+
+procattachbase.h: $(srcdir)/procattachbase.ui
+ rm -rf procattachbase.h;
+ $(UIC) $(srcdir)/procattachbase.ui | $(PERL) -pi -e "s,public QWizard,public KWizard,g; s,#include <qwizard.h>,#include <kwizard.h>,g" >> procattachbase.h ;
+procattachbase.moc: procattachbase.h
+ $(MOC) procattachbase.h -o procattachbase.moc
diff --git a/kdbg/brkpt.cpp b/kdbg/brkpt.cpp
new file mode 100644
index 0000000..a61b4f9
--- /dev/null
+++ b/kdbg/brkpt.cpp
@@ -0,0 +1,513 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include <kapplication.h>
+#include <klocale.h> /* i18n */
+#include <kiconloader.h>
+#include <ksimpleconfig.h>
+#include <qdialog.h>
+#include <qkeycode.h>
+#include <qpainter.h>
+#include <qlabel.h>
+#include <qbitmap.h>
+#include "debugger.h"
+#include "brkpt.h"
+#include "dbgdriver.h"
+#include <ctype.h>
+#include <list>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "mydebug.h"
+
+
+class BreakpointItem : public QListViewItem, public Breakpoint
+{
+public:
+ BreakpointItem(QListView* list, const Breakpoint& bp);
+ void updateFrom(const Breakpoint& bp);
+ void display(); /* sets icon and visible texts */
+ bool enabled() const { return Breakpoint::enabled; }
+};
+
+
+BreakpointTable::BreakpointTable(QWidget* parent, const char* name) :
+ QWidget(parent, name),
+ m_debugger(0),
+ m_bpEdit(this, "bpedit"),
+ m_list(this, "bptable"),
+ m_btAddBP(this, "addbp"),
+ m_btAddWP(this, "addwp"),
+ m_btRemove(this, "remove"),
+ m_btEnaDis(this, "enadis"),
+ m_btViewCode(this, "view"),
+ m_btConditional(this, "conditional"),
+ m_layout(this, 8),
+ m_listandedit(8),
+ m_buttons(8)
+{
+ m_bpEdit.setMinimumSize(m_bpEdit.sizeHint());
+ connect(&m_bpEdit, SIGNAL(returnPressed()), this, SLOT(addBP()));
+
+ initListAndIcons();
+ connect(&m_list, SIGNAL(currentChanged(QListViewItem*)), SLOT(updateUI()));
+ // double click on item is same as View code
+ connect(&m_list, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(viewBP()));
+
+ // need mouse button events
+ m_list.viewport()->installEventFilter(this);
+
+ m_btAddBP.setText(i18n("Add &Breakpoint"));
+ m_btAddBP.setMinimumSize(m_btAddBP.sizeHint());
+ connect(&m_btAddBP, SIGNAL(clicked()), this, SLOT(addBP()));
+
+ m_btAddWP.setText(i18n("Add &Watchpoint"));
+ m_btAddWP.setMinimumSize(m_btAddWP.sizeHint());
+ connect(&m_btAddWP, SIGNAL(clicked()), this, SLOT(addWP()));
+
+ m_btRemove.setText(i18n("&Remove"));
+ m_btRemove.setMinimumSize(m_btRemove.sizeHint());
+ connect(&m_btRemove, SIGNAL(clicked()), this, SLOT(removeBP()));
+
+ // the Enable/Disable button changes its label
+ m_btEnaDis.setText(i18n("&Disable"));
+ // make a dummy button to get the size of the alternate label
+ {
+ QSize size = m_btEnaDis.sizeHint();
+ QPushButton dummy(this);
+ dummy.setText(i18n("&Enable"));
+ QSize sizeAlt = dummy.sizeHint();
+ if (sizeAlt.width() > size.width())
+ size.setWidth(sizeAlt.width());
+ if (sizeAlt.height() > size.height())
+ size.setHeight(sizeAlt.height());
+ m_btEnaDis.setMinimumSize(size);
+ }
+ connect(&m_btEnaDis, SIGNAL(clicked()), this, SLOT(enadisBP()));
+
+ m_btViewCode.setText(i18n("&View Code"));
+ m_btViewCode.setMinimumSize(m_btViewCode.sizeHint());
+ connect(&m_btViewCode, SIGNAL(clicked()), this, SLOT(viewBP()));
+
+ m_btConditional.setText(i18n("&Conditional..."));
+ m_btConditional.setMinimumSize(m_btConditional.sizeHint());
+ connect(&m_btConditional, SIGNAL(clicked()), this, SLOT(conditionalBP()));
+
+ m_layout.addLayout(&m_listandedit, 10);
+ m_layout.addLayout(&m_buttons);
+ m_listandedit.addWidget(&m_bpEdit);
+ m_listandedit.addWidget(&m_list, 10);
+ m_buttons.addWidget(&m_btAddBP);
+ m_buttons.addWidget(&m_btAddWP);
+ m_buttons.addWidget(&m_btRemove);
+ m_buttons.addWidget(&m_btEnaDis);
+ m_buttons.addWidget(&m_btViewCode);
+ m_buttons.addWidget(&m_btConditional);
+ m_buttons.addStretch(10);
+
+ m_layout.activate();
+
+ resize(350, 300);
+
+ m_bpEdit.setFocus();
+}
+
+BreakpointTable::~BreakpointTable()
+{
+}
+
+void BreakpointTable::updateBreakList()
+{
+ std::list<BreakpointItem*> deletedItems;
+
+ for (QListViewItem* it = m_list.firstChild(); it != 0; it = it->nextSibling()) {
+ deletedItems.push_back(static_cast<BreakpointItem*>(it));
+ }
+
+ // get the new list
+ for (KDebugger::BrkptROIterator bp = m_debugger->breakpointsBegin(); bp != m_debugger->breakpointsEnd(); ++bp)
+ {
+ // look up this item
+ for (std::list<BreakpointItem*>::iterator o = deletedItems.begin(); o != deletedItems.end(); ++o)
+ {
+ if ((*o)->id == bp->id) {
+ (*o)->updateFrom(*bp);
+ deletedItems.erase(o); /* don't delete */
+ goto nextItem;
+ }
+ }
+ // not in the list; add it
+ new BreakpointItem(&m_list, *bp);
+nextItem:;
+ }
+
+ // delete all untouched breakpoints
+ while (!deletedItems.empty()) {
+ delete deletedItems.front();
+ deletedItems.pop_front();
+ }
+}
+
+BreakpointItem::BreakpointItem(QListView* list, const Breakpoint& bp) :
+ QListViewItem(list),
+ Breakpoint(bp)
+{
+ display();
+}
+
+void BreakpointItem::updateFrom(const Breakpoint& bp)
+{
+ Breakpoint::operator=(bp); /* assign new values */
+ display();
+}
+
+void BreakpointTable::addBP()
+{
+ // set a breakpoint at the specified text
+ QString bpText = m_bpEdit.text();
+ bpText = bpText.stripWhiteSpace();
+ if (m_debugger->isReady())
+ {
+ Breakpoint* bp = new Breakpoint;
+ bp->text = bpText;
+
+ m_debugger->setBreakpoint(bp, false);
+ }
+}
+
+void BreakpointTable::addWP()
+{
+ // set a watchpoint for the specified expression
+ QString wpExpr = m_bpEdit.text();
+ wpExpr = wpExpr.stripWhiteSpace();
+ if (m_debugger->isReady()) {
+ Breakpoint* bp = new Breakpoint;
+ bp->type = Breakpoint::watchpoint;
+ bp->text = wpExpr;
+
+ m_debugger->setBreakpoint(bp, false);
+ }
+}
+
+void BreakpointTable::removeBP()
+{
+ BreakpointItem* bp = static_cast<BreakpointItem*>(m_list.currentItem());
+ if (bp != 0) {
+ m_debugger->deleteBreakpoint(bp->id);
+ // note that bp may be deleted by now
+ // (if bp was an orphaned breakpoint)
+ }
+}
+
+void BreakpointTable::enadisBP()
+{
+ BreakpointItem* bp = static_cast<BreakpointItem*>(m_list.currentItem());
+ if (bp != 0) {
+ m_debugger->enableDisableBreakpoint(bp->id);
+ }
+}
+
+void BreakpointTable::viewBP()
+{
+ BreakpointItem* bp = static_cast<BreakpointItem*>(m_list.currentItem());
+ if (bp == 0)
+ return;
+
+ emit activateFileLine(bp->fileName, bp->lineNo, bp->address);
+}
+
+void BreakpointTable::updateUI()
+{
+ bool enableChkpt = m_debugger->canChangeBreakpoints();
+ m_btAddBP.setEnabled(enableChkpt);
+ m_btAddWP.setEnabled(enableChkpt);
+
+ BreakpointItem* bp = static_cast<BreakpointItem*>(m_list.currentItem());
+ m_btViewCode.setEnabled(bp != 0);
+
+ if (bp == 0) {
+ enableChkpt = false;
+ } else {
+ if (bp->enabled()) {
+ m_btEnaDis.setText(i18n("&Disable"));
+ } else {
+ m_btEnaDis.setText(i18n("&Enable"));
+ }
+ }
+ m_btRemove.setEnabled(enableChkpt);
+ m_btEnaDis.setEnabled(enableChkpt);
+ m_btConditional.setEnabled(enableChkpt);
+}
+
+bool BreakpointTable::eventFilter(QObject* ob, QEvent* ev)
+{
+ if (ev->type() == QEvent::MouseButtonPress)
+ {
+ QMouseEvent* mev = static_cast<QMouseEvent*>(ev);
+ if (mev->button() == MidButton) {
+ // enable or disable the clicked-on item
+ BreakpointItem* bp =
+ static_cast<BreakpointItem*>(m_list.itemAt(mev->pos()));
+ if (bp != 0)
+ {
+ m_debugger->enableDisableBreakpoint(bp->id);
+ }
+ return true;
+ }
+ }
+ return QWidget::eventFilter(ob, ev);
+}
+
+class ConditionalDlg : public QDialog
+{
+public:
+ ConditionalDlg(QWidget* parent);
+ ~ConditionalDlg();
+
+ void setCondition(const QString& text) { m_condition.setText(text); }
+ QString condition() { return m_condition.text(); }
+ void setIgnoreCount(uint count);
+ uint ignoreCount();
+
+protected:
+ QLabel m_conditionLabel;
+ QLineEdit m_condition;
+ QLabel m_ignoreLabel;
+ QLineEdit m_ignoreCount;
+ QPushButton m_buttonOK;
+ QPushButton m_buttonCancel;
+ QVBoxLayout m_layout;
+ QGridLayout m_inputs;
+ QHBoxLayout m_buttons;
+};
+
+void BreakpointTable::conditionalBP()
+{
+ BreakpointItem* bp = static_cast<BreakpointItem*>(m_list.currentItem());
+ if (bp == 0)
+ return;
+
+ /*
+ * Important: we must not keep a pointer to the Breakpoint around,
+ * since it may vanish while the modal dialog is open through other
+ * user interactions (like clicking at the breakpoint in the source
+ * window)!
+ */
+ int id = bp->id;
+
+ ConditionalDlg dlg(this);
+ dlg.setCondition(bp->condition);
+ dlg.setIgnoreCount(bp->ignoreCount);
+
+ if (dlg.exec() != QDialog::Accepted)
+ return;
+
+ QString conditionInput = dlg.condition();
+ int ignoreCount = dlg.ignoreCount();
+ m_debugger->conditionalBreakpoint(id, conditionInput, ignoreCount);
+}
+
+
+void BreakpointTable::initListAndIcons()
+{
+ m_list.addColumn(i18n("Location"), 220);
+ m_list.addColumn(i18n("Address"), 65);
+ m_list.addColumn(i18n("Hits"), 30);
+ m_list.addColumn(i18n("Ignore"), 30);
+ m_list.addColumn(i18n("Condition"), 200);
+
+ m_list.setMinimumSize(200, 100);
+
+ m_list.setSorting(-1);
+
+ // add pixmaps
+ QPixmap brkena = UserIcon("brkena.xpm");
+ QPixmap brkdis = UserIcon("brkdis.xpm");
+ QPixmap watchena = UserIcon("watchena.xpm");
+ QPixmap watchdis = UserIcon("watchdis.xpm");
+ QPixmap brktmp = UserIcon("brktmp.xpm");
+ QPixmap brkcond = UserIcon("brkcond.xpm");
+ QPixmap brkorph = UserIcon("brkorph.xpm");
+
+ /*
+ * There are 32 different pixmaps: The basic enabled or disabled
+ * breakpoint, plus an optional overlaid brktmp icon plus an optional
+ * overlaid brkcond icon, plus an optional overlaid brkorph icon. Then
+ * the same sequence for watchpoints.
+ */
+ m_icons.resize(32);
+ QPixmap canvas(16,16);
+
+ for (int i = 0; i < 32; i++) {
+ {
+ QPainter p(&canvas);
+ // clear canvas
+ p.fillRect(0,0, canvas.width(),canvas.height(), cyan);
+ // basic icon
+ if (i & 1) {
+ p.drawPixmap(1,1, (i & 8) ? watchena : brkena);
+ } else {
+ p.drawPixmap(1,1, (i & 8) ? watchdis : brkdis);
+ }
+ // temporary overlay
+ if (i & 2) {
+ p.drawPixmap(1,1, brktmp);
+ }
+ // conditional overlay
+ if (i & 4) {
+ p.drawPixmap(1,1, brkcond);
+ }
+ // orphan overlay
+ if (i & 16) {
+ p.drawPixmap(1,1, brkorph);
+ }
+ }
+ canvas.setMask(canvas.createHeuristicMask());
+ m_icons[i] = canvas;
+ }
+}
+
+void BreakpointItem::display()
+{
+ BreakpointTable* lb = static_cast<BreakpointTable*>(listView()->parent());
+
+ /* breakpoint icon code; keep order the same as in BreakpointTable::initListAndIcons */
+ int code = enabled() ? 1 : 0;
+ if (temporary)
+ code += 2;
+ if (!condition.isEmpty() || ignoreCount > 0)
+ code += 4;
+ if (type == watchpoint)
+ code += 8;
+ if (isOrphaned())
+ code += 16;
+ setPixmap(0, lb->m_icons[code]);
+
+ // more breakpoint info
+ if (!location.isEmpty()) {
+ setText(0, location);
+ } else if (!Breakpoint::text.isEmpty()) {
+ setText(0, Breakpoint::text);
+ } else if (!fileName.isEmpty()) {
+ // use only the file name portion
+ QString file = fileName;
+ int slash = file.findRev('/');
+ if (slash >= 0) {
+ file = file.mid(slash+1);
+ }
+ // correct zero-based line-numbers
+ setText(0, file + ":" + QString::number(lineNo+1));
+ } else {
+ setText(0, "*" + address.asString());
+ }
+
+ int c = 0;
+ setText(++c, address.asString());
+ QString tmp;
+ if (hitCount == 0) {
+ setText(++c, QString());
+ } else {
+ tmp.setNum(hitCount);
+ setText(++c, tmp);
+ }
+ if (ignoreCount == 0) {
+ setText(++c, QString());
+ } else {
+ tmp.setNum(ignoreCount);
+ setText(++c, tmp);
+ }
+ if (condition.isEmpty()) {
+ setText(++c, QString());
+ } else {
+ setText(++c, condition);
+ }
+}
+
+
+ConditionalDlg::ConditionalDlg(QWidget* parent) :
+ QDialog(parent, "conditional", true),
+ m_conditionLabel(this, "condLabel"),
+ m_condition(this, "condition"),
+ m_ignoreLabel(this, "ignoreLabel"),
+ m_ignoreCount(this, "ignoreCount"),
+ m_buttonOK(this, "ok"),
+ m_buttonCancel(this, "cancel"),
+ m_layout(this, 10),
+ m_inputs(2, 2, 10),
+ m_buttons(4)
+{
+ QString title = kapp->caption();
+ title += i18n(": Conditional breakpoint");
+ setCaption(title);
+
+ m_conditionLabel.setText(i18n("&Condition:"));
+ m_conditionLabel.setMinimumSize(m_conditionLabel.sizeHint());
+ m_ignoreLabel.setText(i18n("Ignore &next hits:"));
+ m_ignoreLabel.setMinimumSize(m_ignoreLabel.sizeHint());
+
+ m_condition.setMinimumSize(150, 24);
+ m_condition.setMaxLength(10000);
+ m_condition.setFrame(true);
+ m_ignoreCount.setMinimumSize(150, 24);
+ m_ignoreCount.setMaxLength(10000);
+ m_ignoreCount.setFrame(true);
+
+ m_conditionLabel.setBuddy(&m_condition);
+ m_ignoreLabel.setBuddy(&m_ignoreCount);
+
+ m_buttonOK.setMinimumSize(100, 30);
+ connect(&m_buttonOK, SIGNAL(clicked()), SLOT(accept()));
+ m_buttonOK.setText(i18n("OK"));
+ m_buttonOK.setDefault(true);
+
+ m_buttonCancel.setMinimumSize(100, 30);
+ connect(&m_buttonCancel, SIGNAL(clicked()), SLOT(reject()));
+ m_buttonCancel.setText(i18n("Cancel"));
+
+ m_layout.addLayout(&m_inputs);
+ m_inputs.addWidget(&m_conditionLabel, 0, 0);
+ m_inputs.addWidget(&m_condition, 0, 1);
+ m_inputs.addWidget(&m_ignoreLabel, 1, 0);
+ m_inputs.addWidget(&m_ignoreCount, 1, 1);
+ m_inputs.setColStretch(1, 10);
+ m_layout.addLayout(&m_buttons);
+ m_layout.addStretch(10);
+ m_buttons.addStretch(10);
+ m_buttons.addWidget(&m_buttonOK);
+ m_buttons.addSpacing(40);
+ m_buttons.addWidget(&m_buttonCancel);
+ m_buttons.addStretch(10);
+
+ m_layout.activate();
+
+ m_condition.setFocus();
+ resize(400, 100);
+}
+
+ConditionalDlg::~ConditionalDlg()
+{
+}
+
+uint ConditionalDlg::ignoreCount()
+{
+ bool ok;
+ QString input = m_ignoreCount.text();
+ uint result = input.toUInt(&ok);
+ return ok ? result : 0;
+}
+
+void ConditionalDlg::setIgnoreCount(uint count)
+{
+ QString text;
+ // set empty if ignore count is zero
+ if (count > 0) {
+ text.setNum(count);
+ }
+ m_ignoreCount.setText(text);
+}
+
+
+#include "brkpt.moc"
diff --git a/kdbg/brkpt.h b/kdbg/brkpt.h
new file mode 100644
index 0000000..c72785b
--- /dev/null
+++ b/kdbg/brkpt.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef BRKPT_H
+#define BRKPT_H
+
+#include <qlistview.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qvaluevector.h>
+
+class KDebugger;
+class BreakpointItem;
+
+
+class BreakpointTable : public QWidget
+{
+ Q_OBJECT
+public:
+ BreakpointTable(QWidget* parent, const char* name);
+ ~BreakpointTable();
+ void setDebugger(KDebugger* deb) { m_debugger = deb; }
+
+protected:
+ KDebugger* m_debugger;
+ QLineEdit m_bpEdit;
+ QListView m_list;
+ QPushButton m_btAddBP;
+ QPushButton m_btAddWP;
+ QPushButton m_btRemove;
+ QPushButton m_btEnaDis;
+ QPushButton m_btViewCode;
+ QPushButton m_btConditional;
+ QHBoxLayout m_layout;
+ QVBoxLayout m_listandedit;
+ QVBoxLayout m_buttons;
+ QValueVector<QPixmap> m_icons;
+
+ void insertBreakpoint(int num, bool temp, bool enabled, QString location,
+ QString fileName = 0, int lineNo = -1,
+ int hits = 0, uint ignoreCount = 0,
+ QString condition = QString());
+ void initListAndIcons();
+ virtual bool eventFilter(QObject* ob, QEvent* ev);
+
+ friend class BreakpointItem;
+
+signals:
+ /**
+ * This signal is emitted when the user wants to go to the source code
+ * where the current breakpoint is in.
+ *
+ * @param file specifies the file; this is not necessarily a full path
+ * name, and if it is relative, you won't know relative to what, you
+ * can only guess.
+ * @param lineNo specifies the line number (0-based!).
+ * @param address specifies the exact address of the breakpoint.
+ */
+ void activateFileLine(const QString& file, int lineNo, const DbgAddr& address);
+public slots:
+ virtual void addBP();
+ virtual void addWP();
+ virtual void removeBP();
+ virtual void enadisBP();
+ virtual void viewBP();
+ virtual void conditionalBP();
+ void updateUI();
+ void updateBreakList();
+};
+
+#endif // BRKPT_H
diff --git a/kdbg/commandids.h b/kdbg/commandids.h
new file mode 100644
index 0000000..35623b2
--- /dev/null
+++ b/kdbg/commandids.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef COMMANDIDS_H
+#define COMMANDIDS_H
+
+// statusbar ids
+#define ID_STATUS_MSG 191
+#define ID_STATUS_BUSY 192
+#define ID_STATUS_ACTIVE 193
+#endif // COMMANDIDS_H
diff --git a/kdbg/dbgdriver.cpp b/kdbg/dbgdriver.cpp
new file mode 100644
index 0000000..479bdd3
--- /dev/null
+++ b/kdbg/dbgdriver.cpp
@@ -0,0 +1,527 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "dbgdriver.h"
+#include "exprwnd.h"
+#include <qstringlist.h>
+#include <ctype.h>
+#include <stdlib.h> /* strtol, atoi */
+#include <algorithm>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "mydebug.h"
+#include <assert.h>
+
+
+DebuggerDriver::DebuggerDriver() :
+ KProcess(),
+ m_state(DSidle),
+ m_output(0),
+ m_outputLen(0),
+ m_outputAlloc(0),
+ m_activeCmd(0),
+ m_promptMinLen(0),
+ m_promptLastChar('\0')
+{
+ m_outputAlloc = 4000;
+ m_output = new char[m_outputAlloc];
+
+ m_prompt[0] = '\0';
+ // Derived classes can set either m_prompt or m_promptRE.
+ // If m_promptRE is set, it must include the '$' at the end.
+ // m_promptLastChar and m_promptMinLen must also be set.
+
+ // debugger process
+ connect(this, SIGNAL(receivedStdout(KProcess*,char*,int)),
+ SLOT(slotReceiveOutput(KProcess*,char*,int)));
+ connect(this, SIGNAL(wroteStdin(KProcess*)), SLOT(slotCommandRead(KProcess*)));
+ connect(this, SIGNAL(processExited(KProcess*)), SLOT(slotExited(KProcess*)));
+}
+
+DebuggerDriver::~DebuggerDriver()
+{
+ delete[] m_output;
+ flushHiPriQueue();
+ flushLoPriQueue();
+}
+
+int DebuggerDriver::commSetupDoneC()
+{
+ TRACE(__PRETTY_FUNCTION__);
+
+ if (!KProcess::commSetupDoneC())
+ return 0;
+
+ close(STDERR_FILENO);
+ return dup2(STDOUT_FILENO, STDERR_FILENO) != -1;
+}
+
+
+bool DebuggerDriver::startup(QString cmdStr)
+{
+ // clear command queues
+ delete m_activeCmd;
+ m_activeCmd = 0;
+ flushHiPriQueue();
+ flushLoPriQueue();
+ m_state = DSidle;
+
+ // debugger executable
+ if (cmdStr.isEmpty())
+ cmdStr = defaultInvocation();
+
+ QStringList cmd = QStringList::split(' ', cmdStr);
+ clearArguments();
+ for (QStringList::iterator i = cmd.begin(); i != cmd.end(); ++i) {
+ *this << *i;
+ }
+
+ if (!start(KProcess::NotifyOnExit,
+ KProcess::Communication(KProcess::Stdin|KProcess::Stdout))) {
+ return false;
+ }
+
+ // open log file
+ if (!m_logFile.isOpen() && !m_logFileName.isEmpty()) {
+ m_logFile.setName(m_logFileName);
+ m_logFile.open(IO_WriteOnly);
+ }
+
+ // these must be set by derived classes in their constructor
+ assert(m_promptMinLen > 0); // _must_ have a prompt
+ assert(m_promptLastChar != '\0'); // last char _must_ be fixed
+ assert(m_prompt[0] == '\0' || strlen(m_prompt) == m_promptMinLen);
+ // either a prompt or a regexp
+ assert(m_prompt[0] != '\0' && m_promptMinLen < sizeof(m_prompt) ||
+ !m_promptRE.isEmpty() && m_promptRE.isValid());
+
+ return true;
+}
+
+void DebuggerDriver::slotExited(KProcess*)
+{
+ static const char txt[] = "\n====== debugger exited ======\n";
+ if (m_logFile.isOpen()) {
+ m_logFile.writeBlock(txt,sizeof(txt)-1);
+ }
+
+ // reset state
+ m_state = DSidle;
+ // empty buffer
+ m_outputLen = 0;
+ *m_output = '\0';
+}
+
+
+CmdQueueItem* DebuggerDriver::executeCmdString(DbgCommand cmd,
+ QString cmdString, bool clearLow)
+{
+ // place a new command into the high-priority queue
+ CmdQueueItem* cmdItem = new CmdQueueItem(cmd, cmdString);
+ m_hipriCmdQueue.push(cmdItem);
+
+ if (clearLow) {
+ if (m_state == DSrunningLow) {
+ // take the liberty to interrupt the running command
+ m_state = DSinterrupted;
+ kill(SIGINT);
+ ASSERT(m_activeCmd != 0);
+ TRACE(QString().sprintf("interrupted the command %d",
+ (m_activeCmd ? m_activeCmd->m_cmd : -1)));
+ delete m_activeCmd;
+ m_activeCmd = 0;
+ }
+ flushLoPriQueue();
+ }
+ // if gdb is idle, send it the command
+ if (m_state == DSidle) {
+ ASSERT(m_activeCmd == 0);
+ writeCommand();
+ }
+
+ return cmdItem;
+}
+
+bool CmdQueueItem::IsEqualCmd::operator()(CmdQueueItem* cmd) const
+{
+ return cmd->m_cmd == m_cmd && cmd->m_cmdString == m_str;
+}
+
+CmdQueueItem* DebuggerDriver::queueCmdString(DbgCommand cmd,
+ QString cmdString, QueueMode mode)
+{
+ // place a new command into the low-priority queue
+ std::list<CmdQueueItem*>::iterator i;
+ CmdQueueItem* cmdItem = 0;
+ switch (mode) {
+ case QMoverrideMoreEqual:
+ case QMoverride:
+ // check whether gdb is currently processing this command
+ if (m_activeCmd != 0 &&
+ m_activeCmd->m_cmd == cmd && m_activeCmd->m_cmdString == cmdString)
+ {
+ return m_activeCmd;
+ }
+ // check whether there is already the same command in the queue
+ i = find_if(m_lopriCmdQueue.begin(), m_lopriCmdQueue.end(), CmdQueueItem::IsEqualCmd(cmd, cmdString));
+ if (i != m_lopriCmdQueue.end()) {
+ // found one
+ cmdItem = *i;
+ if (mode == QMoverrideMoreEqual) {
+ // All commands are equal, but some are more equal than others...
+ // put this command in front of all others
+ m_lopriCmdQueue.erase(i);
+ m_lopriCmdQueue.push_front(cmdItem);
+ }
+ break;
+ } // else none found, so add it
+ // drop through
+ case QMnormal:
+ cmdItem = new CmdQueueItem(cmd, cmdString);
+ m_lopriCmdQueue.push_back(cmdItem);
+ }
+
+ // if gdb is idle, send it the command
+ if (m_state == DSidle) {
+ ASSERT(m_activeCmd == 0);
+ writeCommand();
+ }
+
+ return cmdItem;
+}
+
+// dequeue a pending command, make it the active one and send it to gdb
+void DebuggerDriver::writeCommand()
+{
+// ASSERT(m_activeCmd == 0);
+ assert(m_activeCmd == 0);
+
+ // first check the high-priority queue - only if it is empty
+ // use a low-priority command.
+ CmdQueueItem* cmd;
+ DebuggerState newState = DScommandSent;
+ if (!m_hipriCmdQueue.empty()) {
+ cmd = m_hipriCmdQueue.front();
+ m_hipriCmdQueue.pop();
+ } else if (!m_lopriCmdQueue.empty()) {
+ cmd = m_lopriCmdQueue.front();
+ m_lopriCmdQueue.pop_front();
+ newState = DScommandSentLow;
+ } else {
+ // nothing to do
+ m_state = DSidle; /* is necessary if command was interrupted earlier */
+ return;
+ }
+
+ m_activeCmd = cmd;
+ TRACE("in writeCommand: " + cmd->m_cmdString);
+
+ const char* str = cmd->m_cmdString;
+ writeStdin(const_cast<char*>(str), cmd->m_cmdString.length());
+
+ // write also to log file
+ if (m_logFile.isOpen()) {
+ m_logFile.writeBlock(str, cmd->m_cmdString.length());
+ m_logFile.flush();
+ }
+
+ m_state = newState;
+}
+
+void DebuggerDriver::flushLoPriQueue()
+{
+ while (!m_lopriCmdQueue.empty()) {
+ delete m_lopriCmdQueue.back();
+ m_lopriCmdQueue.pop_back();
+ }
+}
+
+void DebuggerDriver::flushHiPriQueue()
+{
+ while (!m_hipriCmdQueue.empty()) {
+ delete m_hipriCmdQueue.front();
+ m_hipriCmdQueue.pop();
+ }
+}
+
+void DebuggerDriver::flushCommands(bool hipriOnly)
+{
+ flushHiPriQueue();
+ if (!hipriOnly) {
+ flushLoPriQueue();
+ }
+}
+
+void DebuggerDriver::slotCommandRead(KProcess*)
+{
+ TRACE(__PRETTY_FUNCTION__);
+
+ // there must be an active command which is not yet commited
+ ASSERT(m_state == DScommandSent || m_state == DScommandSentLow);
+ ASSERT(m_activeCmd != 0);
+ ASSERT(!m_activeCmd->m_committed);
+
+ // commit the command
+ m_activeCmd->m_committed = true;
+
+ // now the debugger is officially working on the command
+ m_state = m_state == DScommandSent ? DSrunning : DSrunningLow;
+
+ // set the flag that reflects whether the program is really running
+ switch (m_activeCmd->m_cmd) {
+ case DCrun: case DCcont: case DCnext: case DCstep: case DCfinish: case DCuntil:
+ emit inferiorRunning();
+ break;
+ default:
+ break;
+ }
+
+ // re-receive delayed output
+ while (!m_delayedOutput.empty()) {
+ QByteArray delayed = m_delayedOutput.front();
+ m_delayedOutput.pop();
+ slotReceiveOutput(0, const_cast<char*>(delayed.data()), delayed.size());
+ }
+}
+
+void DebuggerDriver::slotReceiveOutput(KProcess*, char* buffer, int buflen)
+{
+ /*
+ * The debugger should be running (processing a command) at this point.
+ * If it is not, it is still idle because we haven't received the
+ * wroteStdin signal yet, in which case there must be an active command
+ * which is not commited.
+ */
+ if (m_state == DScommandSent || m_state == DScommandSentLow) {
+ ASSERT(m_activeCmd != 0);
+ ASSERT(!m_activeCmd->m_committed);
+ /*
+ * We received output before we got signal wroteStdin. Collect this
+ * output, it will be re-sent by commandRead when it gets the
+ * acknowledgment for the uncommitted command.
+ */
+ m_delayedOutput.push(QByteArray().duplicate(buffer, buflen));
+ return;
+ }
+ // write to log file (do not log delayed output - it would appear twice)
+ if (m_logFile.isOpen()) {
+ m_logFile.writeBlock(buffer, buflen);
+ m_logFile.flush();
+ }
+
+ /*
+ * gdb sometimes produces stray output while it's idle. This happens if
+ * it receives a signal, most prominently a SIGCONT after a SIGTSTP:
+ * The user haltet kdbg with Ctrl-Z, then continues it with "fg", which
+ * also continues gdb, which repeats the prompt!
+ */
+ if (m_activeCmd == 0 && m_state != DSinterrupted) {
+ // ignore the output
+ TRACE("ignoring stray output: " + QString::fromLatin1(buffer, buflen));
+ return;
+ }
+ ASSERT(m_state == DSrunning || m_state == DSrunningLow || m_state == DSinterrupted);
+ ASSERT(m_activeCmd != 0 || m_state == DSinterrupted);
+
+ // collect output until next prompt string is found
+
+ // accumulate it
+ if (m_outputLen + buflen >= m_outputAlloc) {
+ /*
+ * Must enlarge m_output: double it. Note: That particular
+ * sequence of commandes here ensures exception safety.
+ */
+ int newSize = m_outputAlloc * 2;
+ char* newBuf = new char[newSize];
+ memcpy(newBuf, m_output, m_outputLen);
+ delete[] m_output;
+ m_output = newBuf;
+ m_outputAlloc = newSize;
+ }
+ memcpy(m_output+m_outputLen, buffer, buflen);
+ m_outputLen += buflen;
+ m_output[m_outputLen] = '\0';
+
+ /*
+ * If there's a prompt string in the collected output, it must be at
+ * the very end. In order to quickly find out whether there is a prompt
+ * string, we check whether the last character of m_output is identical
+ * to the last character of the prompt string. Only if it is, we check
+ * for the full prompt string.
+ *
+ * Note: Using the regular expression here is most expensive, because
+ * it translates m_output to a QString each time.
+ *
+ * Note: It could nevertheless happen that a character sequence that is
+ * equal to the prompt string appears at the end of the output,
+ * although it is very, very unlikely (namely as part of a string that
+ * lingered in gdb's output buffer due to some timing/heavy load
+ * conditions for a very long time such that that buffer overflowed
+ * exactly at the end of the prompt string look-a-like).
+ */
+ int promptStart = -1;
+ if (m_output[m_outputLen-1] == m_promptLastChar &&
+ m_outputLen >= m_promptMinLen)
+ {
+ // this is a candidate for a prompt at the end,
+ // now see if there really is
+ if (m_prompt[0] != '\0') {
+ if (strncmp(m_output+m_outputLen-m_promptMinLen,
+ m_prompt, m_promptMinLen) == 0)
+ {
+ promptStart = m_outputLen-m_promptMinLen;
+ }
+ } else {
+ QString output = QString::fromLatin1(m_output, m_outputLen);
+#if QT_VERSION >= 300
+ promptStart = m_promptRE.search(output);
+#else
+ promptStart = m_promptRE.match(output);
+#endif
+ }
+ }
+ if (promptStart >= 0)
+ {
+ // found prompt!
+
+ // terminate output before the prompt
+ m_output[promptStart] = '\0';
+
+ /*
+ * We've got output for the active command. But if it was
+ * interrupted, ignore it.
+ */
+ if (m_state != DSinterrupted) {
+ /*
+ * m_state shouldn't be DSidle while we are parsing the output
+ * so that all commands produced by parse() go into the queue
+ * instead of being written to gdb immediately.
+ */
+ ASSERT(m_state != DSidle);
+ CmdQueueItem* cmd = m_activeCmd;
+ m_activeCmd = 0;
+ commandFinished(cmd);
+ delete cmd;
+ }
+
+ // empty buffer
+ m_outputLen = 0;
+ *m_output = '\0';
+ // also clear delayed output if interrupted
+ if (m_state == DSinterrupted) {
+ m_delayedOutput = std::queue<QByteArray>();
+ }
+
+ /*
+ * We parsed some output successfully. Unless there's more delayed
+ * output, the debugger must be idle now, so send down the next
+ * command.
+ */
+ if (m_delayedOutput.empty()) {
+ if (m_hipriCmdQueue.empty() && m_lopriCmdQueue.empty()) {
+ // no pending commands
+ m_state = DSidle;
+ emit enterIdleState();
+ } else {
+ writeCommand();
+ }
+ }
+ }
+}
+
+void DebuggerDriver::dequeueCmdByVar(VarTree* var)
+{
+ if (var == 0)
+ return;
+
+ std::list<CmdQueueItem*>::iterator i = m_lopriCmdQueue.begin();
+ while (i != m_lopriCmdQueue.end()) {
+ if ((*i)->m_expr != 0 && var->isAncestorEq((*i)->m_expr)) {
+ // this is indeed a critical command; delete it
+ TRACE("removing critical lopri-cmd: " + (*i)->m_cmdString);
+ delete *i;
+ m_lopriCmdQueue.erase(i++);
+ } else
+ ++i;
+ }
+}
+
+
+QString DebuggerDriver::editableValue(VarTree* value)
+{
+ // by default, let the user edit what is visible
+ return value->value();
+}
+
+
+StackFrame::~StackFrame()
+{
+ delete var;
+}
+
+
+DbgAddr::DbgAddr(const QString& aa) :
+ a(aa)
+{
+ cleanAddr();
+}
+
+/*
+ * We strip off the leading 0x and any leading zeros.
+ */
+void DbgAddr::cleanAddr()
+{
+ if (a.isEmpty())
+ return;
+
+ while (a[0] == '0' || a[0] == 'x') {
+ a.remove(0, 1);
+ }
+}
+
+void DbgAddr::operator=(const QString& aa)
+{
+ a = aa;
+ fnoffs = QString();
+ cleanAddr();
+}
+
+/* Re-attach 0x in front of the address */
+QString DbgAddr::asString() const
+{
+ if (a.isEmpty())
+ return QString();
+ else
+ return "0x" + a;
+}
+
+bool operator==(const DbgAddr& a1, const DbgAddr& a2)
+{
+ return QString::compare(a1.a, a2.a) == 0;
+}
+
+bool operator>(const DbgAddr& a1, const DbgAddr& a2)
+{
+ if (a1.a.length() > a2.a.length())
+ return true;
+ if (a1.a.length() < a2.a.length())
+ return false;
+ return QString::compare(a1.a, a2.a) > 0;
+}
+
+
+Breakpoint::Breakpoint() :
+ id(0),
+ type(breakpoint),
+ temporary(false),
+ enabled(true),
+ ignoreCount(0),
+ hitCount(0),
+ lineNo(0)
+{ }
+
+#include "dbgdriver.moc"
diff --git a/kdbg/dbgdriver.h b/kdbg/dbgdriver.h
new file mode 100644
index 0000000..f5f1f7d
--- /dev/null
+++ b/kdbg/dbgdriver.h
@@ -0,0 +1,622 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef DBGDRIVER_H
+#define DBGDRIVER_H
+
+#include <qfile.h>
+#include <qregexp.h>
+#include <qcstring.h>
+#include <kprocess.h>
+#include <queue>
+#include <list>
+
+
+class VarTree;
+class ExprValue;
+class ExprWnd;
+class KDebugger;
+class QStringList;
+
+
+/**
+ * A type representing an address.
+ */
+struct DbgAddr
+{
+ QString a;
+ QString fnoffs;
+ DbgAddr() { }
+ DbgAddr(const QString& aa);
+ DbgAddr(const DbgAddr& src) : a(src.a), fnoffs(src.fnoffs) { }
+ void operator=(const QString& aa);
+ void operator=(const DbgAddr& src) { a = src.a; fnoffs = src.fnoffs; }
+ QString asString() const;
+ bool isEmpty() const { return a.isEmpty(); }
+protected:
+ void cleanAddr();
+};
+bool operator==(const DbgAddr& a1, const DbgAddr& a2);
+bool operator>(const DbgAddr& a1, const DbgAddr& a2);
+
+
+enum DbgCommand {
+ DCinitialize,
+ DCtty,
+ DCexecutable,
+ DCtargetremote,
+ DCcorefile,
+ DCattach,
+ DCinfolinemain,
+ DCinfolocals,
+ DCinforegisters,
+ DCexamine,
+ DCinfoline,
+ DCdisassemble,
+ DCsetargs,
+ DCsetenv,
+ DCunsetenv,
+ DCsetoption, /* debugger options */
+ DCcd,
+ DCbt,
+ DCrun,
+ DCcont,
+ DCstep,
+ DCstepi,
+ DCnext,
+ DCnexti,
+ DCfinish,
+ DCuntil, /* line number is zero-based! */
+ DCkill,
+ DCbreaktext,
+ DCbreakline, /* line number is zero-based! */
+ DCtbreakline, /* line number is zero-based! */
+ DCbreakaddr,
+ DCtbreakaddr,
+ DCwatchpoint,
+ DCdelete,
+ DCenable,
+ DCdisable,
+ DCprint,
+ DCprintDeref,
+ DCprintStruct,
+ DCprintQStringStruct,
+ DCframe,
+ DCfindType,
+ DCinfosharedlib,
+ DCthread,
+ DCinfothreads,
+ DCinfobreak,
+ DCcondition,
+ DCsetpc,
+ DCignore,
+ DCprintWChar,
+ DCsetvariable
+};
+
+enum RunDevNull {
+ RDNstdin = 0x1, /* redirect stdin to /dev/null */
+ RDNstdout = 0x2, /* redirect stdout to /dev/null */
+ RDNstderr = 0x4 /* redirect stderr to /dev/null */
+};
+
+/**
+ * How the memory dump is formated. The lowest 4 bits define the size of
+ * the entities. The higher bits define how these are formatted. Note that
+ * not all combinations make sense.
+ */
+enum MemoryDumpType {
+ // sizes
+ MDTbyte = 0x1,
+ MDThalfword = 0x2,
+ MDTword = 0x3,
+ MDTgiantword = 0x4,
+ MDTsizemask = 0xf,
+ // formats
+ MDThex = 0x10,
+ MDTsigned = 0x20,
+ MDTunsigned = 0x30,
+ MDToctal = 0x40,
+ MDTbinary = 0x50,
+ MDTaddress = 0x60,
+ MDTchar = 0x70,
+ MDTfloat = 0x80,
+ MDTstring = 0x90,
+ MDTinsn = 0xa0,
+ MDTformatmask = 0xf0
+};
+
+struct Breakpoint;
+
+/**
+ * Debugger commands are placed in a queue. Only one command at a time is
+ * sent down to the debugger. All other commands in the queue are retained
+ * until the sent command has been processed by gdb. The debugger tells us
+ * that it's done with the command by sending the prompt. The output of the
+ * debugger is parsed at that time. Then, if more commands are in the
+ * queue, the next one is sent to the debugger.
+ */
+struct CmdQueueItem
+{
+ DbgCommand m_cmd;
+ QString m_cmdString;
+ bool m_committed; /* just a debugging aid */
+ // remember which expression when printing an expression
+ VarTree* m_expr;
+ ExprWnd* m_exprWnd;
+ // remember file position
+ QString m_fileName;
+ int m_lineNo;
+ // the breakpoint info
+ Breakpoint* m_brkpt;
+ int m_existingBrkpt;
+ // whether command was emitted due to direct user request (only set when relevant)
+ bool m_byUser;
+
+ CmdQueueItem(DbgCommand cmd, const QString& str) :
+ m_cmd(cmd),
+ m_cmdString(str),
+ m_committed(false),
+ m_expr(0),
+ m_exprWnd(0),
+ m_lineNo(0),
+ m_brkpt(0),
+ m_existingBrkpt(0),
+ m_byUser(false)
+ { }
+
+ struct IsEqualCmd
+ {
+ IsEqualCmd(DbgCommand cmd, const QString& str) : m_cmd(cmd), m_str(str) { }
+ bool operator()(CmdQueueItem*) const;
+ DbgCommand m_cmd;
+ const QString& m_str;
+ };
+};
+
+/**
+ * The information about a breakpoint that is parsed from the list of
+ * breakpoints.
+ */
+struct Breakpoint
+{
+ int id; /* gdb's number */
+ enum Type {
+ breakpoint, watchpoint
+ } type;
+ bool temporary;
+ bool enabled;
+ QString location;
+ QString text; /* text if set using DCbreaktext */
+ DbgAddr address; /* exact address of breakpoint */
+ QString condition; /* condition as printed by gdb */
+ int ignoreCount; /* ignore next that may hits */
+ int hitCount; /* as reported by gdb */
+ // the following items repeat the location, but in a better usable way
+ QString fileName;
+ int lineNo; /* zero-based line number */
+ Breakpoint();
+ bool isOrphaned() const { return id < 0; }
+};
+
+/**
+ * Information about a stack frame.
+ */
+struct FrameInfo
+{
+ QString fileName;
+ int lineNo; /* zero-based line number */
+ DbgAddr address; /* exact address of PC */
+};
+
+/**
+ * The information about a stack frame as parsed from the backtrace.
+ */
+struct StackFrame : FrameInfo
+{
+ int frameNo;
+ ExprValue* var; /* more information if non-zero */
+ StackFrame() : var(0) { }
+ ~StackFrame();
+};
+
+/**
+ * The information about a thread as parsed from the threads list.
+ */
+struct ThreadInfo : FrameInfo
+{
+ int id; /* gdb's number */
+ QString threadName; /* the SYSTAG */
+ QString function; /* where thread is halted */
+ bool hasFocus; /* the thread whose stack we are watching */
+};
+
+/**
+ * Register information
+ */
+struct RegisterInfo
+{
+ QString regName;
+ QString rawValue;
+ QString cookedValue; /* may be empty */
+ QString type; /* of vector register if not empty */
+};
+
+/**
+ * Disassembled code
+ */
+struct DisassembledCode
+{
+ DbgAddr address;
+ QString code;
+};
+
+/**
+ * Memory contents
+ */
+struct MemoryDump
+{
+ DbgAddr address;
+ QString dump;
+};
+
+/**
+ * This is an abstract base class for debugger process.
+ *
+ * This class represents the debugger program. It provides the low-level
+ * interface to the commandline debugger. As such it implements the
+ * commands and parses the output.
+ */
+class DebuggerDriver : public KProcess
+{
+ Q_OBJECT
+public:
+ DebuggerDriver();
+ virtual ~DebuggerDriver() = 0;
+
+ virtual QString driverName() const = 0;
+ /**
+ * Returns the default command string to invoke the debugger driver.
+ */
+ virtual QString defaultInvocation() const = 0;
+
+ /**
+ * Returns a list of options that can be turned on and off.
+ */
+ virtual QStringList boolOptionList() const = 0;
+
+ virtual bool startup(QString cmdStr);
+ void setLogFileName(const QString& fname) { m_logFileName = fname; }
+
+protected:
+ QString m_runCmd;
+
+ enum DebuggerState {
+ DSidle, /* gdb waits for input */
+ DSinterrupted, /* a command was interrupted */
+ DSrunningLow, /* gdb is running a low-priority command */
+ DSrunning, /* gdb waits for program */
+ DScommandSent, /* command has been sent, we wait for wroteStdin signal */
+ DScommandSentLow /* low-prioritycommand has been sent */
+ };
+ DebuggerState m_state;
+
+public:
+ bool isIdle() const { return m_state == DSidle; }
+ /**
+ * Tells whether a high prority command would be executed immediately.
+ */
+ bool canExecuteImmediately() const { return m_hipriCmdQueue.empty(); }
+
+protected:
+ char* m_output; /* normal gdb output */
+ size_t m_outputLen; /* amount of data so far accumulated in m_output */
+ size_t m_outputAlloc; /* space available in m_output */
+ std::queue<QByteArray> m_delayedOutput; /* output colleced while we have receivedOutput */
+ /* but before signal wroteStdin arrived */
+
+public:
+ /**
+ * Enqueues a high-priority command. High-priority commands are
+ * executed before any low-priority commands. No user interaction is
+ * possible as long as there is a high-priority command in the queue.
+ */
+ virtual CmdQueueItem* executeCmd(DbgCommand,
+ bool clearLow = false) = 0;
+ virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg,
+ bool clearLow = false) = 0;
+ virtual CmdQueueItem* executeCmd(DbgCommand, int intArg,
+ bool clearLow = false) = 0;
+ virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg, int intArg,
+ bool clearLow = false) = 0;
+ virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg1, QString strArg2,
+ bool clearLow = false) = 0;
+ virtual CmdQueueItem* executeCmd(DbgCommand, int intArg1, int intArg2,
+ bool clearLow = false) = 0;
+
+ enum QueueMode {
+ QMnormal, /* queues the command last */
+ QMoverride, /* removes an already queued command */
+ QMoverrideMoreEqual /* ditto, also puts the command first in the queue */
+ };
+
+ /**
+ * Enqueues a low-priority command. Low-priority commands are executed
+ * after any high-priority commands.
+ */
+ virtual CmdQueueItem* queueCmd(DbgCommand,
+ QueueMode mode) = 0;
+ virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg,
+ QueueMode mode) = 0;
+ virtual CmdQueueItem* queueCmd(DbgCommand, int intArg,
+ QueueMode mode) = 0;
+ virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg, int intArg,
+ QueueMode mode) = 0;
+ virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg1, QString strArg2,
+ QueueMode mode) = 0;
+
+ /**
+ * Flushes the command queues.
+ * @param hipriOnly if true, only the high priority queue is flushed.
+ */
+ virtual void flushCommands(bool hipriOnly = false);
+
+ /**
+ * Terminates the debugger process.
+ */
+ virtual void terminate() = 0;
+
+ /**
+ * Terminates the debugger process, but also detaches any program that
+ * it has been attached to.
+ */
+ virtual void detachAndTerminate() = 0;
+
+ /**
+ * Interrupts the debuggee.
+ */
+ virtual void interruptInferior() = 0;
+
+ /**
+ * Specifies the command that prints the QString data.
+ */
+ virtual void setPrintQStringDataCmd(const char* cmd) = 0;
+
+ /**
+ * Parses the output as an array of QChars.
+ */
+ virtual ExprValue* parseQCharArray(const char* output, bool wantErrorValue, bool qt3like) = 0;
+
+ /**
+ * Parses a back-trace (the output of the DCbt command).
+ */
+ virtual void parseBackTrace(const char* output, std::list<StackFrame>& stack) = 0;
+
+ /**
+ * Parses the output of the DCframe command;
+ * @param frameNo Returns the frame number.
+ * @param file Returns the source file name.
+ * @param lineNo The zero-based line number.
+ * @param address Returns the exact address.
+ * @return false if the frame could not be parsed successfully. The
+ * output values are undefined in this case.
+ */
+ virtual bool parseFrameChange(const char* output, int& frameNo,
+ QString& file, int& lineNo, DbgAddr& address) = 0;
+
+ /**
+ * Parses a list of breakpoints.
+ * @param output The output of the debugger.
+ * @param brks The list of new #Breakpoint objects. The list
+ * must initially be empty.
+ * @return False if there was an error before the first breakpoint
+ * was found. Even if true is returned, #brks may be empty.
+ */
+ virtual bool parseBreakList(const char* output, std::list<Breakpoint>& brks) = 0;
+
+ /**
+ * Parses a list of threads.
+ * @param output The output of the debugger.
+ * @return The new thread list. There is no indication if there was
+ * a parse error.
+ */
+ virtual std::list<ThreadInfo> parseThreadList(const char* output) = 0;
+
+ /**
+ * Parses the output when the program stops to see whether this it
+ * stopped due to a breakpoint.
+ * @param output The output of the debugger.
+ * @param id Returns the breakpoint id.
+ * @param file Returns the file name in which the breakpoint is.
+ * @param lineNo Returns the zero-based line number of the breakpoint.
+ * @param address Returns the address of the breakpoint.
+ * @return False if there was no breakpoint.
+ */
+ virtual bool parseBreakpoint(const char* output, int& id,
+ QString& file, int& lineNo, QString& address) = 0;
+
+ /**
+ * Parses the output of the DCinfolocals command.
+ * @param output The output of the debugger.
+ * @param newVars Receives the parsed variable values. The values are
+ * simply append()ed to the supplied list.
+ */
+ virtual void parseLocals(const char* output, std::list<ExprValue*>& newVars) = 0;
+
+ /**
+ * Parses the output of a DCprint or DCprintStruct command.
+ * @param output The output of the debugger.
+ * @param wantErrorValue Specifies whether the error message should be
+ * provided as the value of a NKplain variable. If this is false,
+ * 0 is returned if the printed value is an error message.
+ * @return the parsed value. It is 0 if there was a parse error
+ * or if the output is an error message and #wantErrorValue
+ * is \c false. The returned object's text() is undefined.
+ */
+ virtual ExprValue* parsePrintExpr(const char* output, bool wantErrorValue) = 0;
+
+ /**
+ * Parses the output of the DCcd command.
+ * @return false if the message is an error message.
+ */
+ virtual bool parseChangeWD(const char* output, QString& message) = 0;
+
+ /**
+ * Parses the output of the DCexecutable command.
+ * @return false if an error occured.
+ */
+ virtual bool parseChangeExecutable(const char* output, QString& message) = 0;
+
+ /**
+ * Parses the output of the DCcorefile command.
+ * @return false if the core file was not loaded successfully.
+ */
+ virtual bool parseCoreFile(const char* output) = 0;
+
+ enum StopFlags {
+ SFrefreshSource = 1, /* refresh of source code is needed */
+ SFrefreshBreak = 2, /* refresh breakpoints */
+ SFrefreshThreads = 4, /* refresh thread list */
+ SFprogramActive = 128 /* program remains active */
+ };
+ /**
+ * Parses the output of commands that execute (a piece of) the program.
+ * @return The inclusive OR of zero or more of the StopFlags.
+ */
+ virtual uint parseProgramStopped(const char* output, QString& message) = 0;
+
+ /**
+ * Parses the output of the DCsharedlibs command.
+ */
+ virtual QStringList parseSharedLibs(const char* output) = 0;
+
+ /**
+ * Parses the output of the DCfindType command.
+ * @return true if a type was found.
+ */
+ virtual bool parseFindType(const char* output, QString& type) = 0;
+
+ /**
+ * Parses the output of the DCinforegisters command.
+ */
+ virtual std::list<RegisterInfo> parseRegisters(const char* output) = 0;
+
+ /**
+ * Parses the output of the DCinfoline command. Returns false if the
+ * two addresses could not be found.
+ */
+ virtual bool parseInfoLine(const char* output,
+ QString& addrFrom, QString& addrTo) = 0;
+
+ /**
+ * Parses the ouput of the DCdisassemble command.
+ */
+ virtual std::list<DisassembledCode> parseDisassemble(const char* output) = 0;
+
+ /**
+ * Parses a memory dump. Returns an empty string if no error was found;
+ * otherwise it contains an error message.
+ */
+ virtual QString parseMemoryDump(const char* output, std::list<MemoryDump>& memdump) = 0;
+
+ /**
+ * Parses the output of the DCsetvariable command. Returns an empty
+ * string if no error was found; otherwise it contains an error
+ * message.
+ */
+ virtual QString parseSetVariable(const char* output) = 0;
+
+ /**
+ * Returns a value that the user can edit.
+ */
+ virtual QString editableValue(VarTree* value);
+
+protected:
+ /** Removes all commands from the low-priority queue. */
+ void flushLoPriQueue();
+ /** Removes all commands from the high-priority queue. */
+ void flushHiPriQueue();
+
+ std::queue<CmdQueueItem*> m_hipriCmdQueue;
+ std::list<CmdQueueItem*> m_lopriCmdQueue;
+ /**
+ * The active command is kept separately from other pending commands.
+ */
+ CmdQueueItem* m_activeCmd;
+ /**
+ * Helper function that queues the given command string in the
+ * low-priority queue.
+ */
+ CmdQueueItem* queueCmdString(DbgCommand cmd, QString cmdString,
+ QueueMode mode);
+ /**
+ * Helper function that queues the given command string in the
+ * high-priority queue.
+ */
+ CmdQueueItem* executeCmdString(DbgCommand cmd, QString cmdString,
+ bool clearLow);
+ void writeCommand();
+ virtual void commandFinished(CmdQueueItem* cmd) = 0;
+
+protected:
+ /** @internal */
+ virtual int commSetupDoneC();
+
+ char m_prompt[10];
+ size_t m_promptMinLen;
+ char m_promptLastChar;
+ QRegExp m_promptRE;
+
+ // log file
+ QString m_logFileName;
+ QFile m_logFile;
+
+public slots:
+ void dequeueCmdByVar(VarTree* var);
+
+protected slots:
+ virtual void slotReceiveOutput(KProcess*, char* buffer, int buflen);
+ virtual void slotCommandRead(KProcess*);
+ virtual void slotExited(KProcess*);
+
+signals:
+ /**
+ * This signal is emitted when the output of a command has been fully
+ * collected and is ready to be interpreted.
+ */
+ void commandReceived(CmdQueueItem* cmd, const char* output);
+
+ /**
+ * This signal is emitted when the debugger recognizes that a specific
+ * location in a file ought to be displayed.
+ *
+ * Gdb's --fullname option supports this for the step, next, frame, and
+ * run commands (and possibly others).
+ *
+ * @param file specifies the file; this is not necessarily a full path
+ * name, and if it is relative, you won't know relative to what, you
+ * can only guess.
+ * @param lineNo specifies the line number (0-based!) (this may be
+ * negative, in which case the file should be activated, but the line
+ * should NOT be changed).
+ * @param address specifies the exact address of the PC or is empty.
+ */
+ void activateFileLine(const QString& file, int lineNo, const DbgAddr& address);
+
+ /**
+ * This signal is emitted when a command that starts the inferior has
+ * been submitted to the debugger.
+ */
+ void inferiorRunning();
+
+ /**
+ * This signal is emitted when all output from the debugger has been
+ * consumed and no more commands are in the queues.
+ */
+ void enterIdleState();
+};
+
+#endif // DBGDRIVER_H
diff --git a/kdbg/dbgmainwnd.cpp b/kdbg/dbgmainwnd.cpp
new file mode 100644
index 0000000..d9b4658
--- /dev/null
+++ b/kdbg/dbgmainwnd.cpp
@@ -0,0 +1,876 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include <kapplication.h>
+#include <klocale.h> /* i18n */
+#include <kmessagebox.h>
+#include <kconfig.h>
+#include <kstatusbar.h>
+#include <kiconloader.h>
+#include <kstdaccel.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <kpopupmenu.h>
+#include <kfiledialog.h>
+#include <kprocess.h>
+#include <kkeydialog.h>
+#include <kanimwidget.h>
+#include <kwin.h>
+#include <qlistbox.h>
+#include <qfileinfo.h>
+#include "dbgmainwnd.h"
+#include "debugger.h"
+#include "commandids.h"
+#include "winstack.h"
+#include "brkpt.h"
+#include "threadlist.h"
+#include "memwindow.h"
+#include "ttywnd.h"
+#include "procattach.h"
+#include "dbgdriver.h"
+#include "mydebug.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+DebuggerMainWnd::DebuggerMainWnd(const char* name) :
+ KDockMainWindow(0, name),
+ DebuggerMainWndBase()
+{
+ QPixmap p;
+
+ KDockWidget* dw0 = createDockWidget("Source", p, 0, i18n("Source"));
+ m_filesWindow = new WinStack(dw0, "files");
+ dw0->setWidget(m_filesWindow);
+ dw0->setDockSite(KDockWidget::DockCorner);
+ dw0->setEnableDocking(KDockWidget::DockNone);
+ setView(dw0);
+ setMainDockWidget(dw0);
+
+ KDockWidget* dw1 = createDockWidget("Stack", p, 0, i18n("Stack"));
+ m_btWindow = new QListBox(dw1, "backtrace");
+ dw1->setWidget(m_btWindow);
+ KDockWidget* dw2 = createDockWidget("Locals", p, 0, i18n("Locals"));
+ m_localVariables = new ExprWnd(dw2, i18n("Variable"), "locals");
+ dw2->setWidget(m_localVariables);
+ KDockWidget* dw3 = createDockWidget("Watches", p, 0, i18n("Watches"));
+ m_watches = new WatchWindow(dw3, "watches");
+ dw3->setWidget(m_watches);
+ KDockWidget* dw4 = createDockWidget("Registers", p, 0, i18n("Registers"));
+ m_registers = new RegisterView(dw4, "registers");
+ dw4->setWidget(m_registers);
+ KDockWidget* dw5 = createDockWidget("Breakpoints", p, 0, i18n("Breakpoints"));
+ m_bpTable = new BreakpointTable(dw5, "breakpoints");
+ dw5->setWidget(m_bpTable);
+ KDockWidget* dw6 = createDockWidget("Output", p, 0, i18n("Output"));
+ m_ttyWindow = new TTYWindow(dw6, "output");
+ dw6->setWidget(m_ttyWindow);
+ KDockWidget* dw7 = createDockWidget("Threads", p, 0, i18n("Threads"));
+ m_threads = new ThreadList(dw7, "threads");
+ dw7->setWidget(m_threads);
+ KDockWidget* dw8 = createDockWidget("Memory", p, 0, i18n("Memory"));
+ m_memoryWindow = new MemoryWindow(dw8, "memory");
+ dw8->setWidget(m_memoryWindow);
+
+ setupDebugger(this, m_localVariables, m_watches->watchVariables(), m_btWindow);
+ m_bpTable->setDebugger(m_debugger);
+ m_memoryWindow->setDebugger(m_debugger);
+
+ setStandardToolBarMenuEnabled(true);
+ initKAction();
+ initToolbar(); // kind of obsolete?
+
+ connect(m_watches, SIGNAL(addWatch()), SLOT(slotAddWatch()));
+ connect(m_watches, SIGNAL(deleteWatch()), m_debugger, SLOT(slotDeleteWatch()));
+ connect(m_watches, SIGNAL(textDropped(const QString&)), SLOT(slotAddWatch(const QString&)));
+
+ connect(&m_filesWindow->m_findDlg, SIGNAL(closed()), SLOT(updateUI()));
+ connect(m_filesWindow, SIGNAL(newFileLoaded()),
+ SLOT(slotNewFileLoaded()));
+ connect(m_filesWindow, SIGNAL(toggleBreak(const QString&,int,const DbgAddr&,bool)),
+ this, SLOT(slotToggleBreak(const QString&,int,const DbgAddr&,bool)));
+ connect(m_filesWindow, SIGNAL(enadisBreak(const QString&,int,const DbgAddr&)),
+ this, SLOT(slotEnaDisBreak(const QString&,int,const DbgAddr&)));
+ connect(m_debugger, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
+ m_filesWindow, SLOT(activate(const QString&,int,const DbgAddr&)));
+ connect(m_debugger, SIGNAL(executableUpdated()),
+ m_filesWindow, SLOT(reloadAllFiles()));
+ connect(m_debugger, SIGNAL(updatePC(const QString&,int,const DbgAddr&,int)),
+ m_filesWindow, SLOT(updatePC(const QString&,int,const DbgAddr&,int)));
+ // value popup communication
+ connect(m_filesWindow, SIGNAL(initiateValuePopup(const QString&)),
+ m_debugger, SLOT(slotValuePopup(const QString&)));
+ connect(m_debugger, SIGNAL(valuePopup(const QString&)),
+ m_filesWindow, SLOT(slotShowValueTip(const QString&)));
+ // disassembling
+ connect(m_filesWindow, SIGNAL(disassemble(const QString&, int)),
+ m_debugger, SLOT(slotDisassemble(const QString&, int)));
+ connect(m_debugger, SIGNAL(disassembled(const QString&,int,const std::list<DisassembledCode>&)),
+ m_filesWindow, SLOT(slotDisassembled(const QString&,int,const std::list<DisassembledCode>&)));
+ connect(m_filesWindow, SIGNAL(moveProgramCounter(const QString&,int,const DbgAddr&)),
+ m_debugger, SLOT(setProgramCounter(const QString&,int,const DbgAddr&)));
+ // program stopped
+ connect(m_debugger, SIGNAL(programStopped()), SLOT(slotProgramStopped()));
+ connect(&m_backTimer, SIGNAL(timeout()), SLOT(slotBackTimer()));
+ // tab width
+ connect(this, SIGNAL(setTabWidth(int)), m_filesWindow, SIGNAL(setTabWidth(int)));
+
+ // connect breakpoint table
+ connect(m_bpTable, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
+ m_filesWindow, SLOT(activate(const QString&,int,const DbgAddr&)));
+ connect(m_debugger, SIGNAL(updateUI()), m_bpTable, SLOT(updateUI()));
+ connect(m_debugger, SIGNAL(breakpointsChanged()), m_bpTable, SLOT(updateBreakList()));
+ connect(m_debugger, SIGNAL(breakpointsChanged()), m_bpTable, SLOT(updateUI()));
+
+ connect(m_debugger, SIGNAL(registersChanged(const std::list<RegisterInfo>&)),
+ m_registers, SLOT(updateRegisters(const std::list<RegisterInfo>&)));
+
+ connect(m_debugger, SIGNAL(memoryDumpChanged(const QString&, const std::list<MemoryDump>&)),
+ m_memoryWindow, SLOT(slotNewMemoryDump(const QString&, const std::list<MemoryDump>&)));
+ connect(m_debugger, SIGNAL(saveProgramSpecific(KConfigBase*)),
+ m_memoryWindow, SLOT(saveProgramSpecific(KConfigBase*)));
+ connect(m_debugger, SIGNAL(restoreProgramSpecific(KConfigBase*)),
+ m_memoryWindow, SLOT(restoreProgramSpecific(KConfigBase*)));
+
+ // thread window
+ connect(m_debugger, SIGNAL(threadsChanged(const std::list<ThreadInfo>&)),
+ m_threads, SLOT(updateThreads(const std::list<ThreadInfo>&)));
+ connect(m_threads, SIGNAL(setThread(int)),
+ m_debugger, SLOT(setThread(int)));
+
+ // view menu changes when docking state changes
+ connect(dockManager, SIGNAL(change()), SLOT(updateUI()));
+
+ // popup menu of the local variables window
+ connect(m_localVariables, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)),
+ this, SLOT(slotLocalsPopup(QListViewItem*, const QPoint&)));
+
+ restoreSettings(kapp->config());
+
+ updateUI();
+ m_bpTable->updateUI();
+}
+
+DebuggerMainWnd::~DebuggerMainWnd()
+{
+ saveSettings(kapp->config());
+ // must delete m_debugger early since it references our windows
+ delete m_debugger;
+ m_debugger = 0;
+
+ delete m_memoryWindow;
+ delete m_threads;
+ delete m_ttyWindow;
+ delete m_bpTable;
+ delete m_registers;
+ delete m_watches;
+ delete m_localVariables;
+ delete m_btWindow;
+ delete m_filesWindow;
+}
+
+void DebuggerMainWnd::initKAction()
+{
+ // file menu
+ KAction* open = KStdAction::open(this, SLOT(slotFileOpen()),
+ actionCollection());
+ open->setText(i18n("&Open Source..."));
+ KStdAction::close(m_filesWindow, SLOT(slotClose()), actionCollection());
+ (void)new KAction(i18n("&Reload Source"), "reload", 0, m_filesWindow,
+ SLOT(slotFileReload()), actionCollection(),
+ "file_reload");
+ (void)new KAction(i18n("&Executable..."), "execopen", 0, this,
+ SLOT(slotFileExe()), actionCollection(),
+ "file_executable");
+ m_recentExecAction = new KRecentFilesAction(i18n("Recent E&xecutables"), 0,
+ this, SLOT(slotRecentExec(const KURL&)),
+ actionCollection(), "file_executable_recent");
+ (void)new KAction(i18n("&Core dump..."), 0, this, SLOT(slotFileCore()),
+ actionCollection(), "file_core_dump");
+ KStdAction::quit(kapp, SLOT(closeAllWindows()), actionCollection());
+
+ // settings menu
+ (void)new KAction(i18n("This &Program..."), 0, this,
+ SLOT(slotFileProgSettings()), actionCollection(),
+ "settings_program");
+ (void)new KAction(i18n("&Global Options..."), 0, this,
+ SLOT(slotFileGlobalSettings()), actionCollection(),
+ "settings_global");
+ KStdAction::keyBindings(this, SLOT(slotConfigureKeys()), actionCollection());
+ KStdAction::showStatusbar(this, SLOT(slotViewStatusbar()), actionCollection());
+
+ // view menu
+ (void)new KToggleAction(i18n("&Find"), "find", CTRL+Key_F, m_filesWindow,
+ SLOT(slotViewFind()), actionCollection(),
+ "view_find");
+ (void)KStdAction::findNext(m_filesWindow, SLOT(slotFindForward()), actionCollection(), "view_findnext");
+ (void)KStdAction::findPrev(m_filesWindow, SLOT(slotFindBackward()), actionCollection(), "view_findprev");
+
+ i18n("Source &code");
+ struct { QString text; QWidget* w; QString id; } dw[] = {
+ { i18n("Stac&k"), m_btWindow, "view_stack"},
+ { i18n("&Locals"), m_localVariables, "view_locals"},
+ { i18n("&Watched expressions"), m_watches, "view_watched_expressions"},
+ { i18n("&Registers"), m_registers, "view_registers"},
+ { i18n("&Breakpoints"), m_bpTable, "view_breakpoints"},
+ { i18n("T&hreads"), m_threads, "view_threads"},
+ { i18n("&Output"), m_ttyWindow, "view_output"},
+ { i18n("&Memory"), m_memoryWindow, "view_memory"}
+ };
+ for (unsigned i = 0; i < sizeof(dw)/sizeof(dw[0]); i++) {
+ KDockWidget* d = dockParent(dw[i].w);
+ (void)new KToggleAction(dw[i].text, 0, d, SLOT(changeHideShowState()),
+ actionCollection(), dw[i].id);
+ }
+
+
+ // execution menu
+ KAction* a = new KAction(i18n("&Run"), "pgmrun", Key_F5, m_debugger,
+ SLOT(programRun()), actionCollection(), "exec_run");
+ connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
+ a = new KAction(i18n("Step &into"), "pgmstep", Key_F8, m_debugger,
+ SLOT(programStep()), actionCollection(),
+ "exec_step_into");
+ connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
+ a = new KAction(i18n("Step &over"), "pgmnext", Key_F10, m_debugger,
+ SLOT(programNext()), actionCollection(),
+ "exec_step_over");
+ connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
+ a = new KAction(i18n("Step o&ut"), "pgmfinish", Key_F6, m_debugger,
+ SLOT(programFinish()), actionCollection(),
+ "exec_step_out");
+ connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
+ a = new KAction(i18n("Run to &cursor"), Key_F7, this,
+ SLOT(slotExecUntil()), actionCollection(),
+ "exec_run_to_cursor");
+ connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
+ a = new KAction(i18n("Step i&nto by instruction"), "pgmstepi",
+ SHIFT+Key_F8, m_debugger, SLOT(programStepi()),
+ actionCollection(), "exec_step_into_by_insn");
+ connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
+ a = new KAction(i18n("Step o&ver by instruction"), "pgmnexti",
+ SHIFT+Key_F10, m_debugger, SLOT(programNexti()),
+ actionCollection(), "exec_step_over_by_insn");
+ connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
+ (void)new KAction(i18n("&Program counter to current line"), 0,
+ m_filesWindow, SLOT(slotMoveProgramCounter()),
+ actionCollection(), "exec_movepc");
+ (void)new KAction(i18n("&Break"), 0, m_debugger,
+ SLOT(programBreak()), actionCollection(),
+ "exec_break");
+ (void)new KAction(i18n("&Kill"), 0, m_debugger,
+ SLOT(programKill()), actionCollection(),
+ "exec_kill");
+ (void)new KAction(i18n("Re&start"), 0, m_debugger,
+ SLOT(programRunAgain()), actionCollection(),
+ "exec_restart");
+ (void)new KAction(i18n("A&ttach..."), 0, this,
+ SLOT(slotExecAttach()), actionCollection(),
+ "exec_attach");
+ (void)new KAction(i18n("&Arguments..."), 0, this,
+ SLOT(slotExecArgs()), actionCollection(),
+ "exec_arguments");
+
+ // breakpoint menu
+ (void)new KAction(i18n("Set/Clear &breakpoint"), "brkpt", Key_F9,
+ m_filesWindow, SLOT(slotBrkptSet()), actionCollection(),
+ "breakpoint_set");
+ (void)new KAction(i18n("Set &temporary breakpoint"), SHIFT+Key_F9,
+ m_filesWindow, SLOT(slotBrkptSetTemp()), actionCollection(),
+ "breakpoint_set_temporary");
+ (void)new KAction(i18n("&Enable/Disable breakpoint"), CTRL+Key_F9,
+ m_filesWindow, SLOT(slotBrkptEnable()), actionCollection(),
+ "breakpoint_enable");
+
+ // only in popup menus
+ (void)new KAction(i18n("Watch Expression"), 0, this,
+ SLOT(slotLocalsToWatch()), actionCollection(),
+ "watch_expression");
+ (void)new KAction(i18n("Edit Value"), Key_F2, this,
+ SLOT(slotEditValue()), actionCollection(),
+ "edit_value");
+
+ // all actions force an UI update
+ QValueList<KAction*> actions = actionCollection()->actions();
+ QValueList<KAction*>::Iterator it = actions.begin();
+ for (; it != actions.end(); ++it) {
+ connect(*it, SIGNAL(activated()), this, SLOT(updateUI()));
+ }
+
+ createGUI("kdbgui.rc");
+}
+
+void DebuggerMainWnd::initToolbar()
+{
+ KToolBar* toolbar = toolBar("mainToolBar");
+ toolbar->insertAnimatedWidget(ID_STATUS_BUSY,
+ actionCollection()->action("exec_break"), SLOT(activate()),
+ "pulse", -1);
+ toolbar->alignItemRight(ID_STATUS_BUSY, true);
+ m_animRunning = false;
+
+ KStatusBar* statusbar = statusBar();
+ statusbar->insertItem(m_statusActive, ID_STATUS_ACTIVE);
+ m_lastActiveStatusText = m_statusActive;
+ statusbar->insertItem("", ID_STATUS_MSG); /* message pane */
+
+ // reserve some translations
+ i18n("Restart");
+ i18n("Core dump");
+}
+
+bool DebuggerMainWnd::queryClose()
+{
+ if (m_debugger != 0) {
+ m_debugger->shutdown();
+ }
+ return true;
+}
+
+
+// instance properties
+void DebuggerMainWnd::saveProperties(KConfig* config)
+{
+ // session management
+ QString executable = "";
+ if (m_debugger != 0) {
+ executable = m_debugger->executable();
+ }
+ config->writeEntry("executable", executable);
+}
+
+void DebuggerMainWnd::readProperties(KConfig* config)
+{
+ // session management
+ QString execName = config->readEntry("executable");
+
+ TRACE("readProperties: executable=" + execName);
+ if (!execName.isEmpty()) {
+ debugProgram(execName, "");
+ }
+}
+
+const char WindowGroup[] = "Windows";
+const char RecentExecutables[] = "RecentExecutables";
+const char LastSession[] = "LastSession";
+
+void DebuggerMainWnd::saveSettings(KConfig* config)
+{
+ KConfigGroupSaver g(config, WindowGroup);
+
+ writeDockConfig(config);
+ fixDockConfig(config, false); // downgrade
+
+ m_recentExecAction->saveEntries(config, RecentExecutables);
+
+ KConfigGroupSaver g2(config, LastSession);
+ config->writeEntry("Width0Locals", m_localVariables->columnWidth(0));
+ config->writeEntry("Width0Watches", m_watches->columnWidth(0));
+
+ DebuggerMainWndBase::saveSettings(config);
+}
+
+void DebuggerMainWnd::restoreSettings(KConfig* config)
+{
+ KConfigGroupSaver g(config, WindowGroup);
+
+ fixDockConfig(config, true); // upgrade
+ readDockConfig(config);
+
+ // Workaround bug #87787: KDockManager stores the titles of the KDockWidgets
+ // in the config files, although they are localized:
+ // If the user changes the language, the titles remain in the previous language.
+ struct { QString text; QWidget* w; } dw[] = {
+ { i18n("Stack"), m_btWindow },
+ { i18n("Locals"), m_localVariables },
+ { i18n("Watches"), m_watches },
+ { i18n("Registers"), m_registers },
+ { i18n("Breakpoints"), m_bpTable },
+ { i18n("Threads"), m_threads },
+ { i18n("Output"), m_ttyWindow },
+ { i18n("Memory"), m_memoryWindow }
+ };
+ for (int i = 0; i < int(sizeof(dw)/sizeof(dw[0])); i++)
+ {
+ KDockWidget* w = dockParent(dw[i].w);
+ w->setTabPageLabel(dw[i].text);
+ // this actually changes the captions in the tabs:
+ QEvent ev(QEvent::CaptionChange);
+ w->event(&ev);
+ }
+
+ m_recentExecAction->loadEntries(config, RecentExecutables);
+
+ KConfigGroupSaver g2(config, LastSession);
+ int w;
+ w = config->readNumEntry("Width0Locals", -1);
+ if (w >= 0 && w < 30000)
+ m_localVariables->setColumnWidth(0, w);
+ w = config->readNumEntry("Width0Watches", -1);
+ if (w >= 0 && w < 30000)
+ m_watches->setColumnWidth(0, w);
+
+ DebuggerMainWndBase::restoreSettings(config);
+
+ emit setTabWidth(m_tabWidth);
+}
+
+void DebuggerMainWnd::updateUI()
+{
+ KToggleAction* viewFind =
+ static_cast<KToggleAction*>(actionCollection()->action("view_find"));
+ viewFind->setChecked(m_filesWindow->m_findDlg.isVisible());
+ viewFind->setEnabled(m_filesWindow->hasWindows());
+ actionCollection()->action("breakpoint_set")->setEnabled(m_debugger->canChangeBreakpoints());
+ actionCollection()->action("breakpoint_set_temporary")->setEnabled(m_debugger->canChangeBreakpoints());
+ actionCollection()->action("breakpoint_enable")->setEnabled(m_debugger->canChangeBreakpoints());
+ dockUpdateHelper("view_breakpoints", m_bpTable);
+ dockUpdateHelper("view_stack", m_btWindow);
+ dockUpdateHelper("view_locals", m_localVariables);
+ dockUpdateHelper("view_watched_expressions", m_watches);
+ dockUpdateHelper("view_registers", m_registers);
+ dockUpdateHelper("view_threads", m_threads);
+ dockUpdateHelper("view_memory", m_memoryWindow);
+ dockUpdateHelper("view_output", m_ttyWindow);
+
+ // AB: maybe in mainwndbase.cpp?
+ actionCollection()->action("file_executable")->setEnabled(m_debugger->isIdle());
+ actionCollection()->action("settings_program")->setEnabled(m_debugger->haveExecutable());
+ actionCollection()->action("file_core_dump")->setEnabled(m_debugger->canStart());
+ actionCollection()->action("file_close")->setEnabled(m_filesWindow->hasWindows());
+ actionCollection()->action("file_reload")->setEnabled(m_filesWindow->hasWindows());
+ actionCollection()->action("exec_step_into")->setEnabled(m_debugger->canSingleStep());
+ actionCollection()->action("exec_step_into_by_insn")->setEnabled(m_debugger->canSingleStep());
+ actionCollection()->action("exec_step_over")->setEnabled(m_debugger->canSingleStep());
+ actionCollection()->action("exec_step_over_by_insn")->setEnabled(m_debugger->canSingleStep());
+ actionCollection()->action("exec_step_out")->setEnabled(m_debugger->canSingleStep());
+ actionCollection()->action("exec_run_to_cursor")->setEnabled(m_debugger->canSingleStep());
+ actionCollection()->action("exec_movepc")->setEnabled(m_debugger->canSingleStep());
+ actionCollection()->action("exec_restart")->setEnabled(m_debugger->canSingleStep());
+ actionCollection()->action("exec_attach")->setEnabled(m_debugger->isReady());
+ actionCollection()->action("exec_run")->setEnabled(m_debugger->canStart() || m_debugger->canSingleStep());
+ actionCollection()->action("exec_kill")->setEnabled(m_debugger->haveExecutable() && m_debugger->isProgramActive());
+ actionCollection()->action("exec_break")->setEnabled(m_debugger->isProgramRunning());
+ actionCollection()->action("exec_arguments")->setEnabled(m_debugger->haveExecutable());
+ actionCollection()->action("edit_value")->setEnabled(m_debugger->canSingleStep());
+
+ // animation
+ KAnimWidget* w = toolBar("mainToolBar")->animatedWidget(ID_STATUS_BUSY);
+ if (m_debugger->isIdle()) {
+ if (m_animRunning) {
+ w->stop();
+ m_animRunning = false;
+ }
+ } else {
+ if (!m_animRunning) {
+ w->start();
+ m_animRunning = true;
+ }
+ }
+
+ // update statusbar
+ QString newStatus;
+ if (m_debugger->isProgramActive())
+ newStatus = m_statusActive;
+ if (newStatus != m_lastActiveStatusText) {
+ statusBar()->changeItem(newStatus, ID_STATUS_ACTIVE);
+ m_lastActiveStatusText = newStatus;
+ }
+}
+
+void DebuggerMainWnd::dockUpdateHelper(QString action, QWidget* w)
+{
+ KToggleAction* item =
+ static_cast<KToggleAction*>(actionCollection()->action(action));
+ bool canChange = canChangeDockVisibility(w);
+ item->setEnabled(canChange);
+ item->setChecked(canChange && isDockVisible(w));
+}
+
+void DebuggerMainWnd::updateLineItems()
+{
+ m_filesWindow->updateLineItems(m_debugger);
+}
+
+void DebuggerMainWnd::slotAddWatch()
+{
+ if (m_debugger != 0) {
+ QString t = m_watches->watchText();
+ m_debugger->addWatch(t);
+ }
+}
+
+void DebuggerMainWnd::slotAddWatch(const QString& text)
+{
+ if (m_debugger != 0) {
+ m_debugger->addWatch(text);
+ }
+}
+
+void DebuggerMainWnd::slotNewFileLoaded()
+{
+ // updates program counter in the new file
+ if (m_debugger != 0)
+ m_filesWindow->updateLineItems(m_debugger);
+}
+
+KDockWidget* DebuggerMainWnd::dockParent(QWidget* w)
+{
+ while ((w = w->parentWidget()) != 0) {
+ if (w->isA("KDockWidget"))
+ return static_cast<KDockWidget*>(w);
+ }
+ return 0;
+}
+
+bool DebuggerMainWnd::isDockVisible(QWidget* w)
+{
+ KDockWidget* d = dockParent(w);
+ return d != 0 && d->mayBeHide();
+}
+
+bool DebuggerMainWnd::canChangeDockVisibility(QWidget* w)
+{
+ KDockWidget* d = dockParent(w);
+ return d != 0 && (d->mayBeHide() || d->mayBeShow());
+}
+
+// upgrades the entries from version 0.0.4 to 0.0.5 and back
+void DebuggerMainWnd::fixDockConfig(KConfig* c, bool upgrade)
+{
+ static const char dockGroup[] = "dock_setting_default";
+ if (!c->hasGroup(dockGroup))
+ return;
+
+ static const char oldVersion[] = "0.0.4";
+ static const char newVersion[] = "0.0.5";
+ const char* from = upgrade ? oldVersion : newVersion;
+ const char* to = upgrade ? newVersion : oldVersion;
+ QMap<QString,QString> e = c->entryMap(dockGroup);
+ if (e["Version"] != from)
+ return;
+
+ KConfigGroupSaver g(c, dockGroup);
+ c->writeEntry("Version", to);
+ TRACE(upgrade ? "upgrading dockconfig" : "downgrading dockconfig");
+
+ // turn all orientation entries from 0 to 1 and from 1 to 0
+ QMap<QString,QString>::Iterator i;
+ for (i = e.begin(); i != e.end(); ++i)
+ {
+ if (i.key().right(12) == ":orientation") {
+ TRACE("upgrading " + i.key() + " old value: " + *i);
+ int orientation = c->readNumEntry(i.key(), -1);
+ if (orientation >= 0) { // paranoia
+ c->writeEntry(i.key(), 1 - orientation);
+ }
+ }
+ }
+}
+
+TTYWindow* DebuggerMainWnd::ttyWindow()
+{
+ return m_ttyWindow;
+}
+
+bool DebuggerMainWnd::debugProgram(const QString& exe, const QString& lang)
+{
+ // check the file name
+ QFileInfo fi(exe);
+
+ bool success = fi.isFile();
+ if (!success)
+ {
+ QString msg = i18n("`%1' is not a file or does not exist");
+ KMessageBox::sorry(this, msg.arg(exe));
+ }
+ else
+ {
+ success = DebuggerMainWndBase::debugProgram(fi.absFilePath(), lang, this);
+ }
+
+ if (success)
+ {
+ m_recentExecAction->addURL(KURL(fi.absFilePath()));
+
+ // keep the directory
+ m_lastDirectory = fi.dirPath(true);
+ m_filesWindow->setExtraDirectory(m_lastDirectory);
+
+ // set caption to basename part of executable
+ QString caption = fi.fileName();
+ setCaption(caption);
+ }
+ else
+ {
+ m_recentExecAction->removeURL(KURL(fi.absFilePath()));
+ }
+
+ return success;
+}
+
+void DebuggerMainWnd::slotNewStatusMsg()
+{
+ newStatusMsg(statusBar());
+}
+
+void DebuggerMainWnd::slotFileGlobalSettings()
+{
+ int oldTabWidth = m_tabWidth;
+
+ doGlobalOptions(this);
+
+ if (m_tabWidth != oldTabWidth) {
+ emit setTabWidth(m_tabWidth);
+ }
+}
+
+void DebuggerMainWnd::slotDebuggerStarting()
+{
+ DebuggerMainWndBase::slotDebuggerStarting();
+}
+
+void DebuggerMainWnd::slotToggleBreak(const QString& fileName, int lineNo,
+ const DbgAddr& address, bool temp)
+{
+ // lineNo is zero-based
+ if (m_debugger != 0) {
+ m_debugger->setBreakpoint(fileName, lineNo, address, temp);
+ }
+}
+
+void DebuggerMainWnd::slotEnaDisBreak(const QString& fileName, int lineNo,
+ const DbgAddr& address)
+{
+ // lineNo is zero-based
+ if (m_debugger != 0) {
+ m_debugger->enableDisableBreakpoint(fileName, lineNo, address);
+ }
+}
+
+QString DebuggerMainWnd::createOutputWindow()
+{
+ QString tty = DebuggerMainWndBase::createOutputWindow();
+ if (!tty.isEmpty()) {
+ connect(m_outputTermProc, SIGNAL(processExited(KProcess*)),
+ SLOT(slotTermEmuExited()));
+ }
+ return tty;
+}
+
+void DebuggerMainWnd::slotTermEmuExited()
+{
+ shutdownTermWindow();
+}
+
+void DebuggerMainWnd::slotProgramStopped()
+{
+ // when the program stopped, move the window to the foreground
+ if (m_popForeground) {
+ // unfortunately, this requires quite some force to work :-(
+ KWin::raiseWindow(winId());
+ KWin::forceActiveWindow(winId());
+ }
+ m_backTimer.stop();
+}
+
+void DebuggerMainWnd::intoBackground()
+{
+ if (m_popForeground) {
+ m_backTimer.start(m_backTimeout, true); /* single-shot */
+ }
+}
+
+void DebuggerMainWnd::slotBackTimer()
+{
+ lower();
+}
+
+void DebuggerMainWnd::slotRecentExec(const KURL& url)
+{
+ QString exe = url.path();
+ debugProgram(exe, "");
+}
+
+QString DebuggerMainWnd::makeSourceFilter()
+{
+ QString f;
+ f = m_sourceFilter + " " + m_headerFilter + i18n("|All source files\n");
+ f += m_sourceFilter + i18n("|Source files\n");
+ f += m_headerFilter + i18n("|Header files\n");
+ f += i18n("*|All files");
+ return f;
+}
+
+/*
+ * Pop up the context menu in the locals window
+ */
+void DebuggerMainWnd::slotLocalsPopup(QListViewItem*, const QPoint& pt)
+{
+ QPopupMenu* popup =
+ static_cast<QPopupMenu*>(factory()->container("popup_locals", this));
+ if (popup == 0) {
+ return;
+ }
+ if (popup->isVisible()) {
+ popup->hide();
+ } else {
+ popup->popup(pt);
+ }
+}
+
+/*
+ * Copies the currently selected item to the watch window.
+ */
+void DebuggerMainWnd::slotLocalsToWatch()
+{
+ VarTree* item = m_localVariables->selectedItem();
+
+ if (item != 0 && m_debugger != 0) {
+ QString text = item->computeExpr();
+ m_debugger->addWatch(text);
+ }
+}
+
+/*
+ * Starts editing a value in a value display
+ */
+void DebuggerMainWnd::slotEditValue()
+{
+ // does one of the value trees have the focus
+ QWidget* f = kapp->focusWidget();
+ ExprWnd* wnd;
+ if (f == m_localVariables) {
+ wnd = m_localVariables;
+ } else if (f == m_watches->watchVariables()) {
+ wnd = m_watches->watchVariables();
+ } else {
+ return;
+ }
+
+ if (m_localVariables->isEditing() ||
+ m_watches->watchVariables()->isEditing())
+ {
+ return; /* don't edit twice */
+ }
+
+ VarTree* expr = wnd->currentItem();
+ if (expr != 0 && m_debugger != 0 && m_debugger->canSingleStep())
+ {
+ TRACE("edit value");
+ // determine the text to edit
+ QString text = m_debugger->driver()->editableValue(expr);
+ wnd->editValue(expr, text);
+ }
+}
+
+void DebuggerMainWnd::slotFileOpen()
+{
+ // start browsing in the active file's directory
+ // fall back to last used directory (executable)
+ QString dir = m_lastDirectory;
+ QString fileName = m_filesWindow->activeFileName();
+ if (!fileName.isEmpty()) {
+ QFileInfo fi(fileName);
+ dir = fi.dirPath();
+ }
+
+ fileName = myGetFileName(i18n("Open"),
+ dir,
+ makeSourceFilter(), this);
+
+ if (!fileName.isEmpty())
+ {
+ QFileInfo fi(fileName);
+ m_lastDirectory = fi.dirPath();
+ m_filesWindow->setExtraDirectory(m_lastDirectory);
+ m_filesWindow->activateFile(fileName);
+ }
+}
+
+void DebuggerMainWnd::slotFileExe()
+{
+ if (m_debugger->isIdle())
+ {
+ // open a new executable
+ QString executable = myGetFileName(i18n("Select the executable to debug"),
+ m_lastDirectory, 0, this);
+ if (executable.isEmpty())
+ return;
+
+ debugProgram(executable, "");
+ }
+}
+
+void DebuggerMainWnd::slotFileCore()
+{
+ if (m_debugger->canStart())
+ {
+ QString corefile = myGetFileName(i18n("Select core dump"),
+ m_lastDirectory, 0, this);
+ if (!corefile.isEmpty()) {
+ m_debugger->useCoreFile(corefile, false);
+ }
+ }
+}
+
+void DebuggerMainWnd::slotFileProgSettings()
+{
+ if (m_debugger != 0) {
+ m_debugger->programSettings(this);
+ }
+}
+
+void DebuggerMainWnd::slotViewStatusbar()
+{
+ if (statusBar()->isVisible())
+ statusBar()->hide();
+ else
+ statusBar()->show();
+ setSettingsDirty();
+}
+
+void DebuggerMainWnd::slotExecUntil()
+{
+ if (m_debugger != 0)
+ {
+ QString file;
+ int lineNo;
+ if (m_filesWindow->activeLine(file, lineNo))
+ m_debugger->runUntil(file, lineNo);
+ }
+}
+
+void DebuggerMainWnd::slotExecAttach()
+{
+#ifdef PS_COMMAND
+ ProcAttachPS dlg(this);
+ // seed filter with executable name
+ QFileInfo fi = m_debugger->executable();
+ dlg.filterEdit->setText(fi.fileName());
+#else
+ ProcAttach dlg(this);
+ dlg.setText(m_debugger->attachedPid());
+#endif
+ if (dlg.exec()) {
+ m_debugger->attachProgram(dlg.text());
+ }
+}
+
+void DebuggerMainWnd::slotExecArgs()
+{
+ if (m_debugger != 0) {
+ m_debugger->programArgs(this);
+ }
+}
+
+void DebuggerMainWnd::slotConfigureKeys()
+{
+ KKeyDialog::configure(actionCollection(), this);
+}
+
+#include "dbgmainwnd.moc"
diff --git a/kdbg/dbgmainwnd.h b/kdbg/dbgmainwnd.h
new file mode 100644
index 0000000..cac766b
--- /dev/null
+++ b/kdbg/dbgmainwnd.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef DBGMAINWND_H
+#define DBGMAINWND_H
+
+#include <qtimer.h>
+#include <kdockwidget.h>
+#include "mainwndbase.h"
+#include "regwnd.h"
+
+class KRecentFilesAction;
+class WinStack;
+class QListBox;
+class QCString;
+class ExprWnd;
+class BreakpointTable;
+class ThreadList;
+class MemoryWindow;
+struct DbgAddr;
+
+class DebuggerMainWnd : public KDockMainWindow, public DebuggerMainWndBase
+{
+ Q_OBJECT
+public:
+ DebuggerMainWnd(const char* name);
+ ~DebuggerMainWnd();
+
+ bool debugProgram(const QString& exe, const QString& lang);
+
+protected:
+ // session properties
+ virtual void saveProperties(KConfig*);
+ virtual void readProperties(KConfig*);
+ // settings
+ void saveSettings(KConfig*);
+ void restoreSettings(KConfig*);
+
+ void initToolbar();
+ void initKAction();
+
+ // view windows
+ WinStack* m_filesWindow;
+ QListBox* m_btWindow;
+ ExprWnd* m_localVariables;
+ WatchWindow* m_watches;
+ RegisterView* m_registers;
+ BreakpointTable* m_bpTable;
+ TTYWindow* m_ttyWindow;
+ ThreadList* m_threads;
+ MemoryWindow* m_memoryWindow;
+
+ QTimer m_backTimer;
+
+ // recent execs in File menu
+ KRecentFilesAction* m_recentExecAction;
+
+protected:
+ virtual bool queryClose();
+ virtual TTYWindow* ttyWindow();
+ virtual QString createOutputWindow();
+
+ KDockWidget* dockParent(QWidget* w);
+ bool isDockVisible(QWidget* w);
+ bool canChangeDockVisibility(QWidget* w);
+ void dockUpdateHelper(QString action, QWidget* w);
+ void fixDockConfig(KConfig* c, bool upgrade);
+
+ QString makeSourceFilter();
+
+ // to avoid flicker when the status bar is updated,
+ // we store the last string that we put there
+ QString m_lastActiveStatusText;
+ bool m_animRunning;
+
+signals:
+ void setTabWidth(int tabWidth);
+
+public slots:
+ virtual void updateUI();
+ virtual void updateLineItems();
+ void slotAddWatch();
+ void slotAddWatch(const QString& text);
+ void slotNewFileLoaded();
+ void slotNewStatusMsg();
+ void slotDebuggerStarting();
+ void slotToggleBreak(const QString&, int, const DbgAddr&, bool);
+ void slotEnaDisBreak(const QString&, int, const DbgAddr&);
+ void slotTermEmuExited();
+ void slotProgramStopped();
+ void slotBackTimer();
+ void slotRecentExec(const KURL& url);
+ void slotLocalsPopup(QListViewItem*, const QPoint& pt);
+ void slotLocalsToWatch();
+ void slotEditValue();
+
+ void slotFileOpen();
+ void slotFileExe();
+ void slotFileCore();
+ void slotFileGlobalSettings();
+ void slotFileProgSettings();
+ void slotViewStatusbar();
+ void slotExecUntil();
+ void slotExecAttach();
+ void slotExecArgs();
+ void intoBackground();
+ void slotConfigureKeys();
+};
+
+#endif // DBGMAINWND_H
diff --git a/kdbg/debugger.cpp b/kdbg/debugger.cpp
new file mode 100644
index 0000000..6a09cf1
--- /dev/null
+++ b/kdbg/debugger.cpp
@@ -0,0 +1,2210 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "debugger.h"
+#include "dbgdriver.h"
+#include "pgmargs.h"
+#include "typetable.h"
+#include "exprwnd.h"
+#include "pgmsettings.h"
+#include "programconfig.h"
+#include <qregexp.h>
+#include <qfileinfo.h>
+#include <qlistbox.h>
+#include <qstringlist.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <klocale.h> /* i18n */
+#include <kmessagebox.h>
+#include <ctype.h>
+#include <stdlib.h> /* strtol, atoi */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* sleep(3) */
+#endif
+#include "mydebug.h"
+
+
+KDebugger::KDebugger(QWidget* parent,
+ ExprWnd* localVars,
+ ExprWnd* watchVars,
+ QListBox* backtrace) :
+ QObject(parent, "debugger"),
+ m_ttyLevel(ttyFull),
+ m_memoryFormat(MDTword | MDThex),
+ m_haveExecutable(false),
+ m_programActive(false),
+ m_programRunning(false),
+ m_sharedLibsListed(false),
+ m_typeTable(0),
+ m_programConfig(0),
+ m_d(0),
+ m_localVariables(*localVars),
+ m_watchVariables(*watchVars),
+ m_btWindow(*backtrace)
+{
+ m_envVars.setAutoDelete(true);
+
+ connect(&m_localVariables, SIGNAL(expanded(QListViewItem*)),
+ SLOT(slotExpanding(QListViewItem*)));
+ connect(&m_watchVariables, SIGNAL(expanded(QListViewItem*)),
+ SLOT(slotExpanding(QListViewItem*)));
+ connect(&m_localVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
+ SLOT(slotValueEdited(VarTree*, const QString&)));
+ connect(&m_watchVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
+ SLOT(slotValueEdited(VarTree*, const QString&)));
+
+ connect(&m_btWindow, SIGNAL(highlighted(int)), SLOT(gotoFrame(int)));
+
+ emit updateUI();
+}
+
+KDebugger::~KDebugger()
+{
+ if (m_programConfig != 0) {
+ saveProgramSettings();
+ m_programConfig->sync();
+ delete m_programConfig;
+ }
+
+ delete m_typeTable;
+}
+
+
+void KDebugger::saveSettings(KConfig* /*config*/)
+{
+}
+
+void KDebugger::restoreSettings(KConfig* /*config*/)
+{
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// external interface
+
+const char GeneralGroup[] = "General";
+const char DebuggerCmdStr[] = "DebuggerCmdStr";
+const char TTYLevelEntry[] = "TTYLevel";
+const char KDebugger::DriverNameEntry[] = "DriverName";
+
+bool KDebugger::debugProgram(const QString& name,
+ DebuggerDriver* driver)
+{
+ if (m_d != 0 && m_d->isRunning())
+ {
+ QApplication::setOverrideCursor(waitCursor);
+
+ stopDriver();
+
+ QApplication::restoreOverrideCursor();
+
+ if (m_d->isRunning() || m_haveExecutable) {
+ /* timed out! We can't really do anything useful now */
+ TRACE("timed out while waiting for gdb to die!");
+ return false;
+ }
+ delete m_d;
+ m_d = 0;
+ }
+
+ // wire up the driver
+ connect(driver, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
+ this, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)));
+ connect(driver, SIGNAL(processExited(KProcess*)), SLOT(gdbExited(KProcess*)));
+ connect(driver, SIGNAL(commandReceived(CmdQueueItem*,const char*)),
+ SLOT(parse(CmdQueueItem*,const char*)));
+ connect(driver, SIGNAL(wroteStdin(KProcess*)), SIGNAL(updateUI()));
+ connect(driver, SIGNAL(inferiorRunning()), SLOT(slotInferiorRunning()));
+ connect(driver, SIGNAL(enterIdleState()), SLOT(backgroundUpdate()));
+ connect(driver, SIGNAL(enterIdleState()), SIGNAL(updateUI()));
+ connect(&m_localVariables, SIGNAL(removingItem(VarTree*)),
+ driver, SLOT(dequeueCmdByVar(VarTree*)));
+ connect(&m_watchVariables, SIGNAL(removingItem(VarTree*)),
+ driver, SLOT(dequeueCmdByVar(VarTree*)));
+
+ // create the program settings object
+ openProgramConfig(name);
+
+ // get debugger command from per-program settings
+ if (m_programConfig != 0) {
+ m_programConfig->setGroup(GeneralGroup);
+ m_debuggerCmd = readDebuggerCmd();
+ // get terminal emulation level
+ m_ttyLevel = TTYLevel(m_programConfig->readNumEntry(TTYLevelEntry, ttyFull));
+ }
+ // the rest is read in later in the handler of DCexecutable
+
+ m_d = driver;
+
+ if (!startDriver()) {
+ TRACE("startDriver failed");
+ m_d = 0;
+ return false;
+ }
+
+ TRACE("before file cmd");
+ m_d->executeCmd(DCexecutable, name);
+ m_executable = name;
+
+ // set remote target
+ if (!m_remoteDevice.isEmpty()) {
+ m_d->executeCmd(DCtargetremote, m_remoteDevice);
+ m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
+ m_d->queueCmd(DCframe, 0, DebuggerDriver::QMnormal);
+ m_programActive = true;
+ m_haveExecutable = true;
+ }
+
+ // create a type table
+ m_typeTable = new ProgramTypeTable;
+ m_sharedLibsListed = false;
+
+ emit updateUI();
+
+ return true;
+}
+
+void KDebugger::shutdown()
+{
+ // shut down debugger driver
+ if (m_d != 0 && m_d->isRunning())
+ {
+ stopDriver();
+ }
+}
+
+void KDebugger::useCoreFile(QString corefile, bool batch)
+{
+ m_corefile = corefile;
+ if (!batch) {
+ CmdQueueItem* cmd = loadCoreFile();
+ cmd->m_byUser = true;
+ }
+}
+
+void KDebugger::setAttachPid(const QString& pid)
+{
+ m_attachedPid = pid;
+}
+
+void KDebugger::programRun()
+{
+ if (!isReady())
+ return;
+
+ // when program is active, but not a core file, continue
+ // otherwise run the program
+ if (m_programActive && m_corefile.isEmpty()) {
+ // gdb command: continue
+ m_d->executeCmd(DCcont, true);
+ } else {
+ // gdb command: run
+ m_d->executeCmd(DCrun, true);
+ m_corefile = QString();
+ m_programActive = true;
+ }
+ m_programRunning = true;
+}
+
+void KDebugger::attachProgram(const QString& pid)
+{
+ if (!isReady())
+ return;
+
+ m_attachedPid = pid;
+ TRACE("Attaching to " + m_attachedPid);
+ m_d->executeCmd(DCattach, m_attachedPid);
+ m_programActive = true;
+ m_programRunning = true;
+}
+
+void KDebugger::programRunAgain()
+{
+ if (canSingleStep()) {
+ m_d->executeCmd(DCrun, true);
+ m_corefile = QString();
+ m_programRunning = true;
+ }
+}
+
+void KDebugger::programStep()
+{
+ if (canSingleStep()) {
+ m_d->executeCmd(DCstep, true);
+ m_programRunning = true;
+ }
+}
+
+void KDebugger::programNext()
+{
+ if (canSingleStep()) {
+ m_d->executeCmd(DCnext, true);
+ m_programRunning = true;
+ }
+}
+
+void KDebugger::programStepi()
+{
+ if (canSingleStep()) {
+ m_d->executeCmd(DCstepi, true);
+ m_programRunning = true;
+ }
+}
+
+void KDebugger::programNexti()
+{
+ if (canSingleStep()) {
+ m_d->executeCmd(DCnexti, true);
+ m_programRunning = true;
+ }
+}
+
+void KDebugger::programFinish()
+{
+ if (canSingleStep()) {
+ m_d->executeCmd(DCfinish, true);
+ m_programRunning = true;
+ }
+}
+
+void KDebugger::programKill()
+{
+ if (haveExecutable() && isProgramActive()) {
+ if (m_programRunning) {
+ m_d->interruptInferior();
+ }
+ // this is an emergency command; flush queues
+ m_d->flushCommands(true);
+ m_d->executeCmd(DCkill, true);
+ }
+}
+
+bool KDebugger::runUntil(const QString& fileName, int lineNo)
+{
+ if (isReady() && m_programActive && !m_programRunning) {
+ // strip off directory part of file name
+ QString file = fileName;
+ int offset = file.findRev("/");
+ if (offset >= 0) {
+ file.remove(0, offset+1);
+ }
+ m_d->executeCmd(DCuntil, file, lineNo, true);
+ m_programRunning = true;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void KDebugger::programBreak()
+{
+ if (m_haveExecutable && m_programRunning) {
+ m_d->interruptInferior();
+ }
+}
+
+void KDebugger::programArgs(QWidget* parent)
+{
+ if (m_haveExecutable) {
+ QStringList allOptions = m_d->boolOptionList();
+ PgmArgs dlg(parent, m_executable, m_envVars, allOptions);
+ dlg.setArgs(m_programArgs);
+ dlg.setWd(m_programWD);
+ dlg.setOptions(m_boolOptions);
+ if (dlg.exec()) {
+ updateProgEnvironment(dlg.args(), dlg.wd(),
+ dlg.envVars(), dlg.options());
+ }
+ }
+}
+
+void KDebugger::programSettings(QWidget* parent)
+{
+ if (!m_haveExecutable)
+ return;
+
+ ProgramSettings dlg(parent, m_executable);
+
+ dlg.m_chooseDriver.setDebuggerCmd(m_debuggerCmd);
+ dlg.m_output.setTTYLevel(m_ttyLevel);
+
+ if (dlg.exec() == QDialog::Accepted)
+ {
+ m_debuggerCmd = dlg.m_chooseDriver.debuggerCmd();
+ m_ttyLevel = TTYLevel(dlg.m_output.ttyLevel());
+ }
+}
+
+bool KDebugger::setBreakpoint(QString file, int lineNo,
+ const DbgAddr& address, bool temporary)
+{
+ if (!isReady()) {
+ return false;
+ }
+
+ BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
+ if (bp == m_brkpts.end())
+ {
+ /*
+ * No such breakpoint, so set a new one. If we have an address, we
+ * set the breakpoint exactly there. Otherwise we use the file name
+ * plus line no.
+ */
+ Breakpoint* bp = new Breakpoint;
+ bp->temporary = temporary;
+
+ if (address.isEmpty())
+ {
+ bp->fileName = file;
+ bp->lineNo = lineNo;
+ }
+ else
+ {
+ bp->address = address;
+ }
+ setBreakpoint(bp, false);
+ }
+ else
+ {
+ /*
+ * If the breakpoint is disabled, enable it; if it's enabled,
+ * delete that breakpoint.
+ */
+ if (bp->enabled) {
+ deleteBreakpoint(bp);
+ } else {
+ enableDisableBreakpoint(bp);
+ }
+ }
+ return true;
+}
+
+void KDebugger::setBreakpoint(Breakpoint* bp, bool queueOnly)
+{
+ CmdQueueItem* cmd = executeBreakpoint(bp, queueOnly);
+ cmd->m_brkpt = bp; // used in newBreakpoint()
+}
+
+CmdQueueItem* KDebugger::executeBreakpoint(const Breakpoint* bp, bool queueOnly)
+{
+ CmdQueueItem* cmd;
+ if (!bp->text.isEmpty())
+ {
+ /*
+ * The breakpoint was set using the text box in the breakpoint
+ * list. This is the only way in which watchpoints are set.
+ */
+ if (bp->type == Breakpoint::watchpoint) {
+ cmd = m_d->executeCmd(DCwatchpoint, bp->text);
+ } else {
+ cmd = m_d->executeCmd(DCbreaktext, bp->text);
+ }
+ }
+ else if (bp->address.isEmpty())
+ {
+ // strip off directory part of file name
+ QString file = bp->fileName;
+ int offset = file.findRev("/");
+ if (offset >= 0) {
+ file.remove(0, offset+1);
+ }
+ if (queueOnly) {
+ cmd = m_d->queueCmd(bp->temporary ? DCtbreakline : DCbreakline,
+ file, bp->lineNo, DebuggerDriver::QMoverride);
+ } else {
+ cmd = m_d->executeCmd(bp->temporary ? DCtbreakline : DCbreakline,
+ file, bp->lineNo);
+ }
+ }
+ else
+ {
+ if (queueOnly) {
+ cmd = m_d->queueCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
+ bp->address.asString(), DebuggerDriver::QMoverride);
+ } else {
+ cmd = m_d->executeCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
+ bp->address.asString());
+ }
+ }
+ return cmd;
+}
+
+bool KDebugger::enableDisableBreakpoint(QString file, int lineNo,
+ const DbgAddr& address)
+{
+ BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
+ return enableDisableBreakpoint(bp);
+}
+
+bool KDebugger::enableDisableBreakpoint(BrkptIterator bp)
+{
+ if (bp == m_brkpts.end())
+ return false;
+
+ /*
+ * Toggle enabled/disabled state.
+ *
+ * The driver is not bothered if we are modifying an orphaned
+ * breakpoint.
+ */
+ if (!bp->isOrphaned()) {
+ if (!canChangeBreakpoints()) {
+ return false;
+ }
+ m_d->executeCmd(bp->enabled ? DCdisable : DCenable, bp->id);
+ } else {
+ bp->enabled = !bp->enabled;
+ emit breakpointsChanged();
+ }
+ return true;
+}
+
+bool KDebugger::conditionalBreakpoint(BrkptIterator bp,
+ const QString& condition,
+ int ignoreCount)
+{
+ if (bp == m_brkpts.end())
+ return false;
+
+ /*
+ * Change the condition and ignore count.
+ *
+ * The driver is not bothered if we are removing an orphaned
+ * breakpoint.
+ */
+
+ if (!bp->isOrphaned()) {
+ if (!canChangeBreakpoints()) {
+ return false;
+ }
+
+ bool changed = false;
+
+ if (bp->condition != condition) {
+ // change condition
+ m_d->executeCmd(DCcondition, condition, bp->id);
+ changed = true;
+ }
+ if (bp->ignoreCount != ignoreCount) {
+ // change ignore count
+ m_d->executeCmd(DCignore, bp->id, ignoreCount);
+ changed = true;
+ }
+ if (changed) {
+ // get the changes
+ m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
+ }
+ } else {
+ bp->condition = condition;
+ bp->ignoreCount = ignoreCount;
+ emit breakpointsChanged();
+ }
+ return true;
+}
+
+bool KDebugger::deleteBreakpoint(BrkptIterator bp)
+{
+ if (bp == m_brkpts.end())
+ return false;
+
+ /*
+ * Remove the breakpoint.
+ *
+ * The driver is not bothered if we are removing an orphaned
+ * breakpoint.
+ */
+ if (!bp->isOrphaned()) {
+ if (!canChangeBreakpoints()) {
+ return false;
+ }
+ m_d->executeCmd(DCdelete, bp->id);
+ } else {
+ m_brkpts.erase(bp);
+ emit breakpointsChanged();
+ }
+ return false;
+}
+
+bool KDebugger::canSingleStep()
+{
+ return isReady() && m_programActive && !m_programRunning;
+}
+
+bool KDebugger::canChangeBreakpoints()
+{
+ return isReady() && !m_programRunning;
+}
+
+bool KDebugger::canStart()
+{
+ return isReady() && !m_programActive;
+}
+
+bool KDebugger::isReady() const
+{
+ return m_haveExecutable &&
+ m_d != 0 && m_d->canExecuteImmediately();
+}
+
+bool KDebugger::isIdle() const
+{
+ return m_d == 0 || m_d->isIdle();
+}
+
+
+//////////////////////////////////////////////////////////
+// debugger driver
+
+bool KDebugger::startDriver()
+{
+ emit debuggerStarting(); /* must set m_inferiorTerminal */
+
+ /*
+ * If the per-program command string is empty, use the global setting
+ * (which might also be empty, in which case the driver uses its
+ * default).
+ */
+ m_explicitKill = false;
+ if (!m_d->startup(m_debuggerCmd)) {
+ return false;
+ }
+
+ /*
+ * If we have an output terminal, we use it. Otherwise we will run the
+ * program with input and output redirected to /dev/null. Other
+ * redirections are also necessary depending on the tty emulation
+ * level.
+ */
+ int redirect = RDNstdin|RDNstdout|RDNstderr; /* redirect everything */
+ if (!m_inferiorTerminal.isEmpty()) {
+ switch (m_ttyLevel) {
+ default:
+ case ttyNone:
+ // redirect everything
+ break;
+ case ttySimpleOutputOnly:
+ redirect = RDNstdin;
+ break;
+ case ttyFull:
+ redirect = 0;
+ break;
+ }
+ }
+ m_d->executeCmd(DCtty, m_inferiorTerminal, redirect);
+
+ return true;
+}
+
+void KDebugger::stopDriver()
+{
+ m_explicitKill = true;
+
+ if (m_attachedPid.isEmpty()) {
+ m_d->terminate();
+ } else {
+ m_d->detachAndTerminate();
+ }
+
+ /*
+ * We MUST wait until the slot gdbExited() has been called. But to
+ * avoid a deadlock, we wait only for some certain maximum time. Should
+ * this timeout be reached, the only reasonable thing one could do then
+ * is exiting kdbg.
+ */
+ kapp->processEvents(1000); /* ideally, this will already shut it down */
+ int maxTime = 20; /* about 20 seconds */
+ while (m_haveExecutable && maxTime > 0) {
+ // give gdb time to die (and send a SIGCLD)
+ ::sleep(1);
+ --maxTime;
+ kapp->processEvents(1000);
+ }
+}
+
+void KDebugger::gdbExited(KProcess*)
+{
+ /*
+ * Save settings, but only if gdb has already processed "info line
+ * main", otherwise we would save an empty config file, because it
+ * isn't read in until then!
+ */
+ if (m_programConfig != 0) {
+ if (m_haveExecutable) {
+ saveProgramSettings();
+ m_programConfig->sync();
+ }
+ delete m_programConfig;
+ m_programConfig = 0;
+ }
+
+ // erase types
+ delete m_typeTable;
+ m_typeTable = 0;
+
+ if (m_explicitKill) {
+ TRACE(m_d->driverName() + " exited normally");
+ } else {
+ QString msg = i18n("%1 exited unexpectedly.\n"
+ "Restart the session (e.g. with File|Executable).");
+ KMessageBox::error(parentWidget(), msg.arg(m_d->driverName()));
+ }
+
+ // reset state
+ m_haveExecutable = false;
+ m_executable = "";
+ m_programActive = false;
+ m_programRunning = false;
+ m_explicitKill = false;
+ m_debuggerCmd = QString(); /* use global setting at next start! */
+ m_attachedPid = QString(); /* we are no longer attached to a process */
+ m_ttyLevel = ttyFull;
+ m_brkpts.clear();
+
+ // erase PC
+ emit updatePC(QString(), -1, DbgAddr(), 0);
+}
+
+QString KDebugger::getConfigForExe(const QString& name)
+{
+ QFileInfo fi(name);
+ QString pgmConfigFile = fi.dirPath(true);
+ if (!pgmConfigFile.isEmpty()) {
+ pgmConfigFile += '/';
+ }
+ pgmConfigFile += ".kdbgrc." + fi.fileName();
+ TRACE("program config file = " + pgmConfigFile);
+ return pgmConfigFile;
+}
+
+void KDebugger::openProgramConfig(const QString& name)
+{
+ ASSERT(m_programConfig == 0);
+
+ QString pgmConfigFile = getConfigForExe(name);
+
+ m_programConfig = new ProgramConfig(pgmConfigFile);
+}
+
+const char EnvironmentGroup[] = "Environment";
+const char WatchGroup[] = "Watches";
+const char FileVersion[] = "FileVersion";
+const char ProgramArgs[] = "ProgramArgs";
+const char WorkingDirectory[] = "WorkingDirectory";
+const char OptionsSelected[] = "OptionsSelected";
+const char Variable[] = "Var%d";
+const char Value[] = "Value%d";
+const char ExprFmt[] = "Expr%d";
+
+void KDebugger::saveProgramSettings()
+{
+ ASSERT(m_programConfig != 0);
+ m_programConfig->setGroup(GeneralGroup);
+ m_programConfig->writeEntry(FileVersion, 1);
+ m_programConfig->writeEntry(ProgramArgs, m_programArgs);
+ m_programConfig->writeEntry(WorkingDirectory, m_programWD);
+ m_programConfig->writeEntry(OptionsSelected, m_boolOptions);
+ m_programConfig->writeEntry(DebuggerCmdStr, m_debuggerCmd);
+ m_programConfig->writeEntry(TTYLevelEntry, int(m_ttyLevel));
+ QString driverName;
+ if (m_d != 0)
+ driverName = m_d->driverName();
+ m_programConfig->writeEntry(DriverNameEntry, driverName);
+
+ // write environment variables
+ m_programConfig->deleteGroup(EnvironmentGroup);
+ m_programConfig->setGroup(EnvironmentGroup);
+ QDictIterator<EnvVar> it = m_envVars;
+ EnvVar* var;
+ QString varName;
+ QString varValue;
+ for (int i = 0; (var = it) != 0; ++it, ++i) {
+ varName.sprintf(Variable, i);
+ varValue.sprintf(Value, i);
+ m_programConfig->writeEntry(varName, it.currentKey());
+ m_programConfig->writeEntry(varValue, var->value);
+ }
+
+ saveBreakpoints(m_programConfig);
+
+ // watch expressions
+ // first get rid of whatever was in this group
+ m_programConfig->deleteGroup(WatchGroup);
+ // then start a new group
+ m_programConfig->setGroup(WatchGroup);
+ VarTree* item = m_watchVariables.firstChild();
+ int watchNum = 0;
+ for (; item != 0; item = item->nextSibling(), ++watchNum) {
+ varName.sprintf(ExprFmt, watchNum);
+ m_programConfig->writeEntry(varName, item->getText());
+ }
+
+ // give others a chance
+ emit saveProgramSpecific(m_programConfig);
+}
+
+void KDebugger::overrideProgramArguments(const QString& args)
+{
+ ASSERT(m_programConfig != 0);
+ m_programConfig->setGroup(GeneralGroup);
+ m_programConfig->writeEntry(ProgramArgs, args);
+}
+
+void KDebugger::restoreProgramSettings()
+{
+ ASSERT(m_programConfig != 0);
+ m_programConfig->setGroup(GeneralGroup);
+ /*
+ * We ignore file version for now we will use it in the future to
+ * distinguish different versions of this configuration file.
+ */
+ // m_debuggerCmd has been read in already
+ // m_ttyLevel has been read in already
+ QString pgmArgs = m_programConfig->readEntry(ProgramArgs);
+ QString pgmWd = m_programConfig->readEntry(WorkingDirectory);
+ QStringList boolOptions = m_programConfig->readListEntry(OptionsSelected);
+ m_boolOptions = QStringList();
+
+ // read environment variables
+ m_programConfig->setGroup(EnvironmentGroup);
+ m_envVars.clear();
+ QDict<EnvVar> pgmVars;
+ EnvVar* var;
+ QString varName;
+ QString varValue;
+ for (int i = 0;; ++i) {
+ varName.sprintf(Variable, i);
+ varValue.sprintf(Value, i);
+ if (!m_programConfig->hasKey(varName)) {
+ /* entry not present, assume that we've hit them all */
+ break;
+ }
+ QString name = m_programConfig->readEntry(varName);
+ if (name.isEmpty()) {
+ // skip empty names
+ continue;
+ }
+ var = new EnvVar;
+ var->value = m_programConfig->readEntry(varValue);
+ var->status = EnvVar::EVnew;
+ pgmVars.insert(name, var);
+ }
+
+ updateProgEnvironment(pgmArgs, pgmWd, pgmVars, boolOptions);
+
+ restoreBreakpoints(m_programConfig);
+
+ // watch expressions
+ m_programConfig->setGroup(WatchGroup);
+ m_watchVariables.clear();
+ for (int i = 0;; ++i) {
+ varName.sprintf(ExprFmt, i);
+ if (!m_programConfig->hasKey(varName)) {
+ /* entry not present, assume that we've hit them all */
+ break;
+ }
+ QString expr = m_programConfig->readEntry(varName);
+ if (expr.isEmpty()) {
+ // skip empty expressions
+ continue;
+ }
+ addWatch(expr);
+ }
+
+ // give others a chance
+ emit restoreProgramSpecific(m_programConfig);
+}
+
+/**
+ * Reads the debugger command line from the program settings. The config
+ * group must have been set by the caller.
+ */
+QString KDebugger::readDebuggerCmd()
+{
+ QString debuggerCmd = m_programConfig->readEntry(DebuggerCmdStr);
+
+ // always let the user confirm the debugger cmd if we are root
+ if (::geteuid() == 0)
+ {
+ if (!debuggerCmd.isEmpty()) {
+ QString msg = i18n(
+ "The settings for this program specify "
+ "the following debugger command:\n%1\n"
+ "Shall this command be used?");
+ if (KMessageBox::warningYesNo(parentWidget(), msg.arg(debuggerCmd))
+ != KMessageBox::Yes)
+ {
+ // don't use it
+ debuggerCmd = QString();
+ }
+ }
+ }
+ return debuggerCmd;
+}
+
+/*
+ * Breakpoints are saved one per group.
+ */
+const char BPGroup[] = "Breakpoint %d";
+const char File[] = "File";
+const char Line[] = "Line";
+const char Text[] = "Text";
+const char Address[] = "Address";
+const char Temporary[] = "Temporary";
+const char Enabled[] = "Enabled";
+const char Condition[] = "Condition";
+
+void KDebugger::saveBreakpoints(ProgramConfig* config)
+{
+ QString groupName;
+ int i = 0;
+ for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
+ {
+ if (bp->type == Breakpoint::watchpoint)
+ continue; /* don't save watchpoints */
+ groupName.sprintf(BPGroup, i++);
+
+ /* remove remmants */
+ config->deleteGroup(groupName);
+
+ config->setGroup(groupName);
+ if (!bp->text.isEmpty()) {
+ /*
+ * The breakpoint was set using the text box in the breakpoint
+ * list. We do not save the location by filename+line number,
+ * but instead honor what the user typed (a function name, for
+ * example, which could move between sessions).
+ */
+ config->writeEntry(Text, bp->text);
+ } else if (!bp->fileName.isEmpty()) {
+ config->writeEntry(File, bp->fileName);
+ config->writeEntry(Line, bp->lineNo);
+ /*
+ * Addresses are hardly correct across sessions, so we don't
+ * save it.
+ */
+ } else {
+ config->writeEntry(Address, bp->address.asString());
+ }
+ config->writeEntry(Temporary, bp->temporary);
+ config->writeEntry(Enabled, bp->enabled);
+ if (!bp->condition.isEmpty())
+ config->writeEntry(Condition, bp->condition);
+ // we do not save the ignore count
+ }
+ // delete remaining groups
+ // we recognize that a group is present if there is an Enabled entry
+ for (;; i++) {
+ groupName.sprintf(BPGroup, i);
+ config->setGroup(groupName);
+ if (!config->hasKey(Enabled)) {
+ /* group not present, assume that we've hit them all */
+ break;
+ }
+ config->deleteGroup(groupName);
+ }
+}
+
+void KDebugger::restoreBreakpoints(ProgramConfig* config)
+{
+ QString groupName;
+ /*
+ * We recognize the end of the list if there is no Enabled entry
+ * present.
+ */
+ for (int i = 0;; i++) {
+ groupName.sprintf(BPGroup, i);
+ config->setGroup(groupName);
+ if (!config->hasKey(Enabled)) {
+ /* group not present, assume that we've hit them all */
+ break;
+ }
+ Breakpoint* bp = new Breakpoint;
+ bp->fileName = config->readEntry(File);
+ bp->lineNo = config->readNumEntry(Line, -1);
+ bp->text = config->readEntry(Text);
+ bp->address = config->readEntry(Address);
+ // check consistency
+ if ((bp->fileName.isEmpty() || bp->lineNo < 0) &&
+ bp->text.isEmpty() &&
+ bp->address.isEmpty())
+ {
+ delete bp;
+ continue;
+ }
+ bp->enabled = config->readBoolEntry(Enabled, true);
+ bp->temporary = config->readBoolEntry(Temporary, false);
+ bp->condition = config->readEntry(Condition);
+
+ /*
+ * Add the breakpoint.
+ */
+ setBreakpoint(bp, false);
+ // the new breakpoint is disabled or conditionalized later
+ // in newBreakpoint()
+ }
+ m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
+}
+
+
+// parse output of command cmd
+void KDebugger::parse(CmdQueueItem* cmd, const char* output)
+{
+ ASSERT(cmd != 0); /* queue mustn't be empty */
+
+ TRACE(QString(__PRETTY_FUNCTION__) + " parsing " + output);
+
+ switch (cmd->m_cmd) {
+ case DCtargetremote:
+ // the output (if any) is uninteresting
+ case DCsetargs:
+ case DCtty:
+ // there is no output
+ case DCsetenv:
+ case DCunsetenv:
+ case DCsetoption:
+ /* if value is empty, we see output, but we don't care */
+ break;
+ case DCcd:
+ /* display gdb's message in the status bar */
+ m_d->parseChangeWD(output, m_statusMessage);
+ emit updateStatusMessage();
+ break;
+ case DCinitialize:
+ break;
+ case DCexecutable:
+ if (m_d->parseChangeExecutable(output, m_statusMessage))
+ {
+ // success; restore breakpoints etc.
+ if (m_programConfig != 0) {
+ restoreProgramSettings();
+ }
+ // load file containing main() or core file
+ if (!m_corefile.isEmpty())
+ {
+ // load core file
+ loadCoreFile();
+ }
+ else if (!m_attachedPid.isEmpty())
+ {
+ m_d->queueCmd(DCattach, m_attachedPid, DebuggerDriver::QMoverride);
+ m_programActive = true;
+ m_programRunning = true;
+ }
+ else if (!m_remoteDevice.isEmpty())
+ {
+ // handled elsewhere
+ }
+ else
+ {
+ m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
+ }
+ if (!m_statusMessage.isEmpty())
+ emit updateStatusMessage();
+ } else {
+ QString msg = m_d->driverName() + ": " + m_statusMessage;
+ KMessageBox::sorry(parentWidget(), msg);
+ m_executable = "";
+ m_corefile = ""; /* don't process core file */
+ m_haveExecutable = false;
+ }
+ break;
+ case DCcorefile:
+ // in any event we have an executable at this point
+ m_haveExecutable = true;
+ if (m_d->parseCoreFile(output)) {
+ // loading a core is like stopping at a breakpoint
+ m_programActive = true;
+ handleRunCommands(output);
+ // do not reset m_corefile
+ } else {
+ // report error
+ QString msg = m_d->driverName() + ": " + QString(output);
+ KMessageBox::sorry(parentWidget(), msg);
+
+ // if core file was loaded from command line, revert to info line main
+ if (!cmd->m_byUser) {
+ m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
+ }
+ m_corefile = QString(); /* core file not available any more */
+ }
+ break;
+ case DCinfolinemain:
+ // ignore the output, marked file info follows
+ m_haveExecutable = true;
+ break;
+ case DCinfolocals:
+ // parse local variables
+ if (output[0] != '\0') {
+ handleLocals(output);
+ }
+ break;
+ case DCinforegisters:
+ handleRegisters(output);
+ break;
+ case DCexamine:
+ handleMemoryDump(output);
+ break;
+ case DCinfoline:
+ handleInfoLine(cmd, output);
+ break;
+ case DCdisassemble:
+ handleDisassemble(cmd, output);
+ break;
+ case DCframe:
+ handleFrameChange(output);
+ updateAllExprs();
+ break;
+ case DCbt:
+ handleBacktrace(output);
+ updateAllExprs();
+ break;
+ case DCprint:
+ handlePrint(cmd, output);
+ break;
+ case DCprintDeref:
+ handlePrintDeref(cmd, output);
+ break;
+ case DCattach:
+ m_haveExecutable = true;
+ // fall through
+ case DCrun:
+ case DCcont:
+ case DCstep:
+ case DCstepi:
+ case DCnext:
+ case DCnexti:
+ case DCfinish:
+ case DCuntil:
+ case DCthread:
+ handleRunCommands(output);
+ break;
+ case DCkill:
+ m_programRunning = m_programActive = false;
+ // erase PC
+ emit updatePC(QString(), -1, DbgAddr(), 0);
+ break;
+ case DCbreaktext:
+ case DCbreakline:
+ case DCtbreakline:
+ case DCbreakaddr:
+ case DCtbreakaddr:
+ case DCwatchpoint:
+ newBreakpoint(cmd, output);
+ // fall through
+ case DCdelete:
+ case DCenable:
+ case DCdisable:
+ // these commands need immediate response
+ m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverrideMoreEqual);
+ break;
+ case DCinfobreak:
+ // note: this handler must not enqueue a command, since
+ // DCinfobreak is used at various different places.
+ updateBreakList(output);
+ break;
+ case DCfindType:
+ handleFindType(cmd, output);
+ break;
+ case DCprintStruct:
+ case DCprintQStringStruct:
+ case DCprintWChar:
+ handlePrintStruct(cmd, output);
+ break;
+ case DCinfosharedlib:
+ handleSharedLibs(output);
+ break;
+ case DCcondition:
+ case DCignore:
+ // we are not interested in the output
+ break;
+ case DCinfothreads:
+ handleThreadList(output);
+ break;
+ case DCsetpc:
+ handleSetPC(output);
+ break;
+ case DCsetvariable:
+ handleSetVariable(cmd, output);
+ break;
+ }
+}
+
+void KDebugger::backgroundUpdate()
+{
+ /*
+ * If there are still expressions that need to be updated, then do so.
+ */
+ if (m_programActive)
+ evalExpressions();
+}
+
+void KDebugger::handleRunCommands(const char* output)
+{
+ uint flags = m_d->parseProgramStopped(output, m_statusMessage);
+ emit updateStatusMessage();
+
+ m_programActive = flags & DebuggerDriver::SFprogramActive;
+
+ // refresh files if necessary
+ if (flags & DebuggerDriver::SFrefreshSource) {
+ TRACE("re-reading files");
+ emit executableUpdated();
+ }
+
+ /*
+ * Try to set any orphaned breakpoints now.
+ */
+ for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
+ {
+ if (bp->isOrphaned()) {
+ TRACE(QString("re-trying brkpt loc: %2 file: %3 line: %1")
+ .arg(bp->lineNo).arg(bp->location, bp->fileName));
+ CmdQueueItem* cmd = executeBreakpoint(&*bp, true);
+ cmd->m_existingBrkpt = bp->id; // used in newBreakpoint()
+ flags |= DebuggerDriver::SFrefreshBreak;
+ }
+ }
+
+ /*
+ * If we stopped at a breakpoint, we must update the breakpoint list
+ * because the hit count changes. Also, if the breakpoint was temporary
+ * it would go away now.
+ */
+ if ((flags & (DebuggerDriver::SFrefreshBreak|DebuggerDriver::SFrefreshSource)) ||
+ stopMayChangeBreakList())
+ {
+ m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
+ }
+
+ /*
+ * If we haven't listed the shared libraries yet, do so. We must do
+ * this before we emit any commands that list variables, since the type
+ * libraries depend on the shared libraries.
+ */
+ if (!m_sharedLibsListed) {
+ // must be a high-priority command!
+ m_d->executeCmd(DCinfosharedlib);
+ }
+
+ // get the backtrace if the program is running
+ if (m_programActive) {
+ m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
+ } else {
+ // program finished: erase PC
+ emit updatePC(QString(), -1, DbgAddr(), 0);
+ // dequeue any commands in the queues
+ m_d->flushCommands();
+ }
+
+ /* Update threads list */
+ if (m_programActive && (flags & DebuggerDriver::SFrefreshThreads)) {
+ m_d->queueCmd(DCinfothreads, DebuggerDriver::QMoverride);
+ }
+
+ m_programRunning = false;
+ emit programStopped();
+}
+
+void KDebugger::slotInferiorRunning()
+{
+ m_programRunning = true;
+}
+
+void KDebugger::updateAllExprs()
+{
+ if (!m_programActive)
+ return;
+
+ // retrieve local variables
+ m_d->queueCmd(DCinfolocals, DebuggerDriver::QMoverride);
+
+ // retrieve registers
+ m_d->queueCmd(DCinforegisters, DebuggerDriver::QMoverride);
+
+ // get new memory dump
+ if (!m_memoryExpression.isEmpty()) {
+ queueMemoryDump(false);
+ }
+
+ // update watch expressions
+ VarTree* item = m_watchVariables.firstChild();
+ for (; item != 0; item = item->nextSibling()) {
+ m_watchEvalExpr.push_back(item->getText());
+ }
+}
+
+void KDebugger::updateProgEnvironment(const QString& args, const QString& wd,
+ const QDict<EnvVar>& newVars,
+ const QStringList& newOptions)
+{
+ m_programArgs = args;
+ m_d->executeCmd(DCsetargs, m_programArgs);
+ TRACE("new pgm args: " + m_programArgs + "\n");
+
+ m_programWD = wd.stripWhiteSpace();
+ if (!m_programWD.isEmpty()) {
+ m_d->executeCmd(DCcd, m_programWD);
+ TRACE("new wd: " + m_programWD + "\n");
+ }
+
+ // update environment variables
+ QDictIterator<EnvVar> it = newVars;
+ EnvVar* val;
+ for (; (val = it) != 0; ++it) {
+ QString var = it.currentKey();
+ switch (val->status) {
+ case EnvVar::EVnew:
+ m_envVars.insert(var, val);
+ // fall thru
+ case EnvVar::EVdirty:
+ // the value must be in our list
+ ASSERT(m_envVars[var] == val);
+ // update value
+ m_d->executeCmd(DCsetenv, var, val->value);
+ break;
+ case EnvVar::EVdeleted:
+ // must be in our list
+ ASSERT(m_envVars[var] == val);
+ // delete value
+ m_d->executeCmd(DCunsetenv, var);
+ m_envVars.remove(var);
+ break;
+ default:
+ ASSERT(false);
+ case EnvVar::EVclean:
+ // variable not changed
+ break;
+ }
+ }
+
+ // update options
+ QStringList::ConstIterator oi;
+ for (oi = newOptions.begin(); oi != newOptions.end(); ++oi)
+ {
+ if (m_boolOptions.findIndex(*oi) < 0) {
+ // the options is currently not set, so set it
+ m_d->executeCmd(DCsetoption, *oi, 1);
+ } else {
+ // option is set, no action required, but move it to the end
+ m_boolOptions.remove(*oi);
+ }
+ m_boolOptions.append(*oi);
+ }
+ /*
+ * Now all options that should be set are at the end of m_boolOptions.
+ * If some options need to be unset, they are at the front of the list.
+ * Here we unset and remove them.
+ */
+ while (m_boolOptions.count() > newOptions.count()) {
+ m_d->executeCmd(DCsetoption, m_boolOptions.first(), 0);
+ m_boolOptions.remove(m_boolOptions.begin());
+ }
+}
+
+void KDebugger::handleLocals(const char* output)
+{
+ // retrieve old list of local variables
+ QStringList oldVars = m_localVariables.exprList();
+
+ /*
+ * Get local variables.
+ */
+ std::list<ExprValue*> newVars;
+ parseLocals(output, newVars);
+
+ /*
+ * Clear any old VarTree item pointers, so that later we don't access
+ * dangling pointers.
+ */
+ m_localVariables.clearPendingUpdates();
+
+ /*
+ * Match old variables against new ones.
+ */
+ for (QStringList::ConstIterator n = oldVars.begin(); n != oldVars.end(); ++n) {
+ // lookup this variable in the list of new variables
+ std::list<ExprValue*>::iterator v = newVars.begin();
+ while (v != newVars.end() && (*v)->m_name != *n)
+ ++v;
+ if (v == newVars.end()) {
+ // old variable not in the new variables
+ TRACE("old var deleted: " + *n);
+ VarTree* v = m_localVariables.topLevelExprByName(*n);
+ if (v != 0) {
+ m_localVariables.removeExpr(v);
+ }
+ } else {
+ // variable in both old and new lists: update
+ TRACE("update var: " + *n);
+ m_localVariables.updateExpr(*v, *m_typeTable);
+ // remove the new variable from the list
+ delete *v;
+ newVars.erase(v);
+ }
+ }
+ // insert all remaining new variables
+ while (!newVars.empty())
+ {
+ ExprValue* v = newVars.front();
+ TRACE("new var: " + v->m_name);
+ m_localVariables.insertExpr(v, *m_typeTable);
+ delete v;
+ newVars.pop_front();
+ }
+}
+
+void KDebugger::parseLocals(const char* output, std::list<ExprValue*>& newVars)
+{
+ std::list<ExprValue*> vars;
+ m_d->parseLocals(output, vars);
+
+ QString origName; /* used in renaming variables */
+ while (!vars.empty())
+ {
+ ExprValue* variable = vars.front();
+ vars.pop_front();
+ /*
+ * When gdb prints local variables, those from the innermost block
+ * come first. We run through the list of already parsed variables
+ * to find duplicates (ie. variables that hide local variables from
+ * a surrounding block). We keep the name of the inner variable, but
+ * rename those from the outer block so that, when the value is
+ * updated in the window, the value of the variable that is
+ * _visible_ changes the color!
+ */
+ int block = 0;
+ origName = variable->m_name;
+ for (std::list<ExprValue*>::iterator v = newVars.begin(); v != newVars.end(); ++v) {
+ if (variable->m_name == (*v)->m_name) {
+ // we found a duplicate, change name
+ block++;
+ QString newName = origName + " (" + QString().setNum(block) + ")";
+ variable->m_name = newName;
+ }
+ }
+ newVars.push_back(variable);
+ }
+}
+
+bool KDebugger::handlePrint(CmdQueueItem* cmd, const char* output)
+{
+ ASSERT(cmd->m_expr != 0);
+
+ ExprValue* variable = m_d->parsePrintExpr(output, true);
+ if (variable == 0)
+ return false;
+
+ // set expression "name"
+ variable->m_name = cmd->m_expr->getText();
+
+ {
+ TRACE("update expr: " + cmd->m_expr->getText());
+ cmd->m_exprWnd->updateExpr(cmd->m_expr, variable, *m_typeTable);
+ delete variable;
+ }
+
+ evalExpressions(); /* enqueue dereferenced pointers */
+
+ return true;
+}
+
+bool KDebugger::handlePrintDeref(CmdQueueItem* cmd, const char* output)
+{
+ ASSERT(cmd->m_expr != 0);
+
+ ExprValue* variable = m_d->parsePrintExpr(output, true);
+ if (variable == 0)
+ return false;
+
+ // set expression "name"
+ variable->m_name = cmd->m_expr->getText();
+
+ {
+ /*
+ * We must insert a dummy parent, because otherwise variable's value
+ * would overwrite cmd->m_expr's value.
+ */
+ ExprValue* dummyParent = new ExprValue(variable->m_name, VarTree::NKplain);
+ dummyParent->m_varKind = VarTree::VKdummy;
+ // the name of the parsed variable is the address of the pointer
+ QString addr = "*" + cmd->m_expr->value();
+ variable->m_name = addr;
+ variable->m_nameKind = VarTree::NKaddress;
+
+ dummyParent->m_child = variable;
+ // expand the first level for convenience
+ variable->m_initiallyExpanded = true;
+ TRACE("update ptr: " + cmd->m_expr->getText());
+ cmd->m_exprWnd->updateExpr(cmd->m_expr, dummyParent, *m_typeTable);
+ delete dummyParent;
+ }
+
+ evalExpressions(); /* enqueue dereferenced pointers */
+
+ return true;
+}
+
+// parse the output of bt
+void KDebugger::handleBacktrace(const char* output)
+{
+ // reduce flicker
+ m_btWindow.setAutoUpdate(false);
+
+ m_btWindow.clear();
+
+ std::list<StackFrame> stack;
+ m_d->parseBackTrace(output, stack);
+
+ if (!stack.empty()) {
+ std::list<StackFrame>::iterator frm = stack.begin();
+ // first frame must set PC
+ // note: frm->lineNo is zero-based
+ emit updatePC(frm->fileName, frm->lineNo, frm->address, frm->frameNo);
+
+ for (; frm != stack.end(); ++frm) {
+ QString func;
+ if (frm->var != 0)
+ func = frm->var->m_name;
+ else
+ func = frm->fileName + ":" + QString().setNum(frm->lineNo+1);
+ m_btWindow.insertItem(func);
+ TRACE("frame " + func + " (" + frm->fileName + ":" +
+ QString().setNum(frm->lineNo+1) + ")");
+ }
+ }
+
+ m_btWindow.setAutoUpdate(true);
+ m_btWindow.repaint();
+}
+
+void KDebugger::gotoFrame(int frame)
+{
+ m_d->executeCmd(DCframe, frame);
+}
+
+void KDebugger::handleFrameChange(const char* output)
+{
+ QString fileName;
+ int frameNo;
+ int lineNo;
+ DbgAddr address;
+ if (m_d->parseFrameChange(output, frameNo, fileName, lineNo, address)) {
+ /* lineNo can be negative here if we can't find a file name */
+ emit updatePC(fileName, lineNo, address, frameNo);
+ } else {
+ emit updatePC(fileName, -1, address, frameNo);
+ }
+}
+
+void KDebugger::evalExpressions()
+{
+ // evaluate expressions in the following order:
+ // watch expressions
+ // pointers in local variables
+ // pointers in watch expressions
+ // types in local variables
+ // types in watch expressions
+ // struct members in local variables
+ // struct members in watch expressions
+ VarTree* exprItem = 0;
+ if (!m_watchEvalExpr.empty())
+ {
+ QString expr = m_watchEvalExpr.front();
+ m_watchEvalExpr.pop_front();
+ exprItem = m_watchVariables.topLevelExprByName(expr);
+ }
+ if (exprItem != 0) {
+ CmdQueueItem* cmd = m_d->queueCmd(DCprint, exprItem->getText(), DebuggerDriver::QMoverride);
+ // remember which expr this was
+ cmd->m_expr = exprItem;
+ cmd->m_exprWnd = &m_watchVariables;
+ } else {
+ ExprWnd* wnd;
+#define POINTER(widget) \
+ wnd = &widget; \
+ exprItem = widget.nextUpdatePtr(); \
+ if (exprItem != 0) goto pointer
+#define STRUCT(widget) \
+ wnd = &widget; \
+ exprItem = widget.nextUpdateStruct(); \
+ if (exprItem != 0) goto ustruct
+#define TYPE(widget) \
+ wnd = &widget; \
+ exprItem = widget.nextUpdateType(); \
+ if (exprItem != 0) goto type
+ repeat:
+ POINTER(m_localVariables);
+ POINTER(m_watchVariables);
+ STRUCT(m_localVariables);
+ STRUCT(m_watchVariables);
+ TYPE(m_localVariables);
+ TYPE(m_watchVariables);
+#undef POINTER
+#undef STRUCT
+#undef TYPE
+ return;
+
+ pointer:
+ // we have an expression to send
+ dereferencePointer(wnd, exprItem, false);
+ return;
+
+ ustruct:
+ // paranoia
+ if (exprItem->m_type == 0 || exprItem->m_type == TypeInfo::unknownType())
+ goto repeat;
+ evalInitialStructExpression(exprItem, wnd, false);
+ return;
+
+ type:
+ /*
+ * Sometimes a VarTree gets registered twice for a type update. So
+ * it may happen that it has already been updated. Hence, we ignore
+ * it here and go on to the next task.
+ */
+ if (exprItem->m_type != 0)
+ goto repeat;
+ determineType(wnd, exprItem);
+ }
+}
+
+void KDebugger::dereferencePointer(ExprWnd* wnd, VarTree* exprItem,
+ bool immediate)
+{
+ ASSERT(exprItem->m_varKind == VarTree::VKpointer);
+
+ QString expr = exprItem->computeExpr();
+ TRACE("dereferencing pointer: " + expr);
+ CmdQueueItem* cmd;
+ if (immediate) {
+ cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverrideMoreEqual);
+ } else {
+ cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverride);
+ }
+ // remember which expr this was
+ cmd->m_expr = exprItem;
+ cmd->m_exprWnd = wnd;
+}
+
+void KDebugger::determineType(ExprWnd* wnd, VarTree* exprItem)
+{
+ ASSERT(exprItem->m_varKind == VarTree::VKstruct);
+
+ QString expr = exprItem->computeExpr();
+ TRACE("get type of: " + expr);
+ CmdQueueItem* cmd;
+ cmd = m_d->queueCmd(DCfindType, expr, DebuggerDriver::QMoverride);
+
+ // remember which expr this was
+ cmd->m_expr = exprItem;
+ cmd->m_exprWnd = wnd;
+}
+
+void KDebugger::handleFindType(CmdQueueItem* cmd, const char* output)
+{
+ QString type;
+ if (m_d->parseFindType(output, type))
+ {
+ ASSERT(cmd != 0 && cmd->m_expr != 0);
+
+ TypeInfo* info = m_typeTable->lookup(type);
+
+ if (info == 0) {
+ /*
+ * We've asked gdb for the type of the expression in
+ * cmd->m_expr, but it returned a name we don't know. The base
+ * class (and member) types have been checked already (at the
+ * time when we parsed that particular expression). Now it's
+ * time to derive the type from the base classes as a last
+ * resort.
+ */
+ info = cmd->m_expr->inferTypeFromBaseClass();
+ // if we found a type through this method, register an alias
+ if (info != 0) {
+ TRACE("infered alias: " + type);
+ m_typeTable->registerAlias(type, info);
+ }
+ }
+ if (info == 0) {
+ TRACE("unknown type "+type);
+ cmd->m_expr->m_type = TypeInfo::unknownType();
+ } else {
+ cmd->m_expr->m_type = info;
+ /* since this node has a new type, we get its value immediately */
+ evalInitialStructExpression(cmd->m_expr, cmd->m_exprWnd, false);
+ return;
+ }
+ }
+
+ evalExpressions(); /* queue more of them */
+}
+
+void KDebugger::handlePrintStruct(CmdQueueItem* cmd, const char* output)
+{
+ VarTree* var = cmd->m_expr;
+ ASSERT(var != 0);
+ ASSERT(var->m_varKind == VarTree::VKstruct);
+
+ ExprValue* partExpr;
+ if (cmd->m_cmd == DCprintQStringStruct) {
+ partExpr = m_d->parseQCharArray(output, false, m_typeTable->qCharIsShort());
+ } else if (cmd->m_cmd == DCprintWChar) {
+ partExpr = m_d->parseQCharArray(output, false, true);
+ } else {
+ partExpr = m_d->parsePrintExpr(output, false);
+ }
+ bool errorValue =
+ partExpr == 0 ||
+ /* we only allow simple values at the moment */
+ partExpr->m_child != 0;
+
+ QString partValue;
+ if (errorValue)
+ {
+ partValue = "?""?""?"; // 2 question marks in a row would be a trigraph
+ } else {
+ partValue = partExpr->m_value;
+ }
+ delete partExpr;
+ partExpr = 0;
+
+ /*
+ * Updating a struct value works like this: var->m_partialValue holds
+ * the value that we have gathered so far (it's been initialized with
+ * var->m_type->m_displayString[0] earlier). Each time we arrive here,
+ * we append the printed result followed by the next
+ * var->m_type->m_displayString to var->m_partialValue.
+ *
+ * If the expression we just evaluated was a guard expression, and it
+ * resulted in an error, we must not evaluate the real expression, but
+ * go on to the next index. (We must still add the question marks to
+ * the value).
+ *
+ * Next, if this was the length expression, we still have not seen the
+ * real expression, but the length of a QString.
+ */
+ ASSERT(var->m_exprIndex >= 0 && var->m_exprIndex <= typeInfoMaxExpr);
+
+ if (errorValue || !var->m_exprIndexUseGuard)
+ {
+ // add current partValue (which might be the question marks)
+ var->m_partialValue += partValue;
+ var->m_exprIndex++; /* next part */
+ var->m_exprIndexUseGuard = true;
+ var->m_partialValue += var->m_type->m_displayString[var->m_exprIndex];
+ }
+ else
+ {
+ // this was a guard expression that succeeded
+ // go for the real expression
+ var->m_exprIndexUseGuard = false;
+ }
+
+ /* go for more sub-expressions if needed */
+ if (var->m_exprIndex < var->m_type->m_numExprs) {
+ /* queue a new print command with quite high priority */
+ evalStructExpression(var, cmd->m_exprWnd, true);
+ return;
+ }
+
+ cmd->m_exprWnd->updateStructValue(var);
+
+ evalExpressions(); /* enqueue dereferenced pointers */
+}
+
+/* queues the first printStruct command for a struct */
+void KDebugger::evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
+{
+ var->m_exprIndex = 0;
+ if (var->m_type != TypeInfo::wchartType())
+ {
+ var->m_exprIndexUseGuard = true;
+ var->m_partialValue = var->m_type->m_displayString[0];
+ evalStructExpression(var, wnd, immediate);
+ }
+ else
+ {
+ var->m_exprIndexUseGuard = false;
+ QString expr = var->computeExpr();
+ CmdQueueItem* cmd = m_d->queueCmd(DCprintWChar, expr,
+ immediate ? DebuggerDriver::QMoverrideMoreEqual
+ : DebuggerDriver::QMoverride);
+ // remember which expression this was
+ cmd->m_expr = var;
+ cmd->m_exprWnd = wnd;
+ }
+}
+
+/** queues a printStruct command; var must have been initialized correctly */
+void KDebugger::evalStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
+{
+ QString base = var->computeExpr();
+ QString expr;
+ if (var->m_exprIndexUseGuard) {
+ expr = var->m_type->m_guardStrings[var->m_exprIndex];
+ if (expr.isEmpty()) {
+ // no guard, omit it and go to expression
+ var->m_exprIndexUseGuard = false;
+ }
+ }
+ if (!var->m_exprIndexUseGuard) {
+ expr = var->m_type->m_exprStrings[var->m_exprIndex];
+ }
+
+ expr.replace("%s", base);
+
+ DbgCommand dbgCmd = DCprintStruct;
+ // check if this is a QString::Data
+ if (expr.left(15) == "/QString::Data ")
+ {
+ if (m_typeTable->parseQt2QStrings())
+ {
+ expr = expr.mid(15, expr.length()); /* strip off /QString::Data */
+ dbgCmd = DCprintQStringStruct;
+ } else {
+ /*
+ * This should not happen: the type libraries should be set up
+ * in a way that this can't happen. If this happens
+ * nevertheless it means that, eg., kdecore was loaded but qt2
+ * was not (only qt2 enables the QString feature).
+ */
+ // TODO: remove this "print"; queue the next printStruct instead
+ expr = "*0";
+ }
+ }
+ TRACE("evalStruct: " + expr + (var->m_exprIndexUseGuard ? " // guard" : " // real"));
+ CmdQueueItem* cmd = m_d->queueCmd(dbgCmd, expr,
+ immediate ? DebuggerDriver::QMoverrideMoreEqual
+ : DebuggerDriver::QMnormal);
+
+ // remember which expression this was
+ cmd->m_expr = var;
+ cmd->m_exprWnd = wnd;
+}
+
+void KDebugger::handleSharedLibs(const char* output)
+{
+ // parse the table of shared libraries
+ m_sharedLibs = m_d->parseSharedLibs(output);
+ m_sharedLibsListed = true;
+
+ // get type libraries
+ m_typeTable->loadLibTypes(m_sharedLibs);
+
+ // hand over the QString data cmd
+ m_d->setPrintQStringDataCmd(m_typeTable->printQStringDataCmd());
+}
+
+CmdQueueItem* KDebugger::loadCoreFile()
+{
+ return m_d->queueCmd(DCcorefile, m_corefile, DebuggerDriver::QMoverride);
+}
+
+void KDebugger::slotExpanding(QListViewItem* item)
+{
+ VarTree* exprItem = static_cast<VarTree*>(item);
+ if (exprItem->m_varKind != VarTree::VKpointer) {
+ return;
+ }
+ ExprWnd* wnd = static_cast<ExprWnd*>(item->listView());
+ dereferencePointer(wnd, exprItem, true);
+}
+
+// add the expression in the edit field to the watch expressions
+void KDebugger::addWatch(const QString& t)
+{
+ QString expr = t.stripWhiteSpace();
+ // don't add a watched expression again
+ if (expr.isEmpty() || m_watchVariables.topLevelExprByName(expr) != 0)
+ return;
+ ExprValue e(expr, VarTree::NKplain);
+ m_watchVariables.insertExpr(&e, *m_typeTable);
+
+ // if we are boring ourselves, send down the command
+ if (m_programActive) {
+ m_watchEvalExpr.push_back(expr);
+ if (m_d->isIdle()) {
+ evalExpressions();
+ }
+ }
+}
+
+// delete a toplevel watch expression
+void KDebugger::slotDeleteWatch()
+{
+ // delete only allowed while debugger is idle; or else we might delete
+ // the very expression the debugger is currently working on...
+ if (m_d == 0 || !m_d->isIdle())
+ return;
+
+ VarTree* item = m_watchVariables.currentItem();
+ if (item == 0 || !item->isToplevelExpr())
+ return;
+
+ // remove the variable from the list to evaluate
+ QStringList::iterator i = m_watchEvalExpr.find(item->getText());
+ if (i != m_watchEvalExpr.end()) {
+ m_watchEvalExpr.erase(i);
+ }
+ m_watchVariables.removeExpr(item);
+ // item is invalid at this point!
+}
+
+void KDebugger::handleRegisters(const char* output)
+{
+ emit registersChanged(m_d->parseRegisters(output));
+}
+
+/*
+ * The output of the DCbreak* commands has more accurate information about
+ * the file and the line number.
+ *
+ * All newly set breakpoints are inserted in the m_brkpts, even those that
+ * were not set sucessfully. The unsuccessful breakpoints ("orphaned
+ * breakpoints") are assigned negative ids, and they are tried to set later
+ * when the program stops again at a breakpoint.
+ */
+void KDebugger::newBreakpoint(CmdQueueItem* cmd, const char* output)
+{
+ BrkptIterator bp;
+ if (cmd->m_brkpt != 0) {
+ // a new breakpoint, put it in the list
+ assert(cmd->m_brkpt->id == 0);
+ m_brkpts.push_back(*cmd->m_brkpt);
+ delete cmd->m_brkpt;
+ bp = m_brkpts.end();
+ --bp;
+ } else {
+ // an existing breakpoint was retried
+ assert(cmd->m_existingBrkpt != 0);
+ bp = breakpointById(cmd->m_existingBrkpt);
+ if (bp == m_brkpts.end())
+ return;
+ }
+
+ // parse the output to determine success or failure
+ int id;
+ QString file;
+ int lineNo;
+ QString address;
+ if (!m_d->parseBreakpoint(output, id, file, lineNo, address))
+ {
+ /*
+ * Failure, the breakpoint could not be set. If this is a new
+ * breakpoint, assign it a negative id. We look for the minimal id
+ * of all breakpoints (that are already in the list) to get the new
+ * id.
+ */
+ if (bp->id == 0)
+ {
+ int minId = 0;
+ for (BrkptIterator i = m_brkpts.begin(); i != m_brkpts.end(); ++i) {
+ if (i->id < minId)
+ minId = i->id;
+ }
+ bp->id = minId-1;
+ }
+ return;
+ }
+
+ // The breakpoint was successfully set.
+ if (bp->id <= 0)
+ {
+ // this is a new or orphaned breakpoint:
+ // set the remaining properties
+ if (!bp->enabled) {
+ m_d->executeCmd(DCdisable, id);
+ }
+ if (!bp->condition.isEmpty()) {
+ m_d->executeCmd(DCcondition, bp->condition, id);
+ }
+ }
+
+ bp->id = id;
+ bp->fileName = file;
+ bp->lineNo = lineNo;
+ if (!address.isEmpty())
+ bp->address = address;
+}
+
+void KDebugger::updateBreakList(const char* output)
+{
+ // get the new list
+ std::list<Breakpoint> brks;
+ m_d->parseBreakList(output, brks);
+
+ // merge existing information into the new list
+ // then swap the old and new lists
+
+ for (BrkptIterator bp = brks.begin(); bp != brks.end(); ++bp)
+ {
+ BrkptIterator i = breakpointById(bp->id);
+ if (i != m_brkpts.end())
+ {
+ // preserve accurate location information
+ // note that xsldbg doesn't have a location in
+ // the listed breakpoint if it has just been set
+ // therefore, we copy it as well if necessary
+ bp->text = i->text;
+ if (!i->fileName.isEmpty()) {
+ bp->fileName = i->fileName;
+ bp->lineNo = i->lineNo;
+ }
+ }
+ }
+
+ // orphaned breakpoints must be copied
+ for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
+ {
+ if (bp->isOrphaned())
+ brks.push_back(*bp);
+ }
+
+ m_brkpts.swap(brks);
+ emit breakpointsChanged();
+}
+
+// look if there is at least one temporary breakpoint
+// or a watchpoint
+bool KDebugger::stopMayChangeBreakList() const
+{
+ for (BrkptROIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
+ {
+ if (bp->temporary || bp->type == Breakpoint::watchpoint)
+ return true;
+ }
+ return false;
+}
+
+KDebugger::BrkptIterator KDebugger::breakpointByFilePos(QString file, int lineNo,
+ const DbgAddr& address)
+{
+ // look for exact file name match
+ for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
+ {
+ if (bp->lineNo == lineNo &&
+ bp->fileName == file &&
+ (address.isEmpty() || bp->address == address))
+ {
+ return bp;
+ }
+ }
+ // not found, so try basename
+ // strip off directory part of file name
+ int offset = file.findRev("/");
+ file.remove(0, offset+1);
+
+ for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
+ {
+ // get base name of breakpoint's file
+ QString basename = bp->fileName;
+ int offset = basename.findRev("/");
+ if (offset >= 0) {
+ basename.remove(0, offset+1);
+ }
+
+ if (bp->lineNo == lineNo &&
+ basename == file &&
+ (address.isEmpty() || bp->address == address))
+ {
+ return bp;
+ }
+ }
+
+ // not found
+ return m_brkpts.end();
+}
+
+KDebugger::BrkptIterator KDebugger::breakpointById(int id)
+{
+ for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
+ {
+ if (bp->id == id) {
+ return bp;
+ }
+ }
+ // not found
+ return m_brkpts.end();
+}
+
+void KDebugger::slotValuePopup(const QString& expr)
+{
+ // search the local variables for a match
+ VarTree* v = m_localVariables.topLevelExprByName(expr);
+ if (v == 0) {
+ // not found, check watch expressions
+ v = m_watchVariables.topLevelExprByName(expr);
+ if (v == 0) {
+ // try a member of 'this'
+ v = m_localVariables.topLevelExprByName("this");
+ if (v != 0)
+ v = ExprWnd::ptrMemberByName(v, expr);
+ if (v == 0) {
+ // nothing found; do nothing
+ return;
+ }
+ }
+ }
+
+ // construct the tip
+ QString tip = v->getText() + " = ";
+ if (!v->value().isEmpty())
+ {
+ tip += v->value();
+ }
+ else
+ {
+ // no value: we use some hint
+ switch (v->m_varKind) {
+ case VarTree::VKstruct:
+ tip += "{...}";
+ break;
+ case VarTree::VKarray:
+ tip += "[...]";
+ break;
+ default:
+ tip += "?""?""?"; // 2 question marks in a row would be a trigraph
+ break;
+ }
+ }
+ emit valuePopup(tip);
+}
+
+void KDebugger::slotDisassemble(const QString& fileName, int lineNo)
+{
+ if (m_haveExecutable) {
+ CmdQueueItem* cmd = m_d->queueCmd(DCinfoline, fileName, lineNo,
+ DebuggerDriver::QMoverrideMoreEqual);
+ cmd->m_fileName = fileName;
+ cmd->m_lineNo = lineNo;
+ }
+}
+
+void KDebugger::handleInfoLine(CmdQueueItem* cmd, const char* output)
+{
+ QString addrFrom, addrTo;
+ if (cmd->m_lineNo >= 0) {
+ // disassemble
+ if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
+ // got the address range, now get the real code
+ CmdQueueItem* c = m_d->queueCmd(DCdisassemble, addrFrom, addrTo,
+ DebuggerDriver::QMoverrideMoreEqual);
+ c->m_fileName = cmd->m_fileName;
+ c->m_lineNo = cmd->m_lineNo;
+ } else {
+ // no code
+ emit disassembled(cmd->m_fileName, cmd->m_lineNo, std::list<DisassembledCode>());
+ }
+ } else {
+ // set program counter
+ if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
+ // move the program counter to the start address
+ m_d->executeCmd(DCsetpc, addrFrom);
+ }
+ }
+}
+
+void KDebugger::handleDisassemble(CmdQueueItem* cmd, const char* output)
+{
+ emit disassembled(cmd->m_fileName, cmd->m_lineNo,
+ m_d->parseDisassemble(output));
+}
+
+void KDebugger::handleThreadList(const char* output)
+{
+ emit threadsChanged(m_d->parseThreadList(output));
+}
+
+void KDebugger::setThread(int id)
+{
+ m_d->queueCmd(DCthread, id, DebuggerDriver::QMoverrideMoreEqual);
+}
+
+void KDebugger::setMemoryExpression(const QString& memexpr)
+{
+ m_memoryExpression = memexpr;
+
+ // queue the new expression
+ if (!m_memoryExpression.isEmpty() &&
+ isProgramActive() &&
+ !isProgramRunning())
+ {
+ queueMemoryDump(true);
+ }
+}
+
+void KDebugger::queueMemoryDump(bool immediate)
+{
+ m_d->queueCmd(DCexamine, m_memoryExpression, m_memoryFormat,
+ immediate ? DebuggerDriver::QMoverrideMoreEqual :
+ DebuggerDriver::QMoverride);
+}
+
+void KDebugger::handleMemoryDump(const char* output)
+{
+ std::list<MemoryDump> memdump;
+ QString msg = m_d->parseMemoryDump(output, memdump);
+ emit memoryDumpChanged(msg, memdump);
+}
+
+void KDebugger::setProgramCounter(const QString& file, int line, const DbgAddr& addr)
+{
+ if (addr.isEmpty()) {
+ // find address of the specified line
+ CmdQueueItem* cmd = m_d->executeCmd(DCinfoline, file, line);
+ cmd->m_lineNo = -1; /* indicates "Set PC" UI command */
+ } else {
+ // move the program counter to that address
+ m_d->executeCmd(DCsetpc, addr.asString());
+ }
+}
+
+void KDebugger::handleSetPC(const char* /*output*/)
+{
+ // TODO: handle errors
+
+ // now go to the top-most frame
+ // this also modifies the program counter indicator in the UI
+ gotoFrame(0);
+}
+
+void KDebugger::slotValueEdited(VarTree* expr, const QString& text)
+{
+ if (text.simplifyWhiteSpace().isEmpty())
+ return; /* no text entered: ignore request */
+
+ ExprWnd* wnd = static_cast<ExprWnd*>(expr->listView());
+ TRACE(QString().sprintf("Changing %s to ",
+ wnd->name()) + text);
+
+ // determine the lvalue to edit
+ QString lvalue = expr->computeExpr();
+ CmdQueueItem* cmd = m_d->executeCmd(DCsetvariable, lvalue, text);
+ cmd->m_expr = expr;
+ cmd->m_exprWnd = wnd;
+}
+
+void KDebugger::handleSetVariable(CmdQueueItem* cmd, const char* output)
+{
+ QString msg = m_d->parseSetVariable(output);
+ if (!msg.isEmpty())
+ {
+ // there was an error; display it in the status bar
+ m_statusMessage = msg;
+ emit updateStatusMessage();
+ return;
+ }
+
+ // get the new value
+ QString expr = cmd->m_expr->computeExpr();
+ CmdQueueItem* printCmd =
+ m_d->queueCmd(DCprint, expr, DebuggerDriver::QMoverrideMoreEqual);
+ printCmd->m_expr = cmd->m_expr;
+ printCmd->m_exprWnd = cmd->m_exprWnd;
+}
+
+
+#include "debugger.moc"
diff --git a/kdbg/debugger.h b/kdbg/debugger.h
new file mode 100644
index 0000000..7d2a367
--- /dev/null
+++ b/kdbg/debugger.h
@@ -0,0 +1,556 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef DEBUGGER_H
+#define DEBUGGER_H
+
+#include <qtimer.h>
+#include <qdict.h>
+#include <qstringlist.h>
+#include "envvar.h"
+#include "exprwnd.h" /* some compilers require this */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+class ExprWnd;
+class VarTree;
+struct ExprValue;
+class ProgramTypeTable;
+class KTreeViewItem;
+class KConfig;
+class KConfigBase;
+class ProgramConfig;
+class QListBox;
+class RegisterInfo;
+class ThreadInfo;
+class DebuggerDriver;
+class CmdQueueItem;
+class Breakpoint;
+struct DisassembledCode;
+struct MemoryDump;
+struct DbgAddr;
+class KProcess;
+
+
+class KDebugger : public QObject
+{
+ Q_OBJECT
+public:
+ KDebugger(QWidget* parent, /* will be used as the parent for dialogs */
+ ExprWnd* localVars,
+ ExprWnd* watchVars,
+ QListBox* backtrace);
+ ~KDebugger();
+
+ /**
+ * This function starts to debug the specified executable using the
+ * specified driver. If a program is currently being debugged, it is
+ * terminated first. Ownership of driver is taken if and only if
+ * true is returned.
+ *
+ * @return false if an error occurs.
+ */
+ bool debugProgram(const QString& executable,
+ DebuggerDriver* driver);
+
+ /**
+ * Uses the specified core to debug the active program.
+ * @param batch tells whether the core file was given on the
+ * command line.
+ */
+ void useCoreFile(QString corefile, bool batch);
+
+ /**
+ * Overrides the program argument in the per-program config
+ * with a new value.
+ */
+ void overrideProgramArguments(const QString& args);
+
+
+ /**
+ * Uses the specified pid to attach to the active program.
+ */
+ void setAttachPid(const QString& pid);
+
+ /**
+ * Attaches to the specified process and debugs it.
+ */
+ void attachProgram(const QString& pid);
+
+ /**
+ * Returns the file name of the per-program config file for the
+ * specified program.
+ */
+ static QString getConfigForExe(const QString& exe);
+
+ /**
+ * The driver name entry in the per-program config file.
+ */
+ static const char DriverNameEntry[];
+
+public slots:
+ /**
+ * Runs the program or continues it if it is stopped at a breakpoint.
+ */
+ void programRun();
+
+ /**
+ * Restarts the debuggee.
+ */
+ void programRunAgain();
+
+ /**
+ * Performs a single-step, possibly stepping into a function call.
+ * If byInsn is true, a step by instruction is performed.
+ */
+ void programStep();
+
+ /**
+ * Performs a single-step, stepping over a function call.
+ * If byInsn is true, a step by instruction is performed.
+ */
+ void programNext();
+
+ /**
+ * Performs a single-step by instruction, possibly stepping into a
+ * function call.
+ */
+ void programStepi();
+
+ /**
+ * Performs a single-step by instruction, stepping over a function
+ * call.
+ */
+ void programNexti();
+
+ /**
+ * Runs the program until it returns from the current function.
+ */
+ void programFinish();
+
+ /**
+ * Kills the program (removes it from memory).
+ */
+ void programKill();
+
+ /**
+ * Interrupts the program if it is currently running.
+ */
+ void programBreak();
+
+ /**
+ * Moves the program counter to the specified line.
+ * If an address is given, it is moved to the address.
+ */
+ void setProgramCounter(const QString&, int, const DbgAddr&);
+
+public:
+ /**
+ * Queries the user for program arguments.
+ */
+ void programArgs(QWidget* parent);
+
+ /**
+ * Queries the user for program settings: Debugger command, terminal
+ * emulator.
+ */
+ void programSettings(QWidget* parent);
+
+ /**
+ * Setup remote debugging device
+ */
+ void setRemoteDevice(const QString& remoteDevice) { m_remoteDevice = remoteDevice; }
+
+ /**
+ * Run the debuggee until the specified line in the specified file is
+ * reached.
+ *
+ * @return false if the command was not executed, e.g. because the
+ * debuggee is running at the moment.
+ */
+ bool runUntil(const QString& fileName, int lineNo);
+
+ /**
+ * Set a breakpoint.
+ *
+ * @param fileName The source file in which to set the breakpoint.
+ * @param lineNo The zero-based line number.
+ * @param address The exact address of the breakpoint.
+ * @param temporary Specifies whether this is a temporary breakpoint
+ * @return false if the command was not executed, e.g. because the
+ * debuggee is running at the moment.
+ */
+ bool setBreakpoint(QString fileName, int lineNo,
+ const DbgAddr& address, bool temporary);
+
+ /**
+ * Set a breakpoint.
+ *
+ * @param bp Describes the breakpoint.
+ * @param queueOnly If false, the breakpoint is set using a high-priority command.
+ */
+ void setBreakpoint(Breakpoint* bp, bool queueOnly);
+
+ /**
+ * Enable or disable a breakpoint at the specified location.
+ *
+ * @param fileName The source file in which the breakpoint is.
+ * @param lineNo The zero-based line number.
+ * @param address The exact address of the breakpoint.
+ * @return false if the command was not executed, e.g. because the
+ * debuggee is running at the moment.
+ */
+ bool enableDisableBreakpoint(QString fileName, int lineNo,
+ const DbgAddr& address);
+
+ /**
+ * Enables or disables the specified breakpoint.
+ *
+ * @return false if the command was not executed, e.g. because the
+ * debuggee is running at the moment.
+ */
+ bool enableDisableBreakpoint(int id)
+ { return enableDisableBreakpoint(breakpointById(id)); }
+
+ /**
+ * Removes the specified breakpoint. Note that if bp is an orphaned
+ * breakpoint, then bp is an invalid pointer if (and only if) this
+ * function returns true.
+ *
+ * @return false if the command was not executed, e.g. because the
+ * debuggee is running at the moment.
+ */
+ bool deleteBreakpoint(int id)
+ { return deleteBreakpoint(breakpointById(id)); }
+
+ /**
+ * Changes the specified breakpoint's condition and ignore count.
+ *
+ * @return false if the command was not executed, e.g. because the
+ * debuggee is running at the moment.
+ */
+ bool conditionalBreakpoint(int id,
+ const QString& condition,
+ int ignoreCount)
+ { return conditionalBreakpoint(breakpointById(id), condition, ignoreCount); }
+
+ /**
+ * Tells whether one of the single stepping commands can be invoked
+ * (step, next, finish, until, also run).
+ */
+ bool canSingleStep();
+
+ /**
+ * Tells whether a breakpoints can be set, deleted, enabled, or disabled.
+ */
+ bool canChangeBreakpoints();
+
+ /**
+ * Tells whether a the program is loaded, but not active.
+ */
+ bool canStart();
+
+ /**
+ * Add a watch expression.
+ */
+ void addWatch(const QString& expr);
+
+ /**
+ * Retrieves the current status message.
+ */
+ const QString& statusMessage() const { return m_statusMessage; }
+
+ /**
+ * Is the debugger ready to receive another high-priority command?
+ */
+ bool isReady() const;
+
+ /**
+ * Is the debuggee running (not just active)?
+ */
+ bool isProgramRunning() { return m_haveExecutable && m_programRunning; }
+
+ /**
+ * Do we have an executable set?
+ */
+ bool haveExecutable() { return m_haveExecutable; }
+
+ /**
+ * Is the debuggee active, i.e. was it started by the debugger?
+ */
+ bool isProgramActive() { return m_programActive; }
+
+ /**
+ * Is the debugger driver idle?
+ */
+ bool isIdle() const;
+
+ /* The list of breakpoints. */
+ typedef std::list<Breakpoint>::const_iterator BrkptROIterator;
+ BrkptROIterator breakpointsBegin() const { return m_brkpts.begin(); }
+ BrkptROIterator breakpointsEnd() const { return m_brkpts.end(); }
+
+ const QString& executable() const { return m_executable; }
+
+ /**
+ * Terminal emulation level.
+ */
+ enum TTYLevel {
+ ttyNone = 0, /* ignore output, input triggers EOF */
+ ttySimpleOutputOnly = 1, /* minmal output emulation, input triggers EOF */
+ ttyFull = 7 /* program needs full emulation */
+ };
+
+ /**
+ * Returns the level of terminal emulation requested by the inferior.
+ */
+ TTYLevel ttyLevel() const { return m_ttyLevel; }
+
+ /** Sets the terminal that is to be used by the debugger. */
+ void setTerminal(const QString& term) { m_inferiorTerminal = term; }
+
+ /** Returns the debugger driver. */
+ DebuggerDriver* driver() { return m_d; }
+
+ /** Returns the pid that the debugger is currently attached to. */
+ const QString& attachedPid() const { return m_attachedPid; }
+
+ /**
+ * The memory at that the expression evaluates to is watched. Can be
+ * empty. Triggers a redisplay even if the expression did not change.
+ */
+ void setMemoryExpression(const QString& memexpr);
+
+ /**
+ * Sets how the watched memory location is displayed.
+ * Call setMemoryExpression() to force a redisplay.
+ */
+ void setMemoryFormat(unsigned format) { m_memoryFormat = format; }
+
+ // settings
+ void saveSettings(KConfig*);
+ void restoreSettings(KConfig*);
+
+protected:
+ QString m_inferiorTerminal;
+ QString m_debuggerCmd; /* per-program setting */
+ TTYLevel m_ttyLevel; /* level of terminal emulation */
+ bool startDriver();
+ void stopDriver();
+ void writeCommand();
+
+ QStringList m_watchEvalExpr; /* exprs to evaluate for watch window */
+ std::list<Breakpoint> m_brkpts;
+ QString m_memoryExpression; /* memory location to watch */
+ unsigned m_memoryFormat; /* how that output should look */
+
+protected slots:
+ void parse(CmdQueueItem* cmd, const char* output);
+protected:
+ void handleRunCommands(const char* output);
+ void updateAllExprs();
+ void updateProgEnvironment(const QString& args, const QString& wd,
+ const QDict<EnvVar>& newVars,
+ const QStringList& newOptions);
+ void parseLocals(const char* output, std::list<ExprValue*>& newVars);
+ void handleLocals(const char* output);
+ bool handlePrint(CmdQueueItem* cmd, const char* output);
+ bool handlePrintDeref(CmdQueueItem* cmd, const char* output);
+ void handleBacktrace(const char* output);
+ void handleFrameChange(const char* output);
+ void handleFindType(CmdQueueItem* cmd, const char* output);
+ void handlePrintStruct(CmdQueueItem* cmd, const char* output);
+ void handleSharedLibs(const char* output);
+ void handleRegisters(const char* output);
+ void handleMemoryDump(const char* output);
+ void handleInfoLine(CmdQueueItem* cmd, const char* output);
+ void handleDisassemble(CmdQueueItem* cmd, const char* output);
+ void handleThreadList(const char* output);
+ void handleSetPC(const char* output);
+ void handleSetVariable(CmdQueueItem* cmd, const char* output);
+ void evalExpressions();
+ void evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate);
+ void evalStructExpression(VarTree* var, ExprWnd* wnd, bool immediate);
+ void dereferencePointer(ExprWnd* wnd, VarTree* var, bool immediate);
+ void determineType(ExprWnd* wnd, VarTree* var);
+ void queueMemoryDump(bool immediate);
+ CmdQueueItem* loadCoreFile();
+ void openProgramConfig(const QString& name);
+
+ typedef std::list<Breakpoint>::iterator BrkptIterator;
+ BrkptIterator breakpointByFilePos(QString file, int lineNo,
+ const DbgAddr& address);
+ BrkptIterator breakpointById(int id);
+ CmdQueueItem* executeBreakpoint(const Breakpoint* bp, bool queueOnly);
+ void newBreakpoint(CmdQueueItem* cmd, const char* output);
+ void updateBreakList(const char* output);
+ bool stopMayChangeBreakList() const;
+ void saveBreakpoints(ProgramConfig* config);
+ void restoreBreakpoints(ProgramConfig* config);
+ bool enableDisableBreakpoint(BrkptIterator bp);
+ bool deleteBreakpoint(BrkptIterator bp);
+ bool conditionalBreakpoint(BrkptIterator bp,
+ const QString& condition,
+ int ignoreCount);
+
+ bool m_haveExecutable; /* has an executable been specified */
+ bool m_programActive; /* is the program active (possibly halting in a brkpt)? */
+ bool m_programRunning; /* is the program executing (not stopped)? */
+ bool m_sharedLibsListed; /* do we know the shared libraries loaded by the prog? */
+ QString m_executable;
+ QString m_corefile;
+ QString m_attachedPid; /* user input of attaching to pid */
+ QString m_programArgs;
+ QString m_remoteDevice;
+ QString m_programWD; /* working directory of gdb */
+ QDict<EnvVar> m_envVars; /* environment variables set by user */
+ QStringList m_boolOptions; /* boolean options */
+ QStringList m_sharedLibs; /* shared libraries used by program */
+ ProgramTypeTable* m_typeTable; /* known types used by the program */
+ ProgramConfig* m_programConfig; /* program-specific settings (brkpts etc) */
+ void saveProgramSettings();
+ void restoreProgramSettings();
+ QString readDebuggerCmd();
+
+ // debugger process
+ DebuggerDriver* m_d;
+ bool m_explicitKill; /* whether we are killing gdb ourselves */
+
+ QString m_statusMessage;
+
+protected slots:
+ void gdbExited(KProcess*);
+ void slotInferiorRunning();
+ void backgroundUpdate();
+ void gotoFrame(int);
+ void slotExpanding(QListViewItem*);
+ void slotDeleteWatch();
+ void slotValuePopup(const QString&);
+ void slotDisassemble(const QString&, int);
+ void slotValueEdited(VarTree*, const QString&);
+public slots:
+ void setThread(int);
+ void shutdown();
+
+signals:
+ /**
+ * This signal is emitted before the debugger is started. The slot is
+ * supposed to set up m_inferiorTerminal.
+ */
+ void debuggerStarting();
+
+ /**
+ * This signal is emitted whenever a part of the debugger needs to
+ * highlight the specfied source code line (e.g. when the program
+ * stops).
+ *
+ * @param file specifies the file; this is not necessarily a full path
+ * name, and if it is relative, you won't know relative to what, you
+ * can only guess.
+ * @param lineNo specifies the line number (0-based!) (this may be
+ * negative, in which case the file should be activated, but the line
+ * should NOT be changed).
+ * @param address specifies the exact address of the PC or is empty.
+ */
+ void activateFileLine(const QString& file, int lineNo, const DbgAddr& address);
+
+ /**
+ * This signal indicates that the program counter has changed.
+ *
+ * @param filename specifies the filename where the program stopped
+ * @param lineNo specifies the line number (zero-based); it can be -1
+ * if it is unknown
+ * @param address specifies the address that the instruction pointer
+ * points to.
+ * @param frameNo specifies the frame number: 0 is the innermost frame,
+ * positive numbers are frames somewhere up the stack (indicates points
+ * where a function was called); the latter cases should be indicated
+ * differently in the source window.
+ */
+ void updatePC(const QString& filename, int lineNo,
+ const DbgAddr& address, int frameNo);
+
+ /**
+ * This signal is emitted when gdb detects that the executable has been
+ * updated, e.g. recompiled. (You usually need not handle this signal
+ * if you are the editor which changed the executable.)
+ */
+ void executableUpdated();
+
+ /**
+ * Indicates that a new status message is available.
+ */
+ void updateStatusMessage();
+
+ /**
+ * Indicates that the internal state of the debugger has changed, and
+ * that this will very likely have an impact on the UI.
+ */
+ void updateUI();
+
+ /**
+ * Indicates that the list of breakpoints has possibly changed.
+ */
+ void breakpointsChanged();
+
+ /**
+ * Indicates that the register values have possibly changed.
+ */
+ void registersChanged(const std::list<RegisterInfo>&);
+
+ /**
+ * Indicates that the list of threads has possibly changed.
+ */
+ void threadsChanged(const std::list<ThreadInfo>&);
+
+ /**
+ * Indicates that the value for a value popup is ready.
+ */
+ void valuePopup(const QString&);
+
+ /**
+ * Provides the disassembled code of the location given by file and
+ * line number (zero-based).
+ */
+ void disassembled(const QString& file, int line, const std::list<DisassembledCode>& code);
+
+ /**
+ * Indicates that the program has stopped for any reason: by a
+ * breakpoint, by a signal that the debugger driver caught, by a single
+ * step instruction.
+ */
+ void programStopped();
+
+ /**
+ * Indicates that a new memory dump output is ready.
+ * @param msg is an error message or empty
+ * @param memdump is the memory dump
+ */
+ void memoryDumpChanged(const QString&, const std::list<MemoryDump>&);
+
+ /**
+ * Gives other objects a chance to save program specific settings.
+ */
+ void saveProgramSpecific(KConfigBase* config);
+
+ /**
+ * Gives other objects a chance to restore program specific settings.
+ */
+ void restoreProgramSpecific(KConfigBase* config);
+
+protected:
+ ExprWnd& m_localVariables;
+ ExprWnd& m_watchVariables;
+ QListBox& m_btWindow;
+
+ // implementation helpers
+protected:
+ QWidget* parentWidget() { return static_cast<QWidget*>(parent()); }
+};
+
+#endif // DEBUGGER_H
diff --git a/kdbg/doc/Makefile.am b/kdbg/doc/Makefile.am
new file mode 100644
index 0000000..081febf
--- /dev/null
+++ b/kdbg/doc/Makefile.am
@@ -0,0 +1,3 @@
+
+# add here all the languages, you have docu for
+SUBDIRS = de en ru
diff --git a/kdbg/doc/Makefile.in b/kdbg/doc/Makefile.in
new file mode 100644
index 0000000..e2d019d
--- /dev/null
+++ b/kdbg/doc/Makefile.in
@@ -0,0 +1,721 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 483858 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = kdbg/doc
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+#>- RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+#>- html-recursive info-recursive install-data-recursive \
+#>- install-dvi-recursive install-exec-recursive \
+#>- install-html-recursive install-info-recursive \
+#>- install-pdf-recursive install-ps-recursive install-recursive \
+#>- installcheck-recursive installdirs-recursive pdf-recursive \
+#>- ps-recursive uninstall-recursive
+#>+ 7
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive nmcheck-recursive bcheck-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARTSCCONFIG = @ARTSCCONFIG@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOPIDLNG = @DCOPIDLNG@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
+KCONFIG_COMPILER = @KCONFIG_COMPILER@
+KDECONFIG = @KDECONFIG@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
+KDE_MT_LIBS = @KDE_MT_LIBS@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_FPIE = @KDE_USE_FPIE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+KDE_USE_PIE = @KDE_USE_PIE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPTHREAD = @LIBPTHREAD@
+LIBRESOLV = @LIBRESOLV@
+LIBS = @LIBS@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBZ = @LIBZ@
+LIB_KAB = @LIB_KAB@
+LIB_KABC = @LIB_KABC@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDED = @LIB_KDED@
+LIB_KDEPIM = @LIB_KDEPIM@
+LIB_KDEPRINT = @LIB_KDEPRINT@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KDNSSD = @LIB_KDNSSD@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMPROXY = @LIB_KIMPROXY@
+LIB_KIO = @LIB_KIO@
+LIB_KJS = @LIB_KJS@
+LIB_KNEWSTUFF = @LIB_KNEWSTUFF@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KUNITTEST = @LIB_KUNITTEST@
+LIB_KUTILS = @LIB_KUTILS@
+LIB_POLL = @LIB_POLL@
+LIB_QPE = @LIB_QPE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_X11 = @LIB_X11@
+LIB_XEXT = @LIB_XEXT@
+LIB_XRENDER = @LIB_XRENDER@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKEKDEWIDGETS = @MAKEKDEWIDGETS@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MKDIR_P = @MKDIR_P@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PS_COMMAND = @PS_COMMAND@
+QTE_NORTTI = @QTE_NORTTI@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+UIC_TR = @UIC_TR@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+XGETTEXT = @XGETTEXT@
+XMKMF = @XMKMF@
+XMLLINT = @XMLLINT@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+X_RPATH = @X_RPATH@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_kcfgdir = @kde_kcfgdir@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_qtver = @kde_qtver@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_styledir = @kde_styledir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+kde_widgetdir = @kde_widgetdir@
+kdeinitdir = @kdeinitdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+xdg_appsdir = @xdg_appsdir@
+xdg_directorydir = @xdg_directorydir@
+xdg_menudir = @xdg_menudir@
+
+# add here all the languages, you have docu for
+SUBDIRS = de en ru
+#>- all: all-recursive
+#>+ 1
+all: docs-am all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu kdbg/doc/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/doc/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/doc/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-recursive
+#>+ 1
+clean: kde-rpo-clean clean-recursive
+
+#>- clean-am: clean-generic clean-libtool mostlyclean-am
+#>+ 1
+clean-am: clean-bcheck clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-info: install-info-recursive
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-ps: install-ps-recursive
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
+ install-strip
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ ctags ctags-recursive distclean distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+
+#>+ 2
+KDE_DIST=Makefile.in Makefile.am
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/doc/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/doc/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-recursive
+
+bcheck-am:
+ @for i in ; do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXX) $(DEFS) -I. -I$(srcdir) -I$(top_builddir) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 3
+final:
+ $(MAKE) all-am
+
+#>+ 3
+final-install:
+ $(MAKE) install-am
+
+#>+ 3
+no-final:
+ $(MAKE) all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/kdbg/doc/de/Makefile.am b/kdbg/doc/de/Makefile.am
new file mode 100644
index 0000000..2981d8b
--- /dev/null
+++ b/kdbg/doc/de/Makefile.am
@@ -0,0 +1,27 @@
+html_DATA = \
+ argspwdenv.html \
+ breakptlist.html \
+ globaloptions.html \
+ howdoi.html \
+ localvars.html \
+ memory.html \
+ pgmoutput.html \
+ pgmsettings.html \
+ registers.html \
+ sourcecode.html \
+ stack.html \
+ threads.html \
+ tips.html \
+ watches.html \
+ index.html
+
+htmldir = $(kde_htmldir)/de/kdbg
+
+EXTRA_DIST = $(html_DATA)
+
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(htmldir)
+ cd $(DESTDIR)$(htmldir) && ln -s -f ../../en/kdbg/types.html .
+
+uninstall-local:
+ -rm -f $(DESTDIR)$(htmldir)/types.html
diff --git a/kdbg/doc/de/Makefile.in b/kdbg/doc/de/Makefile.in
new file mode 100644
index 0000000..2091f62
--- /dev/null
+++ b/kdbg/doc/de/Makefile.in
@@ -0,0 +1,609 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 483858 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = kdbg/doc/de
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(htmldir)"
+htmlDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(html_DATA)
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARTSCCONFIG = @ARTSCCONFIG@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOPIDLNG = @DCOPIDLNG@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
+KCONFIG_COMPILER = @KCONFIG_COMPILER@
+KDECONFIG = @KDECONFIG@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
+KDE_MT_LIBS = @KDE_MT_LIBS@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_FPIE = @KDE_USE_FPIE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+KDE_USE_PIE = @KDE_USE_PIE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPTHREAD = @LIBPTHREAD@
+LIBRESOLV = @LIBRESOLV@
+LIBS = @LIBS@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBZ = @LIBZ@
+LIB_KAB = @LIB_KAB@
+LIB_KABC = @LIB_KABC@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDED = @LIB_KDED@
+LIB_KDEPIM = @LIB_KDEPIM@
+LIB_KDEPRINT = @LIB_KDEPRINT@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KDNSSD = @LIB_KDNSSD@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMPROXY = @LIB_KIMPROXY@
+LIB_KIO = @LIB_KIO@
+LIB_KJS = @LIB_KJS@
+LIB_KNEWSTUFF = @LIB_KNEWSTUFF@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KUNITTEST = @LIB_KUNITTEST@
+LIB_KUTILS = @LIB_KUTILS@
+LIB_POLL = @LIB_POLL@
+LIB_QPE = @LIB_QPE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_X11 = @LIB_X11@
+LIB_XEXT = @LIB_XEXT@
+LIB_XRENDER = @LIB_XRENDER@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKEKDEWIDGETS = @MAKEKDEWIDGETS@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MKDIR_P = @MKDIR_P@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PS_COMMAND = @PS_COMMAND@
+QTE_NORTTI = @QTE_NORTTI@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+UIC_TR = @UIC_TR@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+XGETTEXT = @XGETTEXT@
+XMKMF = @XMKMF@
+XMLLINT = @XMLLINT@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+X_RPATH = @X_RPATH@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = $(kde_htmldir)/de/kdbg
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_kcfgdir = @kde_kcfgdir@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_qtver = @kde_qtver@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_styledir = @kde_styledir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+kde_widgetdir = @kde_widgetdir@
+kdeinitdir = @kdeinitdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+xdg_appsdir = @xdg_appsdir@
+xdg_directorydir = @xdg_directorydir@
+xdg_menudir = @xdg_menudir@
+html_DATA = \
+ argspwdenv.html \
+ breakptlist.html \
+ globaloptions.html \
+ howdoi.html \
+ localvars.html \
+ memory.html \
+ pgmoutput.html \
+ pgmsettings.html \
+ registers.html \
+ sourcecode.html \
+ stack.html \
+ threads.html \
+ tips.html \
+ watches.html \
+ index.html
+
+EXTRA_DIST = $(html_DATA)
+#>- all: all-am
+#>+ 1
+all: docs-am all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/de/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu kdbg/doc/de/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/de/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/doc/de/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/doc/de/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-htmlDATA: $(html_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"
+ @list='$(html_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(htmlDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(htmlDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+
+uninstall-htmlDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(html_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(htmldir)/$$f'"; \
+ rm -f "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(htmldir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-am
+#>+ 1
+clean: kde-rpo-clean clean-am
+
+#>- clean-am: clean-generic clean-libtool mostlyclean-am
+#>+ 1
+clean-am: clean-bcheck clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-htmlDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-htmlDATA uninstall-local
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-data-local install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-htmlDATA install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am uninstall uninstall-am uninstall-htmlDATA \
+ uninstall-local
+
+
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(htmldir)
+ cd $(DESTDIR)$(htmldir) && ln -s -f ../../en/kdbg/types.html .
+
+uninstall-local:
+ -rm -f $(DESTDIR)$(htmldir)/types.html
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+
+#>+ 2
+KDE_DIST=stack.html memory.html index.html watches.html sourcecode.html howdoi.html pgmsettings.html globaloptions.html pgmoutput.html Makefile.in threads.html argspwdenv.html localvars.html registers.html breakptlist.html tips.html Makefile.am
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/de/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/doc/de/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/doc/de/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-am
+
+bcheck-am:
+ @for i in ; do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXX) $(DEFS) -I. -I$(srcdir) -I$(top_builddir) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 3
+final:
+ $(MAKE) all-am
+
+#>+ 3
+final-install:
+ $(MAKE) install-am
+
+#>+ 3
+no-final:
+ $(MAKE) all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/kdbg/doc/de/argspwdenv.html b/kdbg/doc/de/argspwdenv.html
new file mode 100644
index 0000000..696221f
--- /dev/null
+++ b/kdbg/doc/de/argspwdenv.html
@@ -0,0 +1,50 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Argumente, Arbeitsverzeichnis, Umgebungsvariablen</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h3>
+<a NAME="Environment"></a>Programmargumente, Arbeitsverzeichnis, Umgebungsvariablen
+setzen</h3>
+Mit <i>Ausf&uuml;hren|Argumente</i> &ouml;ffnen Sie einen Dialog, in dem
+Sie Programmargumente, das Arbeitsverzeichnis sowie Umgebungsvariablen
+setzen k&ouml;nnen.
+<h3>
+Programmargumente</h3>
+In der obersten Eingabezeile k&ouml;nnen Sie die Programmargumente eingeben,
+die an das Programm &uuml;bergeben werden sollen. Diese werden beim n&auml;chsten
+Programmstart verwendet.
+<h3>
+Arbeitsverzeichnis</h3>
+Im Eingabefeld darunter k&ouml;nnen Sie das Arbeitsverzeichnis angeben.
+Dieses wird sofort an gdb &uuml;bergeben, sobald Sie <i>OK</i> dr&uuml;cken.
+Das Programm verwendet das neue Arbeitsverzeichnis allerdings erst beim
+n&auml;chsten Start.
+<p>Das Arbeitsverzeichnis gilt auch f&uuml;r gdb selbst! Das angegebene
+Arbeitsverzeichnis wird sofort an gdb weitergegeben, d.h. gdb wird die
+neue Einstellung verwenden, sobald Sie <i>OK</i> dr&uuml;cken. Das kann
+einen Einfluss darauf haben, ob gdb Quellcodedateien findet.
+<h3>
+Umgebungsvariablen</h3>
+Im Bereich f&uuml;r Umgebungsvariablen k&ouml;nnen Sie einen Ausdruck in
+der Form
+<tt>VARIABLE=Wert</tt> eingeben und dann <i>&Auml;ndern</i> klicken,
+um der Umgebungsvariablen <tt>VARIABLE</tt> einen <tt>Wert</tt> zuzuweisen.
+Um eine Variable zu entfernen, w&auml;hlen Sie diese zuerst aus der Liste
+darunter aus und klicken dan <i>L&ouml;schen</i>. Um einen Wert zu &auml;ndern,
+geben Sie einfach den neuen Wert ein und klicken <i>&Auml;ndern</i>. Wenn
+Sie den Namen der Variable &auml;ndern und <i>&Auml;ndern</i> clicken,
+erzeugen Sie eine neue Variable! Die neuen Umgebungsvariablen werden erst
+beim n&auml;chsten Programmstart verwendet.
+<p>Wenn Sie glibc2 unter Linux verwenden, ist es sehr wichtig, dass Sie
+der Umgebungsvariablen <tt>LD_BIND_NOW</tt> den Wert <tt>1</tt> zuweisen.
+Wenn diese Variable nicht gesetzt ist, k&ouml;nnen solche Funktionen nicht
+betreten werden, die von der Bibliothek <tt>libc</tt> und anderen Shared
+Libraries importiert werden.
+</body>
+</html>
diff --git a/kdbg/doc/de/breakptlist.html b/kdbg/doc/de/breakptlist.html
new file mode 100644
index 0000000..0acb4d2
--- /dev/null
+++ b/kdbg/doc/de/breakptlist.html
@@ -0,0 +1,82 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Haltepunkte</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Die Liste der Haltepunkte</h1>
+Die Liste der Haltepunkte zeigt alle gesetzten Haltepunkte und Watchpoints
+und erm&ouml;glicht, diese zu manipulieren. Die Liste der Haltepunkte k&ouml;nnen
+Sie mit dem Men&uuml;punkt <i>Ansicht|Haltepunkte</i> anzeigen.
+<h2>
+Die &Uuml;bersicht</h2>
+F&uuml;r jeden Haltepunkt wird folgendes angezeigt:
+<ul>
+<li>
+der Ort,</li>
+
+<li>
+die Anzahl der Stopps,</li>
+
+<li>
+die Anzahl der n&auml;chsten zu ignorierenden Stopps (falls gesetzt)</li>
+
+<li>
+die Haltebedingung (falls gesetzt).</li>
+</ul>
+Das Piktogramm links zeigt an, ob der Haltepunkt aktiviert (tiefroter Punkt)
+oder deaktiviert (hellroter Punkt) ist, ob es sich um einen tempor&auml;ren
+Haltepunkt handelt (eine winzige Uhr ist sichtbar) und ob der Haltepunkt
+bedingt ist (ein Fragezeichen ist sichtbar).
+<p>Watchpoints werden durch ein Brillensymbol gekennzeichnet.
+<h2>
+Haltepunkte manipulieren</h2>
+<a NAME="StopProg"></a>Beachten Sie bitte, dass Haltepunkte und Watchpoints
+nicht manipuliert werden k&ouml;nnen solange das zu debuggende Programm
+l&auml;uft. Wenn das Programm bereits gestartet wurde, muss es zuerst angehalten
+werden - entweder indem es auf einen bereits gesetzten Haltepunkt trifft
+oder "gewaltsam" indem Sie <i>Ausf&uuml;hrung|Unterbrechen</i> w&auml;hlen.
+Dadurch wird das Programm nicht beendet, sondern nur unterbrochen. Sie
+k&ouml;nnen die Haltepunkte jetzt ver&auml;ndern. W&auml;hlen Sie danach
+<i>Ausf&uuml;hrung|Ausf&uuml;hren</i>,
+um das Programm fortzusetzen.
+<p>Am einfachsten kann ein Haltepunkt im <a href="sourcecode.html">Quellcode-Fenster</a>
+gesetzt werden. Wenn Sie den genauen Dateinamen und die Zeilennummer einer
+Funktion nicht kennen, k&ouml;nnen Sie den Funktionsnamen im Feld &uuml;ber
+der Liste eingeben und <i>Haltepunkt</i> w&auml;hlen.
+<p>Sie k&ouml;nnen eine Haltepunkt in der Liste ausw&auml;hlen seine Zustand
+mittels <i>Deaktivieren</i> oder <i>Aktivieren</i> &auml;ndern. Oder Sie
+klicken auf den Haltepunkt mit der mittleren Maustaste - genau so, wie
+Sie im Quellcode-Fenster Haltepunkte aktivieren und deaktivieren.
+<p>Sie k&ouml;nnen eine Bedingung setzen (sodass das Programm nur stehen
+bleibt, wenn die Bedingung erf&uuml;llt ist) oder die Anzahl der zu ignorierenden
+Stopps setzen (sodass das Programm die n&auml;chsten n Male nicht stehen
+bleibt, die es &uuml;ber diesen Haltepunkt l&auml;uft). Dazu w&auml;hlen
+sie den Schalter <i>Bedingt</i> und geben die Anzahl der zu ignorierenden
+Treffer und/oder die Bedingung ein.
+<h2>
+Watchpoints manipulieren</h2>
+Watchpoints sind den Haltepunkten &auml;hnlich, nur dass das Programm angehalten
+wird, sobald sich der Inhalt einer Speicherstelle &auml;ndert. Ebenso wie
+Haltepunkte k&ouml;nnen Watchpoints nicht manipuliert werden, solange das
+Programm l&auml;uft. Weitere Hinweise dazu <a href="#StopProg">siehe oben</a>.
+<p>Einen Watchpoint k&ouml;nnen Sie setzen, indem Sie einen Ausdruck im
+Feld &uuml;ber der Liste eingeben und <i>Watchpoint</i> klicken. Das Programm
+wird dann angehalten, sobald sich der Wert des Ausdrucks &auml;ndert. Beachten
+Sie, dass Sie Watchpoints, die eine lokale Variable ben&ouml;tigen, nur
+setzen k&ouml;nnen, wenn das Programm von einem Haltepunkt (oder mittels
+Ausf&uuml;hrung|Unterbrechen) angehalten wurde.
+<p>Zum Entfernen eines Watchpoints w&auml;hlen Sie diesen in der Liste
+aus und klicken <i>Entfernen</i>. Falls der Ausdruck eine lokale Variable
+enth&auml;lt, wird der Watchpoint automatisch entfernt, sobald das Programm
+die aktive Funktion verl&auml;sst.
+<p>Wie mit Haltepunkten k&ouml;nnen Sie eine Bedingung oder eine Anzahl
+zu ignorierender Stopps setzen, indem Sie den Watchpoint ausw&auml;hlen
+und <i>Bedingt</i> klicken.
+</body>
+</html>
diff --git a/kdbg/doc/de/globaloptions.html b/kdbg/doc/de/globaloptions.html
new file mode 100644
index 0000000..4c0de83
--- /dev/null
+++ b/kdbg/doc/de/globaloptions.html
@@ -0,0 +1,72 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Globale Einstellungen</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Globale Einstellungen</h1>
+Mit dem Men&uuml;punkt <i>Datei|Globale Einstellungen</i> k&ouml;nnen Sie
+folgende Optionen einstellen:
+<ul>
+<li>
+den Befehl, mit dem gdb aufgerufen wird;</li>
+
+<li>
+den Befehl, der das Fenster f&uuml;r die Programmausgabe &ouml;ffnet,</li>
+
+<li>
+ob KDbg in den Vordergrund kommen soll, sobald das Programm stoppt, und
+eine Verz&ouml;gerung, wann er sich wieder zur&uuml;ckzieht,</li>
+
+<li>
+die Tabulatorweite.</li>
+</ul>
+
+<h4>
+Aufruf von gdb</h4>
+
+<blockquote>Wenn Sie eine alternative Version von gdb verwenden wollen,
+geben sie diese unter <i>Aufruf von GDB</i> an. Die Standardeinstellung
+ist <tt>gdb --fullname --nx</tt>. Achtung: Sie m&uuml;ssen jedenfalls diese
+beiden Argumente &uuml;bergeben; wenn Sie sie weglassen, kann KDbg nicht
+funktionieren. Wenn Sie das Eingabefeld leer lassen, wird die Standardeinstellung
+verwendet.</blockquote>
+
+<h4>
+Aufruf eines Terminal-Emulators</h4>
+
+<blockquote>Falls Sie ein anderes Terminal-Programm verwenden wollen, das
+die Ausgabe des Programms anzeigt, geben Sie dieses unter <i>Terminal f&uuml;r
+die Programmausgabe</i> an. Die Standardeinstellung ist <tt>xterm -name
+kdbgio -title %T -e sh -c %C</tt>. In diesem Eintrag wird <tt>%T</tt> durch
+eine &Uuml;berschrift und <tt>%C</tt> durch ein Bourne-Shell-Skript ersetzt,
+das in eine Endlosschleife landet, damit sich das Fenster nicht schlie&szlig;t.
+(Keine Sorge, das Skript frisst keine CPU-Zeit, sondern ruft einfach nur
+<tt>sleep
+3600</tt> in einer Schleife auf :) Eine alternative f&uuml;r diesen Eintrag
+w&auml;re zm Beispiel <tt>konsole --name kdbgio --caption %T -e
+sh -c %C</tt>.</blockquote>
+
+<h4>
+In den Vordergrund</h4>
+
+<blockquote>Sie k&ouml;nnen angeben, ob das KDbg-Fenster in den Vordergrund
+gebracht werden soll, sobald das kontrollierte Programm anh&auml;lt (bei
+einem Breakpoint oder wegen eines Signals). Das Fenster wird allerdings
+nicht aktiviert (zumindest nicht unter KWM, dem Window Manger von KDE).
+Manche Benutzer werden dieses Verhalten als st&ouml;rend empfinden, weshalb
+diese Option standardm&auml;ssig ausgeschaltet ist.</blockquote>
+
+<blockquote>Wenn diese Option eingeschaltet ist, zieht sich das KDbg-Fenster
+auch wieder in den Hintergrund zur&uuml;ck, sobald das Programm fortgesetzt
+wird. Allerdings geschieht das erst nach einer Verz&ouml;gerung, die ebenfalls
+angegeben werden kann. Dadurch wird verhindert, dass das Fenster st&auml;ndig
+nach hinten und vorne blinkt, sobald Sie einen Einzelschritt-Befehl absetzen.</blockquote>
+
+</body>
+</html>
diff --git a/kdbg/doc/de/howdoi.html b/kdbg/doc/de/howdoi.html
new file mode 100644
index 0000000..87d08ae
--- /dev/null
+++ b/kdbg/doc/de/howdoi.html
@@ -0,0 +1,83 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Wie kann ich...?</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Wie kann ich...?</h1>
+
+<h4>
+... eine Haltepunkt setzen?</h4>
+Daf&uuml;r gibt's mehrere M&ouml;glichkeiten:
+<ul>
+<li>
+Sie k&ouml;nnen im <a href="sourcecode.html">Quellcode-Fenster</a> in den
+"aktiven Bereich" am linken Ende der Zeile klicken.</li>
+
+<li>
+Sie k&ouml;nnen im Quellcode-Fenster eine Zeile ausw&auml;hlen und dann
+im Men&uuml; <i>Haltepunkt</i> eine Auswahl treffen.</li>
+
+<li>
+Sie k&ouml;nnen einen Haltepunkt in der <a href="breakptlist.html">Liste
+der Haltepunkte</a> setzen.</li>
+</ul>
+Wenn Sie keinen Haltepunkt setzen k&ouml;nnen, k&ouml;nnte es sein, dass
+das Programm gerade l&auml;uft. Sie k&ouml;nnen keine Haltepunkte setzen,
+solange das Programm l&auml;uft. Halten Sie es zuerst mit <i>Ausf&uuml;hrung|Unterbrechen</i>
+an. Falls Sie dann noch immer keine Haltepunkte setzen k&ouml;nnen, versichern
+Sie sich, dass Sie das Programm mit Debug-Information &uuml;bersetzt <i>und
+gebunden</i> haben.
+<h4>
+... den Wert einer globalen Variablen oder eines beliebigen Ausdrucks anzeigen?</h4>
+Benutzen Sie das <a href="watches.html">Ausdr&uuml;cke-Fenster</a>.
+<h4>
+... Watchpoints setzen?</h4>
+Watchpoints k&ouml;nnen &uuml;ber die <a href="breakptlist.html">Liste
+der Haltepunkte</a> bearbeitet werden.
+<h4>
+... einen Core-Dump benutzen?</h4>
+Laden Sie zuerst das Programm mittels <i>Datei|Programm</i>, dann geben
+Sie den Core-Dump mittels <i>Datei|Core dump</i> an.
+<h4>
+... ein Programm debuggen, das sich in eine Endlosschleife verlaufen hat?</h4>
+Starten Sie das Programm und lassen Sie es laufen, bis es in die Endlosschleife
+gelangt. Dann schalten Sie um zu KDbg und w&auml;hlen <i>Ausf&uuml;hrung|Unterbrechen</i>.
+Hiermit haben Sie das Programm <i>in flagranti</i> erwischt!
+<h4>
+... erreichen, dass das Programm einigemale &uuml;ber einen Haltepunkt
+dr&uuml;berl&auml;uft, ohne anzuhalten?</h4>
+In der <a href="breakptlist.html">Liste der Haltepunkte</a> w&auml;hlen
+Sie den Haltepunkt; dann klicken Sie <i>Bedingt</i> und geben die Anzahl
+in <i>Ignoriere n&auml;chste Treffer</i> an.
+<h4>
+... eine Umgebungsvariable f&uuml;r das Programm setzen?</h4>
+W&auml;hlen Sie <i>Ausf&uuml;hrung|Argumente</i> und geben die Umgebungsvariable
+im <a href="argspwdenv.html#Environment">Argumente-Dialog</a> an.
+<h4>
+... ein Arbeitsverzeichnis f&uuml;r das Programm w&auml;hlen?</h4>
+W&auml;hlen Sie <i>Ausf&uuml;hrung|Argumente</i> und geben das Arbeitsverzeichnis
+im <a href="argspwdenv.html#Environment">Argumente-Dialog</a> an.
+<h4>
+... das Terminal-Fenster los werden?</h4>
+W&auml;hlen Sie <i>Datei|Einstellungen</i> und schalten auf das Register
+<a href="pgmsettings.html#output">Ausgabe</a>
+um. W&auml;hlen Sie <i>Nur Ausgabe, einfache Terminalemulation</i> und
+klicken Sie <i>OK</i>. Nun m&uuml;ssen Sie das Programm neu laden (am einfachsten
+w&auml;hlen Sie es aus der Liste unter <i>Datei|Zuletzt ge&ouml;ffnete
+Programme</i>). Die Programmausgaben werden nun in das eingebaute <a href="pgmoutput.html">Ausgabefenster</a>
+geschrieben und stdin ist auf <tt>/dev/null</tt> umgeleitet.
+<p>Sie m&uuml;ssen diese Einstellungen f&uuml;r jedes neue Programm wiederholen,
+das Sie debuggen.
+<p><b><i>Wichtig:</i></b> Sie sollten dies nicht tun, falls Ihr Programm
+Eingaben vom Terminal (normalerweise stdin) erwartet oder falls mehr als
+nur einfache Terminalemultionen ben&ouml;tigt werden (mehr als nur Wagenr&uuml;cklauf
+und Zeilenvorschub). Das eingebaute Ausgabefenster unterst&uuml;tzt keine
+Eingaben oder Terminalemulationen.
+</body>
+</html>
diff --git a/kdbg/doc/de/index.html b/kdbg/doc/de/index.html
new file mode 100644
index 0000000..5a69b7e
--- /dev/null
+++ b/kdbg/doc/de/index.html
@@ -0,0 +1,190 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+
+<h1>
+KDbg - Benutzerhandbuch</h1>
+
+<h2>
+Inhalt</h2>
+
+<ul>
+<li>
+<a href="#Introduction">Einleitung</a></li>
+
+<li>
+<a href="#UsingKDbg">Mit KDbg arbeiten</a></li>
+
+<li>
+<a href="#InfoWindows">Die Informationsfenster von KDbg</a></li>
+
+<li>
+<a href="#TipsTricks">Tipps und so weiter</a></li>
+
+<li>
+F&uuml;r Fortgeschrittene: <a href="../../en/kdbg/types.html">Typentabellen</a>
+(nur Englisch)</li>
+
+<li>
+<a href="#KnownProblems">Bekannte Probleme</a></li>
+
+<li>
+<a href="#Author">Autor</a></li>
+</ul>
+
+<hr>
+<h2>
+<a NAME="Introduction"></a>Einleitung</h2>
+KDbg ist eine grafische Benutzeroberfl&auml;che f&uuml;r <tt>gdb</tt>,
+den GNU-Debugger.
+<p>Das bedeutet, dass KDbg selbst nicht der Debugger ist. Vielmehr kommuniziert
+KDbg mit <tt>gdb</tt>, indem Befehlszeilen and diesen geschickt werden
+und die Ausgabe, wie z.B. Variablenwerte, entgegengenommen werden. Die
+Men&uuml;befehle und Mausklicks werden in <tt>gdb</tt>-Befehle umgesetzt,
+und die Ausgabe von <tt>gdb</tt> wird in (mehr oder weniger) sichtbare
+Information umgesetzt, wie zum Beispiel die Struktur von Variablen.
+<p>Eine Folge davon ist, dass KDbg vollst&auml;ndig von den F&auml;higkeiten
+des verwendeten Befehlszeilendebuggers, <tt>gdb</tt>, abh&auml;ngig ist.
+KDbg kann nicht mehr als <tt>gdb</tt> leisten. Wenn Sie zum Beispiel einen
+<tt>gdb</tt>
+haben, der Programme mit Threads nicht unterst&uuml;tzt, dann kann auch
+KDbg das nicht (obwohl ein Threads-Fenster vorhanden ist).
+<h2>
+<a NAME="UsingKDbg"></a>Mit KDbg arbeiten</h2>
+Bevor Sie mit der Arbeit beginnen, sollten Sie die <a href="globaloptions.html">globalen
+Einstellungen</a> pr&uuml;fen, indem Sie <i>Datei|Globale Einstellungen</i>
+aufrufen.
+<h4>
+Ein zu debuggendes Program angeben</h4>
+Um ein Programm zu debuggen, w&auml;hlen Sie <i>Datei|Programm</i>. Wenn
+Sie das Programm schon einmal debuggt haben, k&ouml;nnen Sie es auch aus
+der Liste unter <i>Datei|Zuletzt g&ouml;ffnete Programme</i> w&auml;hlen.
+Das Programm wird jetzt geladen.
+<p>Wenn Sie einen Core-Dump verwenden wollen, m&uuml;ssen Sie zuerst das
+Programm, das den Core-Dump erzeugt hat wie gerade erw&auml;hnt laden,
+dann w&auml;hlen Sie <i>Datei|Core dump</i> aus dem Men&uuml;. KDbg zeigt
+die Stelle an, die den Core-Dump verursacht hat.
+<p>Sie k&ouml;nnen nun Haltepunkte setzen, indem Sie die Eintr&auml;ge
+im Men&uuml; <i>Haltepunkt</i> oder im Rechte-Maus-Men&uuml; oder in der
+<a href="breakptlist.html">Liste
+der Haltepunkte</a> verwenden.
+<p>Sie k&ouml;nnen auch <a href="pgmsettings.html">programmspezifische
+Einstellungen</a> vornehmen, indem Sie <i>Datei|Einstellungen</i> w&auml;hlen.
+<h4>
+Das Programm ausf&uuml;hren</h4>
+Nun f&uuml;hren Sie das Programm aus, indem Sie <i>Ausf&uuml;hrung|Ausf&uuml;hren</i>
+w&auml;hlen. Das Programm arbeitet nun wie gew&ouml;hnlich, bis es beendet
+wird, auf einen Haltepunkt oder Watchpoint trifft, oder ein Signal empf&auml;ngt.
+<p>Sie k&ouml;nnen das Programm mit Argumenten ausf&uuml;hren, ein Arbeitsverzeichnis
+festlegen und auch Umgebungsvariablen definieren. Dazu w&auml;hlen Sie
+<i>Ausf&uuml;hrung|Argumente</i>
+und machen Ihre Angaben im <a href="argspwdenv.html">Programmargumente-Dialog</a>.
+<p>Weiters k&ouml;nnen Sie sich in ein Programm einh&auml;ngen (<i>attachen</i>),
+das bereits ausgef&uuml;hrt wird. Dazu laden Sie das Programm zuerst wie
+oben beschrieben, dann w&auml;hlen Sie <i>Ausf&uuml;hrung|Attachen</i>.
+Geben Sie die Prozessnummer an und klicken Sie <i>OK</i>. Das Programm
+wird jetzt angehalten (aber nicht beendet), und der derzeitige Stand des
+Programms wird im <a href="sourcecode.html">Quellcode-Fenster</a> angezeigt.
+<h4>
+Das Programm wurde angehalten - was nun?</h4>
+Wenn das Programm an einem Haltepunkt, Watchpoint oder wegen eines Signals
+angehalten wird, zeigt das <a href="sourcecode.html">Quellcode-Fenster</a>
+die Zeile, in der das Programm gerade arbeitete. Es passiert h&auml;ufig,
+dass das Programm wegen eine Signals (oftmals <tt>SIGSEGV</tt>, Speicherzugriffsfehler)
+in einer Funktion angehalten wird, die sich nicht in jenem Programmteil
+befindet, den Sie geschrieben haben. In diesem Fall betrachten Sie das
+<a href="stack.html">Stack-Fenster</a>
+genauer: Suchen Sie nach einer Funktion, die Sie geschrieben haben (beginnen
+Sie am oberen Ende) und klicken Sie darauf. Das bringt Sie an eine Stelle,
+an der Sie mit der Suche nach dem tats&auml;chlichen Programmfehler beginnen
+k&ouml;nnen.
+<p>Im Men&uuml; <i>Ausf&uuml;hrung</i> finden Sie Befehle, die Sie zum
+Ausf&uuml;hren und schrittweisen Abarbeiten des Programms verwenden. Weiters
+k&ouml;nnen Sie das laufende Programm unterbrechen. Die wichtigen Befehle
+k&ouml;nnen auch mit Funktionstasten gegeben werden. Zum effizienten Arbeiten
+empfehle ich, dass Sie sich diese Tasten eingew&ouml;hnen.
+<br><font size=-1>Diese Funktionen sind nicht konfigurierbar, aber vielleicht
+wollen Sie ein St&uuml;ckchen Code beisteuern, mit dem das geht?</font>
+<p>Im Men&uuml; <i>Haltepunkt</i> finden Sie Befehle zum Setzen, Entfernen,
+Aktivieren und Inaktivieren von permanenten und tempor&auml;ren Haltepunkten.
+Nat&uuml;rlich k&ouml;nnen Sie auch eine <a href="breakptlist.html">Liste
+der Haltepunkte</a> anzeigen. Sie k&ouml;nnen einen Haltepunkt auch setzen,
+indem Sie mit der Maus in den Freiraum links der entsprechenden Quellcode-Zeile
+klicken (mit der linken Maustaste); weiters k&ouml;nnen sie einen vorhandenen
+Haltepunkt mit der mittleren Maustaste aktivieren und deaktivieren.
+<p>Das Zahnrad in der Werkzeugleiste zeigt an, ob <tt>gdb</tt> gerade arbeitet:
+Dies ist der Fall, wenn es rotiert. Solange es schnell rotiert, nimmt KDbg
+kein Eingaben an; wenn es langsam rotiert, aktualisiert KDbg gerade alle
+Variablenanzeigen.
+<h2>
+<a NAME="InfoWindows"></a>Die Informationsfenster von KDbg</h2>
+KDbg zeigt Information in einer Reihe verschiedener Fenster an. Im Men&uuml;
+<i>Ansicht</i>
+finden Sie die Befehle, die diese Fenster anzeigen und schliessen. Es handelt
+sich dabei um <i>dockende</i> Fenster, sodass Sie deren Anordnung beliebig
+ver&auml;ndern k&ouml;nnen.
+<ul>
+<li>
+<a href="sourcecode.html">Das Quellcode-Fenster</a></li>
+
+<li>
+<a href="localvars.html">Lokale Variablen</a></li>
+
+<li>
+<a href="stack.html">Der Programm-Stack</a></li>
+
+<li>
+<a href="watches.html">Ausdr&uuml;cke (<i>Watches</i>)</a></li>
+
+<li>
+<a href="breakptlist.html">Die Liste der Haltepunkte</a></li>
+
+<li>
+<a href="pgmoutput.html">Das Programmausgabefenster</a></li>
+
+<li>
+<a href="registers.html">Die Registerinhalt</a></li>
+
+<li>
+<a href="memory.html">Der Speicherinhalt</a></li>
+
+<li>
+<a href="threads.html">Die Programm-Threads</a></li>
+</ul>
+
+<h2>
+<a NAME="TipsTricks"></a>Tipps und so weiter</h2>
+
+<ul>
+<li>
+<a href="tips.html">Tipps</a></li>
+
+<li>
+<a href="howdoi.html">Wie kann ich...?</a></li>
+</ul>
+
+<h2>
+<a NAME="KnownProblems"></a>Bekannte Probleme</h2>
+<tt>gdb </tt>4.16 hat Probleme bei der Handhabung von C++-Klassen mit virtuellen
+Basisklassen. (Diese kommen h&auml;ufig in CORBA-Programmen vor.) Gdb st&uuml;rzt
+dabei h&auml;ufig aufgrund eines Speicherzugriffsfehlers ab. KDbg erkennt,
+wenn <tt>gdb</tt> unerwartet beendet wird. Leider l&auml;sst sich nicht
+wirklich was dagegen unternehmen. Sie m&uuml;ssen <tt>gdb</tt> mittels
+<i>Datei|Programm</i>
+neu starten, das hei&szlig;t auch f&uuml;r die Debug-Sitzung zur&uuml;ck
+an den Start :-(.
+<p>Die Typerkennung von KDbg arbeitet nur, wenn die Bibilotheken dynamisch
+ins Programm gebunden sind.
+<h2>
+<a NAME="Author"></a>Autor</h2>
+KDbg wurde von <a href="mailto:j6t@kdbg.org">Johannes Sixt</a>
+mit vielen weiteren Helfern geschrieben.
+<br>Die KDbg-Homepage befindet sich unter <a href="http://www.kdbg.org/">http://www.kdbg.org/</a>.
+</body>
+</html>
diff --git a/kdbg/doc/de/localvars.html b/kdbg/doc/de/localvars.html
new file mode 100644
index 0000000..8b1d36c
--- /dev/null
+++ b/kdbg/doc/de/localvars.html
@@ -0,0 +1,25 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; Linux 2.2.18-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Lokale Variablen</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Lokale Variablen</h1>
+Mittels <i>Ansicht|Lokale Variablen</i> wird das Fenster f&uuml;r die lokalen
+Variablen angezeigt. Darin wird der Inhalt der lokalen Variablen des aktiven
+Stack-Frames angezeigt.
+<p>Das im <a href="stack.html">Stack-Fenster</a> ausgew&auml;hlte Frame
+bestimmt die lokalen Variablen, die hier angezeigt werden.
+<p>Sobald das Programm angehalten wird (z.B. durch einen Haltepunkt), wird
+die Anzeige aktualisiert. Variablenwerte, die sich seit dem letzten Anhalten
+ge&auml;ndert haben, werden rot hervorgehoben.
+<p>Sie k&ouml;nnen die ausgew&auml;hlte Variable oder Struktur-Member in
+das <a href="watches.html">Ausdr&uuml;ckefenster</a> kopieren, indem Sie
+mittels der rechten Maustaste das kleine Kontextmen&uuml; aufrufen.
+</body>
+</html>
diff --git a/kdbg/doc/de/memory.html b/kdbg/doc/de/memory.html
new file mode 100644
index 0000000..06a2a5e
--- /dev/null
+++ b/kdbg/doc/de/memory.html
@@ -0,0 +1,29 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Speicherinhalt</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Der Speicherinhalt</h1>
+Das Fenster zur Anzeige des Speicherinhalts k&ouml;nnen Sie mittels <i>Ansicht|Speicher</i>
+aufrufen. Es zeigt den Inhalt des Speichers des Programms an beliebigen
+Adressen an.
+<p>Um Speicherinhalt anzuzeigen, geben Sie eine Adresse an. Die Adresse
+braucht nicht in Hexadezimalform eingegeben werden und es kann sich auch
+um einen beliebigen Ausdruck handeln.
+<p>Sie k&ouml;nnen ein Format w&auml;hlen, wie der Speicherinhalt dargestellt
+werden soll, indem Sie die entsprechenden Optionen im Rechte-Maus-Men&uuml;
+w&auml;hlen.
+<p>Die zuletzt verwendeten Adressen werden zwischengespeichert und k&ouml;nnen
+&uuml;ber die Popup-Liste ausgew&auml;hlt werden. Bitte beachten Sie, dass
+zusammen mit der Adresse auch das Darstellungsformat gespeichert wird.
+<p>Wenn Sie keinen Speicherinhalt ansehen wollen, empfehlen wir, dass Sie
+die Adresse l&ouml;schen, damit kein Speicherinhalt angezeigt wird - dadurch
+arbeitet KDbg etwas schneller.
+</body>
+</html>
diff --git a/kdbg/doc/de/pgmoutput.html b/kdbg/doc/de/pgmoutput.html
new file mode 100644
index 0000000..65cf563
--- /dev/null
+++ b/kdbg/doc/de/pgmoutput.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Programmausgabe</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Das Programmausgabefenster</h1>
+Das Programmausgabefenster wird mit <i>Ansicht|Ausgabe</i> ge&ouml;ffnet.
+Das Ausgabefenster zeichnet den Text auf, den das Programm auf <tt>stdout</tt>
+und <tt>stderr</tt> ausgibt.
+<p>Das Ausgabefenster l&auml;sst keine Eingabe zu und unterst&uuml;tzt
+nur eine &auml;u&szlig;erst minimale Terminalemulation: Lediglich <tt>\n</tt>
+(Zeilenvorschub, line-feed), <tt>\t</tt> (horizontaler Tabulator) und
+<tt>\r</tt> (Wagenr&uuml;cklauf, carriage-return) werden behandelt.
+Das reicht im Allgemeinen f&uuml;r Programme mit grafischer Benutzeroberfl&auml;che
+aus, die nur Debug-Ausgaben schreiben.
+<p>Wenn ein Programm zum ersten Mal in KDbg geladen wird, wird dieses Ausgabefenster
+<i>nicht</i> benutzt. Der Grund daf&uuml;r ist, dass KDbg nicht wissen
+kann, ob das Programm eine ausgefeilte Terminalemulation ben&ouml;tigt
+oder ob es Eingaben &uuml;ber das Terminal erwartet. Deshalb wird standardm&auml;ssig
+ein Terminalemulator verwendet. Um die Ausgaben in das Ausgabefenster umzuleiten,
+gehen sie wie folgt vor:
+<ol>
+<li>
+Rufen Sie mittels <i>Datei|Einstellungen</i> die <a href="pgmsettings.html">programmspezifischen
+Einstellungen</a> auf.</li>
+
+<li>
+Schalten Sie auf das Register <i>Ausgabe</i> um.</li>
+
+<li>
+W&auml;hlen Sie <i>Nur Ausgabe, einfache Terminalemulation</i> und klicken
+Sie <i>OK</i>.</li>
+
+<li>
+Laden Sie das Programm erneut, indem Sie es aus der Liste unter <i>Datei|Zuletzt
+ge&ouml;ffnete Programme</i> w&auml;hlen.</li>
+</ol>
+Sie k&ouml;nnen den Inhalt des Fensters jederzeit l&ouml;schen, indem Sie
+<i>L&ouml;schen</i> aus dem Popup-Men&uuml; w&auml;hlen, das Sie mit der
+rechten Maustaste aufrufen k&ouml;nnen.
+<p>Falls die letzte Zeile des Ausgabefensters sichtbar ist, verschiebt
+sich der Fensterinhalt automatisch, sodass die letzte Zeile immer sichtbar
+bleibt, wenn neuer Text ankommt. Wenn Sie hingegen den Fensterinhalt verschieben,
+sodass die letzte Zeile nicht sichtbar ist, bleibt der sichtbare Teil unver&auml;ndert.
+</body>
+</html>
diff --git a/kdbg/doc/de/pgmsettings.html b/kdbg/doc/de/pgmsettings.html
new file mode 100644
index 0000000..b6a163e
--- /dev/null
+++ b/kdbg/doc/de/pgmsettings.html
@@ -0,0 +1,83 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <title>KDbg - Benutzerhandbuch - Programmspezifische Einstellungen</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Programmspezifische Einstellungen</h1>
+In diesem Dialog k&ouml;nnen programmspezifischen Einstellungen getroffen
+werden. Der Dialog wird mittels <i>Datei|Einstellungen</i> aufgerufen.
+Die Einstellungen werden nur auf das geladene Programm angewendet und bleiben
+&uuml;ber Sitzungen hinweg erhalten.
+<blockquote><b><i>Wichtiger Hinweis:</i></b> Die getroffenen Einstellungen
+werden erst wirksam, wenn das Programm das <i>n&auml;chste Mal geladen</i>
+wird. Das bedeutet, dass Sie nach dem Dr&uuml;cken von OK in diesem Dialog
+das Programm erneut laden m&uuml;ssen (mittels <i>Datei|Programm</i>)!!</blockquote>
+
+<ul>
+<li>
+<a href="#driver">Debugger</a></li>
+
+<li>
+<a href="#output">Ausgabe</a></li>
+</ul>
+
+<h2>
+<a NAME="driver"></a>Debugger</h2>
+Hier kann der Debugger gew&auml;hlt werden, der f&uuml;r dieses Programm
+verwendet werden soll.
+<h4>
+Aufruf von GDB</h4>
+
+<blockquote>Geben Sie den Befehl an, mit dem <tt>gdb</tt> aufgerufen werden
+soll. Wenn Sie das Feld leer lassen, wird die <a href="globaloptions.html">globale
+Einstellung</a> &uuml;bernommen. Wenn Sie cross-compilieren oder remote
+debuggen, werden Sie hier einen <tt>gdb</tt>-Befehl angeben, der f&uuml;r
+die Zielplattform geeignet ist. Die Standardeinstellung ist <tt>gdb&nbsp;--fullname&nbsp;--nx</tt>.
+Sie m&uuml;ssen auf jeden Fall auch diese Optionen angeben, andernfalls
+funktioniert KDbg nicht.</blockquote>
+
+<h2>
+<a NAME="output"></a>Ausgabe</h2>
+Hier geben Sie an, unter welcher Terminalemulation das Programm arbeitet.
+<h4>
+Keine Ein- und Ausgabe</h4>
+
+<blockquote>W&auml;hlen Sie diese Option, falls Ihr Programm keine Eingabe
+vom Terminal erwartet und Sie keine Ausgabe sehen wollen, die auf <tt>stdout</tt>
+oder <tt>stderr</tt> geschrieben wird. Alle drei Standardkan&auml;le (<tt>stdin</tt>,
+<tt>stdout</tt>
+und <tt>stderr</tt>) werden praktisch nach <tt>/dev/null</tt> umgeleitet.</blockquote>
+
+<h4>
+Nur Ausgabe, einfache Terminalemulation</h4>
+
+<blockquote>W&auml;hlen Sie diese Option, falls Ihr Programm keine Eingabe
+vom Terminal erwartet (<tt>stdin</tt> wird nach <tt>/dev/null</tt> umgeleitet)
+und die Ausgabe, die auf <tt>stdout</tt> und <tt>stderr</tt> geschrieben
+wird, keine besondere Terminalemulation erfordert. Die Ausgabe wird im
+<a href="pgmoutput.html">Ausgabefenster</a>
+angezeigt.
+<br><i>Wichtig:</i> Die eingebaute Terminalemulation interpretiert nur
+den Zeilenvorschub <tt>\n</tt> (line-feed, ASCII 10) als Zeilenumbruch.
+Das Zeichen f&uuml;r den Wager&uuml;cklauf <tt>\r</tt> (carriage-return,
+ASCII 13) wird <i>nicht</i> behandelt. Das ist ausreichend f&uuml;r Debug-Ausgaben,
+wie sie h&auml;ufig beim Programmierern grafischer Benutzeroberfl&auml;chen
+verwendet wird.</blockquote>
+
+<h4>
+Volle Terminalemulation</h4>
+
+<blockquote>W&auml;hlen Sie diese Option, falls Ihr Programm Eingaben &uuml;ber
+<tt>stdin</tt>
+liest oder falls die Ausgabe auf <tt>stdout</tt> oder <tt>stderr</tt> Terminalemulation
+erfordert. Ein Terminalemulator kann in den <a href="globaloptions.html">globalen
+Einstellungen</a> angegeben werden.</blockquote>
+
+</body>
+</html>
diff --git a/kdbg/doc/de/registers.html b/kdbg/doc/de/registers.html
new file mode 100644
index 0000000..2d99bcb
--- /dev/null
+++ b/kdbg/doc/de/registers.html
@@ -0,0 +1,37 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Registerinhalt</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Der Registerinhalt</h1>
+Das Fenster zur Anzeige des Registerinhalts wird mittels <i>Ansicht|Register</i>
+angezeigt. Jedesmal, wenn das Programm angehalten wird, zeigt Kdbg hier
+den Inhalt der CPU-Register an.
+<p>Das Fenster ist in 3 Spalten aufgeteilt:
+<ol>
+<li>
+Die Spalte <i>Register</i> zeigt die Namen der Register.</li>
+
+<li>
+Die Spalte <i>Wert</i> zeigt den Inhalt der Register in einer mehr oder
+weniger rohen Form an. Diese rohe Form wird &uuml;blicherweise in Hexadezimaldarstellung
+angezeigt, selbst der Inhalt der Flie&szlig;kommaregister.</li>
+
+<li>
+Die Spalte <i>Dekodierter Wert</i> zeigt den Inhalt der Register in dekotierter
+Form an. Bei den arithmetischen Registern ist das meist eine vorzeichenbehaftete
+Dezimalzahl, bei Flie&szlig;kommaregistern wird die Flie&szlig;kommazahl
+angezeigt, die Flag-Register werden manchmal die gesetzten Flags in Worten
+dargestellt (h&auml;ngt von der verwendeten Version von <tt>gdb</tt> ab).</li>
+</ol>
+Durch Klicken mit der rechten Maustaste k&ouml;nnen Sie ein Kontextmen&uuml;
+aufrufen, &uuml;ber das Sie die Darstellung der Werte in der zweiten Spalte
+w&auml;hlen k&ouml;nnen.
+</body>
+</html>
diff --git a/kdbg/doc/de/sourcecode.html b/kdbg/doc/de/sourcecode.html
new file mode 100644
index 0000000..56b462f
--- /dev/null
+++ b/kdbg/doc/de/sourcecode.html
@@ -0,0 +1,30 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Quellcode</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Das Quellcode-Fenster</h1>
+Das Quellcode-Fenster ist das Hauptfenster und ist immer sichtbar.
+<p>Das Quellcode-Fenster zeigt den Quellcode von Programmen an. Am linken
+Rand jeder Zeile befindet sich ein "aktiver Bereich". Dort wird ein mit
+einem Pfeil angezeigt, an welcher Stelle das Programm gerade ausgef&uuml;hrt
+wird. Weiters wird hier angezeigt, an welchen Stellen Haltepunkte gesetzt
+sind.
+<p>Neue Haltepunkte k&ouml;nnen gesetzt werden, indem Sie mit der linken
+Maustaste in den aktiven Bereich klicken. Mit der mittleren Maustaste k&ouml;nnen
+Sie vorhandene Haltepunkte aktivieren und deaktivieren.
+<p>Das kleine Pluszeichen '+' zwischen dem "aktiven Bereich" und der Quellcodezeile
+zeigt den Assembler-Code der Quellcodezeile an, wenn Sie darauf klicken.
+Dabei wird das Zeichen zu einem Minus '-', das den Assemblercode wieder
+verbirgt, wenn Sie darauf klicken.
+<p>Meistens werden Quellcode-Dateien automatisch ge&ouml;ffnet. Sie k&ouml;nnen
+Dateien manuell &ouml;ffnen, indem Sie <i>Datei|Quellcode &ouml;ffnen</i>
+w&auml;hlen oder <i>Quellcode &ouml;ffnen</i> aus dem Rechte-Maus-Men&uuml;.
+</body>
+</html>
diff --git a/kdbg/doc/de/stack.html b/kdbg/doc/de/stack.html
new file mode 100644
index 0000000..ae6e576
--- /dev/null
+++ b/kdbg/doc/de/stack.html
@@ -0,0 +1,25 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Stack</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Das Stack-Fenster</h1>
+Das Stack-Fenster wird mittels <i>Ansicht|Stack</i> angezeigt. Hierin wird
+der Call-Stack (Backtrace, Stack-Frames) angezeigt, d.h. die Funktionen,
+die das Programm im Augenblick betreten und noch nicht verlassen hat.
+<p>Das innerste Frame (in dem sich das Programm gerade befindet) befindet
+sich an erster Stelle.
+<p>Sie k&ouml;nnen in ein anderes Stack-Frame umschalten, indem Sie einfach
+auf die entsprechende Zeile klicken. Das <a href="sourcecode.html">Quellcode-Fenster</a>
+zeigt die Stelle an, in der der Aufruf in das n&auml;chst-innere Frame
+stattfand; die Anzeige der <a href="localvars.html">lokalen Variablen</a>
+und die <a href="watches.html">Ausdr&uuml;cke</a> werden umgeschaltet,
+sodass die lokalen Variablen des gew&auml;hlten Frames angezeigt werden.
+</body>
+</html>
diff --git a/kdbg/doc/de/threads.html b/kdbg/doc/de/threads.html
new file mode 100644
index 0000000..924eea4
--- /dev/null
+++ b/kdbg/doc/de/threads.html
@@ -0,0 +1,44 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Threads</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Die Programm-Threads</h1>
+Das Fenster mit der Liste der Programm-Threas wird mittels <i>Ansicht|Threads</i>
+aufgerufen. Dieses Fenster listet die aktiven Threads des Programms auf.
+<p><b><i>Wichtig:</i></b> Das Debuggen von Programm-Threads muss von der
+verwendeten <tt>gdb</tt>-Version unterst&uuml;tzt werden - es handelt sich
+hierbei nicht um ein Feature von KDbg. F&uuml;r Linux-Systeme (i386) funktioniert
+<tt>gdb5</tt>
+am besten.
+<p>Der Inhalt des Fensters wird jedesmal erneuert, wenn das Programm vom
+Debugger angehalten wird. (Das heisst, dass <i>nicht</i> der aktuelle Zustand
+des Programms angezeigt wird, w&auml;hrend es l&auml;uft.)
+<p>Die erste Spalte zeigt die Thread-ID an, die zweite Spalte zeigt die
+Stelle, an der der Thread gerade abgearbeitet wird.
+<p>Die Markierung am Zeilenanfang benennt den <i>aktiven</i> Thread:
+<ul>
+<li>
+Das&nbsp; <a href="stack.html">Stack-Fenster</a> zeigt den Call-Stack des
+aktiven Threads.</li>
+
+<li>
+Das <a href="localvars.html">Fenster mit den lokalen Variablen</a> zeigt
+die lokalen Variablen des aktiven Threads.</li>
+
+<li>
+Das <a href="watches.html">Ausdr&uuml;cke-Fenster</a> verwendet zur Evaluierung
+der Ausdr&uuml;cke die lokalen Variablen des aktiven Threads.</li>
+</ul>
+Indem Sie auf einen Thread klicken, wechseln Sie den aktiven Thread und
+die genannten Fenster werden entsprechend auf den aktuellen Stand gebracht.
+Ausserdem schaltet das <a href="sourcecode.html">Quellcode-Fenster</a>
+zu der Programmstelle um, an der der aktive Thread angehalten wurde.
+</body>
+</html>
diff --git a/kdbg/doc/de/tips.html b/kdbg/doc/de/tips.html
new file mode 100644
index 0000000..f27e5a3
--- /dev/null
+++ b/kdbg/doc/de/tips.html
@@ -0,0 +1,45 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.74 [en] (X11; U; Linux 2.2.16-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Tipps</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h2>
+Tipps und Tricks</h2>
+
+<ul>
+<li>
+Setzen Sie immer die Umgebungsvariable <tt>LD_BIND_NOW=1</tt> auf glibc2-Systems.
+Wie Umgebungsvariablen gesetzt werden, wird <a href="argspwdenv.html#Environment">hier
+erkl&auml;rt</a>.</li>
+
+<li>
+Sie k&ouml;nnen Haltepunkte als Lesezeichen verwenden: Setzen Sie einfach
+einen Haltepunkt und deaktivieren Sie diesen. Sp&auml;ter k&ouml;nnen Sie
+rasch an die entsprechende Stelle zur&uuml;ckkehren, indem Sie in der Liste
+der Haltepunkte doppel-klicken (oder&nbsp; <i>Code anzeigen</i> klicken).
+Da sich KDbg alle Haltepunkte &uuml;ber Sitzungen hinaus merkt, werden
+sie sofort wieder gesetzt, sobald sie das entsprechende Programm das n&auml;chste
+Mal debuggen.</li>
+
+<li>
+Auf folgende Weise k&ouml;nnen Sie Programmvariablen &auml;ndern: Im Watch-Bereich
+(rechts unten) geben Sie eine Zuweisung ein, z.B. <tt>var.member=17</tt>
+und Klicken <i>Neu</i>. Die entsprechende Variable wird sofort ge&auml;ndert.
+Sie sollten die Variable nun sofort l&ouml;schen (indem Sie sie ausw&auml;hlen
+und <i>Entf</i> klicken). Das ist notwendig, weil der Ausdruck (d.h die
+Zuweisung) sonst bei jedem Programmstopp ausgewertet wird.</li>
+
+<li>
+Sie k&ouml;nnen Werte im Watch-Bereich in den verschiedenen Formaten anzeigen
+lassen, die gdb versteht. Z.B. zeigt <tt>/x&nbsp;var.member</tt> die Variable
+<tt>var.member</tt>
+in hexadezimaler Notation an.</li>
+</ul>
+
+</body>
+</html>
diff --git a/kdbg/doc/de/watches.html b/kdbg/doc/de/watches.html
new file mode 100644
index 0000000..8de3d4b
--- /dev/null
+++ b/kdbg/doc/de/watches.html
@@ -0,0 +1,27 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; Linux 2.2.18-SMP i686) [Netscape]">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Benutzerhandbuch - Ausdr&uuml;cke</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html">Inhalt</a>
+<h1>
+Ausdr&uuml;cke (Watches)</h1>
+Das Watches-Fenster wird mittels <i>Ansicht|Ausdr&uuml;cke</i> angezeigt.
+Dieses zeigt beliebige Ausdr&uuml;cke an (diese bezeichnet man auch als
+<i>Watches</i>).
+<p>Ein neuer Ausdruck wird hinzugef&uuml;gt, indem dieser im Eingabefeld
+eingegeben wird und dann auf <i>Neu</i> geklickt wird. Um einen Ausdruck
+zu entfernen, klicken Sie diesen an (an der Wurzel des entsprechenden Baums)
+und klicken dann auf <i>Entf</i>.
+<p>Sie k&ouml;nnen auch eine Variable oder einen Struktur-Member aus dem
+<a href="localvars.html">Lokale-Variablen-Fenster</a> her&uuml;berkopieren,
+indem Sie das dortige Kontextmen&uuml; zuhilfe nehmen.
+<p>Die eingegeben Ausdr&uuml;cke werden zwischen Sitzungen gespeichert.
+Wir empfehlen, Ausdr&uuml;cke zu entfernen, die nicht mehr ben&ouml;tigt,
+weil das die Arbeitsgeschwindigkeit von KDbg steigert.
+</body>
+</html>
diff --git a/kdbg/doc/en/Makefile.am b/kdbg/doc/en/Makefile.am
new file mode 100644
index 0000000..e7a6b44
--- /dev/null
+++ b/kdbg/doc/en/Makefile.am
@@ -0,0 +1,23 @@
+html_DATA = \
+ argspwdenv.html \
+ breakptlist.html \
+ globaloptions.html \
+ howdoi.html \
+ invocation.html \
+ localvars.html \
+ memory.html \
+ pgmoutput.html \
+ pgmsettings.html \
+ registers.html \
+ sourcecode.html \
+ stack.html \
+ threads.html \
+ tips.html \
+ types.html \
+ watches.html \
+ xslt.html \
+ index.html
+
+htmldir = $(kde_htmldir)/en/kdbg
+
+EXTRA_DIST = $(html_DATA)
diff --git a/kdbg/doc/en/Makefile.in b/kdbg/doc/en/Makefile.in
new file mode 100644
index 0000000..44aa133
--- /dev/null
+++ b/kdbg/doc/en/Makefile.in
@@ -0,0 +1,604 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 483858 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = kdbg/doc/en
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(htmldir)"
+htmlDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(html_DATA)
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARTSCCONFIG = @ARTSCCONFIG@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOPIDLNG = @DCOPIDLNG@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
+KCONFIG_COMPILER = @KCONFIG_COMPILER@
+KDECONFIG = @KDECONFIG@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
+KDE_MT_LIBS = @KDE_MT_LIBS@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_FPIE = @KDE_USE_FPIE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+KDE_USE_PIE = @KDE_USE_PIE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPTHREAD = @LIBPTHREAD@
+LIBRESOLV = @LIBRESOLV@
+LIBS = @LIBS@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBZ = @LIBZ@
+LIB_KAB = @LIB_KAB@
+LIB_KABC = @LIB_KABC@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDED = @LIB_KDED@
+LIB_KDEPIM = @LIB_KDEPIM@
+LIB_KDEPRINT = @LIB_KDEPRINT@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KDNSSD = @LIB_KDNSSD@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMPROXY = @LIB_KIMPROXY@
+LIB_KIO = @LIB_KIO@
+LIB_KJS = @LIB_KJS@
+LIB_KNEWSTUFF = @LIB_KNEWSTUFF@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KUNITTEST = @LIB_KUNITTEST@
+LIB_KUTILS = @LIB_KUTILS@
+LIB_POLL = @LIB_POLL@
+LIB_QPE = @LIB_QPE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_X11 = @LIB_X11@
+LIB_XEXT = @LIB_XEXT@
+LIB_XRENDER = @LIB_XRENDER@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKEKDEWIDGETS = @MAKEKDEWIDGETS@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MKDIR_P = @MKDIR_P@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PS_COMMAND = @PS_COMMAND@
+QTE_NORTTI = @QTE_NORTTI@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+UIC_TR = @UIC_TR@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+XGETTEXT = @XGETTEXT@
+XMKMF = @XMKMF@
+XMLLINT = @XMLLINT@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+X_RPATH = @X_RPATH@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = $(kde_htmldir)/en/kdbg
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_kcfgdir = @kde_kcfgdir@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_qtver = @kde_qtver@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_styledir = @kde_styledir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+kde_widgetdir = @kde_widgetdir@
+kdeinitdir = @kdeinitdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+xdg_appsdir = @xdg_appsdir@
+xdg_directorydir = @xdg_directorydir@
+xdg_menudir = @xdg_menudir@
+html_DATA = \
+ argspwdenv.html \
+ breakptlist.html \
+ globaloptions.html \
+ howdoi.html \
+ invocation.html \
+ localvars.html \
+ memory.html \
+ pgmoutput.html \
+ pgmsettings.html \
+ registers.html \
+ sourcecode.html \
+ stack.html \
+ threads.html \
+ tips.html \
+ types.html \
+ watches.html \
+ xslt.html \
+ index.html
+
+EXTRA_DIST = $(html_DATA)
+#>- all: all-am
+#>+ 1
+all: docs-am all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/en/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu kdbg/doc/en/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/en/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/doc/en/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/doc/en/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-htmlDATA: $(html_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"
+ @list='$(html_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(htmlDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(htmlDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+
+uninstall-htmlDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(html_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(htmldir)/$$f'"; \
+ rm -f "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(htmldir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-am
+#>+ 1
+clean: kde-rpo-clean clean-am
+
+#>- clean-am: clean-generic clean-libtool mostlyclean-am
+#>+ 1
+clean-am: clean-bcheck clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-htmlDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-htmlDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-htmlDATA install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-am uninstall-htmlDATA
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+
+#>+ 2
+KDE_DIST=stack.html memory.html xslt.html index.html watches.html sourcecode.html howdoi.html pgmsettings.html globaloptions.html pgmoutput.html Makefile.in threads.html types.html argspwdenv.html invocation.html localvars.html registers.html breakptlist.html tips.html Makefile.am
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/en/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/doc/en/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/doc/en/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-am
+
+bcheck-am:
+ @for i in ; do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXX) $(DEFS) -I. -I$(srcdir) -I$(top_builddir) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 3
+final:
+ $(MAKE) all-am
+
+#>+ 3
+final-install:
+ $(MAKE) install-am
+
+#>+ 3
+no-final:
+ $(MAKE) all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/kdbg/doc/en/argspwdenv.html b/kdbg/doc/en/argspwdenv.html
new file mode 100644
index 0000000..22482f0
--- /dev/null
+++ b/kdbg/doc/en/argspwdenv.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Arguments, Environment</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+Specifying program arguments, working directory, environment variables</h1>
+<p>Choose <i>Execution|Arguments</i> to open a dialog where you can set program
+arguments, the working directory for your program, and environment variables.</p>
+<h2><a name="PgmArgs"></a>Tab Arguments</h2>
+<p>In the edit box enter the arguments that shall be passed on to your
+program. <i>Insert file name</i> lets you browse for a file;
+the file name will be <em>inserted</em> in the edit box (at the cursor position).</p>
+<p>Next time the program is started, the new arguments will be used.</p>
+<h2><a name="WorkingDir"></a>Tab Working Directory</h2>
+<p>In the edit box you can specify the working directory for your program.
+<i>Browse</i> lets you browse for a directory.
+Your program will use the new directory only when it is run the next time.</p>
+<p>The working directory also applies to gdb itself! The directory that
+you specify will be passed to gdb immediately, i.e. gdb will work with
+the new setting as soon as you press <i>OK</i>. This can influence whether
+source code files are found.</p>
+<h2><a name="Environment"></a>Tab Environment</h2>
+<p>In the Environment tab you can set environment variables that the program
+sees in addition to those that it inherits.
+In the edit box type in an expression of the form <tt>VARIABLE=value</tt>
+to set the environment variable <tt>VARIABLE</tt> to the value <tt>value</tt>,
+and click <i>Modify</i>. To remove a variable, select it from the list
+below and click <i>Delete</i>. To change the value, edit the value in the
+edit field and click <i>Modify</i>. If you change the name of the variable
+and click <i>Modify</i>, you add a new variable! The new environment variables
+will be used by your program the next time it is run.</p>
+<h2>Tab xsldbg Settings</h2>
+<p>This tab is only available when a <a href="xslt.html">XSLT script is
+debugged</a>. Here you can specify various flags that influence the
+XSL translation and XSLDBG.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/breakptlist.html b/kdbg/doc/en/breakptlist.html
new file mode 100644
index 0000000..fb1c18e
--- /dev/null
+++ b/kdbg/doc/en/breakptlist.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Breakpoint list</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+The Breakpoint List</h1>
+<p>The breakpoint list displays all breakpoints and watchpoints that are set
+and allows you to manipulate them. It can be displayed using <i>View|Breakpoints</i>.</p>
+<h2>
+The list of breakpoints</h2>
+<p>For each breakpoint the following is shown:</p>
+<ul>
+<li>
+the breakpoint location,</li>
+
+<li>
+the hit count,</li>
+
+<li>
+the ignore count if set,</li>
+
+<li>
+the condition if set.</li>
+</ul>
+<p>The icon in front of the entry indicates whether the breakpoint is enabled
+(a red dot) or disabled (a bright red dot), whether the breakpoint is temporary
+(a tiny clock is overlaid), whether the breakpoint is conditional (a
+tiny question mark is overlaid), or whether the breakpoint is <em>orphaned</em>
+(a 'x' is overlaid).</p>
+<p>Watchpoints are indicated by an eye glas icon in front of the line.</p>
+<h2>
+<A name="orphanedbp"></A>Orphaned breakpoints</h2>
+<p><em>Orphaned breakpoints</em> are breakpoints that gdb cannot implant
+immediately. Orphaned breakpoints occur if you try to set a breakpoint in a file
+that is not part of the executable. In particular, this is the case if the file
+belongs to a shared library or dynamically loaded module: When the executable
+is loaded, gdb does not yet know about dynamic modules and, hence, cannot set
+breakpoints there. However, KDbg does not forget about requests to set
+breakpoints in dynamic modules: It tries to set orphaned breakpoints each time
+that the program stops. When the breakpoint can be set successfully, it turns
+into a normal breakpoint.</p>
+<p>But there is an important consequence: Orphaned breakpoints are not effective,
+and the program will <em>not</em> stop there. The remedy is to set a breakpoint
+in the executable at the earliest possible point after which it is known that
+the dynamic module is loaded. For shared libraries this is usually in <tt>main()</tt>
+and for dynamically loaded modules it is after the call to <tt>dlopen()</tt>
+(or equivalent). When the program stops at this breakpoint the orphaned
+breakpoints from the dynamic module are set and become effective.</p>
+<h2>
+Manipulating breakpoints</h2>
+<p><a name="StopProg"></a>It is important to note that breakpoints and watchpoints
+cannot be manipulated while the program is running. If the program has
+already been started, it must stop first - either by hitting a breakpoint
+that is already set or forcefully by choosing <i>Execution|Break</i>. Note
+that this will not terminate the program, it just interrupts it. You can
+now manipulate the breakpoints; then choose <i>Execution|Continue</i> to
+let the program continue.</p>
+<p>To set a breakpoint on a specific source line, it is easiest to do this
+in the source code window. If you don't know the exact file and line number
+of a function, you can set the breakpoint by typing the function name in
+the edit box above the list and click <i>Add Breakpoint</i>.</p>
+<p>You can disable and enable breakpoints by selecting them in the list
+and clicking <i>Disable</i> or <i>Enable</i>. Or you simply click on the
+breakpoint in the list using the middle mouse button - just like you enable
+and disable breakpoints in the source window.</p>
+<p>You can set a condition on a breakpoint (so that the program is only
+stopped if the condition is true) or set an ignore count (so that the program
+is not stopped the next n times that the breakpoint is hit). To do that,
+press the <i>Conditional</i> button and enter the condition and/or ignore
+count.</p>
+<h2>
+Manipulating watchpoints</h2>
+<p>Watchpoints are a like breakpoints, except that they interrupt the program
+when the value of a memory location changes. As with breakpoints, watchpoints
+cannot be manipulated while the program is running. See <a href="#StopProg">above</a>
+for more information.</p>
+<p>To set a watchpoint, type an expression in the edit box above the list,
+then click <i>Add Watchpoint</i>. The program will stop when the value
+of the expression changes. Note that watchpoints that involve local variables
+can only be set when the program is stopped in a breakpoint (or has been
+interrupted by <i>Execution|Break</i>).</p>
+<p>To remove the watchpoint, select it from the list and click <i>Remove</i>.
+If the expression involves a local variable, the watchpoint will be removed
+automatically when the program leaves the current frame.</p>
+<p>You can set a condition and an ignore count on the watchpoint just like
+on breakpoints by selecting it and clicking <i>Conditional</i>.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/globaloptions.html b/kdbg/doc/en/globaloptions.html
new file mode 100644
index 0000000..52faaab
--- /dev/null
+++ b/kdbg/doc/en/globaloptions.html
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Global Options</title>
+</head>
+<body text="#000000" bgcolor="#ffffff">
+<p><a href="index.html">Contents</a></p>
+<h1>
+Global Options Dialog</h1>
+<p>To specify some global options, choose <i>Settings|Global Options</i>. You
+can set the following:</p>
+<ul>
+<li>
+the command by which gdb is invoked,</li>
+
+<li>
+the command that opens a terminal for the program's output,</li>
+
+<li>
+whether the KDbg shall pop into the foreground when the program stops and
+a timeout when it shall go back again,</li>
+
+<li>
+the tab width,</li>
+
+<li>
+filters for source file names.</li>
+</ul>
+
+<h4>
+How to invoke gdb</h4>
+
+<blockquote>If you want to use a different version of gdb, you can specify
+it under
+<i>How to invoke GDB</i>. The default command is <tt>gdb --fullname
+--nx</tt>. Be sure to also specify these options if you change the gdb
+executable. If you leave them away, KDbg will not work. If you messed up
+the entry, you can clear it to revert to the default setting.</blockquote>
+
+<h4>
+How to invoke a terminal emulator</h4>
+
+<blockquote>If you want to use a different terminal program to show the
+output of the program, specify it under <i>Terminal for program output</i>.
+The default setting is <tt>xterm -name kdbgio -title %T -e sh -c %C</tt>.
+In this entry,
+<tt>%T</tt> will be replaced by a title string, <tt>%C</tt>
+will be replaced by a Bourne shell script that loops infinitely so that
+the terminal window doesn't close. (No, it doesn't use CPU, it calls <tt>sleep
+3600</tt> in a loop :) An alternative for this setting could be <tt>konsole
+--name kdbgio --caption %T -e sh -c %C</tt>.</blockquote>
+
+<h4>
+Pop into foreground</h4>
+
+<blockquote>You can specify whether the KDbg window shall move itself into
+the foreground as soon as the program being debugged stops (at a breakpoint
+or due to a signal). The KDbg window is not activated, however (at least
+under KWM, the KDE window manager). Some users may feel that this behavior
+is intrusive, so this option is off by default.</blockquote>
+
+<blockquote>If this option is on, KDbg will also retreat itself into the
+background when the program is continued by any command, but it does so
+only after a timeout that can be specified. This avoids that the debugger
+window flashes back and forth each time you click any of the <i>Step</i>
+commands.</blockquote>
+
+<h4>
+File filters</h4>
+
+<blockquote>You can specify wildcards for source files and header files,
+which are used in the file dialog of the <i>File|Open Source</i>
+command.</blockquote>
+
+</body>
+</html>
diff --git a/kdbg/doc/en/howdoi.html b/kdbg/doc/en/howdoi.html
new file mode 100644
index 0000000..6191144
--- /dev/null
+++ b/kdbg/doc/en/howdoi.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - How Do I...?</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+How Do I...?</h1>
+
+<h4>
+... set breakpoints?</h4>
+<p>There's more than one way to set a breakpoint:</p>
+<ul>
+<li>
+You can set it in the source window by clicking on the "active area" at
+the far left of the line.</li>
+
+<li>
+You can set it by selecting the line in the source window and choosing
+an option from the <i>Breakpoint</i> menu.</li>
+
+<li>
+You can set it in the <a href="breakptlist.html">breakpoint list</a>.</li>
+</ul>
+<p>If you can't set breakpoints, maybe the program is currently running. You
+can't set breakpoints while the program is running. Stop it first using
+<i>Execution|Break</i>.
+If you still can't set breakpoints, make sure that you have compiled <em>and
+linked</em> your program with debugging information enabled.</p>
+<h4>
+... display the value of a global variable or an arbitrary expression?</h4>
+<p>Use the <A href="watches.html">Watch window</A>.</p>
+<h4>
+... set watchpoints?</h4>
+<p>Watchpoints are manipulated in the <a href="breakptlist.html">breakpoint
+list</a>.</p>
+<h4>
+... use a core dump?</h4>
+<p>First load the executable using <i>File|Executable</i>, then specify the
+core dump using <i>File|Core dump</i>.</p>
+<h4>
+... debug a program that's caught in an endless loop?</h4>
+<p>Start the program and let it run until it is in the endless loop. Then
+switch to KDbg and choose <i>Execution|Break</i>. You've just caught the
+nasty program <em>in flagranti</em>!</p>
+<h4>
+... achieve that the program passes over a breakpoint a number of times
+before it stops?</h4>
+<p>In the <a href="breakptlist.html">breakpoint list</a> select the breakpoint;
+then click <i>Conditional</i> and specify the number of times to skip the
+breakpoint in the <i>Ignore count</i> field.</p>
+<h4>
+... set environment variables for the executable?</h4>
+<p>Select <i>Execution|Arguments</i> and specify the environment variables
+in the <a href="argspwdenv.html#Environment">program arguments dialog</a>.</p>
+<h4>
+... set a working directory for the executable?</h4>
+<p>Select <i>Execution|Arguments</i> and specify the working directory in
+the <a href="argspwdenv.html#WorkingDir">program arguments dialog</a>.</p>
+<h4>
+... get rid of this terminal window?</h4>
+<p>Select <i>Settings|This Program</i> and switch to the <a href="pgmsettings.html#output">Output</a> tab.
+Select <i>Only output, simple terminal emulation</i> and click <i>OK</i>.
+Now restart the program (choose it from the list under <i>File|Recent Executables</i>).
+The program output goes now to the built-in <a href="pgmoutput.html">output
+window</a> and stdin is redirected to <tt>/dev/null</tt>.</p>
+<p>You must do this for every new program that you debug.</p>
+<p><b><i>Important:</i></b> You should not do this if your program expects
+input from the terminal (usually stdin) or if its output requires nifty
+terminal emulation (more than carriage-return and line-feed). The built-in
+output window does not support input and terminal emulation.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/index.html b/kdbg/doc/en/index.html
new file mode 100644
index 0000000..454cd08
--- /dev/null
+++ b/kdbg/doc/en/index.html
@@ -0,0 +1,185 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+
+<h1>
+KDbg - User's Manual</h1>
+
+<h2>
+Contents</h2>
+
+<ul>
+<li>
+<a href="#Introduction">Introduction</a></li>
+
+<li>
+<a href="#UsingKDbg">Using KDbg</a></li>
+
+<li>
+<a href="#InfoWindows">KDbg's information windows</a></li>
+
+<li>
+<a href="#Tips">Tips and such</a></li>
+
+<li>
+Advanced topic: <a href="types.html">Type tables</a></li>
+
+<li>
+<a href="invocation.html">How to invoke KDbg from the command line</a></li>
+
+<li>
+<a href="#Author">Author</a></li>
+</ul>
+
+<hr>
+<h2>
+<a name="Introduction"></a>Introduction</h2>
+<p>KDbg is a front-end for <tt>gdb</tt>, the GNU debugger.</p>
+<p>This means that KDbg itself is not the debugger. Rather, it communicates
+with <tt>gdb</tt>, a command line debugger, by sending commands to it and
+receiving the output, such as variable values. The menu commands and mouse
+clicks are translated into <tt>gdb</tt> commands, and the output of <tt>gdb</tt>
+is translated into (more or less) visible information, such as structured
+variable contents.</p>
+<p>The upshot of all this is that KDbg completely relies on the capabilities
+of the underlying command line debugger, <tt>gdb</tt>. KDbg can do no more
+than <tt>gdb</tt> can. For example, if you have a <tt>gdb</tt> that does
+not supports debugging of threaded programs, KDbg cannot, either (even
+though it offers a threads window).</p>
+<h2>
+<a name="UsingKDbg"></a>Using KDbg</h2>
+<p>Before you start using KDbg, you may want to review the options in the
+<a href="globaloptions.html">Global Options</a> dialog that you invoke
+with <i>Settings|Global Options</i>.</p>
+<h4>
+Specifying a debugging target</h4>
+<p>To debug a program, choose <i>File|Executable</i> from the menu. If you
+have debugged the program earlier, you can choose it from <i>File|Recent
+Executables</i>. The program is loaded.</p>
+<p>If you want to debug a core dump, you must first load the executable
+that produced the core dump, then choose
+<i>File|Core Dump</i> from the
+menu. Now KDbg goes to the point in the program that caused the core dump.</p>
+<p>You can now set breakpoints, using the <i>Breakpoint</i> menu, the right
+mouse button menu, or the <a href="breakptlist.html">breakpoint window</a>.</p>
+<p>You can also choose program specific settings that apply only to the
+currently loaded executable using <i>Settings|This Program</i>, in the
+<a href="pgmsettings.html">Program Settings</a> dialog.</p>
+<p>Furthermore, it is possible to <a href="xslt.html">debug XSLT scripts</a>.</p>
+<h4>
+Running the program</h4>
+<p>Now run the program by selecting <i>Execution|Run</i>. The program now
+executes as usual until it either exits, hits a breakpoint or watchpoint,
+or receives a signal.</p>
+<p>You can run the program with arguments, set a working directory, or
+set environment variables. To do this, choose <i>Execution|Arguments</i>
+and specify your options in the <a href="argspwdenv.html">Program Arguments</a>
+dialog (before you start the program).</p>
+<p>You can also attach to a program that is currently running. To do this,
+first load the executable file like above. Then choose <i>Execution|Attach</i>.
+From the list processes specify the one you want to attach to
+and click <i>OK</i>. The running program is
+halted (not terminated), and the current point of execution is displayed
+in the source window.</p>
+<p><font size="-1">On some systems the list of processes may not be available.
+In this case a simple edit box is available where the process number can be
+specified.</font></p>
+<h4>
+The program stopped - now what?</h4>
+<p>When the program stops at a breakpoint, watchpoint, or due to a signal,
+the <a href="sourcecode.html">source code window</a> displays the line
+where the program stopped. It is very common that the program stops due
+to a signal (usually a <tt>SIGSEGV</tt>, segmentation violation) in a function
+that is not part of the program, that you have written. In this case you
+investigate the <a href="stack.html">stack window</a> and look for a function
+that you have written (start at the top of the list) and click on it. This
+will bring you to a location that you can start your search for the real
+bug.</p>
+<p>In the menu <i>Execution</i> you find the commands that you need to
+run
+the program, step through code, and to interrupt the program (<i>Break</i>)
+while it is running. The important commands (<i>Run</i> and all kinds of
+<i>Step</i>) are bound to function keys. For efficient debugging it is
+strongly recommend that you get used to using them. You can use
+<i>Settings|Configure Shortcuts</i> if you want to bind the functions
+to different keys.</p>
+<p>In the menu <i>Breakpoint</i> you find commands to set, clear, disable,
+and enable permanent and temporary breakpoints. You can display a list
+of breakpoints in the <a href="breakptlist.html">breakpoints window</a>.
+You can also set a breakpoint by clicking at the left end of the source
+line (using the left mouse button), and you can enable and disable a breakpoint
+by clicking it using the middle mouse button.</p>
+<p>The animation in the toolbar indicates whether the program
+is running. It stops when the program stopped in a breakpoint or for
+some other reason or when the program exited. This animated button is a shortcut
+for <i>Execution|Break</i>.</p>
+<h2>
+<a name="InfoWindows"></a>KDbg's information windows</h2>
+<p>KDbg displays information and accepts commands in number of different windows.
+In the menu <i>View</i> you find commands to show and hide these windows.
+They are docking windows, which means that you can drag them around and
+arrange them in any manner you like.</p>
+<ul>
+<li>
+<a href="sourcecode.html">The source code window</a></li>
+
+<li>
+<a href="localvars.html">The local variables window</a></li>
+
+<li>
+<a href="stack.html">The stack window</a></li>
+
+<li>
+<a href="watches.html">The watched expressions window</a></li>
+
+<li>
+<a href="breakptlist.html">The breakpoint list</a></li>
+
+<li>
+<a href="pgmoutput.html">The output window</a></li>
+
+<li>
+<a href="registers.html">The register dump window</a></li>
+
+<li>
+<a href="memory.html">The memory dump window</a></li>
+
+<li>
+<a href="threads.html">The threads window</a></li>
+</ul>
+
+<h2>
+<a name="Tips"></a>Tips and such</h2>
+<p>The following topics give some useful hints on using KDbg.</p>
+<ul>
+<li>
+<a href="tips.html">Tips and Tricks</a></li>
+
+<li>
+<a href="howdoi.html">How do I...?</a></li>
+</ul>
+
+<h2>
+<a name="Author"></a>Author</h2>
+<p>KDbg is written by <a href="mailto:j6t@kdbg.org">Johannes Sixt</a>
+with contributions from these people (in no particular order):</p>
+<ul>
+<li>Keith Isdale</li>
+<li>Ben Burton</li>
+<li>Daniel Thor Kristjansson</li>
+<li>Matthew Allen</li>
+<li>Ron Lerech</li>
+<li>Neil Butterworth</li>
+<li>Thomas Sparr</li>
+<li>Max Judin</li>
+<li>Johnny Chan</li>
+<li>Ilmar S. Habibulin</li>
+</ul>
+<p>KDbg homepage is at <a href="http://www.kdbg.org/">http://www.kdbg.org/</a>.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/invocation.html b/kdbg/doc/en/invocation.html
new file mode 100644
index 0000000..d09b07c
--- /dev/null
+++ b/kdbg/doc/en/invocation.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - Invocation</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>Invoking KDbg from the command line</h1>
+<p><pre>
+Usage: kdbg [Qt-options] [KDE-options] [options] [program] [core]
+
+Generic options:
+ --help Show help about options
+ --help-qt Show Qt specific options
+ --help-kde Show KDE specific options
+ --help-all Show all options
+ --author Show author information
+ -v, --version Show version information
+ --license Show license information
+ -- End of options
+
+Options:
+ -t &lt;file&gt; transcript of conversation with the debugger
+ -r &lt;device&gt; remote debugging via &lt;device&gt;
+ -l &lt;language&gt; specify language: C, XSLT []
+ -p &lt;pid&gt; specify PID of process to debug
+
+Arguments:
+ program path of executable to debug
+ core a core file to use
+</pre></p></body>
+</html>
diff --git a/kdbg/doc/en/localvars.html b/kdbg/doc/en/localvars.html
new file mode 100644
index 0000000..1461f70
--- /dev/null
+++ b/kdbg/doc/en/localvars.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Local Variables</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+The Local Variables Window</h1>
+<p>The local variables window is opened using <i>View|Locals</i>. The local
+variables window displays the contents of the local variables at the currently
+selected stack frame.</p>
+<p>The set of local variables that are displayed is determined by the stack
+frame that is selected in the <A href="stack.html">stack window</A>.</p>
+<p>Variable values that changed between stops of the program are displayed
+in red color.</p>
+<p>The values of most variables can be changed. For this purpose, press F2
+while the input focus is in the window or choose <i>Edit value</i> from the
+context menu. Then edit the value and hit Enter. Note that you cannot modify
+the strings that <tt>char*</tt> values point to in this way, just the pointer
+value.</p>
+<p>Using the context menu you can move
+the active variable or structure member to the <a href="watches.html">watched
+expressions window</a>.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/memory.html b/kdbg/doc/en/memory.html
new file mode 100644
index 0000000..75693f9
--- /dev/null
+++ b/kdbg/doc/en/memory.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Memory Dump</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+The Memory Dump Window</h1>
+<p>The memory dump window is displayed using <i>View|Memory</i>. It displays
+the contents of the program's memory at arbitrary adresses.</p>
+<p>To display memory contents, enter an address in the edit field. The
+address need not be given in hexadecimal form - it can be an expression.</p>
+<p>You can specifiy a format how the memory contents shall be displayed
+by chooseing the appropriate options from the popup menu that you invoke
+by clicking the right mouse button.</p>
+<p>A number of address expressions are remembered. You can recall such
+an expression from the drop-down list. Please note that the address expression
+is remembered together with the format.</p>
+<p>If you don't need to investigate memory contents, it is recommended
+that you clear the expression so that no memory dump is displayed - this
+speeds up the debugging process.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/pgmoutput.html b/kdbg/doc/en/pgmoutput.html
new file mode 100644
index 0000000..3e18902
--- /dev/null
+++ b/kdbg/doc/en/pgmoutput.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Program Output</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+The Program Output Window</h1>
+<p>The program output window is displayed using <i>View|Output</i>. The output
+window captures text that is written to stdout and stderr by the program
+being debugged.</p>
+<p>The output window does not allow to type input for the program and it
+features only minimal terminal emulation: <tt>\n</tt> (line-feed),
+<tt>\t</tt> (horizontal tab), and <tt>\r</tt> (carriage-return)
+are treated. These capabilities are usually sufficient to debug GUI programs
+which only write debugging output to stdout and stderr.</p>
+<p>When a program is debugged with KDbg for the first time, the program
+output window is <em>not</em> used. The reason for this is that KDbg cannot
+know whether the program requires sophisticated terminal emulation or if
+it expects input through a terminal. So, a terminal emulator program is
+used by default. In order to redirect the output to the output window,
+you must do the following:</p>
+<ol>
+<li>
+Open the <a href="pgmsettings.html">Settings dialog</a> by selecting <i>Settings|This Program</i>.</li>
+
+<li>
+Switch to the <i>Output</i> tab.</li>
+
+<li>
+Choose <i>Only output, simple terminal emulation</i> and click <i>OK</i>.</li>
+
+<li>
+Reload the program by selecting it from the list in <i>File|Recent Executables</i>.</li>
+</ol>
+<p>You can clear the contents of the output window by selecting <i>Clear</i>
+from the popup menu that appears when you click the right mouse button.</p>
+<p>If the last line of the output is visible, the window always scrolls
+automatically so that the last line remains visible when new output arrives.
+If, however, you manually scroll up so that the last line is not visible,
+the visible portion of text will not change.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/pgmsettings.html b/kdbg/doc/en/pgmsettings.html
new file mode 100644
index 0000000..64225fb
--- /dev/null
+++ b/kdbg/doc/en/pgmsettings.html
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Program Settings</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+The Program Settings Dialog</h1>
+<p>In this dialog, program specific settings can be selected. It is invoked
+by <i>Settings|This Program</i>. The settings apply only to the currently loaded
+executable and will be saved across sessions.</p>
+<blockquote><b><i>Important note:</i></b> The chosen settings will only
+apply the next time the executable is loaded into KDbg. This means that
+after pressing
+<i>OK</i> in this dialog, you must reload the executable
+using <i>File|Recent Executables</i>!!</blockquote>
+
+<ul>
+<li>
+<a href="#driver">Debugger</a></li>
+
+<li>
+<a href="#output">Output</a></li>
+</ul>
+
+<h2>
+<a name="driver"></a>Debugger</h2>
+<p>In this section, the debugger to be used for the program can be chosen.</p>
+<h4>
+How to invoke GDB</h4>
+
+<blockquote>Enter the command to invoke gdb. Leave this field empty to
+use the default gdb command as specified in the <a href="globaloptions.html">global
+options</a>. When you are cross-compiling and remote-debugging, you will
+probably want to use a different gdb suitable for the target platform.
+The default command is <tt>gdb --fullname --nx</tt>. Be sure to specify
+at least <tt>--fullname</tt> if you change the gdb command.
+If you remove this command switch, KDbg will not work.
+</blockquote>
+
+<h2>
+<a name="output"></a>Output</h2>
+<p>In this section, the terminal emulation under which the program will run
+can be selected.</p>
+<h4>
+No input and output</h4>
+
+<blockquote>Check this option if your program does not receive input from
+the terminal and you do not want to see the output that the program writes
+to <tt>stdout</tt> and <tt>stderr</tt> (if any). All three standard channels
+(<tt>stdin</tt>, <tt>stdout</tt>, and <tt>stderr</tt>) are effectively
+redirected to <tt>/dev/null</tt>.</blockquote>
+
+<h4>
+Only output, simple terminal emulation</h4>
+
+<blockquote>Check this option if your program does not receive input from
+the terminal (<tt>stdin</tt> will be redirected to <tt>/dev/null</tt>),
+and the output that it writes to <tt>stdout</tt> and <tt>stderr</tt> does
+not require sophisticated terminal emulation. The output will be shown
+in the <a href="pgmoutput.html">Output window</a>.
+<br><i>Important:</i> The integrated terminal emulator will only interpret
+the line-feed character <tt>\n</tt> (ASCII 10) to break lines. It will
+<em>not</em>
+handle the carriage-return character <tt>\r</tt> (ASCII 13). This is sufficient
+for displaying plain debugging output that is often used by developers
+of GUI programs.</blockquote>
+
+<h4>
+Full terminal emulation</h4>
+
+<blockquote>Check this option if your program reads input from <tt>stdin</tt>
+or if the output to <tt>stdout</tt> or <tt>stderr</tt> requires terminal
+emulation. A terminal emulator will be invoked as specified in the <a href="globaloptions.html">global
+options</a>.</blockquote>
+
+</body>
+</html>
diff --git a/kdbg/doc/en/registers.html b/kdbg/doc/en/registers.html
new file mode 100644
index 0000000..fc9fb5b
--- /dev/null
+++ b/kdbg/doc/en/registers.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Register Dump</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+The Register Dump Window</h1>
+<p>Whenever the program stops, KDbg displays the contents of the CPU registers
+in the register dump window. To display this window, choose <i>View|Registers</i>.</p>
+<p>The registers are grouped by the kind of register. The window contains 3 columns:</p>
+<ol>
+<li>
+The column <i>Register</i> displays the register name.</li>
+
+<li>
+The column <i>Value</i> displays the contents of the registers in a more
+or less raw form. The raw form is usually displayed as hexadecimal numbers,
+even the contents of floating point registers.</li>
+
+<li>
+The column <i>Decoded value</i> displays the contents of the registers
+in a decoded form. For arithmetic registers this is generally a signed
+decimal value, floating point registers are displayed as floating point
+numbers, the flag registers are sometimes decoded into named flags.</li>
+</ol>
+<p>By clicking the right mouse button a context menu is popped up which lets
+you select how the value in the third column is displayed.
+You can change the type to use for all registers of a group at once if you
+choose the format for the group header.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/sourcecode.html b/kdbg/doc/en/sourcecode.html
new file mode 100644
index 0000000..9d1bb7f
--- /dev/null
+++ b/kdbg/doc/en/sourcecode.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Source Code</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+The Source Code Window</h1>
+<p>The source code window is the main window and is always visible.</p>
+<p>The source code window displays program source code. At the left of
+each source line is an "active area". It displays a pointer to indicate
+which source line the program currently executes, and it indicates on which
+source lines breakpoints have been set.</p>
+<p>New breakpoints can be set by clicking into the active area with the
+left mouse button. An existing breakpoint can be enabled and disabled by
+clicking with the middle mouse button.</p>
+<p>The tiny plus '+' between the "active area" and the source line can
+be clicked on. If you do so, the source line's assembler code will be displayed.
+The plus turns into a minus '-', which, if clicked, will hide the disassembled
+code.</p>
+<p>Mostly, source code windows are opened automatically. To open a new
+source file manually, click the right mouse button and choose <i>Open Source</i>
+or choose <i>File|Open Source</i>.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/stack.html b/kdbg/doc/en/stack.html
new file mode 100644
index 0000000..0db570b
--- /dev/null
+++ b/kdbg/doc/en/stack.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Stack</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+The Stack Window</h1>
+<p>The stack window is displayed using <i>View|Stack</i>. The stack window
+lists the stack frames, i.e. the functions that the program has entered,
+but not yet left.</p>
+<p>The innermost frame (where the program currently executes) is shown
+at the top.</p>
+<p>To switch to a different stack frame, simply click on that stack frame.
+The <a href="sourcecode.html">source window</a> displays the source line
+where the function invocation took place and the <a href="localvars.html">local
+variables window</a> and the <a href="watches.html">watch window</a> change
+to reflect the local variables of the selected stack frame.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/threads.html b/kdbg/doc/en/threads.html
new file mode 100644
index 0000000..3f0d7fb
--- /dev/null
+++ b/kdbg/doc/en/threads.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Threads</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+The Threads Window</h1>
+<p>The threads window is displayed using <i>View|Threads</i>. The threads
+window lists the active threads of the program.</p>
+<p><b><i>Note:</i></b> Debugging threaded programs must be supported by
+the version of gdb that is used - it is not a feature of KDbg. For Linux
+systems this works best with gdb5 and later. However, at the time of this writing gdb
+still poorly supports threads on NPTL- (New Posix Threads Library) enabled
+systems (glibc 2.3.x and kernel 2.6.x).</p>
+<p>The contents of the threads window are updated every time the program
+is stopped by the debugger. (That is, the window does <em>not</em> reflect
+the state while the program is running.)</p>
+<p>The first column shows the thread ID, the second column identifies the
+location where the thread currently executes.</p>
+<p>The marker in front of the line tells which thread currently is <em>active</em>:</p>
+<ul>
+<li>
+The <a href="stack.html">stack window</a> displays the active threads's
+backtrace.</li>
+
+<li>
+The <a href="localvars.html">local variables</a> window displays the active
+thread's local variables.</li>
+
+<li>
+The <a href="watches.html">watch window</a> uses the active thread's local
+variables to evaluate the expressions.</li>
+</ul>
+<p>By clicking a listed thread, the active thread is switched, and the corresponding
+windows are updated. In particular, the <a href="sourcecode.html">source
+window</a> displays the location where the active thread is currently halted.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/tips.html b/kdbg/doc/en/tips.html
new file mode 100644
index 0000000..6a0292a
--- /dev/null
+++ b/kdbg/doc/en/tips.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Tips and Tricks</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+Tips and Tricks</h1>
+
+<ul>
+<li>
+You can use breakpoints as bookmarks: Just set a breakpoint and disable
+it. Later, you can quickly come back to that breakpoint by double-clicking
+it in the breakpoint list (or select it and click <i>View Code</i>). Since
+breakpoints are persistent (i.e. KDbg remembers them across invocations
+of a program), you get them back next time you invoke KDbg for that particular
+program.</li>
+
+<li>
+You can display a value in the watch section in different ways by prepending
+gdb's format specifiers in front of the variable to display. E.g. <tt>/x
+var.member</tt> displays the <tt>var.member</tt> in hexadecimal notation.</li>
+
+<li>
+You can set breakpoints in a source files that belong to a shared library.
+Such breakpoints will be marked as <em>orphaned</em> if the program is not active.
+<A href="breakptlist.html#orphanedbp">Orphaned breakpoints</A> are not effective.
+In order to make them effective, the program must stop at a time when the shared
+library is loaded. For this it is usually sufficient to set a breakpoint in
+<tt>main()</tt>. At the time when this breakpoint is hit, the orphaned breakpoints
+in the shared library become effective.</li>
+
+<li>
+Debugging multi-threaded programs on NPTL-enabled Linux systems (kernel 2.6.x
+or later and glibc 2.3.x or later) may sometimes fails; gdb stops the program
+at unexpected instances. In this case the following may help (using bash):
+<pre>
+LD_ASSUME_KERNEL=2.4.19 kdbg myprogram
+</pre>I.e. you run KDbg from the command line such that the old
+Linuxthreads implementation is used.</li>
+</ul>
+
+</body>
+</html>
diff --git a/kdbg/doc/en/types.html b/kdbg/doc/en/types.html
new file mode 100644
index 0000000..10587b9
--- /dev/null
+++ b/kdbg/doc/en/types.html
@@ -0,0 +1,183 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Type Tables</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+KDbg's Type Table</h1>
+<p>KDbg can display a short description of structured types, so
+that it is not necessary to expand the variable in the <a href="localvars.html">local
+variables window</a> or <a href="watches.html">watched expressions window</a>.
+The information which member variable is displayed is stored in <em>type
+tables</em>. There is generally one type table per shared library.</p>
+
+<p>KDbg's default type tables are located under <tt>$prefix/share/apps/kdbg/types</tt>.
+User defined type tables can be placed in <tt>${KDEHOME}/share/apps/kdbg/types</tt>, where
+<tt>${KDEHOME}</tt> is <tt>~/.kde</tt> if it is not a defined environment variable.
+The file names end with <tt>.kdbgtt</tt>. Example: The type table for <tt>libqt.so</tt>
+is named <tt>qt.kdbgtt</tt>.
+User defined type tables override the type tables provided by the system.</p>
+<p>A type table file obeys the regular KDE configuration file syntax. The
+file has the following groups:</p>
+<ul>
+<li>
+A group <tt>[Type Table]</tt> which lists the types and information how
+the debugger can identify whether the program is linked against the library.</li>
+
+<li>
+A group for each type which has information about how the value of such
+a type is displayed by KDbg.</li>
+</ul>
+<p>In order to determine which type tables apply to the program being debugged
+KDbg lists the shared libraries it is linked to. Then it matches the names
+against the <tt>ShlibRE</tt> entries of all type tables. Those that match
+are used. If a type appears in several type tables, it is unspecified which
+one will be used.</p>
+<p>KDbg's type recognition only works for libraries that are linked dynamically
+to the program being debugged.</p>
+<h2>
+The <tt>[Type Table]</tt> group</h2>
+<p>This group contains the following entries:</p>
+<ul>
+<li>
+<tt>Types1</tt>, <tt>Types2</tt>, etc. These entries name the types,
+separated by commas.
+Each of the entries can list any number of types. The entries must be numbered
+consecutively (KDbg stops reading at the first gap), although an entry may be
+empty (i.e. contain no type at all).
+Sometimes the order in which the names are listed is important
+(see <tt>Alias</tt> types below).</li>
+
+<li>
+<tt>ShlibRE</tt>. KDbg uses this entry to determine if the type table applies
+to the program being debugged. For this purpose KDbg determines the shared
+libraries to which the program is linked. If any of the libraries matches
+this entry, the type table applies. The regular expression is a Qt-regular
+expression (the metacharacters <tt>.*?[]^$\</tt> are recognized in the
+usual way, but there is no possibility to group characters.)</li>
+
+<li>
+<tt>LibDisplayName</tt>. This entry is used in lists where the available
+type tables are listed to identify this type table.
+
+<br><font size=-1>This is not used currently.</font></li>
+
+<li>
+<tt>EnableBuiltin</tt> lists extensions that must be enabled if this
+library is used. Currently, two builtins are supported:
+<ul>
+<li>
+<tt>QString::Data</tt> is used to display unicode strings of Qt's <tt>QString</tt>
+class. See below.</li>
+<li><tt>QCharIsShort</tt> is used only in connection with <tt>QString::Data</tt>
+to specify that a unicode character is stored in an object of type <tt>short</tt>.
+See <tt>qt3.kdbgtt</tt> for examples.</li></ul></li>
+</ul>
+
+<p>In the case of regular types the names of types should follow the output of the
+<tt>whatis</tt> gdb command less any <tt>const</tt>, <i>spaces</i>, or trailing
+<tt>&</tt>.
+If the type contains a a comma in its name, it must be escaped with a backslash.
+But note that the comma should not be escaped in the type's group (which is described
+in the next section).
+</p>
+<p>In the case of template types the name can be arbitrary because the type's group
+will mention the template name and a type parameter list.</p>
+
+<h2>
+The type's group</h2>
+<p>There is one group for each type that is named exactly as the type. <font size=-1>At
+the moment C++ template classes are not supported.</font> Each group contains
+the following entries:</p>
+<ul>
+<li>An optional <tt>Template</tt> entry that specifies the exact template type
+name as it is reported by gdb's <tt>whatis</tt> command. However, it is
+possible to replace template parameter types at the top-most level by an
+asterisk&nbsp;<tt>*</tt>, which acts as a wildcard: It matches <b>one</b>
+template type argument that is reported by <tt>whatis</tt> (except that an
+asterisk in the last position matches all remaining template type arguments).
+</li>
+<li>
+<tt>Display</tt> determines how the value of the type is displayed by KDbg.
+The string must contain 1 to 5 percent characters '<tt>%</tt>'. These are
+replaced by the results of the expressions printed by the <tt>Expr</tt><i>x</i>
+entries.</li>
+
+<li>
+One or more of <tt>Expr1</tt>, <tt>Expr2</tt>, etc. Each of them must contain
+one or more <tt>%s</tt> sequence, which will be replaced by the expression
+whose value is investigated. The so constructed expression is submitted
+to gdb, and the result substituted back for the corresponding percent character
+in the <tt>Display</tt> string.</li>
+
+<li>
+An optional <tt>FunctionGuard</tt><i>x</i> that is associated with the corresponding <tt>Expr</tt><i>x</i>.
+If the evaluation of the resulting gdb expression returns an error, the corresponding expression from <tt>Expr</tt><i>x</i> is not evaluated. (This is used to guard function calls.)
+<li>
+<tt>Alias</tt> names an alias type. If this entry is present, the type
+is treated like the specified type. That alias type must appear before
+this type in the <tt>Types</tt><i>x</i> entries in the <tt>Type Table</tt>.</li>
+</ul>
+<p><font size=-1>Currently the number of expressions per type is limited to
+5. This can easily be changed if it's too restrictive, but I recommend
+not to go to that limit at all - it will slow down the debugging process.</font></p>
+<p>KDbg recognizes a special extension that is used to display Qt 2.x's and Qt 3.x's
+unicode strings: If an <tt>Expr</tt><i>x</i> is prepended with <tt>/QString::Data</tt>,
+it is assumed that the result of the expression is a pointer to a <tt>QString::Data</tt>.
+The value displayed is the unicode string that this instance of <tt>QString::Data</tt>
+represents (which can be <tt>QString::null</tt> if it is Qt's well-defined
+null string or <tt>(null)</tt> if the <tt>unicode</tt> member is the null
+pointer). See <tt>qt2.kdbgtt</tt> for examples.</p>
+<p>Tip: It is not necessary to define derived types if they ought to be
+treated the same as the base class - KDbg can deduce derived types and
+uses the type specification of the (leftmost) base class. You can use the
+<tt>Alias</tt>
+entry to quickly specify that a type should be treated like a non-leftmost
+base class for a multiple-inheritance class.</p>
+<h2>
+An example</h2>
+<p>The example shows how <tt>QString</tt> and <tt>QRect</tt> are defined
+in <tt>qt3.kdbgtt</tt>. Furthermore, the template type <tt>QValueVector</tt>
+is defined. This example applies to Qt 3.x, which is located in shared library
+whose name ends in <tt>libqt-mt.so.3</tt>.</p>
+<pre>[Type Table]
+Types1=QString,QRect
+Types2=QValueVector
+LibDisplayName=libqt 3.x
+ShlibRE=libqt-mt\.so\.3$
+EnableBuiltin=QString::Data,QCharIsShort
+
+[QString]
+Display={ % }
+Expr1=/QString::Data (%s).d
+
+[QValueVector]
+Template=QValueVector<*>
+Display={ size=% shared=% capacity=% }
+Expr1=($tmp=(%s).sh)->finish-$tmp->start
+Expr2=(%s).sh->count
+Expr3=($tmp=(%s).sh)->end-$tmp->start
+
+[QRect]
+Display={ tl=(%,%) br=(%,%) }
+Expr1=(%s).x1
+Expr2=(%s).y1
+Expr3=(%s).x2
+Expr4=(%s).y2</pre>
+<p>This example shows these features:</p>
+<ul>
+<li>The name of the template type, <tt>QValueVector</tt> is irrelevant.
+The exact type name is specified under the <tt>Template=</tt> entry.
+It specifies a single wildcard so that it applies to all specializations.
+</li>
+<li>In order to evaluate the expression that was supplied in the <tt>%s</tt>
+only once, the result is stored in a temporary gdb variable and reused later in
+the same expression.</li>
+<li>Note that it is safer to wrap the <tt>%s</tt> in parentheses.</li>
+</ul>
+</body>
+</html>
diff --git a/kdbg/doc/en/watches.html b/kdbg/doc/en/watches.html
new file mode 100644
index 0000000..395cc61
--- /dev/null
+++ b/kdbg/doc/en/watches.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Watched Expressions</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>
+The Watched Expressions Window</h1>
+<p>The watched expressions window is opened using <i>View|Watched Expressions</i>.
+It displays arbitrary expressions.</p>
+<p>To add an expression, type it into the edit field and press Enter or
+click <i>Add</i>. To remove an expression, click on it (choose the root
+of the expression) and click <i>Del</i>.</p>
+<p>You can also move a variable or structure member from the <a href="localvars.html">local
+variables window</a> to this window using the context menu in the local
+variables window.</p>
+<p>The values of most expressions can be changed. For this purpose, press F2
+while the input focus is in the window. Then edit the value and hit Enter.
+Note that you cannot modify the strings that <tt>char*</tt> values point
+to in this way, just the pointer value.</p>
+<p>Watched expressions are stored across debugging sessions. It is recommended
+that you remove expressions that your don't need any longer because that
+speeds up the debugging process.</p>
+</body>
+</html>
diff --git a/kdbg/doc/en/xslt.html b/kdbg/doc/en/xslt.html
new file mode 100644
index 0000000..fdc5ec3
--- /dev/null
+++ b/kdbg/doc/en/xslt.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - User's Manual - Debugging XSLT scripts</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<p><a href="index.html">Contents</a></p>
+<h1>Debugging XSLT scripts</h1>
+<p>KDbg allows to debug XSLT (XML stylesheet translation) scripts using
+<a href="http://xsldbg.sourceforge.net/">xsldbg</a>, which must be available
+on your system.</p>
+<h2>Specifying the script and an XML file to transform</h2>
+<p>XSLT mode is automatically entered if a &quot;program&quot; is loaded
+that has a file name that ends in <tt>.xsl</tt>. In addition, the
+<A href="invocation.html">command line option</A> <tt>-l XSL</tt> can be
+specified to explicitly choose this mode.</p>
+<p>To debug an XSLT script it is necessary to specify an XML data file
+that the script can transform. This is done in the
+<a href="argspwdenv.html">Program Arguments</a> dialog, where the XML
+file is specified in the <em>Program Arguments</em> edit box.</p>
+</body>
+</html>
diff --git a/kdbg/doc/ru/Makefile.am b/kdbg/doc/ru/Makefile.am
new file mode 100644
index 0000000..7fc29b8
--- /dev/null
+++ b/kdbg/doc/ru/Makefile.am
@@ -0,0 +1,27 @@
+html_DATA = \
+ argspwdenv.html \
+ breakptlist.html \
+ globaloptions.html \
+ howdoi.html \
+ localvars.html \
+ memory.html \
+ pgmoutput.html \
+ pgmsettings.html \
+ registers.html \
+ sourcecode.html \
+ stack.html \
+ threads.html \
+ tips.html \
+ watches.html \
+ index.html
+
+htmldir = $(kde_htmldir)/ru/kdbg
+
+EXTRA_DIST = $(html_DATA)
+
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(htmldir)
+ cd $(DESTDIR)$(htmldir) && ln -s -f ../../en/kdbg/types.html .
+
+uninstall-local:
+ -rm -f $(DESTDIR)$(htmldir)/types.html
diff --git a/kdbg/doc/ru/Makefile.in b/kdbg/doc/ru/Makefile.in
new file mode 100644
index 0000000..c70aeeb
--- /dev/null
+++ b/kdbg/doc/ru/Makefile.in
@@ -0,0 +1,609 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 483858 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = kdbg/doc/ru
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(htmldir)"
+htmlDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(html_DATA)
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARTSCCONFIG = @ARTSCCONFIG@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOPIDLNG = @DCOPIDLNG@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
+KCONFIG_COMPILER = @KCONFIG_COMPILER@
+KDECONFIG = @KDECONFIG@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
+KDE_MT_LIBS = @KDE_MT_LIBS@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_FPIE = @KDE_USE_FPIE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+KDE_USE_PIE = @KDE_USE_PIE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPTHREAD = @LIBPTHREAD@
+LIBRESOLV = @LIBRESOLV@
+LIBS = @LIBS@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBZ = @LIBZ@
+LIB_KAB = @LIB_KAB@
+LIB_KABC = @LIB_KABC@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDED = @LIB_KDED@
+LIB_KDEPIM = @LIB_KDEPIM@
+LIB_KDEPRINT = @LIB_KDEPRINT@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KDNSSD = @LIB_KDNSSD@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMPROXY = @LIB_KIMPROXY@
+LIB_KIO = @LIB_KIO@
+LIB_KJS = @LIB_KJS@
+LIB_KNEWSTUFF = @LIB_KNEWSTUFF@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KUNITTEST = @LIB_KUNITTEST@
+LIB_KUTILS = @LIB_KUTILS@
+LIB_POLL = @LIB_POLL@
+LIB_QPE = @LIB_QPE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_X11 = @LIB_X11@
+LIB_XEXT = @LIB_XEXT@
+LIB_XRENDER = @LIB_XRENDER@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKEKDEWIDGETS = @MAKEKDEWIDGETS@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MKDIR_P = @MKDIR_P@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PS_COMMAND = @PS_COMMAND@
+QTE_NORTTI = @QTE_NORTTI@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+UIC_TR = @UIC_TR@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+XGETTEXT = @XGETTEXT@
+XMKMF = @XMKMF@
+XMLLINT = @XMLLINT@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+X_RPATH = @X_RPATH@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = $(kde_htmldir)/ru/kdbg
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_kcfgdir = @kde_kcfgdir@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_qtver = @kde_qtver@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_styledir = @kde_styledir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+kde_widgetdir = @kde_widgetdir@
+kdeinitdir = @kdeinitdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+xdg_appsdir = @xdg_appsdir@
+xdg_directorydir = @xdg_directorydir@
+xdg_menudir = @xdg_menudir@
+html_DATA = \
+ argspwdenv.html \
+ breakptlist.html \
+ globaloptions.html \
+ howdoi.html \
+ localvars.html \
+ memory.html \
+ pgmoutput.html \
+ pgmsettings.html \
+ registers.html \
+ sourcecode.html \
+ stack.html \
+ threads.html \
+ tips.html \
+ watches.html \
+ index.html
+
+EXTRA_DIST = $(html_DATA)
+#>- all: all-am
+#>+ 1
+all: docs-am all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/ru/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu kdbg/doc/ru/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/ru/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/doc/ru/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/doc/ru/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-htmlDATA: $(html_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"
+ @list='$(html_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(htmlDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(htmlDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+
+uninstall-htmlDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(html_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(htmldir)/$$f'"; \
+ rm -f "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(htmldir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-am
+#>+ 1
+clean: kde-rpo-clean clean-am
+
+#>- clean-am: clean-generic clean-libtool mostlyclean-am
+#>+ 1
+clean-am: clean-bcheck clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-htmlDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-htmlDATA uninstall-local
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-data-local install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-htmlDATA install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am uninstall uninstall-am uninstall-htmlDATA \
+ uninstall-local
+
+
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(htmldir)
+ cd $(DESTDIR)$(htmldir) && ln -s -f ../../en/kdbg/types.html .
+
+uninstall-local:
+ -rm -f $(DESTDIR)$(htmldir)/types.html
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+
+#>+ 2
+KDE_DIST=stack.html memory.html index.html watches.html sourcecode.html howdoi.html pgmsettings.html globaloptions.html pgmoutput.html Makefile.in threads.html types.html argspwdenv.html localvars.html registers.html breakptlist.html tips.html Makefile.am
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/doc/ru/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/doc/ru/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/doc/ru/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-am
+
+bcheck-am:
+ @for i in ; do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXX) $(DEFS) -I. -I$(srcdir) -I$(top_builddir) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 3
+final:
+ $(MAKE) all-am
+
+#>+ 3
+final-install:
+ $(MAKE) install-am
+
+#>+ 3
+no-final:
+ $(MAKE) all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/kdbg/doc/ru/argspwdenv.html b/kdbg/doc/ru/argspwdenv.html
new file mode 100644
index 0000000..9108a91
--- /dev/null
+++ b/kdbg/doc/ru/argspwdenv.html
@@ -0,0 +1,43 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - , </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> , , </h1>
+ <i>|</i> ,
+ ,
+ .
+<h2>
+<a NAME="PgmArgs"></a> </h2>
+ ,
+ .
+ .
+<h2>
+<a NAME="WorkingDir"></a> </h2>
+ ,
+. .
+<p> gdb!
+ gdb <i>OK</i>.
+ .
+<h2>
+<a NAME="Environment"></a> </h2>
+ <tt>VARIABLE=value</tt>
+ <tt>VARIABLE</tt> <tt>value</tt>
+ <i></i>. ,
+ <i></i>. ,
+ ,
+ <i></i>.
+ <i></i>, !
+ .
+<p> Linux glibc2,
+ <tt>LD_BIND_NOW</tt>. ,
+ <tt>1</tt> .
+ , gdb ( )
+ , <tt>libc</tt>
+.
+</body>
+</html>
diff --git a/kdbg/doc/ru/breakptlist.html b/kdbg/doc/ru/breakptlist.html
new file mode 100644
index 0000000..b3007b3
--- /dev/null
+++ b/kdbg/doc/ru/breakptlist.html
@@ -0,0 +1,68 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> </h1>
+
+ .
+<i>| </i>.
+<h2> </h2>
+ :
+<ul>
+<li> ,</li>
+
+<li> ,</li>
+
+<li> , ,</li>
+
+<li> , .</li>
+</ul>
+ : -
+, - - , -
+ - .
+<p> .
+<h2> </h2>
+<a NAME="StopProg"></a> ,
+ . ,
+, ,
+ <i>|</i>.
+ , .
+ ,
+<i>|</i> .
+<p>
+ .
+ , ,
+
+<i> </i>.
+<p> , ,
+ <i></i> <i></i>.
+ -
+ , .
+<p>
+ , ,
+ . <i></i>
+ / .
+<h2> </h2>
+ , ,
+ .
+, .
+ . <a href="#StopProg"></a>.
+<p> ,
+ <i> </i>.
+ . , ,
+ ,
+ (
+ <i>|</i>).
+<p> ,
+<i></i>. ,
+
+ ().
+<p> ,
+ <i></i>.
+</body>
+</html>
diff --git a/kdbg/doc/ru/globaloptions.html b/kdbg/doc/ru/globaloptions.html
new file mode 100644
index 0000000..c82a73d
--- /dev/null
+++ b/kdbg/doc/ru/globaloptions.html
@@ -0,0 +1,72 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1>
+ </h1>
+
+<i>| </i>. :
+<ul>
+<li>
+, gdb,</li>
+
+<li>
+, ,</li>
+
+<li>
+ KDbg
+ ,</li>
+
+<li>
+ .</li>
+</ul>
+
+<h4>
+ gdb</h4>
+
+<blockquote> gdb,
+ <i> gdb</i>.
+ <tt>gdb --fullname
+--nx</tt>. , ,
+ gdb. , KDbg
+ . , ,
+ .</blockquote>
+
+<h4>
+ </h4>
+
+<blockquote>
+ ,
+<i> </i>. &#150;
+<tt>xterm -name kdbgio -title %T -e sh -c %C</tt>.
+ ,
+<tt>%T</tt> , <tt>%C</tt>
+ ,
+, .
+( <tt>sleep
+3600</tt>). \
+<tt>konsole --name kdbgio --caption %T -e sh -c %C</tt>.</blockquote>
+
+<h4>
+ </h4>
+
+<blockquote> KDbg ,
+ ( ).
+ KDbg ( KWM &150;
+KDE). ,
+ .
+</blockquote>
+
+<blockquote> , KDbg ,
+ ,
+. ,
+ , .
+</blockquote>
+
+</body>
+</html>
diff --git a/kdbg/doc/ru/howdoi.html b/kdbg/doc/ru/howdoi.html
new file mode 100644
index 0000000..1549702
--- /dev/null
+++ b/kdbg/doc/ru/howdoi.html
@@ -0,0 +1,78 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - ...?</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1>
+ ...?</h1>
+
+<h4>
+... ?</h4>
+ :
+<ul>
+<li> " ",
+ .</li>
+
+<li>
+ <i> </i>.</li>
+
+<li> <a href="breakptlist.html"> </a>.</li>
+</ul>
+ ,
+ . , .
+ <i>|</i>.
+ - , ,
+<i> </i> .
+<h4>... - ?</h4>
+ .
+<h4>
+... ?</h4>
+ <a href="breakptlist.html">
+ </a>.
+<h4>
+... ?</h4>
+ ,
+<i>| </i>, ,
+ <i>| </i>.
+<h4>
+... , ?</h4>
+ , .
+ KDbg <i>|</i>.
+ .
+<h4>
+... ,
+ , ?</h4>
+ <a href="breakptlist.html"> </a>
+; <i></i>
+ <i> </i>.
+<h4>
+... ?</h4>
+ <i>|</i>
+<a href="argspwdenv.html#Environment"> </a>.
+<h4>
+... ?</h4>
+ <i>|</i>
+<a href="argspwdenv.html#WorkingDir"> </a>.
+<h4>
+... ?</h4>
+ <i>|</i>
+<a href="pgmsettings.html#output"></a>.
+ <i> , </i>
+<i>OK</i>.
+ (
+<i>| </i>).
+ <a href="pgmoutput.html"> </a>,
+ <tt>/dev/null</tt>.
+<p>
+.
+<p><b><i>:</i></b> ,
+ ( )
+ (
+ ).
+ .
+</body>
+</html>
diff --git a/kdbg/doc/ru/index.html b/kdbg/doc/ru/index.html
new file mode 100644
index 0000000..08e0d88
--- /dev/null
+++ b/kdbg/doc/ru/index.html
@@ -0,0 +1,177 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+
+<h1>KDbg - </h1>
+
+<h2></h2>
+
+<ul>
+<li>
+<a href="#Introduction"></a></li>
+
+<li>
+<a href="#UsingKDbg"> KDbg</a></li>
+
+<li>
+<a href="#InfoWindows"> KDbg</a></li>
+
+<li>
+<a href="#Tips"> .</a></li>
+
+<li> : <a href="types.html"> </a></li>
+
+<li>
+<a href="#KnownProblems"> </a></li>
+
+<li>
+<a href="#Author"></a></li>
+</ul>
+
+<hr>
+<h2>
+<a NAME="Introduction"></a></h2>
+KDbg <tt>gdb</tt>, GNU.
+<p> , KDbg . ,
+ <tt>gdb</tt>, , ,
+ , , .
+ <tt>gdb</tt>,
+ - ,
+ .
+<p> - KDbg
+ <tt>gdb</tt>. KDbg ,
+<tt>gdb</tt>. , <tt>gdb</tt>
+ , KDbg
+( , ).
+
+<h2>
+<a NAME="UsingKDbg"></a> KDbg</h2>
+ KDbg
+ <a href="globaloptions.html"> </a>,
+ <i>| </i>.
+<h4> </h4>
+ <i>| </i>.
+ ,
+<i>| </i>. .
+<p> ,
+ , , ,
+ <i>| </i>. KDbg ,
+ .
+<p> ,
+<i>Breakpoint</i>, , ,
+<a href="breakptlist.html"> </a>.
+<p>
+ <a href="pgmsettings.html"> </a>,
+ <i>|</i>.
+
+<h4> </h4>
+ , <i>|</i>.
+ ,
+, ,
+ .
+<p> , ,
+ .
+<i>|</i>
+<a href="argspwdenv.html"> </a> ( ).
+<p> .
+ , .
+<i>|</i>.
+<i>OK</i>. ( ),
+ .
+
+<h4> - ?</h4>
+ ,
+, <a href="sourcecode.html"> </a>
+ . ,
+, ( <tt>SIGSEGV</tt>), ,
+ , .
+ <a href="stack.html"> </a> ,
+ ( ) .
+, .
+<p> <i></i> ,
+ , ,
+(<i></i>). , <i></i>
+<i></i>, ,
+ .
+<br><font size=-1> ,
+ ?</font>
+<p> <i> </i> , ,
+ .
+ <a href="breakptlist.html"> </a>.
+ ,
+ .
+ .
+<p> , gdb ,
+ . , KDbg
+ , , KDbg
+.
+<h2>
+<a NAME="InfoWindows"></a> KDbg</h2>
+KDbg .
+<i></i> .
+ , .
+
+<ul>
+<li>
+<a href="sourcecode.html"> </a></li>
+
+<li>
+<a href="localvars.html"> </a></li>
+
+<li>
+<a href="stack.html"> </a></li>
+
+<li>
+<a href="watches.html"> </a></li>
+
+<li>
+<a href="breakptlist.html"> </a></li>
+
+<li>
+<a href="pgmoutput.html"> </a></li>
+
+<li>
+<a href="registers.html"> </a></li>
+
+<li>
+<a href="memory.html"> </a></li>
+
+<li>
+<a href="threads.html"> </a></li>
+</ul>
+
+<h2>
+<a NAME="Tips"></a> .</h2>
+ KDbg.
+<ul>
+<li>
+<a href="tips.html"> </a></li>
+
+<li>
+<a href="howdoi.html"> ...?</a></li>
+</ul>
+
+<h2>
+<a NAME="KnownProblems"></a> </h2>
+gdb 4.16 ++ .
+( , CORBA.)
+ , KDbg , gdb
+. , .
+ gdb, <i>| </i>,
+ .
+<p> KDbg ,
+ .
+
+<h2>
+<a NAME="Author"></a></h2>
+KDbg <a href="mailto:j6t@kdbg.org">Johannes Sixt</a>
+ .
+<br> KDbg
+<a href="http://www.kdbg.org/">http://www.kdbg.org/</a>.
+</body>
+</html>
diff --git a/kdbg/doc/ru/localvars.html b/kdbg/doc/ru/localvars.html
new file mode 100644
index 0000000..31b9a8b
--- /dev/null
+++ b/kdbg/doc/ru/localvars.html
@@ -0,0 +1,19 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> </h1>
+ <i>|</i>.
+ ,
+ (stack frame).
+<p> (stack
+frame), .
+<p> , ,
+ .
+</body>
+</html>
diff --git a/kdbg/doc/ru/memory.html b/kdbg/doc/ru/memory.html
new file mode 100644
index 0000000..e8ba057
--- /dev/null
+++ b/kdbg/doc/ru/memory.html
@@ -0,0 +1,26 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> </h1>
+ <i>|</i>.
+ .
+<p> , .
+
+ .
+<p>
+ ,
+ .
+<p>
+ . ,
+ .
+<p> ,
+ ,
+&#150; .
+</body>
+</html>
diff --git a/kdbg/doc/ru/pgmoutput.html b/kdbg/doc/ru/pgmoutput.html
new file mode 100644
index 0000000..2a17c69
--- /dev/null
+++ b/kdbg/doc/ru/pgmoutput.html
@@ -0,0 +1,43 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> </h1>
+ , <i>|</i>.
+ .
+<p> -
+ : <tt>\n</tt> ( )
+ - , <tt>\r</tt> ( )
+. GUI ,
+
+.
+<p> ,
+<i></i>. KDbg ,
+ .
+ .
+ :
+<ol>
+<li>
+ <a href="pgmsettings.html"></a>
+ <i>|</i>.</li>
+
+<li> <i></i>.</li>
+
+<li> <i> , </i>
+ <i>OK</i>.</li>
+
+<li> <i>| </i>.</li>
+</ol>
+ <i></i> ,
+ .
+<p> ,
+ ,
+ . ,
+ .
+</body>
+</html>
diff --git a/kdbg/doc/ru/pgmsettings.html b/kdbg/doc/ru/pgmsettings.html
new file mode 100644
index 0000000..ca14b4b
--- /dev/null
+++ b/kdbg/doc/ru/pgmsettings.html
@@ -0,0 +1,73 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> </h1>
+ .
+ <i>|</i>.
+
+.
+<blockquote><b><i> :</i></b>
+ KDbg. ,
+ <i>OK</i>
+ <i>| </i>!!</blockquote>
+
+<ul>
+<li>
+<a href="#driver"></a></li>
+
+<li>
+<a href="#output"></a></li>
+</ul>
+
+<h2>
+<a NAME="driver"></a></h2>
+ , .
+<h4> GDB</h4>
+
+<blockquote> gdb.
+gdb ,
+<a href="globaloptions.html"> </a>.
+- ,
+ gdb, .
+<tt>gdb --fullname --nx</tt>.
+ . , KDbg .
+</blockquote>
+
+<h2>
+<a NAME="output"></a></h2>
+ ,
+ .
+<h4> </h4>
+
+<blockquote> ,
+ ,
+ . (<tt>stdin</tt>, <tt>stdout</tt>
+<tt>stderr</tt>) <tt>/dev/null</tt>.</blockquote>
+
+<h4> , </h4>
+
+<blockquote> ,
+ (<tt>stdin</tt> <tt>/dev/null</tt>),
+(<tt>stdout</tt> <tt>stderr</tt>) .
+ <i> </i>.
+
+<br><i>:</i>
+ <tt>\n</tt> (ASCII 10) . <i></i>
+ <tt>\r</tt> (ASCII 13).
+ ,
+ , .</blockquote>
+
+<h4> </h4>
+
+<blockquote> ,
+<tt>stdin</tt>, <tt>stdout</tt> or <tt>stderr</tt>
+ . ,
+ <a href="globaloptions.html"> </a>.</blockquote>
+</body>
+</html>
diff --git a/kdbg/doc/ru/registers.html b/kdbg/doc/ru/registers.html
new file mode 100644
index 0000000..eb5c216
--- /dev/null
+++ b/kdbg/doc/ru/registers.html
@@ -0,0 +1,31 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> </h1>
+ , ,
+KDbg . ,
+ , <i>|</i>.
+<p> 3 :
+<ol>
+<li> <i></i> .</li>
+
+<li> <i></i>
+ .
+, .</li>
+
+<li> <i> </i>
+ .
+ ,
+&#150; ,
+.</li>
+</ol>
+ ,
+ .
+</body>
+</html>
diff --git a/kdbg/doc/ru/sourcecode.html b/kdbg/doc/ru/sourcecode.html
new file mode 100644
index 0000000..fba5f3b
--- /dev/null
+++ b/kdbg/doc/ru/sourcecode.html
@@ -0,0 +1,31 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> </h1>
+ .
+<p> .
+ " ".
+ ,
+, ,
+ .
+<p>
+" ".
+ .
+<p> '+' " "
+ .
+. ,
+ '-'.
+<p> .
+ ,
+ <i> </i>
+ <i>| </i>.
+<p> ,
+ <i></i>.
+</body>
+</html>
diff --git a/kdbg/doc/ru/stack.html b/kdbg/doc/ru/stack.html
new file mode 100644
index 0000000..082ba9b
--- /dev/null
+++ b/kdbg/doc/ru/stack.html
@@ -0,0 +1,23 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> </h1>
+ <i>|</i>.
+ (stack frames), , , ,
+ .
+<p> () ( )
+ .
+<p> ,
+. <a href="sourcecode.html"> </a>
+ , ,
+<a href="localvars.html"> </a>
+<a href="watches.html"> </a> ,
+ .
+</body>
+</html>
diff --git a/kdbg/doc/ru/threads.html b/kdbg/doc/ru/threads.html
new file mode 100644
index 0000000..674c309
--- /dev/null
+++ b/kdbg/doc/ru/threads.html
@@ -0,0 +1,38 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> </h1>
+ , <i>|</i>.
+ .
+<p><b><i>:</i></b>
+ gdb - KDbg.
+Linux- gdb5.
+<p>
+. (.. <i></i>
+ .)
+<p> ,
+ .
+<p> <i></i> :
+<ul>
+<li>
+<a href="stack.html"> </a> .
+</li>
+
+<li><a href="localvars.html"> </a>
+ .</li>
+
+<li><a href="watches.html"> </a>
+ .</li>
+</ul>
+ ,
+ . ,
+<a href="sourcecode.html"> </a> ,
+ .
+</body>
+</html>
diff --git a/kdbg/doc/ru/tips.html b/kdbg/doc/ru/tips.html
new file mode 100644
index 0000000..7739496
--- /dev/null
+++ b/kdbg/doc/ru/tips.html
@@ -0,0 +1,43 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> </h1>
+
+<ul>
+<li> <tt>LD_BIND_NOW=1</tt>
+, glibc2.
+
+
+<a href="argspwdenv.html#Environment"></a>.</li>
+
+<li> , :
+ . ,
+ (
+ <i> </i>). ..
+ (.. KDbg
+),
+ .
+</li>
+
+<li> :
+ ( ) <tt>var.member=17</tt>
+ <i></i>.
+. (
+ <i></i>). ,
+
+ !</li>
+
+<li> ,
+ gdb . ,
+<tt>/x var.member</tt> <tt>var.member</tt>
+.</li>
+</ul>
+
+</body>
+</html>
diff --git a/kdbg/doc/ru/types.html b/kdbg/doc/ru/types.html
new file mode 100644
index 0000000..7df4271
--- /dev/null
+++ b/kdbg/doc/ru/types.html
@@ -0,0 +1,126 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> KDbg</h1>
+KDbg
+,
+<a href="localvars.html"> </a>
+<a href="watches.html"> </a>. ,
+ , <i> </i>.
+ .
+<p> KDbg
+<tt>$KDEDIR/share/apps/kdbg/types</tt>.
+<tt>.kdbgtt</tt>. , <tt>libqt.so</tt>
+<tt>qt.kdbgtt</tt>.
+<p>
+KDE. :
+<ul>
+<li>
+ <tt>[Type Table]</tt>, ,
+ , .</li>
+
+<li> , ,
+ KDbg .</li>
+</ul>
+ , , KDbg
+ , .
+
+<tt>ShlibRE</tt>. ,
+ . ,
+, .
+<h2> <tt>[Type Table]</tt></h2>
+ :
+<ul>
+<li>
+<tt>Types1</tt>, <tt>Types2</tt>, . .
+ .
+ . (
+ ,
+.) .
+ (KDbg ),
+ (.. ).
+ (. <tt>Alias</tt> ).
+</li>
+
+<li>
+<tt>ShlibRE</tt>. KDbg ,
+ . KDbg
+ , .
+ , .
+ Qt (
+<tt>.*?[]^$\</tt> ,
+ .)</li>
+
+<li>
+<tt>LibDisplayName</tt>. ,
+ .</li>
+
+<br><font size=-1> .</font></ul>
+
+<h2> </h2>
+ , .
+<font size=-1> ++ .</font>
+ :
+<ul>
+<li>
+<tt>Display</tt> , KDbg .
+ 1 5 '<tt>%</tt>'.
+ , <tt>Expr</tt><i>x</i>.</li>
+
+<li> <tt>Expr1</tt>, <tt>Expr2</tt>, .
+ <b> </b> <tt>%s</tt>,
+ , .
+ gdb,
+ <tt>Display</tt>.</li>
+
+<li>
+<tt>Alias</tt> -. ,
+ , , .
+-
+<tt>Types</tt><i>x</i> <tt>[Type Table]</tt>.</li>
+</ul>
+<font size=-1>
+. ,
+ - .</font>
+<p>KDbg ,
+ Qt 2.0 unicode: <tt>Expr</tt><i>x</i>
+<tt>/QString::Data</tt>, ,
+ <tt>QString::Data</tt>.
+unicode, <tt>QString::Data</tt> (
+<tt>QString::null</tt>, Qt, <tt>(null)</tt>,
+<tt>unicode</tt> ). .
+<tt>qt2.kdbgtt</tt>.
+
+<p>: ,
+ - KDbg
+ () .
+ <tt>Alias</tt>
+ , .
+<h2></h2>
+ , <tt>QString</tt> <tt>QObject</tt>
+<tt>qt.kdbgtt</tt>. <tt>QTableView</tt>,
+ <tt>QObject</tt>. Qt 1.x,
+ , <tt>libqt.so.1</tt>.
+<pre>[Type Table]
+Types1=QString
+Types2=QObject,QTableView
+LibDisplayName=libqt 1.x
+ShlibRE=libqt\.so\.1$
+[QString]
+Display={ % }
+Expr1=(%s).shd->data
+[QObject]
+Display={ name=% #chld=% }
+Expr1=(%s).objname
+Expr2=(%s).childObjects->numNodes
+[QTableView]
+Alias=QObject</pre>
+: <tt>%s</tt> .
+</body>
+</html>
diff --git a/kdbg/doc/ru/watches.html b/kdbg/doc/ru/watches.html
new file mode 100644
index 0000000..0953b7c
--- /dev/null
+++ b/kdbg/doc/ru/watches.html
@@ -0,0 +1,20 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
+ <meta name="Author" content="Johannes Sixt">
+ <title>KDbg - - </title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#51188E" alink="#FF0000">
+<a href="index.html"></a>
+<h1> </h1>
+
+<i>| </i>. .
+<p> , Enter
+ <i></i>. ,
+( ?) <i>Del</i>.
+<p> .
+ , , ..
+ .
+</body>
+</html>
diff --git a/kdbg/envvar.h b/kdbg/envvar.h
new file mode 100644
index 0000000..20339b2
--- /dev/null
+++ b/kdbg/envvar.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef ENVVAR_H
+#define ENVVAR_H
+
+/*
+ * Description of environment variables. Note that the name of the variable
+ * is given as the key in the QDict, so we don't repeat it here.
+ */
+
+class QListViewItem;
+
+struct EnvVar {
+ QString value;
+ enum EnvVarStatus { EVclean, EVdirty, EVnew, EVdeleted };
+ EnvVarStatus status;
+ QListViewItem* item;
+};
+
+#endif // ENVVAR_H
diff --git a/kdbg/exprwnd.cpp b/kdbg/exprwnd.cpp
new file mode 100644
index 0000000..fc0fc8b
--- /dev/null
+++ b/kdbg/exprwnd.cpp
@@ -0,0 +1,831 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "exprwnd.h"
+#include "exprwnd.moc"
+#include "typetable.h"
+#include <qstringlist.h>
+#include <qpainter.h>
+#include <qscrollbar.h>
+#include <kapplication.h>
+#include <kiconloader.h> /* icons */
+#include <klocale.h> /* i18n */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "mydebug.h"
+
+VarTree::VarTree(VarTree* parent, QListViewItem* after, ExprValue* v) :
+ QListViewItem(parent, after),
+ m_varKind(v->m_varKind),
+ m_nameKind(v->m_nameKind),
+ m_type(0),
+ m_exprIndex(0),
+ m_exprIndexUseGuard(false),
+ m_baseValue(v->m_value),
+ m_baseChanged(false),
+ m_structChanged(false)
+{
+ QListViewItem::setText(0, v->m_name);
+ updateValueText();
+ setExpandable(m_varKind == VarTree::VKpointer);
+ setOpen(v->m_initiallyExpanded);
+}
+
+VarTree::VarTree(ExprWnd* parent, QListViewItem* after, const QString& name) :
+ QListViewItem(parent, after),
+ m_varKind(VKsimple),
+ m_nameKind(VarTree::NKplain),
+ m_type(0),
+ m_exprIndex(0),
+ m_exprIndexUseGuard(false),
+ m_baseChanged(false),
+ m_structChanged(false)
+{
+ QListViewItem::setText(0, name);
+}
+
+VarTree::~VarTree()
+{
+}
+
+void VarTree::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
+{
+ if (column == 1 && (m_baseChanged || m_structChanged)) {
+ QColorGroup cgChg = cg;
+ cgChg.setColor(QColorGroup::Text, Qt::red);
+ QListViewItem::paintCell(p, cgChg, column, width, align);
+ } else {
+ QListViewItem::paintCell(p, cg, column, width, align);
+ }
+}
+
+QString VarTree::computeExpr() const
+{
+ // top-level items are special
+ if (isToplevelExpr())
+ return getText();
+
+ // get parent expr
+ VarTree* par = static_cast<VarTree*>(parent());
+ QString parentExpr = par->computeExpr();
+
+ // skip this item's name if it is a base class or anonymous struct or union
+ if (m_nameKind == NKtype || m_nameKind == NKanonymous) {
+ return parentExpr;
+ }
+ /* augment by this item's text */
+ QString result;
+ /* if this is an address, dereference it */
+ if (m_nameKind == NKaddress) {
+ ASSERT(par->m_varKind == VKpointer);
+ result = "*" + parentExpr;
+ return result;
+ }
+ switch (par->m_varKind) {
+ case VKarray:
+ {
+ QString index = getText();
+ int i = 1;
+ // skip past the index
+ while (index[i].isDigit())
+ i++;
+ /*
+ * Some array indices are actually ranges due to repeated array
+ * values. We use the first index in these cases.
+ */
+ if (index[i] != ']') {
+ // remove second index
+ index.remove(i, index.length()-i-1);
+ }
+ result = "(" + parentExpr + ")" + index;
+ }
+ break;
+ case VKstruct:
+ result = "(" + parentExpr + ")." + getText();
+ break;
+ case VKsimple: /* parent can't be simple */
+ case VKpointer: /* handled in NKaddress */
+ case VKdummy: /* can't occur at all */
+ ASSERT(false);
+ result = parentExpr; /* paranoia */
+ break;
+ }
+ return result;
+}
+
+bool VarTree::isToplevelExpr() const
+{
+ return parent() == 0;
+}
+
+bool VarTree::isAncestorEq(const VarTree* child) const
+{
+ const QListViewItem* c = child;
+ while (c != 0 && c != this) {
+ c = c->parent();
+ }
+ return c != 0;
+}
+
+bool VarTree::updateValue(const QString& newValue)
+{
+ // check whether the value changed
+ bool prevValueChanged = m_baseChanged;
+ if ((m_baseChanged = m_baseValue != newValue)) {
+ m_baseValue = newValue;
+ updateValueText();
+ }
+ /*
+ * We must repaint the cell if the value changed. If it did not change,
+ * we still must repaint the cell if the value changed previously,
+ * because the color of the display must be changed (from red to
+ * black).
+ */
+ return m_baseChanged || prevValueChanged;
+}
+
+bool VarTree::updateStructValue(const QString& newValue)
+{
+ // check whether the value changed
+ bool prevValueChanged = m_structChanged;
+ if ((m_structChanged = m_structValue != newValue)) {
+ m_structValue = newValue;
+ updateValueText();
+ }
+ /*
+ * We must repaint the cell if the value changed. If it did not change,
+ * we still must repaint the cell if the value changed previously,
+ * because the color of the display must be changed (from red to
+ * black).
+ */
+ return m_structChanged || prevValueChanged;
+}
+
+void VarTree::updateValueText()
+{
+ if (m_baseValue.isEmpty()) {
+ QListViewItem::setText(1, m_structValue);
+ } else if (m_structValue.isEmpty()) {
+ QListViewItem::setText(1, m_baseValue);
+ } else {
+ QListViewItem::setText(1, m_baseValue + " " + m_structValue);
+ }
+}
+
+void VarTree::inferTypesOfChildren(ProgramTypeTable& typeTable)
+{
+ /*
+ * Type inference works like this: We use type information of those
+ * children that have a type name in their name (base classes) or in
+ * their value (pointers)
+ */
+
+ // first recurse children
+ VarTree* child = firstChild();
+ while (child != 0) {
+ child->inferTypesOfChildren(typeTable);
+ child = child->nextSibling();
+ }
+
+ // if this is a pointer, get the type from the value (less the pointer)
+ if (m_varKind == VKpointer) {
+ if (isWcharT())
+ {
+ /*
+ * wchart_t pointers must be treated as struct, because the array
+ * of characters is printed similar to how QStrings are decoded.
+ */
+ m_varKind = VKstruct;
+ setExpandable(false);
+ }
+ // don't know how to do this cleanly
+ } else if (m_varKind == VKstruct) {
+ // check if this is a base class part
+ if (m_nameKind == NKtype) {
+ const QString& typeName =
+ getText().mid(1, getText().length()-2); // strip < and >
+ m_type = typeTable.lookup(typeName);
+
+ /* if we don't have a type yet, get it from the base class */
+ if (m_type == 0) {
+ m_type = inferTypeFromBaseClass();
+ /*
+ * If there is a known type now, it is the one from the
+ * first base class whose type we know.
+ */
+ }
+
+ /*
+ * If we still don't have a type, the type is really unknown.
+ */
+ if (m_type == 0) {
+ m_type = TypeInfo::unknownType();
+ }
+ } // else
+ /*
+ * This is not a base class part. We don't assign a type so
+ * that later we can ask gdb.
+ */
+ }
+}
+
+// the value contains the pointer type in parenthesis
+bool VarTree::isWcharT() const
+{
+ return value().startsWith("(const wchar_t *)") ||
+ value().startsWith("(wchar_t *)");
+}
+
+/*
+ * Get the type of the first base class whose type we know.
+ */
+TypeInfo* VarTree::inferTypeFromBaseClass()
+{
+ if (m_varKind == VKstruct) {
+ VarTree* child = firstChild();
+ while (child != 0 &&
+ // only check base class parts (i.e. type names)
+ child->m_nameKind == NKtype)
+ {
+ if (child->m_type != 0 &&
+ child->m_type != TypeInfo::unknownType())
+ {
+ // got a type!
+ return child->m_type;
+ }
+ child = child->nextSibling();
+ }
+ }
+ return 0;
+}
+
+ExprValue::ExprValue(const QString& name, VarTree::NameKind aKind) :
+ m_name(name),
+ m_varKind(VarTree::VKsimple),
+ m_nameKind(aKind),
+ m_child(0),
+ m_next(0),
+ m_initiallyExpanded(false)
+{
+}
+
+ExprValue::~ExprValue()
+{
+ delete m_child;
+ delete m_next;
+}
+
+void ExprValue::appendChild(ExprValue* newChild)
+{
+ if (m_child == 0) {
+ m_child = newChild;
+ } else {
+ // walk chain of children to find the last one
+ ExprValue* last = m_child;
+ while (last->m_next != 0)
+ last = last->m_next;
+ last->m_next = newChild;
+ }
+ newChild->m_next = 0; // just to be sure
+}
+
+int ExprValue::childCount() const
+{
+ int i = 0;
+ ExprValue* c = m_child;
+ while (c) {
+ ++i;
+ c = c->m_next;
+ }
+ return i;
+}
+
+
+
+ExprWnd::ExprWnd(QWidget* parent, const QString& colHeader, const char* name) :
+ QListView(parent, name),
+ m_edit(0)
+{
+ addColumn(colHeader);
+ addColumn(i18n("Value"));
+ setSorting(-1); // do not sort items
+ setColumnWidthMode(0, Manual);
+ setColumnWidthMode(1, Maximum);
+ setRootIsDecorated(true);
+ setAllColumnsShowFocus(true);
+
+ m_pixPointer = UserIcon("pointer.xpm");
+ if (m_pixPointer.isNull())
+ TRACE("Can't load pointer.xpm");
+}
+
+ExprWnd::~ExprWnd()
+{
+}
+
+QStringList ExprWnd::exprList() const
+{
+ QStringList exprs;
+ VarTree* item;
+ for (item = firstChild(); item != 0; item = item->nextSibling()) {
+ exprs.append(item->getText());
+ }
+ return exprs;
+}
+
+VarTree* ExprWnd::insertExpr(ExprValue* expr, ProgramTypeTable& typeTable)
+{
+ // append a new dummy expression
+ VarTree* last = 0; // last top-level item
+ for (VarTree* i = firstChild(); i != 0; i = i->nextSibling()) {
+ last = i;
+ }
+ VarTree* display = new VarTree(this, last, expr->m_name);
+
+ // replace it right away
+ updateExpr(display, expr, typeTable);
+ return display;
+}
+
+void ExprWnd::updateExpr(ExprValue* expr, ProgramTypeTable& typeTable)
+{
+ // search the root variable
+ VarTree* item = firstChild();
+ while (item != 0 && item->getText() != expr->m_name)
+ item = item->nextSibling();
+ if (item == 0) {
+ return;
+ }
+ // now update it
+ updateExprRec(item, expr, typeTable);
+ collectUnknownTypes(item);
+}
+
+void ExprWnd::updateExpr(VarTree* display, ExprValue* newValues, ProgramTypeTable& typeTable)
+{
+ updateExprRec(display, newValues, typeTable);
+ collectUnknownTypes(display);
+}
+
+/*
+ * returns true if there's a visible change
+ */
+void ExprWnd::updateExprRec(VarTree* display, ExprValue* newValues, ProgramTypeTable& typeTable)
+{
+ bool isExpanded = display->isOpen();
+
+ /*
+ * If we are updating a pointer without children by a dummy, we don't
+ * collapse it, but simply insert the new children. This happens when a
+ * pointer has just been expanded by the user.
+ */
+ if (display->m_varKind == VarTree::VKpointer &&
+ display->childCount() == 0 &&
+ newValues->m_varKind == VarTree::VKdummy)
+ {
+ replaceChildren(display, newValues);
+ return;
+ }
+
+ /*
+ * If the display and newValues have different kind or if their number
+ * of children is different, replace the whole sub-tree.
+ */
+ if (// the next two lines mean: not(m_varKind remains unchanged)
+ !(newValues->m_varKind == VarTree::VKdummy ||
+ display->m_varKind == newValues->m_varKind)
+ ||
+ (display->childCount() != newValues->childCount() &&
+ /*
+ * If this is a pointer and newValues doesn't have children, we
+ * don't replace the sub-tree; instead, below we mark this
+ * sub-tree for requiring an update.
+ */
+ (display->m_varKind != VarTree::VKpointer ||
+ newValues->m_child != 0)))
+ {
+ if (isExpanded) {
+ display->setOpen(false);
+ }
+
+ // since children changed, it is likely that the type has also changed
+ display->m_type = 0; /* will re-evaluate the type */
+
+ // display the new value
+ updateSingleExpr(display, newValues);
+ replaceChildren(display, newValues);
+
+ // update the m_varKind
+ if (newValues->m_varKind != VarTree::VKdummy) {
+ display->m_varKind = newValues->m_varKind;
+ display->setExpandable(newValues->m_varKind == VarTree::VKpointer);
+ }
+
+ // get some types (after the new m_varKind has been set!)
+ display->inferTypesOfChildren(typeTable);
+
+ // (note that the new value might not have a sub-tree at all)
+ return;
+ }
+
+ // display the new value
+ updateSingleExpr(display, newValues);
+
+ /*
+ * If this is an expanded pointer, record it for being updated.
+ */
+ if (display->m_varKind == VarTree::VKpointer) {
+ if (isExpanded &&
+ // if newValues is a dummy, we have already updated this pointer
+ newValues->m_varKind != VarTree::VKdummy)
+ {
+ m_updatePtrs.push_back(display);
+ }
+ /*
+ * If the visible sub-tree has children, but newValues doesn't, we
+ * can stop here.
+ */
+ if (newValues->m_child == 0) {
+ return;
+ }
+ }
+
+ ASSERT(display->childCount() == newValues->childCount());
+
+ // go for children
+ VarTree* vDisplay = display->firstChild();
+ ExprValue* vNew = newValues->m_child;
+ while (vDisplay != 0) {
+ // check whether the names are the same
+ if (vDisplay->getText() != vNew->m_name) {
+ // set new name
+ vDisplay->setText(vNew->m_name);
+ }
+ // recurse
+ updateExprRec(vDisplay, vNew, typeTable);
+
+ vDisplay = vDisplay->nextSibling();
+ vNew = vNew->m_next;
+ }
+}
+
+void ExprWnd::updateSingleExpr(VarTree* display, ExprValue* newValue)
+{
+ /*
+ * If newValues is a VKdummy, we are only interested in its children.
+ * No need to update anything here.
+ */
+ if (newValue->m_varKind == VarTree::VKdummy) {
+ return;
+ }
+
+ /*
+ * If this node is a struct and we know its type then we know how to
+ * find a nested value. So register the node for an update.
+ *
+ * wchar_t types are also treated specially here: We consider them
+ * as struct (has been set in inferTypesOfChildren()).
+ */
+ if (display->m_varKind == VarTree::VKstruct &&
+ display->m_type != 0 &&
+ display->m_type != TypeInfo::unknownType())
+ {
+ ASSERT(newValue->m_varKind == VarTree::VKstruct);
+ if (display->m_type == TypeInfo::wchartType())
+ {
+ display->m_partialValue = "L";
+ }
+ else
+ display->m_partialValue = display->m_type->m_displayString[0];
+ m_updateStruct.push_back(display);
+ }
+
+ if (display->updateValue(newValue->m_value)) {
+ triggerUpdate();
+ }
+}
+
+void ExprWnd::updateStructValue(VarTree* display)
+{
+ ASSERT(display->m_varKind == VarTree::VKstruct);
+
+ if (display->updateStructValue(display->m_partialValue)) {
+ triggerUpdate();
+ }
+ // reset the value
+ display->m_partialValue = "";
+ display->m_exprIndex = -1;
+}
+
+void ExprWnd::replaceChildren(VarTree* display, ExprValue* newValues)
+{
+ ASSERT(display->childCount() == 0 || display->m_varKind != VarTree::VKsimple);
+
+ // delete all children of display
+ while (VarTree* c = display->firstChild()) {
+ unhookSubtree(c);
+ delete c;
+ }
+ // insert copies of the newValues
+ VarTree* vNew = 0;
+ for (ExprValue* v = newValues->m_child; v != 0; v = v->m_next)
+ {
+ vNew = new VarTree(display, vNew, v);
+ // recurse
+ replaceChildren(vNew, v);
+ }
+}
+
+void ExprWnd::collectUnknownTypes(VarTree* var)
+{
+ QListViewItemIterator i(var);
+ for (; i.current(); ++i)
+ {
+ checkUnknownType(static_cast<VarTree*>(i.current()));
+ }
+}
+
+void ExprWnd::checkUnknownType(VarTree* var)
+{
+ ASSERT(var->m_varKind != VarTree::VKpointer || var->m_nameKind != VarTree::NKtype);
+ if (var->m_type == 0 &&
+ var->m_varKind == VarTree::VKstruct &&
+ var->m_nameKind != VarTree::NKtype &&
+ var->m_nameKind != VarTree::NKanonymous)
+ {
+ if (!var->isWcharT())
+ {
+ /* this struct node doesn't have a type yet: register it */
+ m_updateType.push_back(var);
+ }
+ else
+ {
+ var->m_type = TypeInfo::wchartType();
+ var->m_partialValue = "L";
+ m_updateStruct.push_back(var);
+ }
+ }
+ // add pointer pixmap to pointers
+ if (var->m_varKind == VarTree::VKpointer) {
+ var->setPixmap(m_pixPointer);
+ }
+}
+
+QString ExprWnd::formatWCharPointer(QString value)
+{
+ int pos = value.find(") ");
+ if (pos > 0)
+ value = value.mid(pos+2);
+ return value + " L";
+}
+
+
+VarTree* ExprWnd::topLevelExprByName(const QString& name) const
+{
+ VarTree* item = firstChild();
+ while (item != 0 && item->getText() != name)
+ item = item->nextSibling();
+
+ return item;
+}
+
+VarTree* ExprWnd::ptrMemberByName(VarTree* v, const QString& name)
+{
+ // v must be a pointer variable, must have children
+ if (v->m_varKind != VarTree::VKpointer || v->childCount() == 0)
+ return 0;
+
+ // the only child of v is the pointer value that represents the struct
+ VarTree* item = v->firstChild();
+ return memberByName(item, name);
+}
+
+VarTree* ExprWnd::memberByName(VarTree* v, const QString& name)
+{
+ // search immediate children for name
+ VarTree* item = v->firstChild();
+ while (item != 0 && item->getText() != name)
+ item = item->nextSibling();
+
+ if (item != 0)
+ return item;
+
+ // try in base classes and members that are anonymous structs or unions
+ item = v->firstChild();
+ while (item != 0)
+ {
+ if (item->m_nameKind == VarTree::NKtype ||
+ item->m_nameKind == VarTree::NKanonymous)
+ {
+ v = memberByName(item, name);
+ if (v != 0)
+ return v;
+ }
+ item = item->nextSibling();
+ }
+ return 0;
+}
+
+void ExprWnd::removeExpr(VarTree* item)
+{
+ unhookSubtree(item);
+
+ delete item;
+}
+
+void ExprWnd::unhookSubtree(VarTree* subTree)
+{
+ // must remove any pointers scheduled for update from the list
+ unhookSubtree(m_updatePtrs, subTree);
+ unhookSubtree(m_updateType, subTree);
+ unhookSubtree(m_updateStruct, subTree);
+ emit removingItem(subTree);
+}
+
+void ExprWnd::unhookSubtree(std::list<VarTree*>& list, VarTree* subTree)
+{
+ if (subTree == 0)
+ return;
+
+ std::list<VarTree*>::iterator i = list.begin();
+ while (i != list.end()) {
+ std::list<VarTree*>::iterator checkItem = i;
+ ++i;
+ if (subTree->isAncestorEq(*checkItem)) {
+ // checkItem is an item from subTree
+ list.erase(checkItem);
+ }
+ }
+}
+
+void ExprWnd::clearPendingUpdates()
+{
+ m_updatePtrs.clear();
+ m_updateType.clear();
+ m_updateStruct.clear();
+}
+
+VarTree* ExprWnd::nextUpdatePtr()
+{
+ VarTree* ptr = 0;
+ if (!m_updatePtrs.empty()) {
+ ptr = m_updatePtrs.front();
+ m_updatePtrs.pop_front();
+ }
+ return ptr;
+}
+
+VarTree* ExprWnd::nextUpdateType()
+{
+ VarTree* ptr = 0;
+ if (!m_updateType.empty()) {
+ ptr = m_updateType.front();
+ m_updateType.pop_front();
+ }
+ return ptr;
+}
+
+VarTree* ExprWnd::nextUpdateStruct()
+{
+ VarTree* ptr = 0;
+ if (!m_updateStruct.empty()) {
+ ptr = m_updateStruct.front();
+ m_updateStruct.pop_front();
+ }
+ return ptr;
+}
+
+
+void ExprWnd::editValue(VarTree* item, const QString& text)
+{
+ if (m_edit == 0)
+ m_edit = new ValueEdit(this);
+
+ QRect r = itemRect(item);
+ int x = r.x()+columnWidth(0);
+ int y = r.y();
+ int w = columnWidth(1);
+ int h = r.height();
+ QListView* lv = item->listView();
+
+ /*
+ * Make the edit widget at least 5 characters wide (but not wider than
+ * this widget). If less than half of this widget is used to display
+ * the text, scroll this widget so that half of it shows the text (or
+ * less than half of it if the text is shorter).
+ */
+ QFontMetrics metr = m_edit->font();
+ int wMin = metr.width("88888");
+ if (w < wMin)
+ w = wMin;
+ int wThis = lv->visibleWidth();
+ if (x >= wThis/2 && // less than half the width displays text
+ x+w > wThis) // not all text is visible
+ {
+ // scroll so that more text is visible
+ int wScroll = QMIN(x-wThis/2, x+w-wThis);
+ lv->scrollBy(wScroll, 0);
+ x -= wScroll;
+ }
+ else if (x < 0)
+ {
+ // don't let the edit move out at the left
+ x = 0;
+ }
+
+ // make the edit box as wide as the visible column
+ QRect rect(x,y, wThis-x,h);
+ m_edit->setText(text);
+ m_edit->selectAll();
+
+ m_edit->setGeometry(rect);
+ m_edit->m_finished = false;
+ m_edit->m_item = item;
+ m_edit->show();
+ m_edit->setFocus();
+}
+
+bool ExprWnd::isEditing() const
+{
+ return m_edit != 0 && m_edit->isVisible();
+}
+
+
+ValueEdit::ValueEdit(ExprWnd* parent) :
+ QLineEdit(parent->viewport(), "valueedit")
+{
+ setFrame(false);
+ hide();
+ lower(); // lower the window below scrollbars
+ connect(parent, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
+ connect(parent, SIGNAL(currentChanged(QListViewItem*)), SLOT(slotSelectionChanged()));
+ connect(parent, SIGNAL(expanded(QListViewItem*)), SLOT(slotSelectionChanged()));
+ connect(parent, SIGNAL(collapsed(QListViewItem*)), SLOT(slotSelectionChanged()));
+ connect(this, SIGNAL(done(VarTree*, const QString&)),
+ parent, SIGNAL(editValueCommitted(VarTree*, const QString&)));
+}
+
+ValueEdit::~ValueEdit()
+{
+}
+
+void ValueEdit::terminate(bool commit)
+{
+ TRACE(commit?"ValueEdit::terminate(true)":"ValueEdit::terminate(false)");
+ if (!m_finished)
+ {
+ m_finished = true;
+ hide(); // will call focusOutEvent, that's why we need m_finished
+ if (commit) {
+ emit done(m_item, text());
+ }
+ }
+}
+
+void ValueEdit::keyPressEvent(QKeyEvent *e)
+{
+ if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter)
+ terminate(true);
+ else if(e->key() == Qt::Key_Escape)
+ terminate(false);
+ else
+ QLineEdit::keyPressEvent(e);
+}
+
+void ValueEdit::paintEvent(QPaintEvent* e)
+{
+ QLineEdit::paintEvent(e);
+
+ QPainter p(this);
+ p.drawRect(rect());
+}
+
+void ValueEdit::focusOutEvent(QFocusEvent* ev)
+{
+ TRACE("ValueEdit::focusOutEvent");
+ QFocusEvent* focusEv = static_cast<QFocusEvent*>(ev);
+ if (focusEv->reason() == QFocusEvent::ActiveWindow)
+ {
+ // Switching to a different window should terminate the edit,
+ // because if the window with this variable display is floating
+ // then that different window could be the main window, where
+ // the user had clicked one of the Execute buttons. This in turn
+ // may pull the item away that we are editing here.
+ terminate(false);
+ }
+ // Don't let a RMB close the editor
+ else if (focusEv->reason() != QFocusEvent::Popup)
+ {
+ terminate(true);
+ }
+}
+
+void ValueEdit::slotSelectionChanged()
+{
+ TRACE("ValueEdit::slotSelectionChanged");
+ terminate(false);
+}
diff --git a/kdbg/exprwnd.h b/kdbg/exprwnd.h
new file mode 100644
index 0000000..6281296
--- /dev/null
+++ b/kdbg/exprwnd.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef EXPRWND_H
+#define EXPRWND_H
+
+#include "qlistview.h"
+#include <qlineedit.h>
+#include <qpixmap.h>
+#include <list>
+
+class ProgramTypeTable;
+class TypeInfo;
+struct ExprValue;
+class ExprWnd;
+class QStringList;
+
+/*! \brief a variable's value is the tree of sub-variables */
+class VarTree : public QListViewItem
+{
+public:
+ enum VarKind { VKsimple, VKpointer, VKstruct, VKarray,
+ VKdummy //!< used to update only children
+ };
+ VarKind m_varKind;
+ enum NameKind { NKplain, NKstatic, NKtype,
+ NKanonymous, //!< an anonymous struct or union
+ NKaddress //!< a dereferenced pointer
+ };
+ NameKind m_nameKind;
+ TypeInfo* m_type; //!< the type of struct if it could be derived
+ int m_exprIndex; //!< used in struct value update
+ bool m_exprIndexUseGuard; //!< ditto; if guard expr should be used
+ QString m_partialValue; //!< while struct value update is in progress
+
+ VarTree(VarTree* parent, QListViewItem* after, ExprValue* v);
+ VarTree(ExprWnd* parent, QListViewItem* after, const QString& name);
+ virtual ~VarTree();
+public:
+ virtual void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
+ QString computeExpr() const;
+ bool isToplevelExpr() const;
+ /** is this element an ancestor of (or equal to) child? */
+ bool isAncestorEq(const VarTree* child) const;
+ /** update the regular value; returns whether a repaint is necessary */
+ bool updateValue(const QString& newValue);
+ /** update the "quick member" value; returns whether repaint is necessary */
+ bool updateStructValue(const QString& newValue);
+ /** find out the type of this value using the child values */
+ void inferTypesOfChildren(ProgramTypeTable& typeTable);
+ /** get the type from base class part */
+ TypeInfo* inferTypeFromBaseClass();
+ /** returns whether the pointer is a wchar_t */
+ bool isWcharT() const;
+
+ QString getText() const { return text(0); }
+ void setText(const QString& t) { QListViewItem::setText(0, t); }
+ void setPixmap(const QPixmap& p) { QListViewItem::setPixmap(0, p); }
+ QString value() const { return m_baseValue; }
+ VarTree* firstChild() const { return static_cast<VarTree*>(QListViewItem::firstChild()); }
+ VarTree* nextSibling() const { return static_cast<VarTree*>(QListViewItem::nextSibling()); }
+
+private:
+ void updateValueText();
+ QString m_baseValue; //!< The "normal value" that the driver reported
+ QString m_structValue; //!< The "quick member" value
+ bool m_baseChanged : 1;
+ bool m_structChanged : 1;
+};
+
+/**
+ * Represents the value tree that is parsed by the debugger drivers.
+ */
+struct ExprValue
+{
+ QString m_name;
+ QString m_value;
+ VarTree::VarKind m_varKind;
+ VarTree::NameKind m_nameKind;
+ ExprValue* m_child; /* the first child expression */
+ ExprValue* m_next; /* the next sibling expression */
+ bool m_initiallyExpanded;
+
+ ExprValue(const QString& name, VarTree::NameKind kind);
+ ~ExprValue();
+
+ void appendChild(ExprValue* newChild);
+ int childCount() const;
+};
+
+
+class ValueEdit : public QLineEdit
+{
+ Q_OBJECT
+public:
+ ValueEdit(ExprWnd* parent);
+ ~ValueEdit();
+
+ void terminate(bool commit);
+ VarTree* m_item;
+ bool m_finished;
+protected:
+ void keyPressEvent(QKeyEvent *e);
+ void focusOutEvent(QFocusEvent* ev);
+ void paintEvent(QPaintEvent* e);
+public slots:
+ void slotSelectionChanged();
+signals:
+ void done(VarTree*, const QString&);
+};
+
+
+class ExprWnd : public QListView
+{
+ Q_OBJECT
+public:
+ ExprWnd(QWidget* parent, const QString& colHeader, const char* name);
+ ~ExprWnd();
+
+ /** returns the list with the expressions at the topmost level */
+ QStringList exprList() const;
+ /** appends a copy of expr to the end of the tree at the topmost level;
+ * returns a pointer to the inserted top-level item */
+ VarTree* insertExpr(ExprValue* expr, ProgramTypeTable& typeTable);
+ /** updates an existing expression */
+ void updateExpr(ExprValue* expr, ProgramTypeTable& typeTable);
+ void updateExpr(VarTree* display, ExprValue* newValues, ProgramTypeTable& typeTable);
+ /** updates the value and repaints it for a single item (not the children) */
+ void updateSingleExpr(VarTree* display, ExprValue* newValues);
+ /** updates only the value of the node */
+ void updateStructValue(VarTree* display);
+ /** get a top-level expression by name */
+ VarTree* topLevelExprByName(const QString& name) const;
+ /** return a member of the struct that pointer \a v refers to */
+ static VarTree* ptrMemberByName(VarTree* v, const QString& name);
+ /** return a member of the struct \a v */
+ static VarTree* memberByName(VarTree* v, const QString& name);
+ /** removes an expression; must be on the topmost level*/
+ void removeExpr(VarTree* item);
+ /** clears the list of pointers needing updates */
+ void clearPendingUpdates();
+ /** returns a pointer to update (or 0) and removes it from the list */
+ VarTree* nextUpdatePtr();
+ VarTree* nextUpdateType();
+ VarTree* nextUpdateStruct();
+ void editValue(VarTree* item, const QString& text);
+ /** tells whether the a value is currently edited */
+ bool isEditing() const;
+
+ VarTree* firstChild() const { return static_cast<VarTree*>(QListView::firstChild()); }
+ VarTree* currentItem() const { return static_cast<VarTree*>(QListView::currentItem()); }
+ VarTree* selectedItem() const { return static_cast<VarTree*>(QListView::selectedItem()); }
+
+protected:
+ void updateExprRec(VarTree* display, ExprValue* newValues, ProgramTypeTable& typeTable);
+ void replaceChildren(VarTree* display, ExprValue* newValues);
+ void collectUnknownTypes(VarTree* item);
+ void checkUnknownType(VarTree* item);
+ static QString formatWCharPointer(QString value);
+ QPixmap m_pixPointer;
+
+ std::list<VarTree*> m_updatePtrs; //!< dereferenced pointers that need update
+ std::list<VarTree*> m_updateType; //!< structs whose type must be determined
+ std::list<VarTree*> m_updateStruct; //!< structs whose nested value needs update
+
+ ValueEdit* m_edit;
+
+ /** remove items that are in the subTree from the list */
+ void unhookSubtree(VarTree* subTree);
+ static void unhookSubtree(std::list<VarTree*>& list, VarTree* subTree);
+
+signals:
+ void removingItem(VarTree*);
+ void editValueCommitted(VarTree*, const QString&);
+};
+
+#endif // EXPRWND_H
diff --git a/kdbg/gdbdriver.cpp b/kdbg/gdbdriver.cpp
new file mode 100644
index 0000000..c0fcc94
--- /dev/null
+++ b/kdbg/gdbdriver.cpp
@@ -0,0 +1,2572 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "gdbdriver.h"
+#include "exprwnd.h"
+#include <qregexp.h>
+#include <qstringlist.h>
+#include <klocale.h> /* i18n */
+#include <ctype.h>
+#include <stdlib.h> /* strtol, atoi */
+#include <string.h> /* strcpy */
+
+#include "assert.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "mydebug.h"
+
+static void skipString(const char*& p);
+static void skipNested(const char*& s, char opening, char closing);
+static ExprValue* parseVar(const char*& s);
+static bool parseName(const char*& s, QString& name, VarTree::NameKind& kind);
+static bool parseValue(const char*& s, ExprValue* variable);
+static bool parseNested(const char*& s, ExprValue* variable);
+static bool parseVarSeq(const char*& s, ExprValue* variable);
+static bool parseValueSeq(const char*& s, ExprValue* variable);
+
+#define PROMPT "(kdbg)"
+#define PROMPT_LEN 6
+#define PROMPT_LAST_CHAR ')' /* needed when searching for prompt string */
+
+
+// TODO: make this cmd info stuff non-static to allow multiple
+// simultaneous gdbs to run!
+
+struct GdbCmdInfo {
+ DbgCommand cmd;
+ const char* fmt; /* format string */
+ enum Args {
+ argNone, argString, argNum,
+ argStringNum, argNumString,
+ argString2, argNum2
+ } argsNeeded;
+};
+
+#if 0
+// This is how the QString data print statement generally looks like.
+// It is set by KDebugger via setPrintQStringDataCmd().
+
+static const char printQStringStructFmt[] =
+ // if the string data is junk, fail early
+ "print ($qstrunicode=($qstrdata=(%s))->unicode)?"
+ // print an array of shorts
+ "(*(unsigned short*)$qstrunicode)@"
+ // limit the length
+ "(($qstrlen=(unsigned int)($qstrdata->len))>100?100:$qstrlen)"
+ // if unicode data is 0, report a special value
+ ":1==0\n";
+#endif
+static const char printQStringStructFmt[] = "print (0?\"%s\":$kdbgundef)\n";
+
+/*
+ * The following array of commands must be sorted by the DC* values,
+ * because they are used as indices.
+ */
+static GdbCmdInfo cmds[] = {
+ { DCinitialize, "", GdbCmdInfo::argNone },
+ { DCtty, "tty %s\n", GdbCmdInfo::argString },
+ { DCexecutable, "file \"%s\"\n", GdbCmdInfo::argString },
+ { DCtargetremote, "target remote %s\n", GdbCmdInfo::argString },
+ { DCcorefile, "core-file %s\n", GdbCmdInfo::argString },
+ { DCattach, "attach %s\n", GdbCmdInfo::argString },
+ { DCinfolinemain, "kdbg_infolinemain\n", GdbCmdInfo::argNone },
+ { DCinfolocals, "kdbg__alllocals\n", GdbCmdInfo::argNone },
+ { DCinforegisters, "info all-registers\n", GdbCmdInfo::argNone},
+ { DCexamine, "x %s %s\n", GdbCmdInfo::argString2 },
+ { DCinfoline, "info line %s:%d\n", GdbCmdInfo::argStringNum },
+ { DCdisassemble, "disassemble %s %s\n", GdbCmdInfo::argString2 },
+ { DCsetargs, "set args %s\n", GdbCmdInfo::argString },
+ { DCsetenv, "set env %s %s\n", GdbCmdInfo::argString2 },
+ { DCunsetenv, "unset env %s\n", GdbCmdInfo::argString },
+ { DCsetoption, "setoption %s %d\n", GdbCmdInfo::argStringNum},
+ { DCcd, "cd %s\n", GdbCmdInfo::argString },
+ { DCbt, "bt\n", GdbCmdInfo::argNone },
+ { DCrun, "run\n", GdbCmdInfo::argNone },
+ { DCcont, "cont\n", GdbCmdInfo::argNone },
+ { DCstep, "step\n", GdbCmdInfo::argNone },
+ { DCstepi, "stepi\n", GdbCmdInfo::argNone },
+ { DCnext, "next\n", GdbCmdInfo::argNone },
+ { DCnexti, "nexti\n", GdbCmdInfo::argNone },
+ { DCfinish, "finish\n", GdbCmdInfo::argNone },
+ { DCuntil, "until %s:%d\n", GdbCmdInfo::argStringNum },
+ { DCkill, "kill\n", GdbCmdInfo::argNone },
+ { DCbreaktext, "break %s\n", GdbCmdInfo::argString },
+ { DCbreakline, "break %s:%d\n", GdbCmdInfo::argStringNum },
+ { DCtbreakline, "tbreak %s:%d\n", GdbCmdInfo::argStringNum },
+ { DCbreakaddr, "break *%s\n", GdbCmdInfo::argString },
+ { DCtbreakaddr, "tbreak *%s\n", GdbCmdInfo::argString },
+ { DCwatchpoint, "watch %s\n", GdbCmdInfo::argString },
+ { DCdelete, "delete %d\n", GdbCmdInfo::argNum },
+ { DCenable, "enable %d\n", GdbCmdInfo::argNum },
+ { DCdisable, "disable %d\n", GdbCmdInfo::argNum },
+ { DCprint, "print %s\n", GdbCmdInfo::argString },
+ { DCprintDeref, "print *(%s)\n", GdbCmdInfo::argString },
+ { DCprintStruct, "print %s\n", GdbCmdInfo::argString },
+ { DCprintQStringStruct, printQStringStructFmt, GdbCmdInfo::argString},
+ { DCframe, "frame %d\n", GdbCmdInfo::argNum },
+ { DCfindType, "whatis %s\n", GdbCmdInfo::argString },
+ { DCinfosharedlib, "info sharedlibrary\n", GdbCmdInfo::argNone },
+ { DCthread, "thread %d\n", GdbCmdInfo::argNum },
+ { DCinfothreads, "info threads\n", GdbCmdInfo::argNone },
+ { DCinfobreak, "info breakpoints\n", GdbCmdInfo::argNone },
+ { DCcondition, "condition %d %s\n", GdbCmdInfo::argNumString},
+ { DCsetpc, "set variable $pc=%s\n", GdbCmdInfo::argString },
+ { DCignore, "ignore %d %d\n", GdbCmdInfo::argNum2},
+ { DCprintWChar, "print ($s=%s)?*$s@wcslen($s):0x0\n", GdbCmdInfo::argString },
+ { DCsetvariable, "set variable %s=%s\n", GdbCmdInfo::argString2 },
+};
+
+#define NUM_CMDS (int(sizeof(cmds)/sizeof(cmds[0])))
+#define MAX_FMTLEN 200
+
+GdbDriver::GdbDriver() :
+ DebuggerDriver(),
+ m_gdbMajor(4), m_gdbMinor(16)
+{
+ strcpy(m_prompt, PROMPT);
+ m_promptMinLen = PROMPT_LEN;
+ m_promptLastChar = PROMPT_LAST_CHAR;
+
+#ifndef NDEBUG
+ // check command info array
+ const char* perc;
+ for (int i = 0; i < NUM_CMDS; i++) {
+ // must be indexable by DbgCommand values, i.e. sorted by DbgCommand values
+ assert(i == cmds[i].cmd);
+ // a format string must be associated
+ assert(cmds[i].fmt != 0);
+ assert(strlen(cmds[i].fmt) <= MAX_FMTLEN);
+ // format string must match arg specification
+ switch (cmds[i].argsNeeded) {
+ case GdbCmdInfo::argNone:
+ assert(strchr(cmds[i].fmt, '%') == 0);
+ break;
+ case GdbCmdInfo::argString:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 's');
+ assert(strchr(perc+2, '%') == 0);
+ break;
+ case GdbCmdInfo::argNum:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 'd');
+ assert(strchr(perc+2, '%') == 0);
+ break;
+ case GdbCmdInfo::argStringNum:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 's');
+ perc = strchr(perc+2, '%');
+ assert(perc != 0 && perc[1] == 'd');
+ assert(strchr(perc+2, '%') == 0);
+ break;
+ case GdbCmdInfo::argNumString:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 'd');
+ perc = strchr(perc+2, '%');
+ assert(perc != 0 && perc[1] == 's');
+ assert(strchr(perc+2, '%') == 0);
+ break;
+ case GdbCmdInfo::argString2:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 's');
+ perc = strchr(perc+2, '%');
+ assert(perc != 0 && perc[1] == 's');
+ assert(strchr(perc+2, '%') == 0);
+ break;
+ case GdbCmdInfo::argNum2:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 'd');
+ perc = strchr(perc+2, '%');
+ assert(perc != 0 && perc[1] == 'd');
+ assert(strchr(perc+2, '%') == 0);
+ break;
+ }
+ }
+ assert(strlen(printQStringStructFmt) <= MAX_FMTLEN);
+#endif
+}
+
+GdbDriver::~GdbDriver()
+{
+}
+
+
+QString GdbDriver::driverName() const
+{
+ return "GDB";
+}
+
+QString GdbDriver::defaultGdb()
+{
+ return
+ "gdb"
+ " --fullname" /* to get standard file names each time the prog stops */
+ " --nx"; /* do not execute initialization files */
+}
+
+QString GdbDriver::defaultInvocation() const
+{
+ if (m_defaultCmd.isEmpty()) {
+ return defaultGdb();
+ } else {
+ return m_defaultCmd;
+ }
+}
+
+QStringList GdbDriver::boolOptionList() const
+{
+ // no options
+ return QStringList();
+}
+
+bool GdbDriver::startup(QString cmdStr)
+{
+ if (!DebuggerDriver::startup(cmdStr))
+ return false;
+
+ static const char gdbInitialize[] =
+ /*
+ * Work around buggy gdbs that do command line editing even if they
+ * are not on a tty. The readline library echos every command back
+ * in this case, which is confusing for us.
+ */
+ "set editing off\n"
+ "set confirm off\n"
+ "set print static-members off\n"
+ "set print asm-demangle on\n"
+ /*
+ * Don't assume that program functions invoked from a watch expression
+ * always succeed.
+ */
+ "set unwindonsignal on\n"
+ /*
+ * Write a short macro that prints all locals: local variables and
+ * function arguments.
+ */
+ "define kdbg__alllocals\n"
+ "info locals\n" /* local vars supersede args with same name */
+ "info args\n" /* therefore, arguments must come last */
+ "end\n"
+ /*
+ * Work around a bug in gdb-6.3: "info line main" crashes gdb.
+ */
+ "define kdbg_infolinemain\n"
+ "list\n"
+ "info line\n"
+ "end\n"
+ // change prompt string and synchronize with gdb
+ "set prompt " PROMPT "\n"
+ ;
+
+ executeCmdString(DCinitialize, gdbInitialize, false);
+
+ // assume that QString::null is ok
+ cmds[DCprintQStringStruct].fmt = printQStringStructFmt;
+
+ return true;
+}
+
+void GdbDriver::commandFinished(CmdQueueItem* cmd)
+{
+ // command string must be committed
+ if (!cmd->m_committed) {
+ // not commited!
+ TRACE("calling " + (__PRETTY_FUNCTION__ + (" with uncommited command:\n\t" +
+ cmd->m_cmdString)));
+ return;
+ }
+
+ switch (cmd->m_cmd) {
+ case DCinitialize:
+ // get version number from preamble
+ {
+ int len;
+ QRegExp GDBVersion("\\nGDB [0-9]+\\.[0-9]+");
+ int offset = GDBVersion.match(m_output, 0, &len);
+ if (offset >= 0) {
+ char* start = m_output + offset + 5; // skip "\nGDB "
+ char* end;
+ m_gdbMajor = strtol(start, &end, 10);
+ m_gdbMinor = strtol(end + 1, 0, 10); // skip "."
+ if (start == end) {
+ // nothing was parsed
+ m_gdbMajor = 4;
+ m_gdbMinor = 16;
+ }
+ } else {
+ // assume some default version (what would make sense?)
+ m_gdbMajor = 4;
+ m_gdbMinor = 16;
+ }
+ // use a feasible core-file command
+ if (m_gdbMajor > 4 || (m_gdbMajor == 4 && m_gdbMinor >= 16)) {
+#ifdef __FreeBSD__
+ cmds[DCcorefile].fmt = "target FreeBSD-core %s\n";
+#else
+ cmds[DCcorefile].fmt = "target core %s\n";
+#endif
+ } else {
+ cmds[DCcorefile].fmt = "core-file %s\n";
+ }
+ }
+ {
+ /*
+ * Check for GDB 7.1 or later; the syntax for the disassemble
+ * command has changed.
+ * This RE picks the last version number in the first line,
+ * because at least OpenSUSE writes its own version number
+ * in the first line (but before GDB's version number).
+ */
+ QRegExp re(
+ " " // must be preceded by space
+ "[(]?" // SLES 10 embeds in parentheses
+ "(\\d+)\\.(\\d+)" // major, minor
+ "[^ ]*\\n" // no space until end of line
+ );
+ int pos = re.search(m_output);
+ const char* disass = "disassemble %s %s\n";
+ if (pos >= 0) {
+ int major = re.cap(1).toInt();
+ int minor = re.cap(2).toInt();
+ if (major > 7 || (major == 7 && minor >= 1))
+ {
+ disass = "disassemble %s, %s\n";
+ }
+ }
+ cmds[DCdisassemble].fmt = disass;
+ }
+ break;
+ default:;
+ }
+
+ /* ok, the command is ready */
+ emit commandReceived(cmd, m_output);
+
+ switch (cmd->m_cmd) {
+ case DCcorefile:
+ case DCinfolinemain:
+ case DCframe:
+ case DCattach:
+ case DCrun:
+ case DCcont:
+ case DCstep:
+ case DCstepi:
+ case DCnext:
+ case DCnexti:
+ case DCfinish:
+ case DCuntil:
+ parseMarker();
+ default:;
+ }
+}
+
+/*
+ * The --fullname option makes gdb send a special normalized sequence print
+ * each time the program stops and at some other points. The sequence has
+ * the form "\032\032filename:lineno:charoffset:(beg|middle):address".
+ */
+void GdbDriver::parseMarker()
+{
+ char* startMarker = strstr(m_output, "\032\032");
+ if (startMarker == 0)
+ return;
+
+ // extract the marker
+ startMarker += 2;
+ TRACE(QString("found marker: ") + startMarker);
+ char* endMarker = strchr(startMarker, '\n');
+ if (endMarker == 0)
+ return;
+
+ *endMarker = '\0';
+
+ // extract filename and line number
+ static QRegExp MarkerRE(":[0-9]+:[0-9]+:[begmidl]+:0x");
+
+ int len;
+ int lineNoStart = MarkerRE.match(startMarker, 0, &len);
+ if (lineNoStart >= 0) {
+ int lineNo = atoi(startMarker + lineNoStart+1);
+
+ // get address
+ const char* addrStart = startMarker + lineNoStart + len - 2;
+ DbgAddr address = QString(addrStart).stripWhiteSpace();
+
+ // now show the window
+ startMarker[lineNoStart] = '\0'; /* split off file name */
+ emit activateFileLine(startMarker, lineNo-1, address);
+ }
+}
+
+
+/*
+ * Escapes characters that might lead to problems when they appear on gdb's
+ * command line.
+ */
+static void normalizeStringArg(QString& arg)
+{
+ /*
+ * Remove trailing backslashes. This approach is a little simplistic,
+ * but we know that there is at the moment no case where a trailing
+ * backslash would make sense.
+ */
+ while (!arg.isEmpty() && arg[arg.length()-1] == '\\') {
+ arg = arg.left(arg.length()-1);
+ }
+}
+
+
+QString GdbDriver::makeCmdString(DbgCommand cmd, QString strArg)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == GdbCmdInfo::argString);
+
+ normalizeStringArg(strArg);
+
+ if (cmd == DCcd) {
+ // need the working directory when parsing the output
+ m_programWD = strArg;
+ } else if (cmd == DCsetargs && !m_redirect.isEmpty()) {
+ /*
+ * Use saved redirection. We prepend it in front of the user's
+ * arguments so that the user can override the redirections.
+ */
+ strArg = m_redirect + " " + strArg;
+ }
+
+ QString cmdString;
+ cmdString.sprintf(cmds[cmd].fmt, strArg.latin1());
+ return cmdString;
+}
+
+QString GdbDriver::makeCmdString(DbgCommand cmd, int intArg)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == GdbCmdInfo::argNum);
+
+ QString cmdString;
+ cmdString.sprintf(cmds[cmd].fmt, intArg);
+ return cmdString;
+}
+
+QString GdbDriver::makeCmdString(DbgCommand cmd, QString strArg, int intArg)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == GdbCmdInfo::argStringNum ||
+ cmds[cmd].argsNeeded == GdbCmdInfo::argNumString ||
+ cmd == DCexamine ||
+ cmd == DCtty);
+
+ normalizeStringArg(strArg);
+
+ QString cmdString;
+
+ if (cmd == DCtty)
+ {
+ /*
+ * intArg specifies which channels should be redirected to
+ * /dev/null. It is a value or'ed together from RDNstdin,
+ * RDNstdout, RDNstderr. We store the value for a later DCsetargs
+ * command.
+ *
+ * Note: We rely on that after the DCtty a DCsetargs will follow,
+ * which will ultimately apply the redirection.
+ */
+ static const char* const runRedir[8] = {
+ "",
+ "</dev/null",
+ ">/dev/null",
+ "</dev/null >/dev/null",
+ "2>/dev/null",
+ "</dev/null 2>/dev/null",
+ ">/dev/null 2>&1",
+ "</dev/null >/dev/null 2>&1"
+ };
+ if (strArg.isEmpty())
+ intArg = 7; /* failsafe if no tty */
+ m_redirect = runRedir[intArg & 7];
+
+ return makeCmdString(DCtty, strArg); /* note: no problem if strArg empty */
+ }
+
+ if (cmd == DCexamine) {
+ // make a format specifier from the intArg
+ static const char size[16] = {
+ '\0', 'b', 'h', 'w', 'g'
+ };
+ static const char format[16] = {
+ '\0', 'x', 'd', 'u', 'o', 't',
+ 'a', 'c', 'f', 's', 'i'
+ };
+ assert(MDTsizemask == 0xf); /* lowest 4 bits */
+ assert(MDTformatmask == 0xf0); /* next 4 bits */
+ int count = 16; /* number of entities to print */
+ char sizeSpec = size[intArg & MDTsizemask];
+ char formatSpec = format[(intArg & MDTformatmask) >> 4];
+ assert(sizeSpec != '\0');
+ assert(formatSpec != '\0');
+ // adjust count such that 16 lines are printed
+ switch (intArg & MDTformatmask) {
+ case MDTstring: case MDTinsn:
+ break; /* no modification needed */
+ default:
+ // all cases drop through:
+ switch (intArg & MDTsizemask) {
+ case MDTbyte:
+ case MDThalfword:
+ count *= 2;
+ case MDTword:
+ count *= 2;
+ case MDTgiantword:
+ count *= 2;
+ }
+ break;
+ }
+ QString spec;
+ spec.sprintf("/%d%c%c", count, sizeSpec, formatSpec);
+
+ return makeCmdString(DCexamine, spec, strArg);
+ }
+
+ if (cmds[cmd].argsNeeded == GdbCmdInfo::argStringNum)
+ {
+ // line numbers are zero-based
+ if (cmd == DCuntil || cmd == DCbreakline ||
+ cmd == DCtbreakline || cmd == DCinfoline)
+ {
+ intArg++;
+ }
+ if (cmd == DCinfoline)
+ {
+ // must split off file name part
+ int slash = strArg.findRev('/');
+ if (slash >= 0)
+ strArg = strArg.right(strArg.length()-slash-1);
+ }
+ cmdString.sprintf(cmds[cmd].fmt, strArg.latin1(), intArg);
+ }
+ else
+ {
+ cmdString.sprintf(cmds[cmd].fmt, intArg, strArg.latin1());
+ }
+ return cmdString;
+}
+
+QString GdbDriver::makeCmdString(DbgCommand cmd, QString strArg1, QString strArg2)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == GdbCmdInfo::argString2);
+
+ normalizeStringArg(strArg1);
+ normalizeStringArg(strArg2);
+
+ QString cmdString;
+ cmdString.sprintf(cmds[cmd].fmt, strArg1.latin1(), strArg2.latin1());
+ return cmdString;
+}
+
+QString GdbDriver::makeCmdString(DbgCommand cmd, int intArg1, int intArg2)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == GdbCmdInfo::argNum2);
+
+ QString cmdString;
+ cmdString.sprintf(cmds[cmd].fmt, intArg1, intArg2);
+ return cmdString;
+}
+
+CmdQueueItem* GdbDriver::executeCmd(DbgCommand cmd, bool clearLow)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == GdbCmdInfo::argNone);
+
+ if (cmd == DCrun) {
+ m_haveCoreFile = false;
+ }
+
+ return executeCmdString(cmd, cmds[cmd].fmt, clearLow);
+}
+
+CmdQueueItem* GdbDriver::executeCmd(DbgCommand cmd, QString strArg,
+ bool clearLow)
+{
+ return executeCmdString(cmd, makeCmdString(cmd, strArg), clearLow);
+}
+
+CmdQueueItem* GdbDriver::executeCmd(DbgCommand cmd, int intArg,
+ bool clearLow)
+{
+
+ return executeCmdString(cmd, makeCmdString(cmd, intArg), clearLow);
+}
+
+CmdQueueItem* GdbDriver::executeCmd(DbgCommand cmd, QString strArg, int intArg,
+ bool clearLow)
+{
+ return executeCmdString(cmd, makeCmdString(cmd, strArg, intArg), clearLow);
+}
+
+CmdQueueItem* GdbDriver::executeCmd(DbgCommand cmd, QString strArg1, QString strArg2,
+ bool clearLow)
+{
+ return executeCmdString(cmd, makeCmdString(cmd, strArg1, strArg2), clearLow);
+}
+
+CmdQueueItem* GdbDriver::executeCmd(DbgCommand cmd, int intArg1, int intArg2,
+ bool clearLow)
+{
+ return executeCmdString(cmd, makeCmdString(cmd, intArg1, intArg2), clearLow);
+}
+
+CmdQueueItem* GdbDriver::queueCmd(DbgCommand cmd, QueueMode mode)
+{
+ return queueCmdString(cmd, cmds[cmd].fmt, mode);
+}
+
+CmdQueueItem* GdbDriver::queueCmd(DbgCommand cmd, QString strArg,
+ QueueMode mode)
+{
+ return queueCmdString(cmd, makeCmdString(cmd, strArg), mode);
+}
+
+CmdQueueItem* GdbDriver::queueCmd(DbgCommand cmd, int intArg,
+ QueueMode mode)
+{
+ return queueCmdString(cmd, makeCmdString(cmd, intArg), mode);
+}
+
+CmdQueueItem* GdbDriver::queueCmd(DbgCommand cmd, QString strArg, int intArg,
+ QueueMode mode)
+{
+ return queueCmdString(cmd, makeCmdString(cmd, strArg, intArg), mode);
+}
+
+CmdQueueItem* GdbDriver::queueCmd(DbgCommand cmd, QString strArg1, QString strArg2,
+ QueueMode mode)
+{
+ return queueCmdString(cmd, makeCmdString(cmd, strArg1, strArg2), mode);
+}
+
+void GdbDriver::terminate()
+{
+ kill(SIGTERM);
+ m_state = DSidle;
+}
+
+void GdbDriver::detachAndTerminate()
+{
+ kill(SIGINT);
+ flushCommands();
+ executeCmdString(DCinitialize, "detach\nquit\n", true);
+}
+
+void GdbDriver::interruptInferior()
+{
+ kill(SIGINT);
+ // remove accidentally queued commands
+ flushHiPriQueue();
+}
+
+static bool isErrorExpr(const char* output)
+{
+ return
+ strncmp(output, "Cannot access memory at", 23) == 0 ||
+ strncmp(output, "Attempt to dereference a generic pointer", 40) == 0 ||
+ strncmp(output, "Attempt to take contents of ", 28) == 0 ||
+ strncmp(output, "Attempt to use a type name as an expression", 43) == 0 ||
+ strncmp(output, "There is no member or method named", 34) == 0 ||
+ strncmp(output, "A parse error in expression", 27) == 0 ||
+ strncmp(output, "No symbol \"", 11) == 0 ||
+ strncmp(output, "Internal error: ", 16) == 0;
+}
+
+/**
+ * Returns true if the output is an error message. If wantErrorValue is
+ * true, a new ExprValue object is created and filled with the error message.
+ * If there are warnings, they are skipped and output points past the warnings
+ * on return (even if there \e are errors).
+ */
+static bool parseErrorMessage(const char*& output,
+ ExprValue*& variable, bool wantErrorValue)
+{
+ // skip warnings
+ while (strncmp(output, "warning:", 8) == 0)
+ {
+ const char* end = strchr(output+8, '\n');
+ if (end == 0)
+ output += strlen(output);
+ else
+ output = end+1;
+ }
+
+ if (isErrorExpr(output))
+ {
+ if (wantErrorValue) {
+ // put the error message as value in the variable
+ variable = new ExprValue(QString(), VarTree::NKplain);
+ const char* endMsg = strchr(output, '\n');
+ if (endMsg == 0)
+ endMsg = output + strlen(output);
+ variable->m_value = QString::fromLatin1(output, endMsg-output);
+ } else {
+ variable = 0;
+ }
+ return true;
+ }
+ return false;
+}
+
+#if QT_VERSION >= 300
+union Qt2QChar {
+ short s;
+ struct {
+ uchar row;
+ uchar cell;
+ } qch;
+};
+#endif
+
+void GdbDriver::setPrintQStringDataCmd(const char* cmd)
+{
+ // don't accept the command if it is empty
+ if (cmd == 0 || *cmd == '\0')
+ return;
+ assert(strlen(cmd) <= MAX_FMTLEN);
+ cmds[DCprintQStringStruct].fmt = cmd;
+}
+
+ExprValue* GdbDriver::parseQCharArray(const char* output, bool wantErrorValue, bool qt3like)
+{
+ ExprValue* variable = 0;
+
+ /*
+ * Parse off white space. gdb sometimes prints white space first if the
+ * printed array leaded to an error.
+ */
+ while (isspace(*output))
+ output++;
+
+ // special case: empty string (0 repetitions)
+ if (strncmp(output, "Invalid number 0 of repetitions", 31) == 0)
+ {
+ variable = new ExprValue(QString(), VarTree::NKplain);
+ variable->m_value = "\"\"";
+ return variable;
+ }
+
+ // check for error conditions
+ if (parseErrorMessage(output, variable, wantErrorValue))
+ return variable;
+
+ // parse the array
+
+ // find '='
+ const char* p = output;
+ p = strchr(p, '=');
+ if (p == 0) {
+ goto error;
+ }
+ // skip white space
+ do {
+ p++;
+ } while (isspace(*p));
+
+ if (*p == '{')
+ {
+ // this is the real data
+ p++; /* skip '{' */
+
+ // parse the array
+ QString result;
+ QString repeatCount;
+ enum { wasNothing, wasChar, wasRepeat } lastThing = wasNothing;
+ /*
+ * A matrix for separators between the individual "things"
+ * that are added to the string. The first index is a bool,
+ * the second index is from the enum above.
+ */
+ static const char* separator[2][3] = {
+ { "\"", 0, ", \"" }, /* normal char is added */
+ { "'", "\", '", ", '" } /* repeated char is added */
+ };
+
+ while (isdigit(*p)) {
+ // parse a number
+ char* end;
+ unsigned short value = (unsigned short) strtoul(p, &end, 0);
+ if (end == p)
+ goto error; /* huh? no valid digits */
+ // skip separator and search for a repeat count
+ p = end;
+ while (isspace(*p) || *p == ',')
+ p++;
+ bool repeats = strncmp(p, "<repeats ", 9) == 0;
+ if (repeats) {
+ const char* start = p;
+ p = strchr(p+9, '>'); /* search end and advance */
+ if (p == 0)
+ goto error;
+ p++; /* skip '>' */
+ repeatCount = QString::fromLatin1(start, p-start);
+ while (isspace(*p) || *p == ',')
+ p++;
+ }
+ // p is now at the next char (or the end)
+
+ // interpret the value as a QChar
+ // TODO: make cross-architecture compatible
+ QChar ch;
+ if (qt3like) {
+ ch = QChar(value);
+ } else {
+#if QT_VERSION < 300
+ (unsigned short&)ch = value;
+#else
+ Qt2QChar c;
+ c.s = value;
+ ch.setRow(c.qch.row);
+ ch.setCell(c.qch.cell);
+#endif
+ }
+
+ // escape a few frequently used characters
+ char escapeCode = '\0';
+ switch (ch.latin1()) {
+ case '\n': escapeCode = 'n'; break;
+ case '\r': escapeCode = 'r'; break;
+ case '\t': escapeCode = 't'; break;
+ case '\b': escapeCode = 'b'; break;
+ case '\"': escapeCode = '\"'; break;
+ case '\\': escapeCode = '\\'; break;
+ case '\0': if (value == 0) { escapeCode = '0'; } break;
+ }
+
+ // add separator
+ result += separator[repeats][lastThing];
+ // add char
+ if (escapeCode != '\0') {
+ result += '\\';
+ ch = escapeCode;
+ }
+ result += ch;
+
+ // fixup repeat count and lastThing
+ if (repeats) {
+ result += "' ";
+ result += repeatCount;
+ lastThing = wasRepeat;
+ } else {
+ lastThing = wasChar;
+ }
+ }
+ if (*p != '}')
+ goto error;
+
+ // closing quote
+ if (lastThing == wasChar)
+ result += "\"";
+
+ // assign the value
+ variable = new ExprValue(QString(), VarTree::NKplain);
+ variable->m_value = result;
+ }
+ else if (strncmp(p, "true", 4) == 0)
+ {
+ variable = new ExprValue(QString(), VarTree::NKplain);
+ variable->m_value = "QString::null";
+ }
+ else if (strncmp(p, "false", 5) == 0)
+ {
+ variable = new ExprValue(QString(), VarTree::NKplain);
+ variable->m_value = "(null)";
+ }
+ else
+ goto error;
+ return variable;
+
+error:
+ if (wantErrorValue) {
+ variable = new ExprValue(QString(), VarTree::NKplain);
+ variable->m_value = "internal parse error";
+ }
+ return variable;
+}
+
+static ExprValue* parseVar(const char*& s)
+{
+ const char* p = s;
+
+ // skip whitespace
+ while (isspace(*p))
+ p++;
+
+ QString name;
+ VarTree::NameKind kind;
+ /*
+ * Detect anonymouse struct values: The 'name =' part is missing:
+ * s = { a = 1, { b = 2 }}
+ * Note that this detection works only inside structs when the anonymous
+ * struct is not the first member:
+ * s = {{ a = 1 }, b = 2}
+ * This is misparsed (by parseNested()) because it is mistakenly
+ * interprets the second opening brace as the first element of an array
+ * of structs.
+ */
+ if (*p == '{')
+ {
+ name = i18n("<anonymous struct or union>");
+ kind = VarTree::NKanonymous;
+ }
+ else
+ {
+ if (!parseName(p, name, kind)) {
+ return 0;
+ }
+
+ // go for '='
+ while (isspace(*p))
+ p++;
+ if (*p != '=') {
+ TRACE(QString().sprintf("parse error: = not found after %s", (const char*)name));
+ return 0;
+ }
+ // skip the '=' and more whitespace
+ p++;
+ while (isspace(*p))
+ p++;
+ }
+
+ ExprValue* variable = new ExprValue(name, kind);
+
+ if (!parseValue(p, variable)) {
+ delete variable;
+ return 0;
+ }
+ s = p;
+ return variable;
+}
+
+static void skipNested(const char*& s, char opening, char closing)
+{
+ const char* p = s;
+
+ // parse a nested type
+ int nest = 1;
+ p++;
+ /*
+ * Search for next matching `closing' char, skipping nested pairs of
+ * `opening' and `closing'.
+ */
+ while (*p && nest > 0) {
+ if (*p == opening) {
+ nest++;
+ } else if (*p == closing) {
+ nest--;
+ }
+ p++;
+ }
+ if (nest != 0) {
+ TRACE(QString().sprintf("parse error: mismatching %c%c at %-20.20s", opening, closing, s));
+ }
+ s = p;
+}
+
+/**
+ * This function skips text that is delimited by nested angle bracktes, '<>'.
+ * A complication arises because the delimited text can contain the names of
+ * operator<<, operator>>, operator<, and operator>, which have to be treated
+ * specially so that they do not count towards the nesting of '<>'.
+ * This function assumes that the delimited text does not contain strings.
+ */
+static void skipNestedAngles(const char*& s)
+{
+ const char* p = s;
+
+ int nest = 1;
+ p++; // skip the initial '<'
+ while (*p && nest > 0)
+ {
+ // Below we can check for p-s >= 9 instead of 8 because
+ // *s is '<' and cannot be part of "operator".
+ if (*p == '<')
+ {
+ if (p-s >= 9 && strncmp(p-8, "operator", 8) == 0) {
+ if (p[1] == '<')
+ p++;
+ } else {
+ nest++;
+ }
+ }
+ else if (*p == '>')
+ {
+ if (p-s >= 9 && strncmp(p-8, "operator", 8) == 0) {
+ if (p[1] == '>')
+ p++;
+ } else {
+ nest--;
+ }
+ }
+ p++;
+ }
+ if (nest != 0) {
+ TRACE(QString().sprintf("parse error: mismatching <> at %-20.20s", s));
+ }
+ s = p;
+}
+
+/**
+ * Find the end of line that is not inside braces
+ */
+static void findEnd(const char*& s)
+{
+ const char* p = s;
+ while (*p && *p!='\n') {
+ while (*p && *p!='\n' && *p!='{')
+ p++;
+ if (*p=='{') {
+ p++;
+ skipNested(p, '{', '}'); p--;
+ }
+ }
+ s = p;
+}
+
+static bool isNumberish(const char ch)
+{
+ return (ch>='0' && ch<='9') || ch=='.' || ch=='x';
+}
+
+void skipString(const char*& p)
+{
+moreStrings:
+ // opening quote
+ char quote = *p++;
+ while (*p != quote) {
+ if (*p == '\\') {
+ // skip escaped character
+ // no special treatment for octal values necessary
+ p++;
+ }
+ // simply return if no more characters
+ if (*p == '\0')
+ return;
+ p++;
+ }
+ // closing quote
+ p++;
+ /*
+ * Strings can consist of several parts, some of which contain repeated
+ * characters.
+ */
+ if (quote == '\'') {
+ // look ahaead for <repeats 123 times>
+ const char* q = p+1;
+ while (isspace(*q))
+ q++;
+ if (strncmp(q, "<repeats ", 9) == 0) {
+ p = q+9;
+ while (*p != '\0' && *p != '>')
+ p++;
+ if (*p != '\0') {
+ p++; /* skip the '>' */
+ }
+ }
+ }
+ // is the string continued?
+ if (*p == ',') {
+ // look ahead for another quote
+ const char* q = p+1;
+ while (isspace(*q))
+ q++;
+ if (*q == '"' || *q == '\'') {
+ // yes!
+ p = q;
+ goto moreStrings;
+ }
+ }
+ /* very long strings are followed by `...' */
+ if (*p == '.' && p[1] == '.' && p[2] == '.') {
+ p += 3;
+ }
+}
+
+static void skipNestedWithString(const char*& s, char opening, char closing)
+{
+ const char* p = s;
+
+ // parse a nested expression
+ int nest = 1;
+ p++;
+ /*
+ * Search for next matching `closing' char, skipping nested pairs of
+ * `opening' and `closing' as well as strings.
+ */
+ while (*p && nest > 0) {
+ if (*p == opening) {
+ nest++;
+ } else if (*p == closing) {
+ nest--;
+ } else if (*p == '\'' || *p == '\"') {
+ skipString(p);
+ continue;
+ }
+ p++;
+ }
+ if (nest > 0) {
+ TRACE(QString().sprintf("parse error: mismatching %c%c at %-20.20s", opening, closing, s));
+ }
+ s = p;
+}
+
+inline void skipName(const char*& p)
+{
+ // allow : (for enumeration values) and $ and . (for _vtbl.)
+ while (isalnum(*p) || *p == '_' || *p == ':' || *p == '$' || *p == '.')
+ p++;
+}
+
+static bool parseName(const char*& s, QString& name, VarTree::NameKind& kind)
+{
+ kind = VarTree::NKplain;
+
+ const char* p = s;
+ // examples of names:
+ // name
+ // <Object>
+ // <string<a,b<c>,7> >
+
+ if (*p == '<') {
+ skipNestedAngles(p);
+ name = QString::fromLatin1(s, p - s);
+ kind = VarTree::NKtype;
+ }
+ else
+ {
+ // name, which might be "static"; allow dot for "_vtbl."
+ skipName(p);
+ if (p == s) {
+ TRACE(QString().sprintf("parse error: not a name %-20.20s", s));
+ return false;
+ }
+ int len = p - s;
+ if (len == 6 && strncmp(s, "static", 6) == 0) {
+ kind = VarTree::NKstatic;
+
+ // its a static variable, name comes now
+ while (isspace(*p))
+ p++;
+ s = p;
+ skipName(p);
+ if (p == s) {
+ TRACE(QString().sprintf("parse error: not a name after static %-20.20s", s));
+ return false;
+ }
+ len = p - s;
+ }
+ name = QString::fromLatin1(s, len);
+ }
+ // return the new position
+ s = p;
+ return true;
+}
+
+static bool parseValue(const char*& s, ExprValue* variable)
+{
+ variable->m_value = "";
+
+repeat:
+ if (*s == '{') {
+ // Sometimes we find the following output:
+ // {<text variable, no debug info>} 0x40012000 <access>
+ // {<data variable, no debug info>}
+ // {<variable (not text or data), no debug info>}
+ if (strncmp(s, "{<text variable, ", 17) == 0 ||
+ strncmp(s, "{<data variable, ", 17) == 0 ||
+ strncmp(s, "{<variable (not text or data), ", 31) == 0)
+ {
+ const char* start = s;
+ skipNested(s, '{', '}');
+ variable->m_value = QString::fromLatin1(start, s-start);
+ variable->m_value += ' '; // add only a single space
+ while (isspace(*s))
+ s++;
+ goto repeat;
+ }
+ else
+ {
+ s++;
+ if (!parseNested(s, variable)) {
+ return false;
+ }
+ // must be the closing brace
+ if (*s != '}') {
+ TRACE("parse error: missing } of " + variable->m_name);
+ return false;
+ }
+ s++;
+ // final white space
+ while (isspace(*s))
+ s++;
+ }
+ } else {
+ // examples of leaf values (cannot be the empty string):
+ // 123
+ // -123
+ // 23.575e+37
+ // 0x32a45
+ // @0x012ab4
+ // (DwContentType&) @0x8123456: {...}
+ // 0x32a45 "text"
+ // 10 '\n'
+ // <optimized out>
+ // 0x823abc <Array<int> virtual table>
+ // (void (*)()) 0x8048480 <f(E *, char)>
+ // (E *) 0xbffff450
+ // red
+ // &parseP (HTMLClueV *, char *)
+ // Variable "x" is not available.
+ // The value of variable 'x' is distributed...
+ // -nan(0xfffff081defa0)
+
+ const char*p = s;
+
+ // check for type
+ QString type;
+ if (*p == '(') {
+ skipNested(p, '(', ')');
+
+ while (isspace(*p))
+ p++;
+ variable->m_value = QString::fromLatin1(s, p - s);
+ }
+
+ bool reference = false;
+ if (*p == '@') {
+ // skip reference marker
+ p++;
+ reference = true;
+ }
+ const char* start = p;
+ if (*p == '-')
+ p++;
+
+ // some values consist of more than one token
+ bool checkMultiPart = false;
+
+ if (p[0] == '0' && p[1] == 'x') {
+ // parse hex number
+ p += 2;
+ while (isxdigit(*p))
+ p++;
+
+ /*
+ * Assume this is a pointer, but only if it's not a reference, since
+ * references can't be expanded.
+ */
+ if (!reference) {
+ variable->m_varKind = VarTree::VKpointer;
+ } else {
+ /*
+ * References are followed by a colon, in which case we'll
+ * find the value following the reference address.
+ */
+ if (*p == ':') {
+ p++;
+ } else {
+ // Paranoia. (Can this happen, i.e. reference not followed by ':'?)
+ reference = false;
+ }
+ }
+ checkMultiPart = true;
+ } else if (isdigit(*p)) {
+ // parse decimal number, possibly a float
+ while (isdigit(*p))
+ p++;
+ if (*p == '.') { /* TODO: obey i18n? */
+ // In long arrays an integer may be followed by '...'.
+ // We test for this situation and don't gobble the '...'.
+ if (p[1] != '.' || p[0] != '.') {
+ // fractional part
+ p++;
+ while (isdigit(*p))
+ p++;
+ }
+ }
+ if (*p == 'e' || *p == 'E') {
+ p++;
+ // exponent
+ if (*p == '-' || *p == '+')
+ p++;
+ while (isdigit(*p))
+ p++;
+ }
+
+ // for char variables there is the char, eg. 10 '\n'
+ checkMultiPart = true;
+ } else if (*p == '<') {
+ // e.g. <optimized out>
+ skipNestedAngles(p);
+ } else if (*p == '"' || *p == '\'') {
+ // character may have multipart: '\000' <repeats 11 times>
+ checkMultiPart = *p == '\'';
+ // found a string
+ skipString(p);
+ } else if (*p == '&') {
+ // function pointer
+ p++;
+ skipName(p);
+ while (isspace(*p)) {
+ p++;
+ }
+ if (*p == '(') {
+ skipNested(p, '(', ')');
+ }
+ } else if (strncmp(p, "Variable \"", 10) == 0) {
+ // Variable "x" is not available.
+ p += 10; // skip to "
+ skipName(p);
+ if (strncmp(p, "\" is not available.", 19) == 0) {
+ p += 19;
+ }
+ } else if (strncmp(p, "The value of variable '", 23) == 0) {
+ p += 23;
+ skipName(p);
+ const char* e = strchr(p, '.');
+ if (e == 0) {
+ p += strlen(p);
+ } else {
+ p = e+1;
+ }
+ } else {
+ // must be an enumeration value
+ skipName(p);
+ // hmm, not necessarily: nan (floating point Not a Number)
+ // is followed by a number in ()
+ if (*p == '(')
+ skipNested(p, '(', ')');
+ }
+ variable->m_value += QString::fromLatin1(start, p - start);
+
+ // remove line breaks from the value; this is ok since
+ // string values never contain a literal line break
+ variable->m_value.replace('\n', ' ');
+
+ if (checkMultiPart) {
+ // white space
+ while (isspace(*p))
+ p++;
+ // may be followed by a string or <...>
+ start = p;
+
+ if (*p == '"' || *p == '\'') {
+ skipString(p);
+ } else if (*p == '<') {
+ // if this value is part of an array, it might be followed
+ // by <repeats 15 times>, which we don't skip here
+ if (strncmp(p, "<repeats ", 9) != 0)
+ skipNestedAngles(p);
+ }
+ if (p != start) {
+ // there is always a blank before the string,
+ // which we will include in the final string value
+ variable->m_value += QString::fromLatin1(start-1, (p - start)+1);
+ // if this was a pointer, reset that flag since we
+ // now got the value
+ variable->m_varKind = VarTree::VKsimple;
+ }
+ }
+
+ if (variable->m_value.length() == 0) {
+ TRACE("parse error: no value for " + variable->m_name);
+ return false;
+ }
+
+ // final white space
+ while (isspace(*p))
+ p++;
+ s = p;
+
+ /*
+ * If this was a reference, the value follows. It might even be a
+ * composite variable!
+ */
+ if (reference) {
+ goto repeat;
+ }
+ }
+
+ return true;
+}
+
+static bool parseNested(const char*& s, ExprValue* variable)
+{
+ // could be a structure or an array
+ while (isspace(*s))
+ s++;
+
+ const char* p = s;
+ bool isStruct = false;
+ /*
+ * If there is a name followed by an = or an < -- which starts a type
+ * name -- or "static", it is a structure
+ */
+ if (*p == '<' || *p == '}') {
+ isStruct = true;
+ } else if (strncmp(p, "static ", 7) == 0) {
+ isStruct = true;
+ } else if (isalpha(*p) || *p == '_' || *p == '$') {
+ // look ahead for a comma after the name
+ skipName(p);
+ while (isspace(*p))
+ p++;
+ if (*p == '=') {
+ isStruct = true;
+ }
+ p = s; /* rescan the name */
+ }
+ if (isStruct) {
+ if (!parseVarSeq(p, variable)) {
+ return false;
+ }
+ variable->m_varKind = VarTree::VKstruct;
+ } else {
+ if (!parseValueSeq(p, variable)) {
+ return false;
+ }
+ variable->m_varKind = VarTree::VKarray;
+ }
+ s = p;
+ return true;
+}
+
+static bool parseVarSeq(const char*& s, ExprValue* variable)
+{
+ // parse a comma-separated sequence of variables
+ ExprValue* var = variable; /* var != 0 to indicate success if empty seq */
+ for (;;) {
+ if (*s == '}')
+ break;
+ if (strncmp(s, "<No data fields>}", 17) == 0)
+ {
+ // no member variables, so break out immediately
+ s += 16; /* go to the closing brace */
+ break;
+ }
+ var = parseVar(s);
+ if (var == 0)
+ break; /* syntax error */
+ variable->appendChild(var);
+ if (*s != ',')
+ break;
+ // skip the comma and whitespace
+ s++;
+ while (isspace(*s))
+ s++;
+ }
+ return var != 0;
+}
+
+static bool parseValueSeq(const char*& s, ExprValue* variable)
+{
+ // parse a comma-separated sequence of variables
+ int index = 0;
+ bool good;
+ for (;;) {
+ QString name;
+ name.sprintf("[%d]", index);
+ ExprValue* var = new ExprValue(name, VarTree::NKplain);
+ good = parseValue(s, var);
+ if (!good) {
+ delete var;
+ return false;
+ }
+ // a value may be followed by "<repeats 45 times>"
+ if (strncmp(s, "<repeats ", 9) == 0) {
+ s += 9;
+ char* end;
+ int l = strtol(s, &end, 10);
+ if (end == s || strncmp(end, " times>", 7) != 0) {
+ // should not happen
+ delete var;
+ return false;
+ }
+ TRACE(QString().sprintf("found <repeats %d times> in array", l));
+ // replace name and advance index
+ name.sprintf("[%d .. %d]", index, index+l-1);
+ var->m_name = name;
+ index += l;
+ // skip " times>" and space
+ s = end+7;
+ // possible final space
+ while (isspace(*s))
+ s++;
+ } else {
+ index++;
+ }
+ variable->appendChild(var);
+ // long arrays may be terminated by '...'
+ if (strncmp(s, "...", 3) == 0) {
+ s += 3;
+ ExprValue* var = new ExprValue("...", VarTree::NKplain);
+ var->m_value = i18n("<additional entries of the array suppressed>");
+ variable->appendChild(var);
+ break;
+ }
+ if (*s != ',') {
+ break;
+ }
+ // skip the comma and whitespace
+ s++;
+ while (isspace(*s))
+ s++;
+ // sometimes there is a closing brace after a comma
+// if (*s == '}')
+// break;
+ }
+ return true;
+}
+
+/**
+ * Parses a stack frame.
+ */
+static void parseFrameInfo(const char*& s, QString& func,
+ QString& file, int& lineNo, DbgAddr& address)
+{
+ const char* p = s;
+
+ // next may be a hexadecimal address
+ if (*p == '0') {
+ const char* start = p;
+ p++;
+ if (*p == 'x')
+ p++;
+ while (isxdigit(*p))
+ p++;
+ address = QString::fromLatin1(start, p-start);
+ if (strncmp(p, " in ", 4) == 0)
+ p += 4;
+ } else {
+ address = DbgAddr();
+ }
+ const char* start = p;
+ // check for special signal handler frame
+ if (strncmp(p, "<signal handler called>", 23) == 0) {
+ func = QString::fromLatin1(start, 23);
+ file = QString();
+ lineNo = -1;
+ s = p+23;
+ if (*s == '\n')
+ s++;
+ return;
+ }
+
+ /*
+ * Skip the function name. It is terminated by a left parenthesis
+ * which does not delimit "(anonymous namespace)" and which is
+ * outside the angle brackets <> of template parameter lists
+ * and is preceded by a space.
+ */
+ while (*p != '\0')
+ {
+ if (*p == '<') {
+ // check for operator<< and operator<
+ if (p-start >= 8 && strncmp(p-8, "operator", 8) == 0)
+ {
+ p++;
+ if (*p == '<')
+ p++;
+ }
+ else
+ {
+ // skip template parameter list
+ skipNestedAngles(p);
+ }
+ } else if (*p == '(') {
+ // this skips "(anonymous namespace)" as well as the formal
+ // parameter list of the containing function if this is a member
+ // of a nested class
+ skipNestedWithString(p, '(', ')');
+ } else if (*p == ' ') {
+ ++p;
+ if (*p == '(')
+ break; // parameter list found
+ } else {
+ p++;
+ }
+ }
+
+ if (*p == '\0') {
+ func = start;
+ file = QString();
+ lineNo = -1;
+ s = p;
+ return;
+ }
+ /*
+ * Skip parameters. But notice that for complicated conversion
+ * functions (eg. "operator int(**)()()", ie. convert to pointer to
+ * pointer to function) as well as operator()(...) we have to skip
+ * additional pairs of parentheses. Furthermore, recent gdbs write the
+ * demangled name followed by the arguments in a pair of parentheses,
+ * where the demangled name can end in "const".
+ */
+ do {
+ skipNestedWithString(p, '(', ')');
+ while (isspace(*p))
+ p++;
+ // skip "const"
+ if (strncmp(p, "const", 5) == 0) {
+ p += 5;
+ while (isspace(*p))
+ p++;
+ }
+ } while (*p == '(');
+
+ // check for file position
+ if (strncmp(p, "at ", 3) == 0) {
+ p += 3;
+ const char* fileStart = p;
+ // go for the end of the line
+ while (*p != '\0' && *p != '\n')
+ p++;
+ // search back for colon
+ const char* colon = p;
+ do {
+ --colon;
+ } while (*colon != ':');
+ file = QString::fromLatin1(fileStart, colon-fileStart);
+ lineNo = atoi(colon+1)-1;
+ // skip new-line
+ if (*p != '\0')
+ p++;
+ } else {
+ // check for "from shared lib"
+ if (strncmp(p, "from ", 5) == 0) {
+ p += 5;
+ // go for the end of the line
+ while (*p != '\0' && *p != '\n')
+ p++;
+ // skip new-line
+ if (*p != '\0')
+ p++;
+ }
+ file = "";
+ lineNo = -1;
+ }
+ // construct the function name (including file info)
+ if (*p == '\0') {
+ func = start;
+ } else {
+ func = QString::fromLatin1(start, p-start-1); /* don't include \n */
+ }
+ s = p;
+
+ /*
+ * Replace \n (and whitespace around it) in func by a blank. We cannot
+ * use QString::simplifyWhiteSpace() for this because this would also
+ * simplify space that belongs to a string arguments that gdb sometimes
+ * prints in the argument lists of the function.
+ */
+ ASSERT(!isspace(func[0].latin1())); /* there must be non-white before first \n */
+ int nl = 0;
+ while ((nl = func.find('\n', nl)) >= 0) {
+ // search back to the beginning of the whitespace
+ int startWhite = nl;
+ do {
+ --startWhite;
+ } while (isspace(func[startWhite].latin1()));
+ startWhite++;
+ // search forward to the end of the whitespace
+ do {
+ nl++;
+ } while (isspace(func[nl].latin1()));
+ // replace
+ func.replace(startWhite, nl-startWhite, " ");
+ /* continue searching for more \n's at this place: */
+ nl = startWhite+1;
+ }
+}
+
+
+/**
+ * Parses a stack frame including its frame number
+ */
+static bool parseFrame(const char*& s, int& frameNo, QString& func,
+ QString& file, int& lineNo, DbgAddr& address)
+{
+ // Example:
+ // #1 0x8048881 in Dl::Dl (this=0xbffff418, r=3214) at testfile.cpp:72
+ // Breakpoint 3, Cl::f(int) const (this=0xbffff3c0, x=17) at testfile.cpp:155
+
+ // must start with a hash mark followed by number
+ // or with "Breakpoint " followed by number and comma
+ if (s[0] == '#') {
+ if (!isdigit(s[1]))
+ return false;
+ s++; /* skip the hash mark */
+ } else if (strncmp(s, "Breakpoint ", 11) == 0) {
+ if (!isdigit(s[11]))
+ return false;
+ s += 11; /* skip "Breakpoint" */
+ } else
+ return false;
+
+ // frame number
+ frameNo = atoi(s);
+ while (isdigit(*s))
+ s++;
+ // space and comma
+ while (isspace(*s) || *s == ',')
+ s++;
+ parseFrameInfo(s, func, file, lineNo, address);
+ return true;
+}
+
+void GdbDriver::parseBackTrace(const char* output, std::list<StackFrame>& stack)
+{
+ QString func, file;
+ int lineNo, frameNo;
+ DbgAddr address;
+
+ while (::parseFrame(output, frameNo, func, file, lineNo, address)) {
+ stack.push_back(StackFrame());
+ StackFrame* frm = &stack.back();
+ frm->frameNo = frameNo;
+ frm->fileName = file;
+ frm->lineNo = lineNo;
+ frm->address = address;
+ frm->var = new ExprValue(func, VarTree::NKplain);
+ }
+}
+
+bool GdbDriver::parseFrameChange(const char* output, int& frameNo,
+ QString& file, int& lineNo, DbgAddr& address)
+{
+ QString func;
+ return ::parseFrame(output, frameNo, func, file, lineNo, address);
+}
+
+
+bool GdbDriver::parseBreakList(const char* output, std::list<Breakpoint>& brks)
+{
+ // skip first line, which is the headline
+ const char* p = strchr(output, '\n');
+ if (p == 0)
+ return false;
+ p++;
+ if (*p == '\0')
+ return false;
+
+ // split up a line
+ const char* end;
+ char* dummy;
+ while (*p != '\0') {
+ Breakpoint bp;
+ // get Num
+ bp.id = strtol(p, &dummy, 10); /* don't care about overflows */
+ p = dummy;
+ // get Type
+ while (isspace(*p))
+ p++;
+ if (strncmp(p, "breakpoint", 10) == 0) {
+ p += 10;
+ } else if (strncmp(p, "hw watchpoint", 13) == 0) {
+ bp.type = Breakpoint::watchpoint;
+ p += 13;
+ } else if (strncmp(p, "watchpoint", 10) == 0) {
+ bp.type = Breakpoint::watchpoint;
+ p += 10;
+ }
+ while (isspace(*p))
+ p++;
+ if (*p == '\0')
+ break;
+ // get Disp
+ bp.temporary = *p++ == 'd';
+ while (*p != '\0' && !isspace(*p)) /* "keep" or "del" */
+ p++;
+ while (isspace(*p))
+ p++;
+ if (*p == '\0')
+ break;
+ // get Enb
+ bp.enabled = *p++ == 'y';
+ while (*p != '\0' && !isspace(*p)) /* "y" or "n" */
+ p++;
+ while (isspace(*p))
+ p++;
+ if (*p == '\0')
+ break;
+ // the address, if present
+ if (bp.type == Breakpoint::breakpoint &&
+ strncmp(p, "0x", 2) == 0)
+ {
+ const char* start = p;
+ while (*p != '\0' && !isspace(*p))
+ p++;
+ bp.address = QString::fromLatin1(start, p-start);
+ while (isspace(*p) && *p != '\n')
+ p++;
+ if (*p == '\0')
+ break;
+ }
+ // remainder is location, hit and ignore count, condition
+ end = strchr(p, '\n');
+ if (end == 0) {
+ bp.location = p;
+ p += bp.location.length();
+ } else {
+ bp.location = QString::fromLatin1(p, end-p).stripWhiteSpace();
+ p = end+1; /* skip over \n */
+ }
+
+ // may be continued in next line
+ while (isspace(*p)) { /* p points to beginning of line */
+ // skip white space at beginning of line
+ while (isspace(*p))
+ p++;
+
+ // seek end of line
+ end = strchr(p, '\n');
+ if (end == 0)
+ end = p+strlen(p);
+
+ if (strncmp(p, "breakpoint already hit", 22) == 0) {
+ // extract the hit count
+ p += 22;
+ bp.hitCount = strtol(p, &dummy, 10);
+ TRACE(QString("hit count %1").arg(bp.hitCount));
+ } else if (strncmp(p, "stop only if ", 13) == 0) {
+ // extract condition
+ p += 13;
+ bp.condition = QString::fromLatin1(p, end-p).stripWhiteSpace();
+ TRACE("condition: "+bp.condition);
+ } else if (strncmp(p, "ignore next ", 12) == 0) {
+ // extract ignore count
+ p += 12;
+ bp.ignoreCount = strtol(p, &dummy, 10);
+ TRACE(QString("ignore count %1").arg(bp.ignoreCount));
+ } else {
+ // indeed a continuation
+ bp.location += " " + QString::fromLatin1(p, end-p).stripWhiteSpace();
+ }
+ p = end;
+ if (*p != '\0')
+ p++; /* skip '\n' */
+ }
+ brks.push_back(bp);
+ }
+ return true;
+}
+
+std::list<ThreadInfo> GdbDriver::parseThreadList(const char* output)
+{
+ std::list<ThreadInfo> threads;
+ if (strcmp(output, "\n") == 0 || strncmp(output, "No stack.", 9) == 0) {
+ // no threads
+ return threads;
+ }
+
+ const char* p = output;
+ while (*p != '\0') {
+ ThreadInfo thr;
+ // seach look for thread id, watching out for the focus indicator
+ thr.hasFocus = false;
+ while (isspace(*p)) /* may be \n from prev line: see "No stack" below */
+ p++;
+ if (*p == '*') {
+ thr.hasFocus = true;
+ p++;
+ // there follows only whitespace
+ }
+ const char* end;
+ char *temp_end = NULL; /* we need a non-const 'end' for strtol to use...*/
+ thr.id = strtol(p, &temp_end, 10);
+ end = temp_end;
+ if (p == end) {
+ // syntax error: no number found; bail out
+ return threads;
+ }
+ p = end;
+
+ // skip space
+ while (isspace(*p))
+ p++;
+
+ /*
+ * Now follows the thread's SYSTAG. It is terminated by two blanks.
+ */
+ end = strstr(p, " ");
+ if (end == 0) {
+ // syntax error; bail out
+ return threads;
+ }
+ thr.threadName = QString::fromLatin1(p, end-p);
+ p = end+2;
+
+ /*
+ * Now follows a standard stack frame. Sometimes, however, gdb
+ * catches a thread at an instant where it doesn't have a stack.
+ */
+ if (strncmp(p, "[No stack.]", 11) != 0) {
+ ::parseFrameInfo(p, thr.function, thr.fileName, thr.lineNo, thr.address);
+ } else {
+ thr.function = "[No stack]";
+ thr.lineNo = -1;
+ p += 11; /* \n is skipped above */
+ }
+
+ threads.push_back(thr);
+ }
+ return threads;
+}
+
+static bool parseNewBreakpoint(const char* o, int& id,
+ QString& file, int& lineNo, QString& address);
+static bool parseNewWatchpoint(const char* o, int& id,
+ QString& expr);
+
+bool GdbDriver::parseBreakpoint(const char* output, int& id,
+ QString& file, int& lineNo, QString& address)
+{
+ const char* o = output;
+ // skip lines of that begin with "(Cannot find"
+ while (strncmp(o, "(Cannot find", 12) == 0) {
+ o = strchr(o, '\n');
+ if (o == 0)
+ return false;
+ o++; /* skip newline */
+ }
+
+ if (strncmp(o, "Breakpoint ", 11) == 0) {
+ output += 11; /* skip "Breakpoint " */
+ return ::parseNewBreakpoint(output, id, file, lineNo, address);
+ } else if (strncmp(o, "Hardware watchpoint ", 20) == 0) {
+ output += 20;
+ return ::parseNewWatchpoint(output, id, address);
+ } else if (strncmp(o, "Watchpoint ", 11) == 0) {
+ output += 11;
+ return ::parseNewWatchpoint(output, id, address);
+ }
+ return false;
+}
+
+static bool parseNewBreakpoint(const char* o, int& id,
+ QString& file, int& lineNo, QString& address)
+{
+ // breakpoint id
+ char* p;
+ id = strtoul(o, &p, 10);
+ if (p == o)
+ return false;
+
+ // check for the address
+ if (strncmp(p, " at 0x", 6) == 0) {
+ char* start = p+4; /* skip " at ", but not 0x */
+ p += 6;
+ while (isxdigit(*p))
+ ++p;
+ address = QString::fromLatin1(start, p-start);
+ }
+
+ // file name
+ char* fileStart = strstr(p, "file ");
+ if (fileStart == 0)
+ return !address.isEmpty(); /* parse error only if there's no address */
+ fileStart += 5;
+
+ // line number
+ char* numStart = strstr(fileStart, ", line ");
+ QString fileName = QString::fromLatin1(fileStart, numStart-fileStart);
+ numStart += 7;
+ int line = strtoul(numStart, &p, 10);
+ if (numStart == p)
+ return false;
+
+ file = fileName;
+ lineNo = line-1; /* zero-based! */
+ return true;
+}
+
+static bool parseNewWatchpoint(const char* o, int& id,
+ QString& expr)
+{
+ // watchpoint id
+ char* p;
+ id = strtoul(o, &p, 10);
+ if (p == o)
+ return false;
+
+ if (strncmp(p, ": ", 2) != 0)
+ return false;
+ p += 2;
+
+ // all the rest on the line is the expression
+ expr = QString::fromLatin1(p, strlen(p)).stripWhiteSpace();
+ return true;
+}
+
+void GdbDriver::parseLocals(const char* output, std::list<ExprValue*>& newVars)
+{
+ // check for possible error conditions
+ if (strncmp(output, "No symbol table", 15) == 0)
+ {
+ return;
+ }
+
+ while (*output != '\0') {
+ while (isspace(*output))
+ output++;
+ if (*output == '\0')
+ break;
+ // skip occurrences of "No locals" and "No args"
+ if (strncmp(output, "No locals", 9) == 0 ||
+ strncmp(output, "No arguments", 12) == 0)
+ {
+ output = strchr(output, '\n');
+ if (output == 0) {
+ break;
+ }
+ continue;
+ }
+
+ ExprValue* variable = parseVar(output);
+ if (variable == 0) {
+ break;
+ }
+ // do not add duplicates
+ for (std::list<ExprValue*>::iterator o = newVars.begin(); o != newVars.end(); ++o) {
+ if ((*o)->m_name == variable->m_name) {
+ delete variable;
+ goto skipDuplicate;
+ }
+ }
+ newVars.push_back(variable);
+ skipDuplicate:;
+ }
+}
+
+ExprValue* GdbDriver::parsePrintExpr(const char* output, bool wantErrorValue)
+{
+ ExprValue* var = 0;
+ // check for error conditions
+ if (!parseErrorMessage(output, var, wantErrorValue))
+ {
+ // parse the variable
+ var = parseVar(output);
+ }
+ return var;
+}
+
+bool GdbDriver::parseChangeWD(const char* output, QString& message)
+{
+ bool isGood = false;
+ message = QString(output).simplifyWhiteSpace();
+ if (message.isEmpty()) {
+ message = i18n("New working directory: ") + m_programWD;
+ isGood = true;
+ }
+ return isGood;
+}
+
+bool GdbDriver::parseChangeExecutable(const char* output, QString& message)
+{
+ message = output;
+
+ m_haveCoreFile = false;
+
+ /*
+ * Lines starting with the following do not indicate errors:
+ * Using host libthread_db
+ * (no debugging symbols found)
+ */
+ while (strncmp(output, "Using host libthread_db", 23) == 0 ||
+ strncmp(output, "(no debugging symbols found)", 28) == 0)
+ {
+ // this line is good, go to the next one
+ const char* end = strchr(output, '\n');
+ if (end == 0)
+ output += strlen(output);
+ else
+ output = end+1;
+ }
+
+ /*
+ * If we've parsed all lines, there was no error.
+ */
+ return output[0] == '\0';
+}
+
+bool GdbDriver::parseCoreFile(const char* output)
+{
+ // if command succeeded, gdb emits a line starting with "#0 "
+ m_haveCoreFile = strstr(output, "\n#0 ") != 0;
+ return m_haveCoreFile;
+}
+
+uint GdbDriver::parseProgramStopped(const char* output, QString& message)
+{
+ // optionally: "program changed, rereading symbols",
+ // followed by:
+ // "Program exited normally"
+ // "Program terminated with wignal SIGSEGV"
+ // "Program received signal SIGINT" or other signal
+ // "Breakpoint..."
+
+ // go through the output, line by line, checking what we have
+ const char* start = output - 1;
+ uint flags = SFprogramActive;
+ message = QString();
+ do {
+ start++; /* skip '\n' */
+
+ if (strncmp(start, "Program ", 8) == 0 ||
+ strncmp(start, "ptrace: ", 8) == 0) {
+ /*
+ * When we receive a signal, the program remains active.
+ *
+ * Special: If we "stopped" in a corefile, the string "Program
+ * terminated with signal"... is displayed. (Normally, we see
+ * "Program received signal"... when a signal happens.)
+ */
+ if (strncmp(start, "Program exited", 14) == 0 ||
+ (strncmp(start, "Program terminated", 18) == 0 && !m_haveCoreFile) ||
+ strncmp(start, "ptrace: ", 8) == 0)
+ {
+ flags &= ~SFprogramActive;
+ }
+
+ // set message
+ const char* endOfMessage = strchr(start, '\n');
+ if (endOfMessage == 0)
+ endOfMessage = start + strlen(start);
+ message = QString::fromLatin1(start, endOfMessage-start);
+ } else if (strncmp(start, "Breakpoint ", 11) == 0) {
+ /*
+ * We stopped at a (permanent) breakpoint (gdb doesn't tell us
+ * that it stopped at a temporary breakpoint).
+ */
+ flags |= SFrefreshBreak;
+ } else if (strstr(start, "re-reading symbols.") != 0) {
+ flags |= SFrefreshSource;
+ }
+
+ // next line, please
+ start = strchr(start, '\n');
+ } while (start != 0);
+
+ /*
+ * Gdb only notices when new threads have appeared, but not when a
+ * thread finishes. So we always have to assume that the list of
+ * threads has changed.
+ */
+ flags |= SFrefreshThreads;
+
+ return flags;
+}
+
+QStringList GdbDriver::parseSharedLibs(const char* output)
+{
+ QStringList shlibs;
+ if (strncmp(output, "No shared libraries loaded", 26) == 0)
+ return shlibs;
+
+ // parse the table of shared libraries
+
+ // strip off head line
+ output = strchr(output, '\n');
+ if (output == 0)
+ return shlibs;
+ output++; /* skip '\n' */
+ QString shlibName;
+ while (*output != '\0') {
+ // format of a line is
+ // 0x404c5000 0x40580d90 Yes /lib/libc.so.5
+ // 3 blocks of non-space followed by space
+ for (int i = 0; *output != '\0' && i < 3; i++) {
+ while (*output != '\0' && !isspace(*output)) { /* non-space */
+ output++;
+ }
+ while (isspace(*output)) { /* space */
+ output++;
+ }
+ }
+ if (*output == '\0')
+ return shlibs;
+ const char* start = output;
+ output = strchr(output, '\n');
+ if (output == 0)
+ output = start + strlen(start);
+ shlibName = QString::fromLatin1(start, output-start);
+ if (*output != '\0')
+ output++;
+ shlibs.append(shlibName);
+ TRACE("found shared lib " + shlibName);
+ }
+ return shlibs;
+}
+
+bool GdbDriver::parseFindType(const char* output, QString& type)
+{
+ if (strncmp(output, "type = ", 7) != 0)
+ return false;
+
+ /*
+ * Everything else is the type. We strip off any leading "const" and any
+ * trailing "&" on the grounds that neither affects the decoding of the
+ * object. We also strip off all white-space from the type.
+ */
+ output += 7;
+ if (strncmp(output, "const ", 6) == 0)
+ output += 6;
+ type = output;
+ type.replace(QRegExp("\\s+"), "");
+ if (type.endsWith("&"))
+ type.truncate(type.length() - 1);
+ return true;
+}
+
+std::list<RegisterInfo> GdbDriver::parseRegisters(const char* output)
+{
+ std::list<RegisterInfo> regs;
+ if (strncmp(output, "The program has no registers now", 32) == 0) {
+ return regs;
+ }
+
+ QString value;
+
+ // parse register values
+ while (*output != '\0')
+ {
+ RegisterInfo reg;
+ // skip space at the start of the line
+ while (isspace(*output))
+ output++;
+
+ // register name
+ const char* start = output;
+ while (*output != '\0' && !isspace(*output))
+ output++;
+ if (*output == '\0')
+ break;
+ reg.regName = QString::fromLatin1(start, output-start);
+
+ // skip space
+ while (isspace(*output))
+ output++;
+
+ /*
+ * If we find a brace now, this is a vector register. We look for
+ * the closing brace and treat the result as cooked value.
+ */
+ if (*output == '{')
+ {
+ start = output;
+ skipNested(output, '{', '}');
+ value = QString::fromLatin1(start, output-start).simplifyWhiteSpace();
+ // skip space, but not the end of line
+ while (isspace(*output) && *output != '\n')
+ output++;
+ // get rid of the braces at the begining and the end
+ value.remove(0, 1);
+ if (value[value.length()-1] == '}') {
+ value = value.left(value.length()-1);
+ }
+ // gdb 5.3 doesn't print a separate set of raw values
+ if (*output == '{') {
+ // another set of vector follows
+ // what we have so far is the raw value
+ reg.rawValue = value;
+
+ start = output;
+ skipNested(output, '{', '}');
+ value = QString::fromLatin1(start, output-start).simplifyWhiteSpace();
+ } else {
+ // for gdb 5.3
+ // find first type that does not have an array, this is the RAW value
+ const char* end=start;
+ findEnd(end);
+ const char* cur=start;
+ while (cur<end) {
+ while (*cur != '=' && cur<end)
+ cur++;
+ cur++;
+ while (isspace(*cur) && cur<end)
+ cur++;
+ if (isNumberish(*cur)) {
+ end=cur;
+ while (*end && (*end!='}') && (*end!=',') && (*end!='\n'))
+ end++;
+ QString rawValue = QString::fromLatin1(cur, end-cur).simplifyWhiteSpace();
+ reg.rawValue = rawValue;
+
+ if (rawValue.left(2)=="0x") {
+ // ok we have a raw value, now get it's type
+ end=cur-1;
+ while (isspace(*end) || *end=='=') end--;
+ end++;
+ cur=end-1;
+ while (*cur!='{' && *cur!=' ')
+ cur--;
+ cur++;
+ reg.type = QString::fromLatin1(cur, end-cur);
+ }
+
+ // end while loop
+ cur=end;
+ }
+ }
+ // skip to the end of line
+ while (*output != '\0' && *output != '\n')
+ output++;
+ // get rid of the braces at the begining and the end
+ value.remove(0, 1);
+ if (value[value.length()-1] == '}') {
+ value.truncate(value.length()-1);
+ }
+ }
+ reg.cookedValue = value;
+ }
+ else
+ {
+ // the rest of the line is the register value
+ start = output;
+ output = strchr(output,'\n');
+ if (output == 0)
+ output = start + strlen(start);
+ value = QString::fromLatin1(start, output-start).simplifyWhiteSpace();
+
+ /*
+ * We split the raw from the cooked values.
+ * Some modern gdbs explicitly say: "0.1234 (raw 0x3e4567...)".
+ * Here, the cooked value comes first, and the raw value is in
+ * the second part.
+ */
+ int pos = value.find(" (raw ");
+ if (pos >= 0)
+ {
+ reg.cookedValue = value.left(pos);
+ reg.rawValue = value.mid(pos+6);
+ if (reg.rawValue.right(1) == ")") // remove closing bracket
+ reg.rawValue.truncate(reg.rawValue.length()-1);
+ }
+ else
+ {
+ /*
+ * In other cases we split off the first token (separated by
+ * whitespace). It is the raw value. The remainder of the line
+ * is the cooked value.
+ */
+ int pos = value.find(' ');
+ if (pos < 0) {
+ reg.rawValue = value;
+ reg.cookedValue = QString();
+ } else {
+ reg.rawValue = value.left(pos);
+ reg.cookedValue = value.mid(pos+1);
+ }
+ }
+ }
+ if (*output != '\0')
+ output++; /* skip '\n' */
+
+ regs.push_back(reg);
+ }
+ return regs;
+}
+
+bool GdbDriver::parseInfoLine(const char* output, QString& addrFrom, QString& addrTo)
+{
+ // "is at address" or "starts at address"
+ const char* start = strstr(output, "s at address ");
+ if (start == 0)
+ return false;
+
+ start += 13;
+ const char* p = start;
+ while (*p != '\0' && !isspace(*p))
+ p++;
+ addrFrom = QString::fromLatin1(start, p-start);
+
+ start = strstr(p, "and ends at ");
+ if (start == 0) {
+ addrTo = addrFrom;
+ return true;
+ }
+
+ start += 12;
+ p = start;
+ while (*p != '\0' && !isspace(*p))
+ p++;
+ addrTo = QString::fromLatin1(start, p-start);
+
+ return true;
+}
+
+std::list<DisassembledCode> GdbDriver::parseDisassemble(const char* output)
+{
+ std::list<DisassembledCode> code;
+
+ if (strncmp(output, "Dump of assembler", 17) != 0) {
+ // error message?
+ DisassembledCode c;
+ c.code = output;
+ code.push_back(c);
+ return code;
+ }
+
+ // remove first line
+ const char* p = strchr(output, '\n');
+ if (p == 0)
+ return code; /* not a regular output */
+
+ p++;
+
+ // remove last line
+ const char* end = strstr(output, "End of assembler");
+ if (end == 0)
+ end = p + strlen(p);
+
+ // remove function offsets from the lines
+ while (p != end)
+ {
+ DisassembledCode c;
+ const char* start = p;
+ // address
+ while (p != end && !isspace(*p))
+ p++;
+ c.address = QString::fromLatin1(start, p-start);
+
+ // function name (enclosed in '<>', followed by ':')
+ while (p != end && *p != '<')
+ p++;
+ if (*p == '<')
+ skipNestedAngles(p);
+ if (*p == ':')
+ p++;
+
+ // space until code
+ while (p != end && isspace(*p))
+ p++;
+
+ // code until end of line
+ start = p;
+ while (p != end && *p != '\n')
+ p++;
+ if (p != end) /* include '\n' */
+ p++;
+
+ c.code = QString::fromLatin1(start, p-start);
+ code.push_back(c);
+ }
+ return code;
+}
+
+QString GdbDriver::parseMemoryDump(const char* output, std::list<MemoryDump>& memdump)
+{
+ if (isErrorExpr(output)) {
+ // error; strip space
+ QString msg = output;
+ return msg.stripWhiteSpace();
+ }
+
+ const char* p = output; /* save typing */
+
+ // the address
+ while (*p != 0) {
+ MemoryDump md;
+
+ const char* start = p;
+ while (*p != '\0' && *p != ':' && !isspace(*p))
+ p++;
+ md.address = QString::fromLatin1(start, p-start);
+ if (*p != ':') {
+ // parse function offset
+ while (isspace(*p))
+ p++;
+ start = p;
+ while (*p != '\0' && !(*p == ':' && isspace(p[1])))
+ p++;
+ md.address.fnoffs = QString::fromLatin1(start, p-start);
+ }
+ if (*p == ':')
+ p++;
+ // skip space; this may skip a new-line char!
+ while (isspace(*p))
+ p++;
+ // everything to the end of the line is the memory dump
+ const char* end = strchr(p, '\n');
+ if (end != 0) {
+ md.dump = QString::fromLatin1(p, end-p);
+ p = end+1;
+ } else {
+ md.dump = QString::fromLatin1(p, strlen(p));
+ p += strlen(p);
+ }
+ memdump.push_back(md);
+ }
+
+ return QString();
+}
+
+QString GdbDriver::editableValue(VarTree* value)
+{
+ const char* s = value->value().latin1();
+
+ // if the variable is a pointer value that contains a cast,
+ // remove the cast
+ if (*s == '(') {
+ skipNested(s, '(', ')');
+ // skip space
+ while (isspace(*s))
+ ++s;
+ }
+
+repeat:
+ const char* start = s;
+
+ if (strncmp(s, "0x", 2) == 0)
+ {
+ s += 2;
+ while (isxdigit(*s))
+ ++s;
+
+ /*
+ * What we saw so far might have been a reference. If so, edit the
+ * referenced value. Otherwise, edit the pointer.
+ */
+ if (*s == ':') {
+ // a reference
+ ++s;
+ goto repeat;
+ }
+ // a pointer
+ // if it's a pointer to a string, remove the string
+ const char* end = s;
+ while (isspace(*s))
+ ++s;
+ if (*s == '"') {
+ // a string
+ return QString::fromLatin1(start, end-start);
+ } else {
+ // other pointer
+ return QString::fromLatin1(start, strlen(start));
+ }
+ }
+
+ // else leave it unchanged (or stripped of the reference preamble)
+ return s;
+}
+
+QString GdbDriver::parseSetVariable(const char* output)
+{
+ // if there is any output, it is an error message
+ QString msg = output;
+ return msg.stripWhiteSpace();
+}
+
+
+#include "gdbdriver.moc"
diff --git a/kdbg/gdbdriver.h b/kdbg/gdbdriver.h
new file mode 100644
index 0000000..c92248a
--- /dev/null
+++ b/kdbg/gdbdriver.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef GDBDRIVER_H
+#define GDBDRIVER_H
+
+#include "dbgdriver.h"
+
+
+class GdbDriver : public DebuggerDriver
+{
+ Q_OBJECT
+public:
+ GdbDriver();
+ ~GdbDriver();
+
+ virtual QString driverName() const;
+ virtual QString defaultInvocation() const;
+ virtual QStringList boolOptionList() const;
+ void setDefaultInvocation(QString cmd) { m_defaultCmd = cmd; }
+ static QString defaultGdb();
+ virtual bool startup(QString cmdStr);
+ virtual void commandFinished(CmdQueueItem* cmd);
+ virtual CmdQueueItem* executeCmd(DbgCommand,
+ bool clearLow = false);
+ virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg,
+ bool clearLow = false);
+ virtual CmdQueueItem* executeCmd(DbgCommand, int intArg,
+ bool clearLow = false);
+ virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg, int intArg,
+ bool clearLow = false);
+ virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg1, QString strArg2,
+ bool clearLow = false);
+ virtual CmdQueueItem* executeCmd(DbgCommand, int intArg1, int intArg2,
+ bool clearLow = false);
+ virtual CmdQueueItem* queueCmd(DbgCommand,
+ QueueMode mode);
+ virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg,
+ QueueMode mode);
+ virtual CmdQueueItem* queueCmd(DbgCommand, int intArg,
+ QueueMode mode);
+ virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg, int intArg,
+ QueueMode mode);
+ virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg1, QString strArg2,
+ QueueMode mode);
+
+ virtual void terminate();
+ virtual void detachAndTerminate();
+ virtual void interruptInferior();
+ virtual void setPrintQStringDataCmd(const char* cmd);
+ virtual ExprValue* parseQCharArray(const char* output, bool wantErrorValue, bool qt3like);
+ virtual void parseBackTrace(const char* output, std::list<StackFrame>& stack);
+ virtual bool parseFrameChange(const char* output, int& frameNo,
+ QString& file, int& lineNo, DbgAddr& address);
+ virtual bool parseBreakList(const char* output, std::list<Breakpoint>& brks);
+ virtual std::list<ThreadInfo> parseThreadList(const char* output);
+ virtual bool parseBreakpoint(const char* output, int& id,
+ QString& file, int& lineNo, QString& address);
+ virtual void parseLocals(const char* output, std::list<ExprValue*>& newVars);
+ virtual ExprValue* parsePrintExpr(const char* output, bool wantErrorValue);
+ virtual bool parseChangeWD(const char* output, QString& message);
+ virtual bool parseChangeExecutable(const char* output, QString& message);
+ virtual bool parseCoreFile(const char* output);
+ virtual uint parseProgramStopped(const char* output, QString& message);
+ virtual QStringList parseSharedLibs(const char* output);
+ virtual bool parseFindType(const char* output, QString& type);
+ virtual std::list<RegisterInfo> parseRegisters(const char* output);
+ virtual bool parseInfoLine(const char* output,
+ QString& addrFrom, QString& addrTo);
+ virtual std::list<DisassembledCode> parseDisassemble(const char* output);
+ virtual QString parseMemoryDump(const char* output, std::list<MemoryDump>& memdump);
+ virtual QString parseSetVariable(const char* output);
+ virtual QString editableValue(VarTree* value);
+protected:
+ int m_gdbMajor, m_gdbMinor;
+ QString m_programWD; /* just an intermediate storage */
+ QString m_redirect; /* redirection to /dev/null */
+ bool m_haveCoreFile;
+ QString m_defaultCmd; /* how to invoke gdb */
+
+ QString makeCmdString(DbgCommand cmd, QString strArg);
+ QString makeCmdString(DbgCommand cmd, int intArg);
+ QString makeCmdString(DbgCommand cmd, QString strArg, int intArg);
+ QString makeCmdString(DbgCommand cmd, QString strArg1, QString strArg2);
+ QString makeCmdString(DbgCommand cmd, int intArg1, int intArg2);
+ void parseMarker();
+};
+
+#endif // GDBDRIVER_H
diff --git a/kdbg/kdbg.desktop b/kdbg/kdbg.desktop
new file mode 100644
index 0000000..f80fb55
--- /dev/null
+++ b/kdbg/kdbg.desktop
@@ -0,0 +1,42 @@
+[Desktop Entry]
+Exec=kdbg -caption "%c" %i
+Icon=kdbg
+Type=Application
+X-DocPath=kdbg/index.html
+Name=KDbg
+GenericName=Debugger
+GenericName[br]=Dizraener
+GenericName[da]=Afluser
+GenericName[es]=Depurador
+GenericName[fi]=Debuggeri
+GenericName[fr]=Débogueur
+GenericName[is]=Aflúsun
+GenericName[no]=Avluser
+GenericName[pt]=Depurador
+GenericName[pt_BR]=Depurador
+GenericName[ro]=Depanator
+GenericName[ru]=Отладчик
+GenericName[sk]=Ladiaci program
+GenericName[sl]=Razhroščevalnik
+GenericName[sv]=Avlusare
+Comment=Debug programs
+Comment[br]=Goulevioù dizraenañ
+Comment[ca]=Programes per localització d'errors
+Comment[cs]=Ladídí program
+Comment[da]=Afluseprogrammer
+Comment[de]=Programme debuggen
+Comment[es]=Depurador de programas
+Comment[fi]=Tutki ohjelmien toimintaa
+Comment[fr]=Déboguer un programme
+Comment[is]=kdbg: Forrit til ađ aflúsa önnur forrit
+Comment[no]=Avluse programmer
+Comment[pl]=Program do debugowania
+Comment[pt]=Depurador de programas
+Comment[pt_BR]=Depurador de programas
+Comment[ro]=Depanator de programe
+Comment[ru]=Отлаживает программы
+Comment[sk]=Ladiaci program
+Comment[sl]=Odpravljanje napak v programih
+Comment[sv]=Avlusar program
+Terminal=false
+Categories=Qt;KDE;Development;Debugger;
diff --git a/kdbg/kdbgrc b/kdbg/kdbgrc
new file mode 100644
index 0000000..5c3eb17
--- /dev/null
+++ b/kdbg/kdbgrc
@@ -0,0 +1,50 @@
+[dock_setting_default]
+Breakpoints:type=DOCK
+Locals,Watches:first_name=Locals
+Locals,Watches:last_name=Watches
+Locals,Watches:orientation=1
+Locals,Watches:parent=yes
+Locals,Watches:sepPos=68
+Locals,Watches:type=GROUP
+Locals:type=DOCK
+Main:Geometry=0,0,880,778
+Main:dock=Source
+Main:view=Source,Stack,Breakpoints,Output,Locals,Watches
+Main:visible=false
+Memory:dockBackTo=
+Memory:dockBackToPos=0
+Memory:geometry=0,0,640,409
+Memory:type=NULL_DOCK
+Memory:visible=false
+NameList=Source,Stack,Locals,Watches,Registers,Breakpoints,Output,Threads,Memory,Locals\\,Watches,Stack\\,Breakpoints\\,Output,Source\\,Stack\\,Breakpoints\\,Output,Source\\,Stack\\,Breakpoints\\,Output\\,Locals\\,Watches
+Output:type=DOCK
+Registers:dockBackTo=
+Registers:dockBackToPos=0
+Registers:geometry=0,0,640,409
+Registers:type=NULL_DOCK
+Registers:visible=false
+Source,Stack,Breakpoints,Output,Locals,Watches:first_name=Source,Stack,Breakpoints,Output
+Source,Stack,Breakpoints,Output,Locals,Watches:last_name=Locals,Watches
+Source,Stack,Breakpoints,Output,Locals,Watches:orientation=0
+Source,Stack,Breakpoints,Output,Locals,Watches:parent=yes
+Source,Stack,Breakpoints,Output,Locals,Watches:sepPos=63
+Source,Stack,Breakpoints,Output,Locals,Watches:type=GROUP
+Source,Stack,Breakpoints,Output:first_name=Source
+Source,Stack,Breakpoints,Output:last_name=Stack,Breakpoints,Output
+Source,Stack,Breakpoints,Output:orientation=1
+Source,Stack,Breakpoints,Output:parent=yes
+Source,Stack,Breakpoints,Output:sepPos=59
+Source,Stack,Breakpoints,Output:type=GROUP
+Source:type=DOCK
+Stack,Breakpoints,Output:curTab=1
+Stack,Breakpoints,Output:parent=yes
+Stack,Breakpoints,Output:tabNames=Stack,Breakpoints,Output
+Stack,Breakpoints,Output:type=TAB_GROUP
+Stack:type=DOCK
+Threads:dockBackTo=
+Threads:dockBackToPos=0
+Threads:geometry=0,0,640,409
+Threads:type=NULL_DOCK
+Threads:visible=false
+Version=0.0.4
+Watches:type=DOCK
diff --git a/kdbg/kdbgui.rc b/kdbg/kdbgui.rc
new file mode 100644
index 0000000..5d93a80
--- /dev/null
+++ b/kdbg/kdbgui.rc
@@ -0,0 +1,88 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="kdbg" version="2">
+<MenuBar>
+ <Menu name="file"><text>&amp;File</text>
+ <Action name="file_executable" append="open_merge"/>
+ <Action name="file_executable_recent"/>
+ <Action name="file_core_dump"/>
+ <Action name="file_reload" append="close_merge"/>
+
+ </Menu>
+ <Menu name="view"><text>&amp;View</text>
+ <Action name="view_find"/>
+ <Action name="view_findnext"/>
+ <Action name="view_findprev"/>
+ <Separator/>
+ <Action name="view_stack"/>
+ <Action name="view_locals"/>
+ <Action name="view_watched_expressions"/>
+ <Action name="view_registers"/>
+ <Action name="view_breakpoints"/>
+ <Action name="view_threads"/>
+ <Action name="view_output"/>
+ <Action name="view_memory"/>
+ </Menu>
+ <Menu name="execution"><text>E&amp;xecution</text>
+ <Action name="exec_run"/>
+ <Action name="exec_step_into"/>
+ <Action name="exec_step_over"/>
+ <Action name="exec_step_out"/>
+ <Action name="exec_run_to_cursor"/>
+ <Action name="exec_step_into_by_insn"/>
+ <Action name="exec_step_over_by_insn"/>
+ <Action name="exec_movepc"/>
+ <Separator/>
+ <Action name="exec_break"/>
+ <Action name="exec_kill"/>
+ <Action name="exec_restart"/>
+ <Action name="exec_attach"/>
+ <Separator/>
+ <Action name="exec_arguments"/>
+ </Menu>
+ <Menu name="breakpoint"><text>&amp;Breakpoint</text>
+ <Action name="breakpoint_set"/>
+ <Action name="breakpoint_set_temporary"/>
+ <Action name="breakpoint_enable"/>
+ </Menu>
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Action name="settings_program"/>
+ <Action name="settings_global"/>
+ </Menu>
+</MenuBar>
+<Menu name="popup_files">
+ <Action name="file_open"/>
+ <Separator/>
+ <Action name="exec_step_into"/>
+ <Action name="exec_step_over"/>
+ <Action name="exec_step_out"/>
+ <Action name="exec_step_run_to_cursor"/>
+ <Action name="exec_movepc"/>
+ <Separator/>
+ <Action name="breakpoint_set"/>
+</Menu>
+<Menu name="popup_files_empty">
+ <Action name="file_open"/>
+ <Separator/>
+ <Action name="file_executable"/>
+ <Action name="file_core_dump"/>
+</Menu>
+<Menu name="popup_locals">
+ <Action name="watch_expression"/>
+ <Action name="edit_value"/>
+</Menu>
+<ToolBar name="mainToolBar">
+ <Action name="file_reload"/>
+ <Action name="file_executable"/>
+ <Separator/>
+ <Action name="exec_run"/>
+ <Action name="exec_step_into"/>
+ <Action name="exec_step_over"/>
+ <Action name="exec_step_out"/>
+ <Action name="exec_step_into_by_insn"/>
+ <Action name="exec_step_over_by_insn"/>
+ <Separator/>
+ <Action name="breakpoint_set"/>
+ <Separator/>
+ <Action name="view_find"/>
+</ToolBar>
+</kpartgui>
diff --git a/kdbg/main.cpp b/kdbg/main.cpp
new file mode 100644
index 0000000..0f067e3
--- /dev/null
+++ b/kdbg/main.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include <kapplication.h>
+#include <klocale.h> /* i18n */
+#include <kmessagebox.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <kpopupmenu.h>
+#include <kmenubar.h>
+#include "dbgmainwnd.h"
+#include "typetable.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifndef VERSION
+#define VERSION ""
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h> /* open(2) */
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* getopt(3) */
+#endif
+#include <stdlib.h> /* getenv(3) */
+#include "mydebug.h"
+
+
+int main(int argc, char** argv)
+{
+ KAboutData aboutData("kdbg", "KDbg",
+ VERSION,
+ I18N_NOOP("A Debugger"),
+ KAboutData::License_GPL,
+ "(c) 1998-2010 Johannes Sixt",
+ 0, /* any text */
+ "http://www.kdbg.org/",
+ "j6t@kdbg.org");
+ aboutData.addAuthor("Johannes Sixt", 0, "j6t@kdbg.org");
+ aboutData.addCredit("Keith Isdale",
+ I18N_NOOP("XSLT debugging"),
+ "k_isdale@tpg.com.au");
+ aboutData.addCredit("Daniel Kristjansson",
+ I18N_NOOP("Register groups and formating"),
+ "danielk@cat.nyu.edu");
+ KCmdLineArgs::init( argc, argv, &aboutData );
+
+ static KCmdLineOptions options[] = {
+ { "t <file>", I18N_NOOP("transcript of conversation with the debugger"), 0 },
+ { "r <device>", I18N_NOOP("remote debugging via <device>"), 0 },
+ { "l <language>", I18N_NOOP("specify language: C, XSLT"), ""},
+ { "x", I18N_NOOP("use language XSLT (deprecated)"), 0 },
+ { "a <args>", I18N_NOOP("specify arguments of debugged executable"), 0},
+ { "p <pid>", I18N_NOOP("specify PID of process to debug"), 0},
+ { "+[program]", I18N_NOOP("path of executable to debug"), 0 },
+ { "+[core]", I18N_NOOP("a core file to use"), 0},
+ { 0, 0, 0 }
+ };
+ KCmdLineArgs::addCmdLineOptions(options);
+
+ KApplication app;
+
+ KGlobal::dirs()->addResourceType("types", "share/apps/kdbg/types");
+
+ DebuggerMainWnd* debugger = new DebuggerMainWnd("kdbg_main");
+
+ /* type libraries */
+ TypeTable::initTypeLibraries();
+
+ // session management
+ bool restored = false;
+ if (app.isRestored()) {
+ if (KMainWindow::canBeRestored(1)) {
+ debugger->restore(1);
+ restored = true;
+ }
+ }
+
+ app.setMainWidget(debugger);
+
+ debugger->show();
+
+ // handle options
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ QString transcript = args->getOption("t");
+ QString remote = args->getOption("r");
+ if (!remote.isEmpty())
+ debugger->setRemoteDevice(remote);
+
+ QString lang = args->getOption("l");
+
+ // deprecated option; overrides -l
+ if (args->isSet("x")){
+ /* run in xsldbg mode */
+ lang = "xslt";
+ }
+
+ // check environment variable for transcript file name
+ if (transcript.isEmpty()) {
+ transcript = getenv("KDBG_TRANSCRIPT");
+ }
+ debugger->setTranscript(transcript);
+
+ QString pid = args->getOption("p");
+ QString programArgs = args->getOption("a");
+
+ if (!restored && args->count() > 0) {
+ // attach to process?
+ if (!pid.isEmpty()) {
+ TRACE("pid: " + pid);
+ debugger->setAttachPid(pid);
+ }
+ // check for core file; use it only if we're not attaching to a process
+ else if (args->count() > 1 && pid.isEmpty()) {
+ debugger->setCoreFile(args->arg(1));
+ }
+ if (!debugger->debugProgram(args->arg(0), lang)) {
+ // failed
+ TRACE("cannot start debugger");
+ KMessageBox::error(debugger, i18n("Cannot start debugger."));
+
+ debugger->setCoreFile(QString());
+ debugger->setAttachPid(QString());
+ } else {
+ if (!programArgs.isEmpty()) {
+ debugger->overrideProgramArguments(programArgs);
+ }
+ }
+ }
+
+ int rc = app.exec();
+ return rc;
+}
diff --git a/kdbg/mainwndbase.cpp b/kdbg/mainwndbase.cpp
new file mode 100644
index 0000000..924e5a7
--- /dev/null
+++ b/kdbg/mainwndbase.cpp
@@ -0,0 +1,637 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include <kapplication.h>
+#include <klocale.h> /* i18n */
+#include <kconfig.h>
+#include <kmessagebox.h>
+#include <kstatusbar.h>
+#include <kfiledialog.h>
+#include <qtabdialog.h>
+#include <qfile.h>
+#include <qdragobject.h>
+#include "mainwndbase.h"
+#include "debugger.h"
+#include "gdbdriver.h"
+#include "xsldbgdriver.h"
+#include "prefdebugger.h"
+#include "prefmisc.h"
+#include "ttywnd.h"
+#include "commandids.h"
+#ifdef HAVE_CONFIG
+#include "config.h"
+#endif
+#include "mydebug.h"
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h> /* mknod(2) */
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h> /* open(2) */
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* getpid, unlink etc. */
+#endif
+
+#define MAX_RECENT_FILES 4
+
+WatchWindow::WatchWindow(QWidget* parent, const char* name, WFlags f) :
+ QWidget(parent, name, f),
+ m_watchEdit(this, "watch_edit"),
+ m_watchAdd(i18n(" Add "), this, "watch_add"),
+ m_watchDelete(i18n(" Del "), this, "watch_delete"),
+ m_watchVariables(this, i18n("Expression"), "watch_variables"),
+ m_watchV(this, 0),
+ m_watchH(0)
+{
+ // setup the layout
+ m_watchAdd.setMinimumSize(m_watchAdd.sizeHint());
+ m_watchDelete.setMinimumSize(m_watchDelete.sizeHint());
+ m_watchV.addLayout(&m_watchH, 0);
+ m_watchV.addWidget(&m_watchVariables, 10);
+ m_watchH.addWidget(&m_watchEdit, 10);
+ m_watchH.addWidget(&m_watchAdd, 0);
+ m_watchH.addWidget(&m_watchDelete, 0);
+
+ connect(&m_watchEdit, SIGNAL(returnPressed()), SIGNAL(addWatch()));
+ connect(&m_watchAdd, SIGNAL(clicked()), SIGNAL(addWatch()));
+ connect(&m_watchDelete, SIGNAL(clicked()), SIGNAL(deleteWatch()));
+ connect(&m_watchVariables, SIGNAL(currentChanged(QListViewItem*)),
+ SLOT(slotWatchHighlighted()));
+
+ m_watchVariables.installEventFilter(this);
+ setAcceptDrops(true);
+}
+
+WatchWindow::~WatchWindow()
+{
+}
+
+bool WatchWindow::eventFilter(QObject*, QEvent* ev)
+{
+ if (ev->type() == QEvent::KeyPress)
+ {
+ QKeyEvent* kev = static_cast<QKeyEvent*>(ev);
+ if (kev->key() == Key_Delete) {
+ emit deleteWatch();
+ return true;
+ }
+ }
+ return false;
+}
+
+void WatchWindow::dragEnterEvent(QDragEnterEvent* event)
+{
+ event->accept(QTextDrag::canDecode(event));
+}
+
+void WatchWindow::dropEvent(QDropEvent* event)
+{
+ QString text;
+ if (QTextDrag::decode(event, text))
+ {
+ // pick only the first line
+ text = text.stripWhiteSpace();
+ int pos = text.find('\n');
+ if (pos > 0)
+ text.truncate(pos);
+ text = text.stripWhiteSpace();
+ if (!text.isEmpty())
+ emit textDropped(text);
+ }
+}
+
+
+// place the text of the hightlighted watch expr in the edit field
+void WatchWindow::slotWatchHighlighted()
+{
+ VarTree* expr = m_watchVariables.selectedItem();
+ QString text = expr ? expr->computeExpr() : QString();
+ m_watchEdit.setText(text);
+}
+
+
+const char defaultTermCmdStr[] = "xterm -name kdbgio -title %T -e sh -c %C";
+const char defaultSourceFilter[] = "*.c *.cc *.cpp *.c++ *.C *.CC";
+const char defaultHeaderFilter[] = "*.h *.hh *.hpp *.h++";
+
+
+DebuggerMainWndBase::DebuggerMainWndBase() :
+ m_outputTermCmdStr(defaultTermCmdStr),
+ m_outputTermProc(0),
+ m_ttyLevel(-1), /* no tty yet */
+#ifdef GDB_TRANSCRIPT
+ m_transcriptFile(GDB_TRANSCRIPT),
+#endif
+ m_popForeground(false),
+ m_backTimeout(1000),
+ m_tabWidth(0),
+ m_sourceFilter(defaultSourceFilter),
+ m_headerFilter(defaultHeaderFilter),
+ m_debugger(0)
+{
+ m_statusActive = i18n("active");
+}
+
+DebuggerMainWndBase::~DebuggerMainWndBase()
+{
+ delete m_debugger;
+
+ // if the output window is open, close it
+ if (m_outputTermProc != 0) {
+ m_outputTermProc->disconnect(); /* ignore signals */
+ m_outputTermProc->kill();
+ shutdownTermWindow();
+ }
+}
+
+void DebuggerMainWndBase::setupDebugger(QWidget* parent,
+ ExprWnd* localVars,
+ ExprWnd* watchVars,
+ QListBox* backtrace)
+{
+ m_debugger = new KDebugger(parent, localVars, watchVars, backtrace);
+
+ QObject::connect(m_debugger, SIGNAL(updateStatusMessage()),
+ parent, SLOT(slotNewStatusMsg()));
+ QObject::connect(m_debugger, SIGNAL(updateUI()),
+ parent, SLOT(updateUI()));
+
+ QObject::connect(m_debugger, SIGNAL(breakpointsChanged()),
+ parent, SLOT(updateLineItems()));
+
+ QObject::connect(m_debugger, SIGNAL(debuggerStarting()),
+ parent, SLOT(slotDebuggerStarting()));
+}
+
+
+void DebuggerMainWndBase::setCoreFile(const QString& corefile)
+{
+ assert(m_debugger != 0);
+ m_debugger->useCoreFile(corefile, true);
+}
+
+void DebuggerMainWndBase::setRemoteDevice(const QString& remoteDevice)
+{
+ if (m_debugger != 0) {
+ m_debugger->setRemoteDevice(remoteDevice);
+ }
+}
+
+void DebuggerMainWndBase::overrideProgramArguments(const QString& args)
+{
+ assert(m_debugger != 0);
+ m_debugger->overrideProgramArguments(args);
+}
+
+void DebuggerMainWndBase::setTranscript(const QString& name)
+{
+ m_transcriptFile = name;
+ if (m_debugger != 0 && m_debugger->driver() != 0)
+ m_debugger->driver()->setLogFileName(m_transcriptFile);
+}
+
+const char OutputWindowGroup[] = "OutputWindow";
+const char TermCmdStr[] = "TermCmdStr";
+const char KeepScript[] = "KeepScript";
+const char DebuggerGroup[] = "Debugger";
+const char DebuggerCmdStr[] = "DebuggerCmdStr";
+const char PreferencesGroup[] = "Preferences";
+const char PopForeground[] = "PopForeground";
+const char BackTimeout[] = "BackTimeout";
+const char TabWidth[] = "TabWidth";
+const char FilesGroup[] = "Files";
+const char SourceFileFilter[] = "SourceFileFilter";
+const char HeaderFileFilter[] = "HeaderFileFilter";
+const char GeneralGroup[] = "General";
+
+void DebuggerMainWndBase::saveSettings(KConfig* config)
+{
+ if (m_debugger != 0) {
+ m_debugger->saveSettings(config);
+ }
+
+ KConfigGroupSaver g(config, OutputWindowGroup);
+ config->writeEntry(TermCmdStr, m_outputTermCmdStr);
+
+ config->setGroup(DebuggerGroup);
+ config->writeEntry(DebuggerCmdStr, m_debuggerCmdStr);
+
+ config->setGroup(PreferencesGroup);
+ config->writeEntry(PopForeground, m_popForeground);
+ config->writeEntry(BackTimeout, m_backTimeout);
+ config->writeEntry(TabWidth, m_tabWidth);
+ config->writeEntry(SourceFileFilter, m_sourceFilter);
+ config->writeEntry(HeaderFileFilter, m_headerFilter);
+}
+
+void DebuggerMainWndBase::restoreSettings(KConfig* config)
+{
+ if (m_debugger != 0) {
+ m_debugger->restoreSettings(config);
+ }
+
+ KConfigGroupSaver g(config, OutputWindowGroup);
+ /*
+ * For debugging and emergency purposes, let the config file override
+ * the shell script that is used to keep the output window open. This
+ * string must have EXACTLY 1 %s sequence in it.
+ */
+ setTerminalCmd(config->readEntry(TermCmdStr, defaultTermCmdStr));
+ m_outputTermKeepScript = config->readEntry(KeepScript);
+
+ config->setGroup(DebuggerGroup);
+ setDebuggerCmdStr(config->readEntry(DebuggerCmdStr));
+
+ config->setGroup(PreferencesGroup);
+ m_popForeground = config->readBoolEntry(PopForeground, false);
+ m_backTimeout = config->readNumEntry(BackTimeout, 1000);
+ m_tabWidth = config->readNumEntry(TabWidth, 0);
+ m_sourceFilter = config->readEntry(SourceFileFilter, m_sourceFilter);
+ m_headerFilter = config->readEntry(HeaderFileFilter, m_headerFilter);
+}
+
+void DebuggerMainWndBase::setAttachPid(const QString& pid)
+{
+ assert(m_debugger != 0);
+ m_debugger->setAttachPid(pid);
+}
+
+bool DebuggerMainWndBase::debugProgram(const QString& executable,
+ QString lang, QWidget* parent)
+{
+ assert(m_debugger != 0);
+
+ TRACE(QString("trying language '%1'...").arg(lang));
+ DebuggerDriver* driver = driverFromLang(lang);
+
+ if (driver == 0)
+ {
+ // see if there is a language in the per-program config file
+ QString configName = m_debugger->getConfigForExe(executable);
+ if (QFile::exists(configName))
+ {
+ KSimpleConfig c(configName, true); // read-only
+ c.setGroup(GeneralGroup);
+
+ // Using "GDB" as default here is for backwards compatibility:
+ // The config file exists but doesn't have an entry,
+ // so it must have been created by an old version of KDbg
+ // that had only the GDB driver.
+ lang = c.readEntry(KDebugger::DriverNameEntry, "GDB");
+
+ TRACE(QString("...bad, trying config driver %1...").arg(lang));
+ driver = driverFromLang(lang);
+ }
+
+ }
+ if (driver == 0)
+ {
+ QString name = driverNameFromFile(executable);
+
+ TRACE(QString("...no luck, trying %1 derived"
+ " from file contents").arg(name));
+ driver = driverFromLang(name);
+ }
+ if (driver == 0)
+ {
+ // oops
+ QString msg = i18n("Don't know how to debug language `%1'");
+ KMessageBox::sorry(parent, msg.arg(lang));
+ return false;
+ }
+
+ driver->setLogFileName(m_transcriptFile);
+
+ bool success = m_debugger->debugProgram(executable, driver);
+
+ if (!success)
+ {
+ delete driver;
+
+ QString msg = i18n("Could not start the debugger process.\n"
+ "Please shut down KDbg and resolve the problem.");
+ KMessageBox::sorry(parent, msg);
+ }
+
+ return success;
+}
+
+// derive driver from language
+DebuggerDriver* DebuggerMainWndBase::driverFromLang(QString lang)
+{
+ // lang is needed in all lowercase
+ lang = lang.lower();
+
+ // The following table relates languages and debugger drivers
+ static const struct L {
+ const char* shortest; // abbreviated to this is still unique
+ const char* full; // full name of language
+ int driver;
+ } langs[] = {
+ { "c", "c++", 1 },
+ { "f", "fortran", 1 },
+ { "p", "python", 3 },
+ { "x", "xslt", 2 },
+ // the following are actually driver names
+ { "gdb", "gdb", 1 },
+ { "xsldbg", "xsldbg", 2 },
+ };
+ const int N = sizeof(langs)/sizeof(langs[0]);
+
+ // lookup the language name
+ int driverID = 0;
+ for (int i = 0; i < N; i++)
+ {
+ const L& l = langs[i];
+
+ // shortest must match
+ if (!lang.startsWith(l.shortest))
+ continue;
+
+ // lang must not be longer than the full name, and it must match
+ if (QString(l.full).startsWith(lang))
+ {
+ driverID = l.driver;
+ break;
+ }
+ }
+ DebuggerDriver* driver = 0;
+ switch (driverID) {
+ case 1:
+ {
+ GdbDriver* gdb = new GdbDriver;
+ gdb->setDefaultInvocation(m_debuggerCmdStr);
+ driver = gdb;
+ }
+ break;
+ case 2:
+ driver = new XsldbgDriver;
+ break;
+ default:
+ // unknown language
+ break;
+ }
+ return driver;
+}
+
+/**
+ * Try to guess the language to use from the contents of the file.
+ */
+QString DebuggerMainWndBase::driverNameFromFile(const QString& exe)
+{
+ /* Inprecise but simple test to see if file is in XSLT language */
+ if (exe.right(4).lower() == ".xsl")
+ return "XSLT";
+
+ return "GDB";
+}
+
+// helper that gets a file name (it only differs in the caption of the dialog)
+QString DebuggerMainWndBase::myGetFileName(QString caption,
+ QString dir, QString filter,
+ QWidget* parent)
+{
+ QString filename;
+ KFileDialog dlg(dir, filter, parent, "filedialog", true);
+
+ dlg.setCaption(caption);
+
+ if (dlg.exec() == QDialog::Accepted)
+ filename = dlg.selectedFile();
+
+ return filename;
+}
+
+void DebuggerMainWndBase::newStatusMsg(KStatusBar* statusbar)
+{
+ QString msg = m_debugger->statusMessage();
+ statusbar->changeItem(msg, ID_STATUS_MSG);
+}
+
+void DebuggerMainWndBase::doGlobalOptions(QWidget* parent)
+{
+ QTabDialog dlg(parent, "global_options", true);
+ QString title = kapp->caption();
+ title += i18n(": Global options");
+ dlg.setCaption(title);
+ dlg.setCancelButton(i18n("Cancel"));
+ dlg.setOKButton(i18n("OK"));
+
+ PrefDebugger prefDebugger(&dlg);
+ prefDebugger.setDebuggerCmd(m_debuggerCmdStr.isEmpty() ?
+ GdbDriver::defaultGdb() : m_debuggerCmdStr);
+ prefDebugger.setTerminal(m_outputTermCmdStr);
+
+ PrefMisc prefMisc(&dlg);
+ prefMisc.setPopIntoForeground(m_popForeground);
+ prefMisc.setBackTimeout(m_backTimeout);
+ prefMisc.setTabWidth(m_tabWidth);
+ prefMisc.setSourceFilter(m_sourceFilter);
+ prefMisc.setHeaderFilter(m_headerFilter);
+
+ dlg.addTab(&prefDebugger, i18n("&Debugger"));
+ dlg.addTab(&prefMisc, i18n("&Miscellaneous"));
+ if (dlg.exec() == QDialog::Accepted)
+ {
+ setDebuggerCmdStr(prefDebugger.debuggerCmd());
+ setTerminalCmd(prefDebugger.terminal());
+ m_popForeground = prefMisc.popIntoForeground();
+ m_backTimeout = prefMisc.backTimeout();
+ m_tabWidth = prefMisc.tabWidth();
+ m_sourceFilter = prefMisc.sourceFilter();
+ if (m_sourceFilter.isEmpty())
+ m_sourceFilter = defaultSourceFilter;
+ m_headerFilter = prefMisc.headerFilter();
+ if (m_headerFilter.isEmpty())
+ m_headerFilter = defaultHeaderFilter;
+ }
+}
+
+const char fifoNameBase[] = "/tmp/kdbgttywin%05d";
+
+/*
+ * We use the scope operator :: in this function, so that we don't
+ * accidentally use the wrong close() function (I've been bitten ;-),
+ * outch!) (We use it for all the libc functions, to be consistent...)
+ */
+QString DebuggerMainWndBase::createOutputWindow()
+{
+ // create a name for a fifo
+ QString fifoName;
+ fifoName.sprintf(fifoNameBase, ::getpid());
+
+ // create a fifo that will pass in the tty name
+ QFile::remove(fifoName); // remove remnants
+#ifdef HAVE_MKFIFO
+ if (::mkfifo(fifoName.local8Bit(), S_IRUSR|S_IWUSR) < 0) {
+ // failed
+ TRACE("mkfifo " + fifoName + " failed");
+ return QString();
+ }
+#else
+ if (::mknod(fifoName.local8Bit(), S_IFIFO | S_IRUSR|S_IWUSR, 0) < 0) {
+ // failed
+ TRACE("mknod " + fifoName + " failed");
+ return QString();
+ }
+#endif
+
+ m_outputTermProc = new KProcess;
+
+ {
+ /*
+ * Spawn an xterm that in turn runs a shell script that passes us
+ * back the terminal name and then only sits and waits.
+ */
+ static const char shellScriptFmt[] =
+ "tty>%s;"
+ "trap \"\" INT QUIT TSTP;" /* ignore various signals */
+ "exec<&-;exec>&-;" /* close stdin and stdout */
+ "while :;do sleep 3600;done";
+ // let config file override this script
+ QString shellScript;
+ if (!m_outputTermKeepScript.isEmpty()) {
+ shellScript = m_outputTermKeepScript;
+ } else {
+ shellScript = shellScriptFmt;
+ }
+
+ shellScript.replace("%s", fifoName);
+ TRACE("output window script is " + shellScript);
+
+ QString title = kapp->caption();
+ title += i18n(": Program output");
+
+ // parse the command line specified in the preferences
+ QStringList cmdParts = QStringList::split(' ', m_outputTermCmdStr);
+
+ /*
+ * Build the argv array. Thereby substitute special sequences:
+ */
+ struct {
+ char seq[4];
+ QString replace;
+ } substitute[] = {
+ { "%T", title },
+ { "%C", shellScript }
+ };
+
+ for (QStringList::iterator i = cmdParts.begin(); i != cmdParts.end(); ++i)
+ {
+ QString& str = *i;
+ for (int j = sizeof(substitute)/sizeof(substitute[0])-1; j >= 0; j--) {
+ int pos = str.find(substitute[j].seq);
+ if (pos >= 0) {
+ str.replace(pos, 2, substitute[j].replace);
+ break; /* substitute only one sequence */
+ }
+ }
+ *m_outputTermProc << str;
+ }
+
+ }
+
+ if (m_outputTermProc->start())
+ {
+ QString tty;
+
+ // read the ttyname from the fifo
+ QFile f(fifoName);
+ if (f.open(IO_ReadOnly))
+ {
+ QByteArray t = f.readAll();
+ tty = QString::fromLocal8Bit(t, t.size());
+ f.close();
+ }
+ f.remove();
+
+ // remove whitespace
+ tty = tty.stripWhiteSpace();
+ TRACE("tty=" + tty);
+ return tty;
+ }
+ else
+ {
+ // error, could not start xterm
+ TRACE("fork failed for fifo " + fifoName);
+ QFile::remove(fifoName);
+ shutdownTermWindow();
+ return QString();
+ }
+}
+
+void DebuggerMainWndBase::shutdownTermWindow()
+{
+ delete m_outputTermProc;
+ m_outputTermProc = 0;
+}
+
+void DebuggerMainWndBase::setTerminalCmd(const QString& cmd)
+{
+ m_outputTermCmdStr = cmd;
+ // revert to default if empty
+ if (m_outputTermCmdStr.isEmpty()) {
+ m_outputTermCmdStr = defaultTermCmdStr;
+ }
+}
+
+void DebuggerMainWndBase::slotDebuggerStarting()
+{
+ if (m_debugger == 0) /* paranoia check */
+ return;
+
+ if (m_ttyLevel == m_debugger->ttyLevel())
+ {
+ }
+ else
+ {
+ // shut down terminal emulations we will not need
+ switch (m_ttyLevel) {
+ case KDebugger::ttySimpleOutputOnly:
+ ttyWindow()->deactivate();
+ break;
+ case KDebugger::ttyFull:
+ if (m_outputTermProc != 0) {
+ m_outputTermProc->kill();
+ // will be deleted in slot
+ }
+ break;
+ default: break;
+ }
+
+ m_ttyLevel = m_debugger->ttyLevel();
+
+ QString ttyName;
+ switch (m_ttyLevel) {
+ case KDebugger::ttySimpleOutputOnly:
+ ttyName = ttyWindow()->activate();
+ break;
+ case KDebugger::ttyFull:
+ if (m_outputTermProc == 0) {
+ // create an output window
+ ttyName = createOutputWindow();
+ TRACE(ttyName.isEmpty() ?
+ "createOuputWindow failed" : "successfully created output window");
+ }
+ break;
+ default: break;
+ }
+
+ m_debugger->setTerminal(ttyName);
+ }
+}
+
+void DebuggerMainWndBase::setDebuggerCmdStr(const QString& cmd)
+{
+ m_debuggerCmdStr = cmd;
+ // make empty if it is the default
+ if (m_debuggerCmdStr == GdbDriver::defaultGdb()) {
+ m_debuggerCmdStr = QString();
+ }
+}
+
+
+#include "mainwndbase.moc"
diff --git a/kdbg/mainwndbase.h b/kdbg/mainwndbase.h
new file mode 100644
index 0000000..36b1c6d
--- /dev/null
+++ b/kdbg/mainwndbase.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef MAINWNDBASE_H
+#define MAINWNDBASE_H
+
+#include <qlineedit.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qcstring.h>
+#include "exprwnd.h"
+#include "sys/types.h" /* pid_t */
+
+// forward declarations
+class KDebugger;
+class TTYWindow;
+class UpdateUI;
+class KToolBar;
+class KStatusBar;
+class KProcess;
+class DebuggerDriver;
+
+class WatchWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ WatchWindow(QWidget* parent, const char* name, WFlags f = 0);
+ ~WatchWindow();
+ ExprWnd* watchVariables() { return &m_watchVariables; }
+ QString watchText() const { return m_watchEdit.text(); }
+ int columnWidth(int i) const { return m_watchVariables.columnWidth(i); }
+ void setColumnWidth(int i, int w) { m_watchVariables.setColumnWidth(i, w); }
+
+protected:
+ QLineEdit m_watchEdit;
+ QPushButton m_watchAdd;
+ QPushButton m_watchDelete;
+ ExprWnd m_watchVariables;
+ QVBoxLayout m_watchV;
+ QHBoxLayout m_watchH;
+
+ virtual bool eventFilter(QObject* ob, QEvent* ev);
+ virtual void dragEnterEvent(QDragEnterEvent* event);
+ virtual void dropEvent(QDropEvent* event);
+
+signals:
+ void addWatch();
+ void deleteWatch();
+ void textDropped(const QString& text);
+
+protected slots:
+ void slotWatchHighlighted();
+};
+
+
+class DebuggerMainWndBase
+{
+public:
+ DebuggerMainWndBase();
+ virtual ~DebuggerMainWndBase();
+
+ /**
+ * Sets the command to invoke the terminal that displays the program
+ * output. If cmd is the empty string, the default is substituted.
+ */
+ void setTerminalCmd(const QString& cmd);
+ /**
+ * Sets the command to invoke the debugger.
+ */
+ void setDebuggerCmdStr(const QString& cmd);
+ /**
+ * Specifies the file where to write the transcript.
+ */
+ void setTranscript(const QString& name);
+ /**
+ * Starts to debug the specified program using the specified language
+ * driver.
+ */
+ bool debugProgram(const QString& executable, QString lang, QWidget* parent);
+ /**
+ * Specifies the process to attach to after the program is loaded.
+ */
+ void setAttachPid(const QString& pid);
+
+ // the following are needed to handle program arguments
+ void setCoreFile(const QString& corefile);
+ void setRemoteDevice(const QString &remoteDevice);
+ void overrideProgramArguments(const QString& args);
+ /** helper around KFileDialog */
+ static QString myGetFileName(QString caption,
+ QString dir, QString filter,
+ QWidget* parent);
+ /** invokes the global options dialog */
+ virtual void doGlobalOptions(QWidget* parent);
+
+protected:
+ // settings
+ virtual void saveSettings(KConfig*);
+ virtual void restoreSettings(KConfig*);
+
+ // override must return the integrated output window
+ virtual TTYWindow* ttyWindow() = 0;
+
+ // statusbar texts
+ QString m_statusActive;
+
+ // output window
+ QString m_outputTermCmdStr;
+ QString m_outputTermKeepScript;
+ KProcess* m_outputTermProc;
+ int m_ttyLevel;
+ virtual QString createOutputWindow(); /* returns terminal name */
+ void shutdownTermWindow();
+
+ QString m_lastDirectory; /* the dir of the most recently opened file */
+
+ QString m_transcriptFile; /* where gdb dialog is logged */
+
+ bool m_popForeground; /* whether main wnd raises when prog stops */
+ int m_backTimeout; /* when wnd goes back */
+ int m_tabWidth; /* tab width in characters (can be 0) */
+ QString m_sourceFilter;
+ QString m_headerFilter;
+
+ // the debugger proper
+ QString m_debuggerCmdStr;
+ KDebugger* m_debugger;
+ void setupDebugger(QWidget* parent,
+ ExprWnd* localVars,
+ ExprWnd* watchVars,
+ QListBox* backtrace);
+ DebuggerDriver* driverFromLang(QString lang);
+ /**
+ * This function derives a driver name from the contents of the named
+ * file.
+ */
+ QString driverNameFromFile(const QString& exe);
+
+public:
+ /*
+ * Important! The following functions must be overridden in derived
+ * classes and be declared as slots! Note: These must not be declared
+ * virtual here since Qt signal mechanism fails miserably (because this
+ * class will not be the left-most base class!).
+ */
+ void newStatusMsg(KStatusBar* statusbar);
+ void slotDebuggerStarting();
+};
+
+#endif // MAINWNDBASE_H
diff --git a/kdbg/memwindow.cpp b/kdbg/memwindow.cpp
new file mode 100644
index 0000000..5c51346
--- /dev/null
+++ b/kdbg/memwindow.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "memwindow.h"
+#include <qheader.h>
+#include <klocale.h>
+#include <kconfigbase.h>
+#include "debugger.h"
+
+
+class MemoryViewItem : public QListViewItem
+{
+public:
+ MemoryViewItem(QListView* parent, QListViewItem* insertAfter, QString raw, QString cooked)
+ : QListViewItem(parent, insertAfter, raw, cooked) {}
+
+ void setChanged(uint pos, bool b) { m_changed[pos] = b; }
+
+protected:
+ virtual void paintCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int alignment);
+
+ bool m_changed[8];
+};
+
+void MemoryViewItem::paintCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int alignment)
+{
+ if( column > 0 && m_changed[column - 1] ) {
+ QColorGroup newcg = cg;
+ newcg.setColor(QColorGroup::Text, red);
+ QListViewItem::paintCell(p, newcg, column, width, alignment);
+ } else {
+ QListViewItem::paintCell(p, cg, column, width, alignment);
+ }
+}
+
+
+MemoryWindow::MemoryWindow(QWidget* parent, const char* name) :
+ QWidget(parent, name),
+ m_debugger(0),
+ m_expression(true, this, "expression"),
+ m_memory(this, "memory"),
+ m_layout(this, 0, 2),
+ m_format(MDTword | MDThex)
+{
+ QSize minSize = m_expression.sizeHint();
+ m_expression.setMinimumSize(minSize);
+ m_expression.setInsertionPolicy(QComboBox::NoInsertion);
+ m_expression.setMaxCount(15);
+
+ m_memory.addColumn(i18n("Address"), 80);
+
+ m_memory.setSorting(-1); /* don't sort */
+ m_memory.setAllColumnsShowFocus(true);
+ m_memory.header()->setClickEnabled(false);
+
+ // create layout
+ m_layout.addWidget(&m_expression, 0);
+ m_layout.addWidget(&m_memory, 10);
+ m_layout.activate();
+
+ connect(&m_expression, SIGNAL(activated(const QString&)),
+ this, SLOT(slotNewExpression(const QString&)));
+
+ // the popup menu
+ m_popup.insertItem(i18n("B&ytes"), MDTbyte);
+ m_popup.insertItem(i18n("Halfwords (&2 Bytes)"), MDThalfword);
+ m_popup.insertItem(i18n("Words (&4 Bytes)"), MDTword);
+ m_popup.insertItem(i18n("Giantwords (&8 Bytes)"), MDTgiantword);
+ m_popup.insertSeparator();
+ m_popup.insertItem(i18n("He&xadecimal"), MDThex);
+ m_popup.insertItem(i18n("Signed &decimal"), MDTsigned);
+ m_popup.insertItem(i18n("&Unsigned decimal"), MDTunsigned);
+ m_popup.insertItem(i18n("&Octal"), MDToctal);
+ m_popup.insertItem(i18n("&Binary"), MDTbinary);
+ m_popup.insertItem(i18n("&Addresses"), MDTaddress);
+ m_popup.insertItem(i18n("&Character"), MDTchar);
+ m_popup.insertItem(i18n("&Floatingpoint"), MDTfloat);
+ m_popup.insertItem(i18n("&Strings"), MDTstring);
+ m_popup.insertItem(i18n("&Instructions"), MDTinsn);
+ connect(&m_popup, SIGNAL(activated(int)), this, SLOT(slotTypeChange(int)));
+
+ /*
+ * Handle right mouse button. Signal righteButtonClicked cannot be
+ * used, because it works only over items, not over the blank window.
+ */
+ m_memory.viewport()->installEventFilter(this);
+}
+
+MemoryWindow::~MemoryWindow()
+{
+}
+
+bool MemoryWindow::eventFilter(QObject*, QEvent* ev)
+{
+ if (ev->type() == QEvent::MouseButtonRelease) {
+ handlePopup(static_cast<QMouseEvent*>(ev));
+ return true;
+ }
+ return false;
+}
+
+void MemoryWindow::handlePopup(QMouseEvent* ev)
+{
+ if (ev->button() == RightButton)
+ {
+ // show popup menu
+ if (m_popup.isVisible())
+ {
+ m_popup.hide();
+ }
+ else
+ {
+ m_popup.popup(mapToGlobal(ev->pos()));
+ }
+ return;
+ }
+}
+
+void MemoryWindow::slotNewExpression(const QString& newText)
+{
+ QString text = newText.simplifyWhiteSpace();
+
+ // see if the string is in the list
+ // (note: must count downwards because of removeItem!)
+ for (int i = m_expression.count()-1; i >= 0; i--)
+ {
+ if (m_expression.text(i) == text) {
+ // yes it is!
+ // look up the format that was used last time for this expr
+ QMap<QString,unsigned>::iterator pFormat = m_formatCache.find(text);
+ if (pFormat != m_formatCache.end()) {
+ m_format = *pFormat;
+ m_debugger->setMemoryFormat(m_format);
+ }
+ // remove this text, will be inserted at the top
+ m_expression.removeItem(i);
+ }
+ }
+ m_expression.insertItem(text, 0);
+
+ if (!text.isEmpty()) {
+ m_formatCache[text] = m_format;
+ }
+
+ displayNewExpression(text);
+}
+
+void MemoryWindow::displayNewExpression(const QString& expr)
+{
+ m_debugger->setMemoryExpression(expr);
+ m_expression.setEditText(expr);
+
+ // clear memory dump if no dump wanted
+ if (expr.isEmpty()) {
+ m_memory.clear();
+ m_old_memory.clear();
+ }
+}
+
+void MemoryWindow::slotTypeChange(int id)
+{
+ m_old_memory.clear();
+
+ // compute new type
+ if (id & MDTsizemask)
+ m_format = (m_format & ~MDTsizemask) | id;
+ if (id & MDTformatmask)
+ m_format = (m_format & ~MDTformatmask) | id;
+ m_debugger->setMemoryFormat(m_format);
+
+ // change the format in the cache
+ QString expr = m_expression.currentText();
+ m_formatCache[expr.simplifyWhiteSpace()] = m_format;
+
+ // force redisplay
+ displayNewExpression(expr);
+}
+
+void MemoryWindow::slotNewMemoryDump(const QString& msg, const std::list<MemoryDump>& memdump)
+{
+ m_memory.clear();
+ if (!msg.isEmpty()) {
+ new QListViewItem(&m_memory, QString(), msg);
+ return;
+ }
+
+ MemoryViewItem* after = 0;
+ std::list<MemoryDump>::const_iterator md = memdump.begin();
+
+ // remove all columns, except the address column
+ for(int k = m_memory.columns() - 1; k > 0; k--)
+ m_memory.removeColumn(k);
+
+ //add the needed columns
+ QStringList sl = QStringList::split( "\t", md->dump );
+ for (uint i = 0; i < sl.count(); i++)
+ m_memory.addColumn("", -1);
+
+ QMap<QString,QString> tmpMap;
+
+ for (; md != memdump.end(); ++md)
+ {
+ QString addr = md->address.asString() + " " + md->address.fnoffs;
+ QStringList sl = QStringList::split( "\t", md->dump );
+
+ // save memory
+ tmpMap[addr] = md->dump;
+
+ after = new MemoryViewItem(&m_memory, after, addr, "");
+
+ QStringList tmplist;
+ QMap<QString,QString>::Iterator pos = m_old_memory.find( addr );
+
+ if( pos != m_old_memory.end() )
+ tmplist = QStringList::split( "\t", pos.data() );
+
+ for (uint i = 0; i < sl.count(); i++)
+ {
+ after->setText( i+1, *sl.at(i) );
+
+ bool changed =
+ tmplist.count() > 0 &&
+ *sl.at(i) != *tmplist.at(i);
+ after->setChanged(i, changed);
+ }
+ }
+
+ m_old_memory.clear();
+ m_old_memory = tmpMap;
+}
+
+static const char MemoryGroup[] = "Memory";
+static const char NumExprs[] = "NumExprs";
+static const char ExpressionFmt[] = "Expression%d";
+static const char FormatFmt[] = "Format%d";
+static const char ColumnWidths[] = "ColumnWidths";
+
+void MemoryWindow::saveProgramSpecific(KConfigBase* config)
+{
+ KConfigGroupSaver s(config, MemoryGroup);
+
+ int numEntries = m_expression.count();
+ config->writeEntry(NumExprs, numEntries);
+ QString exprEntry;
+ QString fmtEntry;
+ for (int i = 0; i < numEntries;) {
+ QString text = m_expression.text(i);
+ i++; /* entries are counted 1-based */
+ exprEntry.sprintf(ExpressionFmt, i);
+ fmtEntry.sprintf(FormatFmt, i);
+ config->writeEntry(exprEntry, text);
+ QMap<QString,unsigned>::iterator pFormat = m_formatCache.find(text);
+ unsigned fmt = pFormat != m_formatCache.end() ? *pFormat : MDTword | MDThex;
+ config->writeEntry(fmtEntry, fmt);
+ }
+
+ // column widths
+ QStrList widths;
+ QString wStr;
+ for (int i = 0; i < 2; i++) {
+ int w = m_memory.columnWidth(i);
+ wStr.setNum(w);
+ widths.append(wStr);
+ }
+ config->writeEntry(ColumnWidths, widths);
+}
+
+void MemoryWindow::restoreProgramSpecific(KConfigBase* config)
+{
+ KConfigGroupSaver s(config, MemoryGroup);
+
+ int numEntries = config->readNumEntry(NumExprs, 0);
+ m_expression.clear();
+
+ QString exprEntry;
+ QString fmtEntry;
+ // entries are counted 1-based
+ for (int i = 1; i <= numEntries; i++) {
+ exprEntry.sprintf(ExpressionFmt, i);
+ fmtEntry.sprintf(FormatFmt, i);
+ QString expr = config->readEntry(exprEntry);
+ unsigned fmt = config->readNumEntry(fmtEntry, MDTword | MDThex);
+ m_expression.insertItem(expr);
+ m_formatCache[expr] = fmt & (MDTsizemask | MDTformatmask);
+ }
+
+ // initialize with top expression
+ if (numEntries > 0) {
+ m_expression.setCurrentItem(0);
+ QString expr = m_expression.text(0);
+ m_format = m_formatCache[expr];
+ m_debugger->setMemoryFormat(m_format);
+ displayNewExpression(expr);
+ }
+
+ // column widths
+ QStrList widths;
+ int n = config->readListEntry(ColumnWidths, widths);
+ if (n > 2)
+ n = 2;
+ for (int i = 0; i < n; i++) {
+ QString wStr = widths.at(i);
+ bool ok;
+ int w = wStr.toInt(&ok);
+ if (ok)
+ m_memory.setColumnWidth(i, w);
+ }
+}
+
+
+#include "memwindow.moc"
diff --git a/kdbg/memwindow.h b/kdbg/memwindow.h
new file mode 100644
index 0000000..af23265
--- /dev/null
+++ b/kdbg/memwindow.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef MEMWINDOW_H
+#define MEMWINDOW_H
+
+#include <qpopupmenu.h>
+#include <qlistview.h>
+#include <qcombobox.h>
+#include <qlayout.h>
+#include <qmap.h>
+#include "dbgdriver.h"
+
+class KDebugger;
+class KConfigBase;
+
+class MemoryWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ MemoryWindow(QWidget* parent, const char* name);
+ ~MemoryWindow();
+
+ void setDebugger(KDebugger* deb) { m_debugger = deb; }
+
+protected:
+ KDebugger* m_debugger;
+ QComboBox m_expression;
+
+ QListView m_memory;
+ QMap<QString,QString> m_old_memory;
+
+ QVBoxLayout m_layout;
+
+ unsigned m_format;
+ QMap<QString,unsigned> m_formatCache;
+
+ QPopupMenu m_popup;
+
+ virtual bool eventFilter(QObject* o, QEvent* ev);
+ void handlePopup(QMouseEvent* ev);
+ void displayNewExpression(const QString& expr);
+
+public slots:
+ void slotNewExpression(const QString&);
+ void slotTypeChange(int id);
+ void slotNewMemoryDump(const QString&, const std::list<MemoryDump>&);
+ void saveProgramSpecific(KConfigBase* config);
+ void restoreProgramSpecific(KConfigBase* config);
+};
+
+#endif // MEMWINDOW_H
diff --git a/kdbg/mydebug.h b/kdbg/mydebug.h
new file mode 100644
index 0000000..99f4b58
--- /dev/null
+++ b/kdbg/mydebug.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include <kdebug.h>
+#include <assert.h>
+
+#ifdef ASSERT
+#undef ASSERT
+#endif
+
+#ifdef NDEBUG
+# define ASSERT(x) ((void)0)
+#else
+# define ASSERT(x) ((x) ? void(0) : void(kdDebug() << \
+ (QString("assertion failed: ") + #x).ascii() << "\n"))
+#endif
+
+#ifdef WANT_TRACE_OUTPUT
+# define TRACE(x) (kdDebug() << (const char*)(x) << "\n")
+#else
+# define TRACE(x) ((void)0)
+#endif
diff --git a/kdbg/pgmargs.cpp b/kdbg/pgmargs.cpp
new file mode 100644
index 0000000..d51cf79
--- /dev/null
+++ b/kdbg/pgmargs.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "pgmargs.h"
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qlistview.h>
+#include <qlistbox.h>
+#include <qtabwidget.h>
+#include <kapplication.h>
+#include <kfiledialog.h>
+#include <klocale.h> /* i18n */
+#include "config.h"
+#include "mydebug.h"
+
+PgmArgs::PgmArgs(QWidget* parent, const QString& pgm, QDict<EnvVar>& envVars,
+ const QStringList& allOptions) :
+ PgmArgsBase(parent, "pgmargs", true),
+ m_envVars(envVars)
+{
+ m_envVars.setAutoDelete(false);
+
+ {
+ QFileInfo fi = pgm;
+ QString newText = labelArgs->text().arg(fi.fileName());
+ labelArgs->setText(newText);
+ }
+
+ // add options only if the option list is non-empty
+ if (!allOptions.isEmpty())
+ {
+ xsldbgOptions->insertStringList(allOptions);
+ }
+ else
+ {
+ delete xsldbgOptionsPage;
+ xsldbgOptionsPage = 0;
+ }
+
+ initEnvList();
+}
+
+PgmArgs::~PgmArgs()
+{
+}
+
+// initializes the selected options
+void PgmArgs::setOptions(const QStringList& selectedOptions)
+{
+ QStringList::ConstIterator it;
+ for (it = selectedOptions.begin(); it != selectedOptions.end(); ++it) {
+ for (uint i = 0; i < xsldbgOptions->count(); i++) {
+ if (xsldbgOptions->text(i) == *it) {
+ xsldbgOptions->setSelected(i, true);
+ break;
+ }
+ }
+ }
+}
+
+// returns the selected options
+QStringList PgmArgs::options() const
+{
+ QStringList sel;
+ if (xsldbgOptionsPage != 0)
+ {
+ for (uint i = 0; i < xsldbgOptions->count(); i++) {
+ if (xsldbgOptions->isSelected(i))
+ sel.append(xsldbgOptions->text(i));
+ }
+ }
+ return sel;
+}
+
+// this is a slot
+void PgmArgs::modifyVar()
+{
+ modifyVar(true); // re-add deleted entries
+}
+
+void PgmArgs::modifyVar(bool resurrect)
+{
+ QString name, value;
+ parseEnvInput(name, value);
+ if (name.isEmpty() || name.find(' ') >= 0) /* disallow spaces in names */
+ return;
+
+ // lookup the value in the dictionary
+ EnvVar* val = m_envVars[name];
+ if (val != 0) {
+ // see if this is a zombie
+ if (val->status == EnvVar::EVdeleted) {
+ // resurrect
+ if (resurrect)
+ {
+ val->value = value;
+ val->status = EnvVar::EVdirty;
+ val->item = new QListViewItem(envList, name, value); // inserts itself
+ m_envVars.insert(name, val);
+ }
+ } else if (value != val->value) {
+ // change the value
+ val->value = value;
+ val->status = EnvVar::EVdirty;
+ val->item->setText(1, value);
+ }
+ } else {
+ // add the value
+ val = new EnvVar;
+ val->value = value;
+ val->status = EnvVar::EVnew;
+ val->item = new QListViewItem(envList, name, value); // inserts itself
+ m_envVars.insert(name, val);
+ }
+ envList->setSelected(val->item, true);
+ buttonDelete->setEnabled(true);
+}
+
+// delete the selected item
+void PgmArgs::deleteVar()
+{
+ QListViewItem* item = envList->selectedItem();
+ if (item == 0)
+ return;
+ QString name = item->text(0);
+
+ // lookup the value in the dictionary
+ EnvVar* val = m_envVars[name];
+ if (val != 0)
+ {
+ // delete from list
+ val->item = 0;
+ // if this is a new item, delete it completely, otherwise zombie-ize it
+ if (val->status == EnvVar::EVnew) {
+ m_envVars.remove(name);
+ delete val;
+ } else {
+ // mark value deleted
+ val->status = EnvVar::EVdeleted;
+ }
+ }
+ delete item;
+ // there is no selected item anymore
+ buttonDelete->setEnabled(false);
+}
+
+void PgmArgs::parseEnvInput(QString& name, QString& value)
+{
+ // parse input from edit field
+ QString input = envVar->text();
+ int equalSign = input.find('=');
+ if (equalSign >= 0) {
+ name = input.left(equalSign).stripWhiteSpace();
+ value = input.mid(equalSign+1);
+ } else {
+ name = input.stripWhiteSpace();
+ value = QString(); /* value is empty */
+ }
+}
+
+void PgmArgs::initEnvList()
+{
+ QDictIterator<EnvVar> it = m_envVars;
+ EnvVar* val;
+ QString name;
+ for (; (val = it) != 0; ++it) {
+ val->status = EnvVar::EVclean;
+ name = it.currentKey();
+ val->item = new QListViewItem(envList, name, val->value); // inserts itself
+ }
+
+ envList->setAllColumnsShowFocus(true);
+ buttonDelete->setEnabled(envList->selectedItem() != 0);
+}
+
+void PgmArgs::envListCurrentChanged()
+{
+ QListViewItem* item = envList->selectedItem();
+ buttonDelete->setEnabled(item != 0);
+ if (item == 0)
+ return;
+
+ // must get name from list box
+ QString name = item->text(0);
+ EnvVar* val = m_envVars[name];
+ ASSERT(val != 0);
+ if (val != 0) {
+ envVar->setText(name + "=" + val->value);
+ } else {
+ envVar->setText(name);
+ }
+}
+
+void PgmArgs::accept()
+{
+ // simulate that the Modify button was pressed, but don't revive
+ // dead entries even if the user changed the edit box
+ modifyVar(false);
+ QDialog::accept();
+}
+
+void PgmArgs::browseWd()
+{
+ // browse for the working directory
+ QString newDir = KFileDialog::getExistingDirectory(wd(), this);
+ if (!newDir.isEmpty()) {
+ setWd(newDir);
+ }
+}
+
+void PgmArgs::browseArgFile()
+{
+ QString caption = i18n("Select a file name to insert as program argument");
+
+ // use the selection as default
+ QString f = programArgs->markedText();
+ f = KFileDialog::getSaveFileName(f, QString::null,
+ this, caption);
+ // don't clear the selection if no file was selected
+ if (!f.isEmpty()) {
+ programArgs->insert(f);
+ }
+}
+
+void PgmArgs::browseArgDir()
+{
+ QString caption = i18n("Select a directory to insert as program argument");
+
+ // use the selection as default
+ QString f = programArgs->markedText();
+ f = KFileDialog::getExistingDirectory(f, this, caption);
+ // don't clear the selection if no file was selected
+ if (!f.isEmpty()) {
+ programArgs->insert(f);
+ }
+}
+
+void PgmArgs::invokeHelp()
+{
+ kapp->invokeHTMLHelp("kdbg/argspwdenv.html");
+}
+
+#include "pgmargs.moc"
diff --git a/kdbg/pgmargs.h b/kdbg/pgmargs.h
new file mode 100644
index 0000000..fb1ec76
--- /dev/null
+++ b/kdbg/pgmargs.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef PgmArgs_included
+#define PgmArgs_included
+
+#include "pgmargsbase.h"
+#include <qlineedit.h>
+#include <qdict.h>
+#include "envvar.h"
+
+class QStringList;
+
+class PgmArgs : public PgmArgsBase
+{
+ Q_OBJECT
+public:
+ PgmArgs(QWidget* parent, const QString& pgm, QDict<EnvVar>& envVars,
+ const QStringList& allOptions);
+ virtual ~PgmArgs();
+
+ void setArgs(const QString& text) { programArgs->setText(text); }
+ QString args() const { return programArgs->text(); }
+ void setOptions(const QStringList& selectedOptions);
+ QStringList options() const;
+ void setWd(const QString& wd) { wdEdit->setText(wd); }
+ QString wd() const { return wdEdit->text(); }
+ QDict<EnvVar>& envVars() { return m_envVars; }
+
+protected:
+ QDict<EnvVar> m_envVars;
+
+ void initEnvList();
+ void parseEnvInput(QString& name, QString& value);
+ void modifyVar(bool resurrect);
+
+protected slots:
+ void modifyVar();
+ void deleteVar();
+ void envListCurrentChanged();
+ void accept();
+ void browseWd();
+ void browseArgFile();
+ void browseArgDir();
+ void invokeHelp();
+};
+
+#endif // PgmArgs_included
diff --git a/kdbg/pgmargsbase.cpp b/kdbg/pgmargsbase.cpp
new file mode 100644
index 0000000..efebbd9
--- /dev/null
+++ b/kdbg/pgmargsbase.cpp
@@ -0,0 +1,237 @@
+#include <kdialog.h>
+#include <klocale.h>
+/****************************************************************************
+** Form implementation generated from reading ui file '../../exper/kdbg/pgmargsbase.ui'
+**
+** Created: Sun Jun 6 14:57:15 2010
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+
+#include "pgmargsbase.h"
+
+#include <qvariant.h>
+#include <qpushbutton.h>
+#include <qtabwidget.h>
+#include <qwidget.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qheader.h>
+#include <qlistview.h>
+#include <qlistbox.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+
+/*
+ * Constructs a PgmArgsBase as 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.
+ */
+PgmArgsBase::PgmArgsBase( QWidget* parent, const char* name, bool modal, WFlags fl )
+ : QDialog( parent, name, modal, fl )
+{
+ if ( !name )
+ setName( "PgmArgsBase" );
+ setSizeGripEnabled( TRUE );
+ PgmArgsBaseLayout = new QHBoxLayout( this, 11, 6, "PgmArgsBaseLayout");
+
+ layout1 = new QVBoxLayout( 0, 0, 6, "layout1");
+
+ tabWidget = new QTabWidget( this, "tabWidget" );
+
+ argsPage = new QWidget( tabWidget, "argsPage" );
+ argsPageLayout = new QHBoxLayout( argsPage, 11, 6, "argsPageLayout");
+
+ layout2 = new QVBoxLayout( 0, 0, 6, "layout2");
+
+ labelArgs = new QLabel( argsPage, "labelArgs" );
+ layout2->addWidget( labelArgs );
+
+ programArgs = new QLineEdit( argsPage, "programArgs" );
+ layout2->addWidget( programArgs );
+
+ layout3 = new QHBoxLayout( 0, 0, 6, "layout3");
+
+ insertFile = new QPushButton( argsPage, "insertFile" );
+ layout3->addWidget( insertFile );
+
+ insertDir = new QPushButton( argsPage, "insertDir" );
+ layout3->addWidget( insertDir );
+ spacer1 = new QSpacerItem( 61, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ layout3->addItem( spacer1 );
+ layout2->addLayout( layout3 );
+ spacer2 = new QSpacerItem( 81, 180, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ layout2->addItem( spacer2 );
+ argsPageLayout->addLayout( layout2 );
+ tabWidget->insertTab( argsPage, QString::fromLatin1("") );
+
+ wdPage = new QWidget( tabWidget, "wdPage" );
+ wdPageLayout = new QHBoxLayout( wdPage, 11, 6, "wdPageLayout");
+
+ layout6 = new QVBoxLayout( 0, 0, 6, "layout6");
+
+ wdEdit = new QLineEdit( wdPage, "wdEdit" );
+ layout6->addWidget( wdEdit );
+
+ layout5 = new QHBoxLayout( 0, 0, 6, "layout5");
+
+ wdBrowse = new QPushButton( wdPage, "wdBrowse" );
+ layout5->addWidget( wdBrowse );
+ spacer4 = new QSpacerItem( 321, 31, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ layout5->addItem( spacer4 );
+ layout6->addLayout( layout5 );
+ spacer5 = new QSpacerItem( 111, 161, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ layout6->addItem( spacer5 );
+ wdPageLayout->addLayout( layout6 );
+ tabWidget->insertTab( wdPage, QString::fromLatin1("") );
+
+ envPage = new QWidget( tabWidget, "envPage" );
+ envPageLayout = new QHBoxLayout( envPage, 11, 6, "envPageLayout");
+
+ layout9 = new QHBoxLayout( 0, 0, 6, "layout9");
+
+ layout7 = new QVBoxLayout( 0, 0, 6, "layout7");
+
+ envLabel = new QLabel( envPage, "envLabel" );
+ layout7->addWidget( envLabel );
+
+ envVar = new QLineEdit( envPage, "envVar" );
+ layout7->addWidget( envVar );
+
+ envList = new QListView( envPage, "envList" );
+ envList->addColumn( tr2i18n( "Name" ) );
+ envList->header()->setClickEnabled( FALSE, envList->header()->count() - 1 );
+ envList->addColumn( tr2i18n( "Value" ) );
+ envList->header()->setClickEnabled( FALSE, envList->header()->count() - 1 );
+ envList->setSelectionMode( QListView::Single );
+ layout7->addWidget( envList );
+ layout9->addLayout( layout7 );
+
+ layout8 = new QVBoxLayout( 0, 0, 6, "layout8");
+
+ buttonModify = new QPushButton( envPage, "buttonModify" );
+ layout8->addWidget( buttonModify );
+
+ buttonDelete = new QPushButton( envPage, "buttonDelete" );
+ layout8->addWidget( buttonDelete );
+ spacer6 = new QSpacerItem( 51, 141, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ layout8->addItem( spacer6 );
+ layout9->addLayout( layout8 );
+ envPageLayout->addLayout( layout9 );
+ tabWidget->insertTab( envPage, QString::fromLatin1("") );
+
+ xsldbgOptionsPage = new QWidget( tabWidget, "xsldbgOptionsPage" );
+ xsldbgOptionsPageLayout = new QHBoxLayout( xsldbgOptionsPage, 11, 6, "xsldbgOptionsPageLayout");
+
+ xsldbgOptions = new QListBox( xsldbgOptionsPage, "xsldbgOptions" );
+ xsldbgOptions->setSelectionMode( QListBox::Multi );
+ xsldbgOptionsPageLayout->addWidget( xsldbgOptions );
+ tabWidget->insertTab( xsldbgOptionsPage, QString::fromLatin1("") );
+ layout1->addWidget( tabWidget );
+
+ layout4 = new QHBoxLayout( 0, 0, 6, "layout4");
+
+ buttonHelp = new QPushButton( this, "buttonHelp" );
+ buttonHelp->setAutoDefault( TRUE );
+ layout4->addWidget( buttonHelp );
+ spacer3 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ layout4->addItem( spacer3 );
+
+ buttonOk = new QPushButton( this, "buttonOk" );
+ buttonOk->setAutoDefault( TRUE );
+ buttonOk->setDefault( TRUE );
+ layout4->addWidget( buttonOk );
+
+ buttonCancel = new QPushButton( this, "buttonCancel" );
+ buttonCancel->setAutoDefault( TRUE );
+ layout4->addWidget( buttonCancel );
+ layout1->addLayout( layout4 );
+ PgmArgsBaseLayout->addLayout( layout1 );
+ languageChange();
+ resize( QSize(528, 410).expandedTo(minimumSizeHint()) );
+ clearWState( WState_Polished );
+
+ // signals and slots connections
+ connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) );
+ connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
+ connect( insertFile, SIGNAL( clicked() ), this, SLOT( browseArgFile() ) );
+ connect( wdBrowse, SIGNAL( clicked() ), this, SLOT( browseWd() ) );
+ connect( buttonModify, SIGNAL( clicked() ), this, SLOT( modifyVar() ) );
+ connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( deleteVar() ) );
+ connect( envList, SIGNAL( selectionChanged() ), this, SLOT( envListCurrentChanged() ) );
+ connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( invokeHelp() ) );
+ connect( insertDir, SIGNAL( clicked() ), this, SLOT( browseArgDir() ) );
+
+ // tab order
+ setTabOrder( envVar, envList );
+ setTabOrder( envList, buttonModify );
+ setTabOrder( buttonModify, buttonDelete );
+ setTabOrder( buttonDelete, programArgs );
+ setTabOrder( programArgs, insertFile );
+ setTabOrder( insertFile, insertDir );
+ setTabOrder( insertDir, buttonHelp );
+ setTabOrder( buttonHelp, buttonOk );
+ setTabOrder( buttonOk, buttonCancel );
+ setTabOrder( buttonCancel, tabWidget );
+ setTabOrder( tabWidget, wdEdit );
+ setTabOrder( wdEdit, wdBrowse );
+
+ // buddies
+ labelArgs->setBuddy( programArgs );
+ envLabel->setBuddy( envVar );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+PgmArgsBase::~PgmArgsBase()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void PgmArgsBase::languageChange()
+{
+ setCaption( tr2i18n( "Program Arguments" ) );
+ labelArgs->setText( tr2i18n( "Run <i>%1</i> with these arguments:" ) );
+ QWhatsThis::add( programArgs, tr2i18n( "Specify the arguments with which the program shall be invoked for this debugging session. You specify the arguments just as you would on the command line, that is, you can even use quotes and environment variables, for example:<p><tt>--message 'start in: ' $HOME</tt>" ) );
+ insertFile->setText( tr2i18n( "Insert &file name..." ) );
+ insertFile->setAccel( QKeySequence( tr2i18n( "Alt+F" ) ) );
+ QWhatsThis::add( insertFile, tr2i18n( "Browse for a file; the full path name will be inserted at the current cursor location in the edit box above." ) );
+ insertDir->setText( tr2i18n( "Insert &directory name..." ) );
+ insertDir->setAccel( QKeySequence( tr2i18n( "Alt+D" ) ) );
+ QWhatsThis::add( insertDir, tr2i18n( "Browse for a directory; the full path name will be inserted at the current cursor location in the edit box above." ) );
+ tabWidget->changeTab( argsPage, tr2i18n( "&Arguments" ) );
+ QWhatsThis::add( wdEdit, tr2i18n( "Specify here the initial working directory where the program is run." ) );
+ wdBrowse->setText( tr2i18n( "&Browse..." ) );
+ wdBrowse->setAccel( QKeySequence( tr2i18n( "Alt+B" ) ) );
+ QWhatsThis::add( wdBrowse, tr2i18n( "Browse for the initial working directory where the program is run." ) );
+ tabWidget->changeTab( wdPage, tr2i18n( "&Working Directory" ) );
+ envLabel->setText( tr2i18n( "Environment variables (<tt>NAME=value</tt>):" ) );
+ QWhatsThis::add( envVar, tr2i18n( "To add a new environment variable or to modify one, specify it here in the form <tt>NAME=value</tt> and click <b>Modify</b>." ) );
+ envList->header()->setLabel( 0, tr2i18n( "Name" ) );
+ envList->header()->setLabel( 1, tr2i18n( "Value" ) );
+ QWhatsThis::add( envList, tr2i18n( "Environment variables that are set <i>in addition</i> to those that are inherited are listed in this table. To add new environment variables, specify them as <tt>NAME=value</tt> in the edit box above and click <b>Modify</b>. To modify a value, select it in this list and click <b>Modify</b>. To delete an environment variable, select it in this list and click <b>Delete</b>." ) );
+ buttonModify->setText( tr2i18n( "&Modify" ) );
+ buttonModify->setAccel( QKeySequence( tr2i18n( "Alt+M" ) ) );
+ QWhatsThis::add( buttonModify, tr2i18n( "Enters the environment variable that is currently specified in the edit box into the list. If the named variable is already in the list, it receives a new value; otherwise, a new entry is created." ) );
+ buttonDelete->setText( tr2i18n( "&Delete" ) );
+ buttonDelete->setAccel( QKeySequence( tr2i18n( "Alt+D" ) ) );
+ QWhatsThis::add( buttonDelete, tr2i18n( "Deletes the selected environment variable from the list. This cannot be used to delete environment variables that are inherited." ) );
+ tabWidget->changeTab( envPage, tr2i18n( "&Environment" ) );
+ tabWidget->changeTab( xsldbgOptionsPage, tr2i18n( "&xsldbg Options" ) );
+ buttonHelp->setText( tr2i18n( "&Help" ) );
+ buttonHelp->setAccel( QKeySequence( tr2i18n( "F1" ) ) );
+ buttonOk->setText( tr2i18n( "&OK" ) );
+ buttonOk->setAccel( QKeySequence( QString::null ) );
+ buttonCancel->setText( tr2i18n( "&Cancel" ) );
+ buttonCancel->setAccel( QKeySequence( QString::null ) );
+}
+
+#include "pgmargsbase.moc"
diff --git a/kdbg/pgmargsbase.ui b/kdbg/pgmargsbase.ui
new file mode 100644
index 0000000..0c81632
--- /dev/null
+++ b/kdbg/pgmargsbase.ui
@@ -0,0 +1,571 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>PgmArgsBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>PgmArgsBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>528</width>
+ <height>410</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Program Arguments</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <hbox>
+ <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>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTabWidget">
+ <property name="name">
+ <cstring>tabWidget</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>argsPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Arguments</string>
+ </attribute>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelArgs</cstring>
+ </property>
+ <property name="text">
+ <string>Run &lt;i&gt;%1&lt;/i&gt; with these arguments:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>programArgs</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>programArgs</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Specify the arguments with which the program shall be invoked for this debugging session. You specify the arguments just as you would on the command line, that is, you can even use quotes and environment variables, for example:&lt;p&gt;&lt;tt&gt;--message 'start in: ' $HOME&lt;/tt&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>insertFile</cstring>
+ </property>
+ <property name="text">
+ <string>Insert &amp;file name...</string>
+ </property>
+ <property name="accel">
+ <string>Alt+F</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Browse for a file; the full path name will be inserted at the current cursor location in the edit box above.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>insertDir</cstring>
+ </property>
+ <property name="text">
+ <string>Insert &amp;directory name...</string>
+ </property>
+ <property name="accel">
+ <string>Alt+D</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Browse for a directory; the full path name will be inserted at the current cursor location in the edit box above.</string>
+ </property>
+ </widget>
+ <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>61</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>81</width>
+ <height>180</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>wdPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Working Directory</string>
+ </attribute>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>wdEdit</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Specify here the initial working directory where the program is run.</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>wdBrowse</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Browse...</string>
+ </property>
+ <property name="accel">
+ <string>Alt+B</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Browse for the initial working directory where the program is run.</string>
+ </property>
+ </widget>
+ <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>321</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </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>111</width>
+ <height>161</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>envPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Environment</string>
+ </attribute>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout9</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>envLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Environment variables (&lt;tt&gt;NAME=value&lt;/tt&gt;):</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>envVar</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>envVar</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>To add a new environment variable or to modify one, specify it here in the form &lt;tt&gt;NAME=value&lt;/tt&gt; and click &lt;b&gt;Modify&lt;/b&gt;.</string>
+ </property>
+ </widget>
+ <widget class="QListView">
+ <column>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ <property name="clickable">
+ <bool>false</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Value</string>
+ </property>
+ <property name="clickable">
+ <bool>false</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>envList</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Single</enum>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Environment variables that are set &lt;i&gt;in addition&lt;/i&gt; to those that are inherited are listed in this table. To add new environment variables, specify them as &lt;tt&gt;NAME=value&lt;/tt&gt; in the edit box above and click &lt;b&gt;Modify&lt;/b&gt;. To modify a value, select it in this list and click &lt;b&gt;Modify&lt;/b&gt;. To delete an environment variable, select it in this list and click &lt;b&gt;Delete&lt;/b&gt;.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonModify</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Modify</string>
+ </property>
+ <property name="accel">
+ <string>Alt+M</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enters the environment variable that is currently specified in the edit box into the list. If the named variable is already in the list, it receives a new value; otherwise, a new entry is created.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonDelete</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ <property name="accel">
+ <string>Alt+D</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Deletes the selected environment variable from the list. This cannot be used to delete environment variables that are inherited.</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>51</width>
+ <height>141</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>xsldbgOptionsPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;xsldbg Options</string>
+ </attribute>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListBox">
+ <property name="name">
+ <cstring>xsldbgOptions</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Multi</enum>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </widget>
+ <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="QPushButton">
+ <property name="name">
+ <cstring>buttonHelp</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Help</string>
+ </property>
+ <property name="accel">
+ <string>F1</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</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>buttonOk</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonCancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>PgmArgsBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>PgmArgsBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>insertFile</sender>
+ <signal>clicked()</signal>
+ <receiver>PgmArgsBase</receiver>
+ <slot>browseArgFile()</slot>
+ </connection>
+ <connection>
+ <sender>wdBrowse</sender>
+ <signal>clicked()</signal>
+ <receiver>PgmArgsBase</receiver>
+ <slot>browseWd()</slot>
+ </connection>
+ <connection>
+ <sender>buttonModify</sender>
+ <signal>clicked()</signal>
+ <receiver>PgmArgsBase</receiver>
+ <slot>modifyVar()</slot>
+ </connection>
+ <connection>
+ <sender>buttonDelete</sender>
+ <signal>clicked()</signal>
+ <receiver>PgmArgsBase</receiver>
+ <slot>deleteVar()</slot>
+ </connection>
+ <connection>
+ <sender>envList</sender>
+ <signal>selectionChanged()</signal>
+ <receiver>PgmArgsBase</receiver>
+ <slot>envListCurrentChanged()</slot>
+ </connection>
+ <connection>
+ <sender>buttonHelp</sender>
+ <signal>clicked()</signal>
+ <receiver>PgmArgsBase</receiver>
+ <slot>invokeHelp()</slot>
+ </connection>
+ <connection>
+ <sender>insertDir</sender>
+ <signal>clicked()</signal>
+ <receiver>PgmArgsBase</receiver>
+ <slot>browseArgDir()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>envVar</tabstop>
+ <tabstop>envList</tabstop>
+ <tabstop>buttonModify</tabstop>
+ <tabstop>buttonDelete</tabstop>
+ <tabstop>programArgs</tabstop>
+ <tabstop>insertFile</tabstop>
+ <tabstop>insertDir</tabstop>
+ <tabstop>buttonHelp</tabstop>
+ <tabstop>buttonOk</tabstop>
+ <tabstop>buttonCancel</tabstop>
+ <tabstop>tabWidget</tabstop>
+ <tabstop>wdEdit</tabstop>
+ <tabstop>wdBrowse</tabstop>
+</tabstops>
+<slots>
+ <slot specifier="pure virtual">browseArgFile()</slot>
+ <slot specifier="pure virtual">browseWd()</slot>
+ <slot specifier="pure virtual">modifyVar()</slot>
+ <slot specifier="pure virtual">deleteVar()</slot>
+ <slot specifier="pure virtual">envListCurrentChanged()</slot>
+ <slot specifier="pure virtual">invokeHelp()</slot>
+ <slot specifier="pure virtual">browseArgDir()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kdbg/pgmsettings.cpp b/kdbg/pgmsettings.cpp
new file mode 100644
index 0000000..8bfebab
--- /dev/null
+++ b/kdbg/pgmsettings.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "pgmsettings.h"
+#include <klocale.h> /* i18n */
+#include <kapplication.h>
+#include <qfileinfo.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include "config.h"
+#include "mydebug.h"
+
+
+ChooseDriver::ChooseDriver(QWidget* parent) :
+ QWidget(parent, "driver")
+{
+ QVBoxLayout* layout = new QVBoxLayout(this, 10);
+
+ QLabel* label = new QLabel(this);
+ label->setText(i18n("How to invoke &GDB - leave empty to use\n"
+ "the default from the global options:"));
+ label->setMinimumSize(label->sizeHint());
+ layout->addWidget(label);
+
+ m_debuggerCmd = new QLineEdit(this);
+ m_debuggerCmd->setMinimumSize(m_debuggerCmd->sizeHint());
+ layout->addWidget(m_debuggerCmd);
+ label->setBuddy(m_debuggerCmd);
+
+ layout->addStretch(10);
+}
+
+void ChooseDriver::setDebuggerCmd(const QString& cmd)
+{
+ m_debuggerCmd->setText(cmd);
+}
+
+QString ChooseDriver::debuggerCmd() const
+{
+ return m_debuggerCmd->text();
+}
+
+
+OutputSettings::OutputSettings(QWidget* parent) :
+ QWidget(parent, "output")
+{
+ // the group is invisible
+ m_group = new QButtonGroup(this);
+ m_group->hide();
+
+ QVBoxLayout* layout = new QVBoxLayout(this, 10);
+
+ QRadioButton* btn;
+
+ btn = new QRadioButton(i18n("&No input and output"), this);
+ m_group->insert(btn, 0);
+ btn->setMinimumSize(btn->sizeHint());
+ layout->addWidget(btn);
+
+ btn = new QRadioButton(i18n("&Only output, simple terminal emulation"), this);
+ m_group->insert(btn, 1);
+ btn->setMinimumSize(btn->sizeHint());
+ layout->addWidget(btn);
+
+ btn = new QRadioButton(i18n("&Full terminal emulation"), this);
+ m_group->insert(btn, 7);
+ btn->setMinimumSize(btn->sizeHint());
+ layout->addWidget(btn);
+
+ layout->addStretch(10);
+
+ // there is no simpler way to get to the active button than
+ // to connect to a signal
+ connect(m_group, SIGNAL(clicked(int)), SLOT(slotLevelChanged(int)));
+}
+
+void OutputSettings::setTTYLevel(int l)
+{
+ m_group->setButton(l);
+ m_ttyLevel = l;
+}
+
+void OutputSettings::slotLevelChanged(int id)
+{
+ m_ttyLevel = id;
+ TRACE("new ttyLevel: " + QString().setNum(id));
+}
+
+
+
+ProgramSettings::ProgramSettings(QWidget* parent, QString exeName, bool modal) :
+ QTabDialog(parent, "program_settings", modal),
+ m_chooseDriver(this),
+ m_output(this)
+{
+ // construct title
+ QFileInfo fi(exeName);
+ QString cap = kapp->caption();
+ QString title = i18n("%1: Settings for %2");
+ setCaption(title.arg(cap, fi.fileName()));
+
+ setCancelButton(i18n("Cancel"));
+ setOKButton(i18n("OK"));
+
+ addTab(&m_chooseDriver, i18n("&Debugger"));
+ addTab(&m_output, i18n("&Output"));
+}
+
+#include "pgmsettings.moc"
diff --git a/kdbg/pgmsettings.h b/kdbg/pgmsettings.h
new file mode 100644
index 0000000..27ab174
--- /dev/null
+++ b/kdbg/pgmsettings.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef PGMSETTINGS_H
+#define PGMSETTINGS_H
+
+#include <qtabdialog.h>
+
+class QButtonGroup;
+class QLineEdit;
+
+
+class ChooseDriver : public QWidget
+{
+public:
+ ChooseDriver(QWidget* parent);
+ void setDebuggerCmd(const QString& cmd);
+ QString debuggerCmd() const;
+protected:
+ QLineEdit* m_debuggerCmd;
+};
+
+
+class OutputSettings : public QWidget
+{
+ Q_OBJECT
+public:
+ OutputSettings(QWidget* parent);
+ void setTTYLevel(int l);
+ int ttyLevel() const { return m_ttyLevel; }
+protected:
+ int m_ttyLevel;
+ QButtonGroup* m_group;
+protected slots:
+ void slotLevelChanged(int);
+};
+
+
+class ProgramSettings : public QTabDialog
+{
+ Q_OBJECT
+public:
+ ProgramSettings(QWidget* parent, QString exeName, bool modal = true);
+
+public:
+ ChooseDriver m_chooseDriver;
+ OutputSettings m_output;
+};
+
+#endif
diff --git a/kdbg/pics/Makefile.am b/kdbg/pics/Makefile.am
new file mode 100644
index 0000000..d5d7163
--- /dev/null
+++ b/kdbg/pics/Makefile.am
@@ -0,0 +1,56 @@
+# toolbar icons
+
+kdbgiconsdir = $(kde_datadir)/kdbg/icons
+kdbgicons_ICON = \
+ pulse \
+ brkpt \
+ pgmfinish \
+ pgmnext \
+ pgmnexti \
+ pgmrun \
+ pgmstep \
+ pgmstepi \
+ execopen
+
+# line items and other pictograms
+PICTOGRAMS = \
+ brkena.xpm \
+ brkdis.xpm \
+ brktmp.xpm \
+ brkcond.xpm \
+ brkorph.xpm \
+ pcinner.xpm \
+ pcup.xpm \
+ regs.xpm \
+ watch.xpm \
+ watchcoded.xpm \
+ watchena.xpm \
+ watchdis.xpm \
+ pointer.xpm
+
+
+pics_DATA = $(PICTOGRAMS)
+picsdir = $(kde_datadir)/kdbg/pics
+
+# application icon
+KDE_ICON = kdbg
+
+animation = $(shell cd "$(srcdir)" && echo hi22-action-pulse0000*.png)
+
+# this requires ImageMagick
+hi22-action-pulse.png: hi22-action-pulse.pngseq
+ list="$(animation)" ; \
+ montage +frame +shadow +label -background black \
+ -geometry 22x22 \
+ -tile 1x`echo $$list | wc -w` \
+ $$list hi22-action-pulse.png
+
+hi22-action-pulse.pngseq: hi22-action-pulse.xml
+ @echo "Using cinelerra render $< into a PNG sequence $@"
+ @echo "If you do not have cinelerra, just touch $@"
+ exit 1
+
+# This file can be rendered by cinelerra into a "PNG sequence".
+# This produces the PNG sequence $(animation), which is pasted together
+# by `make hi22-action-pulse.png'.
+EXTRA_DIST = hi22-action-pulse.xml $(animation)
diff --git a/kdbg/pics/Makefile.in b/kdbg/pics/Makefile.in
new file mode 100644
index 0000000..e403f01
--- /dev/null
+++ b/kdbg/pics/Makefile.in
@@ -0,0 +1,698 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 483858 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# toolbar icons
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = kdbg/pics
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(picsdir)"
+picsDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(pics_DATA)
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARTSCCONFIG = @ARTSCCONFIG@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOPIDLNG = @DCOPIDLNG@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
+KCONFIG_COMPILER = @KCONFIG_COMPILER@
+KDECONFIG = @KDECONFIG@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
+KDE_MT_LIBS = @KDE_MT_LIBS@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_FPIE = @KDE_USE_FPIE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+KDE_USE_PIE = @KDE_USE_PIE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPTHREAD = @LIBPTHREAD@
+LIBRESOLV = @LIBRESOLV@
+LIBS = @LIBS@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBZ = @LIBZ@
+LIB_KAB = @LIB_KAB@
+LIB_KABC = @LIB_KABC@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDED = @LIB_KDED@
+LIB_KDEPIM = @LIB_KDEPIM@
+LIB_KDEPRINT = @LIB_KDEPRINT@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KDNSSD = @LIB_KDNSSD@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMPROXY = @LIB_KIMPROXY@
+LIB_KIO = @LIB_KIO@
+LIB_KJS = @LIB_KJS@
+LIB_KNEWSTUFF = @LIB_KNEWSTUFF@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KUNITTEST = @LIB_KUNITTEST@
+LIB_KUTILS = @LIB_KUTILS@
+LIB_POLL = @LIB_POLL@
+LIB_QPE = @LIB_QPE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_X11 = @LIB_X11@
+LIB_XEXT = @LIB_XEXT@
+LIB_XRENDER = @LIB_XRENDER@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKEKDEWIDGETS = @MAKEKDEWIDGETS@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MKDIR_P = @MKDIR_P@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PS_COMMAND = @PS_COMMAND@
+QTE_NORTTI = @QTE_NORTTI@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+UIC_TR = @UIC_TR@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+XGETTEXT = @XGETTEXT@
+XMKMF = @XMKMF@
+XMLLINT = @XMLLINT@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+X_RPATH = @X_RPATH@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_kcfgdir = @kde_kcfgdir@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_qtver = @kde_qtver@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_styledir = @kde_styledir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+kde_widgetdir = @kde_widgetdir@
+kdeinitdir = @kdeinitdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+xdg_appsdir = @xdg_appsdir@
+xdg_directorydir = @xdg_directorydir@
+xdg_menudir = @xdg_menudir@
+kdbgiconsdir = $(kde_datadir)/kdbg/icons
+kdbgicons_ICON = \
+ pulse \
+ brkpt \
+ pgmfinish \
+ pgmnext \
+ pgmnexti \
+ pgmrun \
+ pgmstep \
+ pgmstepi \
+ execopen
+
+
+# line items and other pictograms
+PICTOGRAMS = \
+ brkena.xpm \
+ brkdis.xpm \
+ brktmp.xpm \
+ brkcond.xpm \
+ brkorph.xpm \
+ pcinner.xpm \
+ pcup.xpm \
+ regs.xpm \
+ watch.xpm \
+ watchcoded.xpm \
+ watchena.xpm \
+ watchdis.xpm \
+ pointer.xpm
+
+pics_DATA = $(PICTOGRAMS)
+picsdir = $(kde_datadir)/kdbg/pics
+
+# application icon
+KDE_ICON = kdbg
+animation = $(shell cd "$(srcdir)" && echo hi22-action-pulse0000*.png)
+
+# This file can be rendered by cinelerra into a "PNG sequence".
+# This produces the PNG sequence $(animation), which is pasted together
+# by `make hi22-action-pulse.png'.
+EXTRA_DIST = hi22-action-pulse.xml $(animation)
+#>- all: all-am
+#>+ 1
+all: docs-am all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/pics/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu kdbg/pics/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/pics/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/pics/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/pics/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-picsDATA: $(pics_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(picsdir)" || $(MKDIR_P) "$(DESTDIR)$(picsdir)"
+ @list='$(pics_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(picsDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(picsdir)/$$f'"; \
+ $(picsDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(picsdir)/$$f"; \
+ done
+
+uninstall-picsDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pics_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(picsdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(picsdir)/$$f"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(picsdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-am
+#>+ 1
+clean: kde-rpo-clean clean-am
+
+#>- clean-am: clean-generic clean-libtool mostlyclean-am
+#>+ 1
+clean-am: clean-bcheck clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+#>- install-data-am: install-picsDATA
+#>+ 1
+install-data-am: install-kde-icons install-picsDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+#>- uninstall-am: uninstall-picsDATA
+#>+ 1
+uninstall-am: uninstall-kde-icons uninstall-picsDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-picsDATA install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-am uninstall-picsDATA
+
+
+# this requires ImageMagick
+hi22-action-pulse.png: hi22-action-pulse.pngseq
+ list="$(animation)" ; \
+ montage +frame +shadow +label -background black \
+ -geometry 22x22 \
+ -tile 1x`echo $$list | wc -w` \
+ $$list hi22-action-pulse.png
+
+hi22-action-pulse.pngseq: hi22-action-pulse.xml
+ @echo "Using cinelerra render $< into a PNG sequence $@"
+ @echo "If you do not have cinelerra, just touch $@"
+ exit 1
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+
+#>+ 2
+KDE_DIST=hi22-action-pulse000007.png hi22-action-pulse000005.png hi22-action-pulse000010.png hi22-action-pulse000026.png hi16-action-pgmstep.png hi16-action-pgmfinish.png hi22-action-pulse000013.png regs.xpm hi22-action-pgmstepi.png hi22-action-pulse000009.png hi22-action-pulse000016.png hi22-action-pulse000000.png brktmp.xpm brkena.xpm hi22-action-pulse000011.png lo32-app-kdbg.png pointer.xpm pcinner.xpm hi22-action-pulse000018.png hi22-action-execopen.png hi22-action-pgmrun.png hi22-action-pulse000028.png hi32-app-kdbg.png hi22-action-pgmnext.png hi22-action-pulse000025.png hi22-action-pulse000021.png hi16-action-pgmnext.png watch.xpm genanim.sh watchdis.xpm hi16-action-pgmrun.png lo16-app-kdbg.png brkcond.xpm hi22-action-pulse000024.png hi22-action-pulse000020.png hi48-app-kdbg.png hi22-action-pgmstep.png hi22-action-pulse000001.png hi22-action-pulse000003.png watchena.xpm hi22-action-pgmfinish.png pcup.xpm hi22-action-pgmnexti.png hi22-action-pulse000008.png hi16-action-pgmstepi.png hi16-action-brkpt.png hi22-action-pulse000017.png hi22-action-pulse.png Makefile.in hi16-action-execopen.png hi22-action-pulse000004.png hi16-app-kdbg.png brkorph.xpm hi22-action-pulse000027.png brkdis.xpm watchcoded.xpm hi22-action-pulse000015.png hi22-action-pulse000002.png hi22-action-brkpt.png hi22-action-pulse000012.png hi22-action-pulse000022.png hi22-action-pulse000014.png hi22-action-pulse000006.png Makefile.am hi22-action-pulse000023.png hi16-action-pgmnexti.png hi22-action-pulse000019.png
+
+#>+ 2
+docs-am:
+
+#>+ 55
+install-kde-icons:
+ $(mkinstalldirs) $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions
+ $(INSTALL_DATA) $(srcdir)/hi16-action-pgmrun.png $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmrun.png
+ $(INSTALL_DATA) $(srcdir)/hi16-action-pgmfinish.png $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmfinish.png
+ $(mkinstalldirs) $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions
+ $(INSTALL_DATA) $(srcdir)/hi22-action-pgmstepi.png $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmstepi.png
+ $(INSTALL_DATA) $(srcdir)/hi16-action-pgmnext.png $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmnext.png
+ $(INSTALL_DATA) $(srcdir)/hi22-action-pgmfinish.png $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmfinish.png
+ $(INSTALL_DATA) $(srcdir)/hi16-action-pgmstepi.png $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmstepi.png
+ $(INSTALL_DATA) $(srcdir)/hi22-action-pgmrun.png $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmrun.png
+ $(INSTALL_DATA) $(srcdir)/hi22-action-brkpt.png $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/brkpt.png
+ $(INSTALL_DATA) $(srcdir)/hi16-action-brkpt.png $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/brkpt.png
+ $(INSTALL_DATA) $(srcdir)/hi22-action-pgmnexti.png $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmnexti.png
+ $(INSTALL_DATA) $(srcdir)/hi22-action-pgmstep.png $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmstep.png
+ $(INSTALL_DATA) $(srcdir)/hi22-action-execopen.png $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/execopen.png
+ $(INSTALL_DATA) $(srcdir)/hi22-action-pgmnext.png $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmnext.png
+ $(INSTALL_DATA) $(srcdir)/hi22-action-pulse.png $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pulse.png
+ $(INSTALL_DATA) $(srcdir)/hi16-action-execopen.png $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/execopen.png
+ $(INSTALL_DATA) $(srcdir)/hi16-action-pgmstep.png $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmstep.png
+ $(INSTALL_DATA) $(srcdir)/hi16-action-pgmnexti.png $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmnexti.png
+ $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/hicolor/48x48/apps
+ $(INSTALL_DATA) $(srcdir)/hi48-app-kdbg.png $(DESTDIR)$(kde_icondir)/hicolor/48x48/apps/kdbg.png
+ $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/locolor/16x16/apps
+ $(INSTALL_DATA) $(srcdir)/lo16-app-kdbg.png $(DESTDIR)$(kde_icondir)/locolor/16x16/apps/kdbg.png
+ $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/hicolor/16x16/apps
+ $(INSTALL_DATA) $(srcdir)/hi16-app-kdbg.png $(DESTDIR)$(kde_icondir)/hicolor/16x16/apps/kdbg.png
+ $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/locolor/32x32/apps
+ $(INSTALL_DATA) $(srcdir)/lo32-app-kdbg.png $(DESTDIR)$(kde_icondir)/locolor/32x32/apps/kdbg.png
+ $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/hicolor/32x32/apps
+ $(INSTALL_DATA) $(srcdir)/hi32-app-kdbg.png $(DESTDIR)$(kde_icondir)/hicolor/32x32/apps/kdbg.png
+
+uninstall-kde-icons:
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmrun.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmfinish.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmstepi.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmnext.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmfinish.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmstepi.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmrun.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/brkpt.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/brkpt.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmnexti.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmstep.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/execopen.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pgmnext.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/22x22/actions/pulse.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/execopen.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmstep.png
+ -rm -f $(DESTDIR)$(kdbgiconsdir)/hicolor/16x16/actions/pgmnexti.png
+ -rm -f $(DESTDIR)$(kde_icondir)/hicolor/48x48/apps/kdbg.png
+ -rm -f $(DESTDIR)$(kde_icondir)/locolor/16x16/apps/kdbg.png
+ -rm -f $(DESTDIR)$(kde_icondir)/hicolor/16x16/apps/kdbg.png
+ -rm -f $(DESTDIR)$(kde_icondir)/locolor/32x32/apps/kdbg.png
+ -rm -f $(DESTDIR)$(kde_icondir)/hicolor/32x32/apps/kdbg.png
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/pics/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/pics/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/pics/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-am
+
+bcheck-am:
+ @for i in ; do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXX) $(DEFS) -I. -I$(srcdir) -I$(top_builddir) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 3
+final:
+ $(MAKE) all-am
+
+#>+ 3
+final-install:
+ $(MAKE) install-am
+
+#>+ 3
+no-final:
+ $(MAKE) all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/kdbg/pics/brkcond.xpm b/kdbg/pics/brkcond.xpm
new file mode 100644
index 0000000..203a908
--- /dev/null
+++ b/kdbg/pics/brkcond.xpm
@@ -0,0 +1,20 @@
+/* XPM */
+static char*brkcond[]={
+"14 14 3 1",
+"a c #0000ff",
+". c None",
+"# c #ffffff",
+"..###.........",
+".#aaa#........",
+"#aa#aa#.......",
+".###aa#.......",
+"..#aa#........",
+".#aa#.........",
+"..##..........",
+".#aa#.........",
+"..##..........",
+"..............",
+"..............",
+"..............",
+"..............",
+".............."};
diff --git a/kdbg/pics/brkdis.xpm b/kdbg/pics/brkdis.xpm
new file mode 100644
index 0000000..dbfbfe4
--- /dev/null
+++ b/kdbg/pics/brkdis.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static char * brkdis_xpm[] = {
+"14 14 4 1",
+" c None",
+". c white",
+"X c #BE8383",
+"o c #D2A9A9",
+" ",
+" .... ",
+" .XXXX. ",
+" .XooooX. ",
+" .XooooooX. ",
+" .XooooooooX. ",
+" .XooooooooX. ",
+" .XooooooooX. ",
+" .XooooooooX. ",
+" .XooooooX. ",
+" .XooooX. ",
+" .XXXX. ",
+" .... ",
+" "};
diff --git a/kdbg/pics/brkena.xpm b/kdbg/pics/brkena.xpm
new file mode 100644
index 0000000..f9adf6b
--- /dev/null
+++ b/kdbg/pics/brkena.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static char * brkena_xpm[] = {
+"14 14 4 1",
+" c None",
+". c #FFFFFF",
+"+ c #8B0000",
+"@ c #FF0000",
+" ",
+" .... ",
+" .++++. ",
+" .+@@@@+. ",
+" .+@@@@@@+. ",
+" .+@@@@@@@@+. ",
+" .+@@@@@@@@+. ",
+" .+@@@@@@@@+. ",
+" .+@@@@@@@@+. ",
+" .+@@@@@@+. ",
+" .+@@@@+. ",
+" .++++. ",
+" .... ",
+" "};
diff --git a/kdbg/pics/brkorph.xpm b/kdbg/pics/brkorph.xpm
new file mode 100644
index 0000000..52704af
--- /dev/null
+++ b/kdbg/pics/brkorph.xpm
@@ -0,0 +1,19 @@
+/* XPM */
+static char * brkorph_xpm[] = {
+"14 14 2 1",
+" c None",
+". c #563131",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" .. .. ",
+" ... ... ",
+" ..... ",
+" ... ",
+" ..... ",
+" ... ... ",
+" .. .. "};
diff --git a/kdbg/pics/brktmp.xpm b/kdbg/pics/brktmp.xpm
new file mode 100644
index 0000000..9b63680
--- /dev/null
+++ b/kdbg/pics/brktmp.xpm
@@ -0,0 +1,20 @@
+/* XPM */
+static char * brktmp_xpm[] = {
+"14 14 3 1",
+" s None c None",
+". c black",
+"X c white",
+" ",
+" ... ",
+" .X.X. ",
+" .XX.XX. ",
+" .XX.... ",
+" .XXXXX. ",
+" .XXX. ",
+" ... ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/kdbg/pics/genanim.sh b/kdbg/pics/genanim.sh
new file mode 100755
index 0000000..ab213c6
--- /dev/null
+++ b/kdbg/pics/genanim.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# usage example:
+# $0 hi22-action-pulse
+
+delay=4
+
+# this is GraphicMagick
+gm convert -loop $delay -delay $delay "$1"??????.png "$1".mng
diff --git a/kdbg/pics/hi16-action-brkpt.png b/kdbg/pics/hi16-action-brkpt.png
new file mode 100644
index 0000000..77f3d5e
--- /dev/null
+++ b/kdbg/pics/hi16-action-brkpt.png
Binary files differ
diff --git a/kdbg/pics/hi16-action-execopen.png b/kdbg/pics/hi16-action-execopen.png
new file mode 100644
index 0000000..82aa996
--- /dev/null
+++ b/kdbg/pics/hi16-action-execopen.png
Binary files differ
diff --git a/kdbg/pics/hi16-action-pgmfinish.png b/kdbg/pics/hi16-action-pgmfinish.png
new file mode 100644
index 0000000..86eae86
--- /dev/null
+++ b/kdbg/pics/hi16-action-pgmfinish.png
Binary files differ
diff --git a/kdbg/pics/hi16-action-pgmnext.png b/kdbg/pics/hi16-action-pgmnext.png
new file mode 100644
index 0000000..4d70b98
--- /dev/null
+++ b/kdbg/pics/hi16-action-pgmnext.png
Binary files differ
diff --git a/kdbg/pics/hi16-action-pgmnexti.png b/kdbg/pics/hi16-action-pgmnexti.png
new file mode 100644
index 0000000..bd87517
--- /dev/null
+++ b/kdbg/pics/hi16-action-pgmnexti.png
Binary files differ
diff --git a/kdbg/pics/hi16-action-pgmrun.png b/kdbg/pics/hi16-action-pgmrun.png
new file mode 100644
index 0000000..b4f87e2
--- /dev/null
+++ b/kdbg/pics/hi16-action-pgmrun.png
Binary files differ
diff --git a/kdbg/pics/hi16-action-pgmstep.png b/kdbg/pics/hi16-action-pgmstep.png
new file mode 100644
index 0000000..d33236a
--- /dev/null
+++ b/kdbg/pics/hi16-action-pgmstep.png
Binary files differ
diff --git a/kdbg/pics/hi16-action-pgmstepi.png b/kdbg/pics/hi16-action-pgmstepi.png
new file mode 100644
index 0000000..c54a28f
--- /dev/null
+++ b/kdbg/pics/hi16-action-pgmstepi.png
Binary files differ
diff --git a/kdbg/pics/hi16-app-kdbg.png b/kdbg/pics/hi16-app-kdbg.png
new file mode 100644
index 0000000..b831d98
--- /dev/null
+++ b/kdbg/pics/hi16-app-kdbg.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-brkpt.png b/kdbg/pics/hi22-action-brkpt.png
new file mode 100644
index 0000000..ca72584
--- /dev/null
+++ b/kdbg/pics/hi22-action-brkpt.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-execopen.png b/kdbg/pics/hi22-action-execopen.png
new file mode 100644
index 0000000..fa92d54
--- /dev/null
+++ b/kdbg/pics/hi22-action-execopen.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pgmfinish.png b/kdbg/pics/hi22-action-pgmfinish.png
new file mode 100644
index 0000000..0a7fd42
--- /dev/null
+++ b/kdbg/pics/hi22-action-pgmfinish.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pgmnext.png b/kdbg/pics/hi22-action-pgmnext.png
new file mode 100644
index 0000000..5cb30c2
--- /dev/null
+++ b/kdbg/pics/hi22-action-pgmnext.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pgmnexti.png b/kdbg/pics/hi22-action-pgmnexti.png
new file mode 100644
index 0000000..07ede40
--- /dev/null
+++ b/kdbg/pics/hi22-action-pgmnexti.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pgmrun.png b/kdbg/pics/hi22-action-pgmrun.png
new file mode 100644
index 0000000..28b9beb
--- /dev/null
+++ b/kdbg/pics/hi22-action-pgmrun.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pgmstep.png b/kdbg/pics/hi22-action-pgmstep.png
new file mode 100644
index 0000000..7c59ea3
--- /dev/null
+++ b/kdbg/pics/hi22-action-pgmstep.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pgmstepi.png b/kdbg/pics/hi22-action-pgmstepi.png
new file mode 100644
index 0000000..d88464b
--- /dev/null
+++ b/kdbg/pics/hi22-action-pgmstepi.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse.png b/kdbg/pics/hi22-action-pulse.png
new file mode 100644
index 0000000..d757fe0
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse.xml b/kdbg/pics/hi22-action-pulse.xml
new file mode 100644
index 0000000..1284915
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse.xml
@@ -0,0 +1,259 @@
+<?xml version="1.0"?>
+<EDL VERSION="1.2.2" PROJECT_PATH="/home/jsixt/Src/X11/KDbg/kdbg-2/kdbg/pics/hi22-action-pulse.xml">
+<LOCALSESSION IN_POINT="-1.0000000000000000e+00" LOOP_PLAYBACK="1" LOOP_START="0.0000000000000000e+00" LOOP_END="1.4500000000000000e+00" OUT_POINT="-1.0000000000000000e+00" SELECTION_START="0.0000000000000000e+00" SELECTION_END="1.4500000000000000e+00" CLIP_TITLE="/home/jsixt/Src/X11/KDbg/kdbg-2/kdbg/pics/hi22-action-pulse.xml" CLIP_NOTES="Hello world" FOLDER="Clips" TRACK_START="0" VIEW_START="0" ZOOM_SAMPLE="128" ZOOMY="64" ZOOM_TRACK="32" PREVIEW_START="1.3500931098696455e-02" PREVIEW_END="1.4337988826815642e+00"></LOCALSESSION>
+
+<SESSION ASSETLIST_FORMAT="0" ASSET_COLUMN0="229" ASSET_COLUMN1="46" SHOW_FADE="0" SHOW_PAN="1" SHOW_MUTE="0" SHOW_TRANSITIONS="1" SHOW_PLUGINS="0" SHOW_CAMERA="0" SHOW_PROJECTOR="0" SHOW_MODE="1" SHOW_MASK="1" SHOW_CZOOM="0" SHOW_PZOOM="0" AUTO_KEYFRAMES="0" AUTOS_FOLLOW_EDITS="1" BRENDER_START="0.0000000000000000e+00" CROP_X1="16" CROP_Y1="16" CROP_X2="16" CROP_Y2="16" CURRENT_FOLDER="Video Effects" CURSOR_ON_FRAMES="1" CWINDOW_DEST="0" CWINDOW_MASK="0" CWINDOW_METER="1" CWINDOW_OPERATION="2" CWINDOW_SCROLLBARS="0" CWINDOW_XSCROLL="-1437" CWINDOW_YSCROLL="-1093" CWINDOW_ZOOM="2.500000e-01" DEFAULT_ATRANSITION="Crossfade" DEFAULT_VTRANSITION="Dissolve" DEFAULT_TRANSITION_LENGTH="1.0000000000000001e-01" EDITING_MODE="1" FOLDERLIST_FORMAT="1" HIGHLIGHTED_TRACK="2" LABELS_FOLLOW_EDITS="0" MPEG4_DEBLOCK="1" PLUGINS_FOLLOW_EDITS="1" PLAYBACK_PRELOAD="0" SAFE_REGIONS="0" SHOW_TITLES="1" TEST_PLAYBACK_EDITS="1" TIME_FORMAT="1" TIMECODE_OFFSET_0="0" TIMECODE_OFFSET_1="0" TIMECODE_OFFSET_2="0" TIMECODE_OFFSET_3="0" NUDGE_SECONDS="1" TOOL_WINDOW="0" VWINDOW_METER="1" VWINDOW_FOLDER="" VWINDOW_SOURCE="-1" VWINDOW_ZOOM="1.000000e+00"></SESSION>
+
+<VIDEO INTERPOLATION_TYPE="3" COLORMODEL="RGBA-8 Bit" CHANNELS="1" VCHANNEL_X_0="0" VCHANNEL_Y_0="0" FRAMERATE="2.0000000000000000e+01" FRAMES_PER_FOOT="1.600000e+01" OUTPUTW="22" OUTPUTH="22" ASPECTW="1.000000e+00" ASPECTH="1.000000e+00"></VIDEO>
+
+<AUDIO SAMPLERATE="48000" CHANNELS="2" ACHANNEL_ANGLE_0="270" ACHANNEL_ANGLE_1="90"></AUDIO>
+
+<FOLDER>Clips</FOLDER>
+<FOLDER>Media</FOLDER>
+<ASSETS>
+</ASSETS>
+
+
+
+<LABELS>
+</LABELS>
+
+<TRACK RECORD="1" NUDGE="0" PLAY="1" GANG="1" DRAW="1" EXPAND="1" TRACK_W="22" TRACK_H="22" TYPE="VIDEO">
+<TITLE>White</TITLE>
+<EDITS>
+</EDITS>
+<MUTEAUTOS>
+<AUTO POSITION="0" VALUE="0"></AUTO>
+</MUTEAUTOS>
+<FADEAUTOS>
+<AUTO POSITION="0" VALUE="1.000000e+02" CONTROL_IN_VALUE="0.000000e+00" CONTROL_OUT_VALUE="0.000000e+00" CONTROL_IN_POSITION="0" CONTROL_OUT_POSITION="0"></AUTO>
+</FADEAUTOS>
+<CAMERAAUTOS>
+<AUTO POSITION="0" CENTER_X="0.000000e+00" CENTER_Y="0.000000e+00" CENTER_Z="1.000000e+00" CONTROL_IN_X="0.000000e+00" CONTROL_IN_Y="0.000000e+00" CONTROL_IN_Z="0.000000e+00" CONTROL_OUT_X="0.000000e+00" CONTROL_OUT_Y="0.000000e+00" CONTROL_OUT_Z="0.000000e+00"></AUTO>
+</CAMERAAUTOS>
+<PROJECTORAUTOS>
+<AUTO POSITION="0" CENTER_X="0.000000e+00" CENTER_Y="0.000000e+00" CENTER_Z="1.000000e+00" CONTROL_IN_X="0.000000e+00" CONTROL_IN_Y="0.000000e+00" CONTROL_IN_Z="0.000000e+00" CONTROL_OUT_X="0.000000e+00" CONTROL_OUT_Y="0.000000e+00" CONTROL_OUT_Z="0.000000e+00"></AUTO>
+</PROJECTORAUTOS>
+<MODEAUTOS>
+<AUTO POSITION="0" VALUE="0"></AUTO>
+</MODEAUTOS>
+<MASKAUTOS>
+<AUTO MODE="1" VALUE="100" FEATHER="0.000000e+00" POSITION="0">
+<MASK NUMBER="0">
+
+<POINT>0.000000e+00, 1.000000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>6.500000e+00, 1.000000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>8.590909e+00, 1.640909e+01, -5.909090e-01, -2.545456e+00, 8.181820e-01, -3.545455e+00</POINT>
+<POINT>1.300000e+01, 1.909091e+00, -8.181820e-01, -1.818181e-01, 6.363640e-01, 4.545462e-02</POINT>
+<POINT>1.536364e+01, 1.222727e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.800000e+01, 1.000000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>2.200000e+01, 1.000000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>2.200000e+01, 1.200000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.800000e+01, 1.200000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.468182e+01, 1.504545e+01, 5.000000e-01, 0.000000e+00, -6.363640e-01, 0.000000e+00</POINT>
+<POINT>1.272727e+01, 6.318182e+00, 3.181820e-01, -7.727273e-01, -3.181810e-01, 5.000000e-01</POINT>
+<POINT>8.363637e+00, 1.904545e+01, 2.090908e+00, -1.272728e+00, -6.818180e-01, -5.000000e-01</POINT>
+<POINT>5.772700e+00, 1.200000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>0.000000e+00, 1.200000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+</MASK>
+<MASK NUMBER="1">
+
+<POINT>3.000000e+00, 1.000000e+00, -2.919846e+00, 3.058505e-02, 3.128208e+00, 1.865485e-02</POINT>
+<POINT>1.900000e+01, 1.000000e+00, -9.967632e-01, 3.559867e-02, 2.990291e+00, 3.559858e-02</POINT>
+<POINT>2.200000e+01, 4.000000e+00, 0.000000e+00, -2.919094e+00, 2.990292e+00, -2.385113e+00</POINT>
+<POINT>8.466020e+00, -6.293528e+01, -1.907349e-06, -2.990291e+00, 1.922329e+00, -7.119727e-02</POINT>
+<POINT>0.000000e+00, 4.000000e+00, -5.449749e+00, -6.654691e-01, 6.980991e-02, -2.956489e+00</POINT>
+</MASK>
+<MASK NUMBER="2">
+
+<POINT>0.000000e+00, 1.800000e+01, -1.293845e+01, 2.234233e+01, -3.042877e-02, 3.027367e+00</POINT>
+<POINT>3.000000e+00, 2.100000e+01, -2.990291e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.900000e+01, 2.100000e+01, -1.317152e+00, 0.000000e+00, 2.990292e+00, -3.559875e-02</POINT>
+<POINT>2.200000e+01, 1.800000e+01, 8.273602e-03, 2.919092e+00, 3.620749e+01, 2.604206e+01</POINT>
+</MASK>
+
+</AUTO>
+</MASKAUTOS>
+<CZOOMAUTOS>
+<AUTO POSITION="0" VALUE="1.000000e+00" CONTROL_IN_VALUE="0.000000e+00" CONTROL_OUT_VALUE="0.000000e+00" CONTROL_IN_POSITION="0" CONTROL_OUT_POSITION="0"></AUTO>
+</CZOOMAUTOS>
+<PZOOMAUTOS>
+<AUTO POSITION="0" VALUE="1.000000e+00" CONTROL_IN_VALUE="0.000000e+00" CONTROL_OUT_VALUE="0.000000e+00" CONTROL_IN_POSITION="0" CONTROL_OUT_POSITION="0"></AUTO>
+</PZOOMAUTOS>
+<PLUGINSET RECORD="1">
+<PLUGIN LENGTH="31" TYPE="1" TITLE="Gradient">
+<IN></IN><OUT></OUT><ON></ON>
+<KEYFRAME POSITION="0" DEFAULT="1"><GRADIENT ANGLE="-8.9000000000000000e+01" IN_RADIUS="0.0000000000000000e+00" OUT_RADIUS="1.0000000000000000e+02" IN_R="0" IN_G="0" IN_B="0" IN_A="255" OUT_R="0" OUT_G="0" OUT_B="0" OUT_A="255"></KEYFRAME>
+</PLUGIN>
+</PLUGINSET>
+</TRACK>
+
+
+
+<TRACK RECORD="0" NUDGE="0" PLAY="1" GANG="1" DRAW="1" EXPAND="1" TRACK_W="22" TRACK_H="22" TYPE="VIDEO">
+<TITLE>Video 1</TITLE>
+<EDITS>
+</EDITS>
+<MUTEAUTOS>
+<AUTO POSITION="0" VALUE="0"></AUTO>
+</MUTEAUTOS>
+<FADEAUTOS>
+<AUTO POSITION="0" VALUE="1.000000e+02" CONTROL_IN_VALUE="0.000000e+00" CONTROL_OUT_VALUE="0.000000e+00" CONTROL_IN_POSITION="0" CONTROL_OUT_POSITION="0"></AUTO>
+</FADEAUTOS>
+<CAMERAAUTOS>
+<AUTO POSITION="0" CENTER_X="0.000000e+00" CENTER_Y="0.000000e+00" CENTER_Z="1.000000e+00" CONTROL_IN_X="0.000000e+00" CONTROL_IN_Y="0.000000e+00" CONTROL_IN_Z="0.000000e+00" CONTROL_OUT_X="0.000000e+00" CONTROL_OUT_Y="0.000000e+00" CONTROL_OUT_Z="0.000000e+00"></AUTO>
+</CAMERAAUTOS>
+<PROJECTORAUTOS>
+<AUTO POSITION="0" CENTER_X="0.000000e+00" CENTER_Y="0.000000e+00" CENTER_Z="1.000000e+00" CONTROL_IN_X="0.000000e+00" CONTROL_IN_Y="0.000000e+00" CONTROL_IN_Z="0.000000e+00" CONTROL_OUT_X="0.000000e+00" CONTROL_OUT_Y="0.000000e+00" CONTROL_OUT_Z="0.000000e+00"></AUTO>
+</PROJECTORAUTOS>
+<MODEAUTOS>
+<AUTO POSITION="0" VALUE="0"></AUTO>
+</MODEAUTOS>
+<MASKAUTOS>
+<AUTO MODE="0" VALUE="100" FEATHER="0.000000e+00" POSITION="0">
+<MASK NUMBER="0">
+
+<POINT>8.954546e+00, 4.545455e-02, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.131818e+01, 2.272727e-01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.204545e+01, 2.177273e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>9.954546e+00, 2.172727e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+</MASK>
+
+</AUTO>
+<AUTO MODE="1" VALUE="100" FEATHER="1.000000e+00" POSITION="0">
+<MASK NUMBER="0">
+
+<POINT>1.829126e+01, 2.634304e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>2.061489e+01, 2.563107e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>2.113636e+01, 7.409091e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.995455e+01, 6.636364e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+</MASK>
+
+</AUTO>
+<AUTO MODE="1" VALUE="100" FEATHER="1.000000e+00" POSITION="1">
+<MASK NUMBER="0">
+
+<POINT>-2.000000e+00, 7.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.000000e+00, 6.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.000000e+00, 1.500000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>-2.000000e+00, 1.400000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+</MASK>
+
+</AUTO>
+<AUTO MODE="1" VALUE="100" FEATHER="2.000000e+00" POSITION="9">
+<MASK NUMBER="0">
+
+<POINT>4.285700e+00, 4.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>7.285714e+00, 2.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>7.285714e+00, 2.000000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>4.285700e+00, 1.800000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+</MASK>
+
+</AUTO>
+<AUTO MODE="1" VALUE="100" FEATHER="1.000000e+00" POSITION="22">
+<MASK NUMBER="0">
+
+<POINT>1.450000e+01, 2.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.750000e+01, 2.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.750000e+01, 2.000000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.450000e+01, 2.000000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+</MASK>
+
+</AUTO>
+<AUTO MODE="1" VALUE="100" FEATHER="1.000000e+00" POSITION="23">
+<MASK NUMBER="0">
+
+<POINT>1.528571e+01, 2.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.828570e+01, 4.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.828570e+01, 1.800000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.528571e+01, 2.000000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+</MASK>
+
+</AUTO>
+<AUTO MODE="1" VALUE="100" FEATHER="1.000000e+00" POSITION="29">
+<MASK NUMBER="0">
+
+<POINT>2.000000e+01, 5.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>2.300000e+01, 7.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>2.300000e+01, 1.500000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>2.000000e+01, 1.700000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+</MASK>
+
+</AUTO>
+<AUTO MODE="1" VALUE="100" FEATHER="1.000000e+00" POSITION="30">
+<MASK NUMBER="0">
+
+<POINT>1.829126e+01, 2.634304e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>2.061489e+01, 2.563107e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>2.113636e+01, 7.409091e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.995455e+01, 6.636364e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+</MASK>
+
+</AUTO>
+</MASKAUTOS>
+<CZOOMAUTOS>
+<AUTO POSITION="0" VALUE="1.000000e+00" CONTROL_IN_VALUE="0.000000e+00" CONTROL_OUT_VALUE="0.000000e+00" CONTROL_IN_POSITION="0" CONTROL_OUT_POSITION="0"></AUTO>
+</CZOOMAUTOS>
+<PZOOMAUTOS>
+<AUTO POSITION="0" VALUE="1.000000e+00" CONTROL_IN_VALUE="0.000000e+00" CONTROL_OUT_VALUE="0.000000e+00" CONTROL_IN_POSITION="0" CONTROL_OUT_POSITION="0"></AUTO>
+</PZOOMAUTOS>
+<PLUGINSET RECORD="1">
+<PLUGIN LENGTH="31" TYPE="1" TITLE="Gradient">
+<IN></IN><OUT></OUT><ON></ON>
+<KEYFRAME POSITION="0" DEFAULT="1"><GRADIENT ANGLE="-8.9000000000000000e+01" IN_RADIUS="1.8000000000000000e+01" OUT_RADIUS="8.4000000000000000e+01" IN_R="255" IN_G="0" IN_B="0" IN_A="255" OUT_R="255" OUT_G="0" OUT_B="0" OUT_A="255" SHAPE="0" RATE="0" CENTER_X="5.0000000000000000e+01" CENTER_Y="5.0000000000000000e+01"></KEYFRAME>
+</PLUGIN>
+</PLUGINSET>
+</TRACK>
+
+
+
+<TRACK RECORD="0" NUDGE="0" PLAY="1" GANG="1" DRAW="1" EXPAND="1" TRACK_W="22" TRACK_H="22" TYPE="VIDEO">
+<TITLE>White Line</TITLE>
+<EDITS>
+</EDITS>
+<MUTEAUTOS>
+<AUTO POSITION="0" VALUE="0"></AUTO>
+</MUTEAUTOS>
+<FADEAUTOS>
+<AUTO POSITION="0" VALUE="1.000000e+02" CONTROL_IN_VALUE="0.000000e+00" CONTROL_OUT_VALUE="0.000000e+00" CONTROL_IN_POSITION="0" CONTROL_OUT_POSITION="0"></AUTO>
+</FADEAUTOS>
+<CAMERAAUTOS>
+<AUTO POSITION="0" CENTER_X="0.000000e+00" CENTER_Y="0.000000e+00" CENTER_Z="1.000000e+00" CONTROL_IN_X="0.000000e+00" CONTROL_IN_Y="0.000000e+00" CONTROL_IN_Z="0.000000e+00" CONTROL_OUT_X="0.000000e+00" CONTROL_OUT_Y="0.000000e+00" CONTROL_OUT_Z="0.000000e+00"></AUTO>
+</CAMERAAUTOS>
+<PROJECTORAUTOS>
+<AUTO POSITION="0" CENTER_X="0.000000e+00" CENTER_Y="0.000000e+00" CENTER_Z="1.000000e+00" CONTROL_IN_X="0.000000e+00" CONTROL_IN_Y="0.000000e+00" CONTROL_IN_Z="0.000000e+00" CONTROL_OUT_X="0.000000e+00" CONTROL_OUT_Y="0.000000e+00" CONTROL_OUT_Z="0.000000e+00"></AUTO>
+</PROJECTORAUTOS>
+<MODEAUTOS>
+<AUTO POSITION="0" VALUE="0"></AUTO>
+</MODEAUTOS>
+<MASKAUTOS>
+<AUTO MODE="0" VALUE="100" FEATHER="0.000000e+00" POSITION="0">
+<MASK NUMBER="0">
+
+<POINT>0.000000e+00, 8.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>1.300000e+01, 1.505758e+00, -6.904849e+00, -1.818181e-01, 6.063031e+00, -2.845454e-01</POINT>
+<POINT>2.200000e+01, 8.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>2.200000e+01, 1.400000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+<POINT>8.620300e+00, 2.047545e+01, 3.484241e+00, -9.427280e-01, -7.538484e+00, 1.233349e-01</POINT>
+<POINT>0.000000e+00, 1.400000e+01, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00</POINT>
+</MASK>
+
+</AUTO>
+</MASKAUTOS>
+<CZOOMAUTOS>
+<AUTO POSITION="0" VALUE="1.000000e+00" CONTROL_IN_VALUE="0.000000e+00" CONTROL_OUT_VALUE="0.000000e+00" CONTROL_IN_POSITION="0" CONTROL_OUT_POSITION="0"></AUTO>
+</CZOOMAUTOS>
+<PZOOMAUTOS>
+<AUTO POSITION="0" VALUE="1.000000e+00" CONTROL_IN_VALUE="0.000000e+00" CONTROL_OUT_VALUE="0.000000e+00" CONTROL_IN_POSITION="0" CONTROL_OUT_POSITION="0"></AUTO>
+</PZOOMAUTOS>
+<PLUGINSET RECORD="1">
+<PLUGIN LENGTH="31" TYPE="1" TITLE="Gradient">
+<IN></IN><OUT></OUT><ON></ON>
+<KEYFRAME POSITION="0" DEFAULT="1"><GRADIENT ANGLE="-8.9000000000000000e+01" IN_RADIUS="1.2500000000000000e+01" OUT_RADIUS="8.4000000000000000e+01" IN_R="255" IN_G="255" IN_B="255" IN_A="255" OUT_R="255" OUT_G="255" OUT_B="255" OUT_A="255"></KEYFRAME>
+</PLUGIN>
+</PLUGINSET>
+</TRACK>
+
+
+
+</EDL>
diff --git a/kdbg/pics/hi22-action-pulse000000.png b/kdbg/pics/hi22-action-pulse000000.png
new file mode 100644
index 0000000..851b517
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000000.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000001.png b/kdbg/pics/hi22-action-pulse000001.png
new file mode 100644
index 0000000..5f3d46c
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000001.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000002.png b/kdbg/pics/hi22-action-pulse000002.png
new file mode 100644
index 0000000..a557671
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000002.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000003.png b/kdbg/pics/hi22-action-pulse000003.png
new file mode 100644
index 0000000..b3a278b
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000003.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000004.png b/kdbg/pics/hi22-action-pulse000004.png
new file mode 100644
index 0000000..11a4ef0
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000004.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000005.png b/kdbg/pics/hi22-action-pulse000005.png
new file mode 100644
index 0000000..8330a75
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000005.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000006.png b/kdbg/pics/hi22-action-pulse000006.png
new file mode 100644
index 0000000..41a37ba
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000006.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000007.png b/kdbg/pics/hi22-action-pulse000007.png
new file mode 100644
index 0000000..1210606
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000007.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000008.png b/kdbg/pics/hi22-action-pulse000008.png
new file mode 100644
index 0000000..4643a6e
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000008.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000009.png b/kdbg/pics/hi22-action-pulse000009.png
new file mode 100644
index 0000000..5f958f4
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000009.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000010.png b/kdbg/pics/hi22-action-pulse000010.png
new file mode 100644
index 0000000..eade071
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000010.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000011.png b/kdbg/pics/hi22-action-pulse000011.png
new file mode 100644
index 0000000..e429e57
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000011.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000012.png b/kdbg/pics/hi22-action-pulse000012.png
new file mode 100644
index 0000000..c694311
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000012.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000013.png b/kdbg/pics/hi22-action-pulse000013.png
new file mode 100644
index 0000000..beb7a08
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000013.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000014.png b/kdbg/pics/hi22-action-pulse000014.png
new file mode 100644
index 0000000..8a6ede4
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000014.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000015.png b/kdbg/pics/hi22-action-pulse000015.png
new file mode 100644
index 0000000..ab96e03
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000015.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000016.png b/kdbg/pics/hi22-action-pulse000016.png
new file mode 100644
index 0000000..5f83e3d
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000016.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000017.png b/kdbg/pics/hi22-action-pulse000017.png
new file mode 100644
index 0000000..118f253
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000017.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000018.png b/kdbg/pics/hi22-action-pulse000018.png
new file mode 100644
index 0000000..dff8ade
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000018.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000019.png b/kdbg/pics/hi22-action-pulse000019.png
new file mode 100644
index 0000000..7b512ca
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000019.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000020.png b/kdbg/pics/hi22-action-pulse000020.png
new file mode 100644
index 0000000..a4dad79
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000020.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000021.png b/kdbg/pics/hi22-action-pulse000021.png
new file mode 100644
index 0000000..5deb1b5
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000021.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000022.png b/kdbg/pics/hi22-action-pulse000022.png
new file mode 100644
index 0000000..acee422
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000022.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000023.png b/kdbg/pics/hi22-action-pulse000023.png
new file mode 100644
index 0000000..91f0816
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000023.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000024.png b/kdbg/pics/hi22-action-pulse000024.png
new file mode 100644
index 0000000..c81e865
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000024.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000025.png b/kdbg/pics/hi22-action-pulse000025.png
new file mode 100644
index 0000000..02c079a
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000025.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000026.png b/kdbg/pics/hi22-action-pulse000026.png
new file mode 100644
index 0000000..4138c59
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000026.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000027.png b/kdbg/pics/hi22-action-pulse000027.png
new file mode 100644
index 0000000..4c2c8f8
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000027.png
Binary files differ
diff --git a/kdbg/pics/hi22-action-pulse000028.png b/kdbg/pics/hi22-action-pulse000028.png
new file mode 100644
index 0000000..13f0598
--- /dev/null
+++ b/kdbg/pics/hi22-action-pulse000028.png
Binary files differ
diff --git a/kdbg/pics/hi32-app-kdbg.png b/kdbg/pics/hi32-app-kdbg.png
new file mode 100644
index 0000000..6de18a9
--- /dev/null
+++ b/kdbg/pics/hi32-app-kdbg.png
Binary files differ
diff --git a/kdbg/pics/hi48-app-kdbg.png b/kdbg/pics/hi48-app-kdbg.png
new file mode 100644
index 0000000..7ef7a79
--- /dev/null
+++ b/kdbg/pics/hi48-app-kdbg.png
Binary files differ
diff --git a/kdbg/pics/lo16-app-kdbg.png b/kdbg/pics/lo16-app-kdbg.png
new file mode 100644
index 0000000..161ffc1
--- /dev/null
+++ b/kdbg/pics/lo16-app-kdbg.png
Binary files differ
diff --git a/kdbg/pics/lo32-app-kdbg.png b/kdbg/pics/lo32-app-kdbg.png
new file mode 100644
index 0000000..8b77a21
--- /dev/null
+++ b/kdbg/pics/lo32-app-kdbg.png
Binary files differ
diff --git a/kdbg/pics/pcinner.xpm b/kdbg/pics/pcinner.xpm
new file mode 100644
index 0000000..ccc4db5
--- /dev/null
+++ b/kdbg/pics/pcinner.xpm
@@ -0,0 +1,14 @@
+/* XPM */
+static char * pcinner_xpm[] = {
+"14 8 3 1",
+" c None",
+". c #FFFFFF",
+"+ c #006400",
+" ...... ",
+" .+++++... ",
+" .++++++++.. ",
+" .++++++++++. ",
+" .++++++++++. ",
+" .++++++++.. ",
+" .+++++.... ",
+" ...... "};
diff --git a/kdbg/pics/pcup.xpm b/kdbg/pics/pcup.xpm
new file mode 100644
index 0000000..3134e14
--- /dev/null
+++ b/kdbg/pics/pcup.xpm
@@ -0,0 +1,14 @@
+/* XPM */
+static char * pcup_xpm[] = {
+"14 8 3 1",
+" c None",
+". c #FFFFFF",
+"+ c #006400",
+" ...... ",
+" .+++++... ",
+" .++++++++.. ",
+" .++....++++. ",
+" .++....++++. ",
+" .++++++++.. ",
+" .+++++.... ",
+" ...... "};
diff --git a/kdbg/pics/pointer.xpm b/kdbg/pics/pointer.xpm
new file mode 100644
index 0000000..635b04e
--- /dev/null
+++ b/kdbg/pics/pointer.xpm
@@ -0,0 +1,18 @@
+/* XPM */
+static char * pointer_xpm[] = {
+"12 12 3 1",
+" c None",
+". c #FF0000",
+"+ c #8B0000",
+" ",
+" ",
+" ",
+" ",
+". .. ",
+"+. ... ",
+"++..........",
+" +++++++++++",
+" ..+ ",
+" ++ ",
+" ",
+" "};
diff --git a/kdbg/pics/regs.xpm b/kdbg/pics/regs.xpm
new file mode 100644
index 0000000..d2abaa5
--- /dev/null
+++ b/kdbg/pics/regs.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static const char *regs[] = {
+"16 16 6 1",
+" c Gray0",
+". c #808000",
+"X c Yellow",
+"o c #808080",
+"O c None",
+"+ c Gray100",
+"OOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOO",
+"OOO........... O",
+"OO.XXXXXXXXXX. O",
+"OO...........O O",
+"OOo++++++++++O O",
+"OOo+OOO+++OO+O O",
+"OOo++++++++++O O",
+"OOo+OOOOOOOO+O O",
+"OOo++++++++++O O",
+"OOo+OOOOOOOO+O O",
+"OOo++++++++++O O",
+"OOo++++++++++O O",
+"OOooooooooooooOO",
+"OOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOO"
+};
diff --git a/kdbg/pics/watch.xpm b/kdbg/pics/watch.xpm
new file mode 100644
index 0000000..d24759f
--- /dev/null
+++ b/kdbg/pics/watch.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static const char*watch[]={
+"16 16 5 1",
+"# c #000000",
+"c c #ffffff",
+"a c #808080",
+". c None",
+"b c #00ffff",
+"................",
+"................",
+"................",
+".....#..........",
+"....#.#.......#.",
+"...#..#......#.#",
+"..#...#.....#..#",
+".#.........#...#",
+"a###.##.###a....",
+"#bcb#..#bcb#....",
+"#cb.#..#cb.#....",
+"#b.b#..#b.b#....",
+"#.b.#..#.b.#....",
+".###....###.....",
+"................",
+"................"};
diff --git a/kdbg/pics/watchcoded.xpm b/kdbg/pics/watchcoded.xpm
new file mode 100644
index 0000000..b2461ba
--- /dev/null
+++ b/kdbg/pics/watchcoded.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static char * watchcoded_xpm[] = {
+"16 16 7 1",
+" c None",
+". c #000000",
+"+ c #B5B5B5",
+"@ c #FFFFFF",
+"# c #808080",
+"$ c #00FFFF",
+"% c #B5FFFF",
+" ",
+" ",
+" ",
+" . ",
+" +@+ . ",
+" +...@ . .",
+" +..@..@@@ +@ .",
+" .@.@ @.@..+..@.",
+"#.+.@.+.++...@ ",
+".$@.+ @.%@%.@ ",
+".@%..@..@%.+.@ ",
+".$ %...+%..+..@ ",
+". $ +@@. %@.@@ ",
+" ... ... ",
+" ",
+" "};
diff --git a/kdbg/pics/watchdis.xpm b/kdbg/pics/watchdis.xpm
new file mode 100644
index 0000000..0af7119
--- /dev/null
+++ b/kdbg/pics/watchdis.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char * watchdis_xpm[] = {
+"14 14 5 1",
+" c None",
+". c #5C5C5C",
+"+ c #ADADAD",
+"@ c #93C6C6",
+"# c #FFFFFF",
+" ",
+" ",
+" . . ",
+" . . . .",
+" . . . .",
+" . . . .",
+" . . ",
+"+... .. ...+ ",
+".@#@. .@#@. ",
+"..... ..... ",
+". . . . ",
+" ",
+" ",
+" "};
diff --git a/kdbg/pics/watchena.xpm b/kdbg/pics/watchena.xpm
new file mode 100644
index 0000000..57b52aa
--- /dev/null
+++ b/kdbg/pics/watchena.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char * watchena_xpm[] = {
+"14 14 5 1",
+" c None",
+". c #000000",
+"+ c #808080",
+"@ c #00FFFF",
+"# c #FFFFFF",
+" ",
+" ",
+" . . ",
+" . . . .",
+" . . . .",
+" . . . .",
+" . . ",
+"+... .. ...+ ",
+".@#@. .@#@. ",
+".#@+. .#@+. ",
+".@+@. .@+@. ",
+".+@+. .+@+. ",
+" ... ... ",
+" "};
diff --git a/kdbg/prefdebugger.cpp b/kdbg/prefdebugger.cpp
new file mode 100644
index 0000000..f47dd53
--- /dev/null
+++ b/kdbg/prefdebugger.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include <klocale.h> /* i18n */
+#include <qlayout.h>
+#include "prefdebugger.h"
+
+PrefDebugger::PrefDebugger(QWidget* parent) :
+ QWidget(parent, "debugger"),
+ m_grid(this, 5, 2, 10),
+ m_defaultHint(this, "default_hint"),
+ m_debuggerCCppLabel(this, "debugger_label"),
+ m_debuggerCCpp(this, "debugger"),
+ m_terminalHint(this, "terminal_hint"),
+ m_terminalLabel(this, "terminal_label"),
+ m_terminal(this, "terminal")
+{
+ m_defaultHint.setText(i18n("To revert to the default settings, clear the entries."));
+ m_defaultHint.setMinimumHeight(m_defaultHint.sizeHint().height());
+ m_grid.addWidget(&m_defaultHint, 0, 1);
+
+ m_debuggerCCppLabel.setText(i18n("How to invoke &GDB:"));
+ m_debuggerCCppLabel.setMinimumSize(m_debuggerCCppLabel.sizeHint());
+ m_debuggerCCppLabel.setBuddy(&m_debuggerCCpp);
+ m_debuggerCCpp.setMinimumSize(m_debuggerCCpp.sizeHint());
+ m_grid.addWidget(&m_debuggerCCppLabel, 1, 0);
+ m_grid.addWidget(&m_debuggerCCpp, 1, 1);
+
+ m_terminalHint.setText(i18n("%T will be replaced with a title string,\n"
+ "%C will be replaced by a Bourne shell script that\n"
+ "keeps the terminal window open."));
+ m_terminalHint.setMinimumHeight(m_terminalHint.sizeHint().height());
+ m_grid.addWidget(&m_terminalHint, 2, 1);
+
+ m_terminalLabel.setText(i18n("&Terminal for program output:"));
+ m_terminalLabel.setMinimumSize(m_terminalLabel.sizeHint());
+ m_terminalLabel.setBuddy(&m_terminal);
+ m_terminal.setMinimumSize(m_terminal.sizeHint());
+ m_grid.addWidget(&m_terminalLabel, 3, 0);
+ m_grid.addWidget(&m_terminal, 3, 1);
+
+ m_grid.setColStretch(1, 10);
+ // last (empty) row gets all the vertical stretch
+ m_grid.setRowStretch(4, 10);
+}
diff --git a/kdbg/prefdebugger.h b/kdbg/prefdebugger.h
new file mode 100644
index 0000000..594bfa2
--- /dev/null
+++ b/kdbg/prefdebugger.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef PREFDEBUGGER_H
+#define PREFDEBUGGER_H
+
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+
+class PrefDebugger : public QWidget
+{
+public:
+ PrefDebugger(QWidget* parent);
+
+ QGridLayout m_grid;
+
+ // --- the hint about defaults
+protected:
+ QLabel m_defaultHint;
+
+ // --- the debugger command
+protected:
+ QLabel m_debuggerCCppLabel;
+ QLineEdit m_debuggerCCpp;
+public:
+ QString debuggerCmd() const { return m_debuggerCCpp.text(); }
+ void setDebuggerCmd(const QString& cmd) { m_debuggerCCpp.setText(cmd); }
+
+ // --- the output terminal
+protected:
+ QLabel m_terminalHint;
+ QLabel m_terminalLabel;
+ QLineEdit m_terminal;
+public:
+ QString terminal() const { return m_terminal.text(); }
+ void setTerminal(const QString& t) { m_terminal.setText(t); }
+};
+
+#endif // PREFDEBUGGER_H
diff --git a/kdbg/prefmisc.cpp b/kdbg/prefmisc.cpp
new file mode 100644
index 0000000..2c79bf8
--- /dev/null
+++ b/kdbg/prefmisc.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "prefmisc.h"
+#include <klocale.h> /* i18n */
+
+PrefMisc::PrefMisc(QWidget* parent) :
+ QWidget(parent, "debugger"),
+ m_grid(this, 6, 2, 10),
+ m_popForeground(this, "pop_fore"),
+ m_backTimeoutLabel(this, "back_to_lab"),
+ m_backTimeout(this, "back_to"),
+ m_tabWidthLabel(this, "tabwidth_lab"),
+ m_tabWidth(this, "tabwidth"),
+ m_sourceFilterLabel(this, "sourcefilter_lab"),
+ m_sourceFilter(this, "sourcefilter"),
+ m_headerFilterLabel(this, "headerfilter_lab"),
+ m_headerFilter(this, "headerfilter")
+{
+ m_popForeground.setText(i18n("&Pop into foreground when program stops"));
+ m_popForeground.setMinimumSize(m_popForeground.sizeHint());
+ m_grid.addMultiCellWidget(&m_popForeground, 0, 0, 0, 1);
+ m_grid.addRowSpacing(0, m_popForeground.sizeHint().height());
+
+ m_backTimeoutLabel.setText(i18n("Time until window goes &back (in milliseconds):"));
+ m_backTimeoutLabel.setMinimumSize(m_backTimeoutLabel.sizeHint());
+ m_backTimeoutLabel.setBuddy(&m_backTimeout);
+ m_backTimeout.setMinimumSize(m_backTimeout.sizeHint());
+ m_grid.addWidget(&m_backTimeoutLabel, 1, 0);
+ m_grid.addWidget(&m_backTimeout, 1, 1);
+
+ setupEditGroup(i18n("&Tabstop every (characters):"),
+ m_tabWidthLabel, m_tabWidth, 2);
+ setupEditGroup(i18n("File filter for &source files:"),
+ m_sourceFilterLabel, m_sourceFilter, 3);
+ setupEditGroup(i18n("File filter for &header files:"),
+ m_headerFilterLabel, m_headerFilter, 4);
+
+ m_grid.setColStretch(1, 10);
+ // last (empty) row gets all the vertical stretch
+ m_grid.setRowStretch(5, 10);
+}
+
+void PrefMisc::setupEditGroup(const QString& label, QLabel& labWidget, QLineEdit& edit, int row)
+{
+ labWidget.setText(label);
+ labWidget.setMinimumSize(labWidget.sizeHint());
+ labWidget.setBuddy(&edit);
+ edit.setMinimumSize(edit.sizeHint());
+ m_grid.addWidget(&labWidget, row, 0);
+ m_grid.addWidget(&edit, row, 1);
+}
+
+static int readNumeric(const QLineEdit& edit)
+{
+ QString str = edit.text();
+ return str.toInt();
+}
+
+int PrefMisc::backTimeout() const
+{
+ return readNumeric(m_backTimeout);
+}
+
+void PrefMisc::setBackTimeout(int to)
+{
+ QString str;
+ str.setNum(to);
+ m_backTimeout.setText(str);
+}
+
+int PrefMisc::tabWidth() const
+{
+ return readNumeric(m_tabWidth);
+}
+
+void PrefMisc::setTabWidth(int tw)
+{
+ QString str;
+ str.setNum(tw);
+ m_tabWidth.setText(str);
+}
diff --git a/kdbg/prefmisc.h b/kdbg/prefmisc.h
new file mode 100644
index 0000000..45701db
--- /dev/null
+++ b/kdbg/prefmisc.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef PREFMISC_H
+#define PREFMISC_H
+
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+
+class PrefMisc : public QWidget
+{
+public:
+ PrefMisc(QWidget* parent);
+
+ QGridLayout m_grid;
+
+protected:
+ QCheckBox m_popForeground;
+
+ QLabel m_backTimeoutLabel;
+ QLineEdit m_backTimeout;
+
+ QLabel m_tabWidthLabel;
+ QLineEdit m_tabWidth;
+
+ QLabel m_sourceFilterLabel;
+ QLineEdit m_sourceFilter;
+ QLabel m_headerFilterLabel;
+ QLineEdit m_headerFilter;
+
+ void setupEditGroup(const QString& label, QLabel& labWidget, QLineEdit& edit, int row);
+
+public:
+ bool popIntoForeground() const { return m_popForeground.isChecked(); }
+ void setPopIntoForeground(bool pop) { m_popForeground.setChecked(pop); }
+ int backTimeout() const;
+ void setBackTimeout(int to);
+ int tabWidth() const;
+ void setTabWidth(int tw);
+ QString sourceFilter() const { return m_sourceFilter.text(); }
+ void setSourceFilter(const QString& f) { m_sourceFilter.setText(f); }
+ QString headerFilter() const { return m_headerFilter.text(); }
+ void setHeaderFilter(const QString& f) { m_headerFilter.setText(f); }
+};
+
+#endif // PREFMISC_H
diff --git a/kdbg/procattach.cpp b/kdbg/procattach.cpp
new file mode 100644
index 0000000..985a4e9
--- /dev/null
+++ b/kdbg/procattach.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "procattach.h"
+#include <qlistview.h>
+#include <qtoolbutton.h>
+#include <qlineedit.h>
+#include <kprocess.h>
+#include <ctype.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <klocale.h> /* i18n */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+ProcAttachPS::ProcAttachPS(QWidget* parent) :
+ ProcAttachBase(parent),
+ m_pidCol(-1),
+ m_ppidCol(-1)
+{
+ m_ps = new KProcess;
+ connect(m_ps, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(slotTextReceived(KProcess*, char*, int)));
+ connect(m_ps, SIGNAL(processExited(KProcess*)),
+ this, SLOT(slotPSDone()));
+
+ QIconSet icon = SmallIconSet("clear_left");
+ filterClear->setIconSet(icon);
+
+ processList->setColumnWidth(0, 300);
+ processList->setColumnWidthMode(0, QListView::Manual);
+ processList->setColumnAlignment(1, Qt::AlignRight);
+ processList->setColumnAlignment(2, Qt::AlignRight);
+
+ // set the command line
+ static const char* const psCommand[] = {
+#ifdef PS_COMMAND
+ PS_COMMAND,
+#else
+ "/bin/false",
+#endif
+ 0
+ };
+ for (int i = 0; psCommand[i] != 0; i++) {
+ *m_ps << psCommand[i];
+ }
+
+ runPS();
+}
+
+ProcAttachPS::~ProcAttachPS()
+{
+ delete m_ps; // kills a running ps
+}
+
+void ProcAttachPS::runPS()
+{
+ // clear the parse state from previous runs
+ m_token = "";
+ m_line.clear();
+ m_pidCol = -1;
+ m_ppidCol = -1;
+
+ m_ps->start(KProcess::NotifyOnExit, KProcess::Stdout);
+}
+
+void ProcAttachPS::slotTextReceived(KProcess*, char* buffer, int buflen)
+{
+ const char* end = buffer+buflen;
+ while (buffer < end)
+ {
+ // check new line
+ if (*buffer == '\n')
+ {
+ // push a tokens onto the line
+ if (!m_token.isEmpty()) {
+ m_line.push_back(QString::fromLatin1(m_token));
+ m_token = "";
+ }
+ // and insert the line in the list
+ pushLine();
+ m_line.clear();
+ ++buffer;
+ }
+ // blanks: the last column gets the rest of the line, including blanks
+ else if ((m_pidCol < 0 || int(m_line.size()) < processList->columns()-1) &&
+ isspace(*buffer))
+ {
+ // push a token onto the line
+ if (!m_token.isEmpty()) {
+ m_line.push_back(QString::fromLatin1(m_token));
+ m_token = "";
+ }
+ do {
+ ++buffer;
+ } while (buffer < end && isspace(*buffer));
+ }
+ // tokens
+ else
+ {
+ const char* start = buffer;
+ do {
+ ++buffer;
+ } while (buffer < end && !isspace(*buffer));
+ // append to the current token
+ m_token += QCString(start, buffer-start+1); // must count the '\0'
+ }
+ }
+}
+
+void ProcAttachPS::pushLine()
+{
+ if (m_line.size() < 3) // we need the PID, PPID, and COMMAND columns
+ return;
+
+ if (m_pidCol < 0)
+ {
+ // create columns if we don't have them yet
+ bool allocate = processList->columns() == 3;
+
+ // we assume that the last column is the command
+ m_line.pop_back();
+
+ for (uint i = 0; i < m_line.size(); i++) {
+ // we don't allocate the PID and PPID columns,
+ // but we need to know where in the ps output they are
+ if (m_line[i] == "PID") {
+ m_pidCol = i;
+ } else if (m_line[i] == "PPID") {
+ m_ppidCol = i;
+ } else if (allocate) {
+ processList->addColumn(m_line[i]);
+ // these columns are normally numbers
+ processList->setColumnAlignment(processList->columns()-1,
+ Qt::AlignRight);
+ }
+ }
+ }
+ else
+ {
+ // insert a line
+ // find the parent process
+ QListViewItem* parent = 0;
+ if (m_ppidCol >= 0 && m_ppidCol < int(m_line.size())) {
+ parent = processList->findItem(m_line[m_ppidCol], 1);
+ }
+
+ // we assume that the last column is the command
+ QListViewItem* item;
+ if (parent == 0) {
+ item = new QListViewItem(processList, m_line.back());
+ } else {
+ item = new QListViewItem(parent, m_line.back());
+ }
+ item->setOpen(true);
+ m_line.pop_back();
+ int k = 3;
+ for (uint i = 0; i < m_line.size(); i++)
+ {
+ // display the pid and ppid columns' contents in columns 1 and 2
+ if (int(i) == m_pidCol)
+ item->setText(1, m_line[i]);
+ else if (int(i) == m_ppidCol)
+ item->setText(2, m_line[i]);
+ else
+ item->setText(k++, m_line[i]);
+ }
+
+ if (m_ppidCol >= 0 && m_pidCol >= 0) { // need PID & PPID for this
+ /*
+ * It could have happened that a process was earlier inserted,
+ * whose parent process is the current process. Such processes
+ * were placed at the root. Here we go through all root items
+ * and check whether we must reparent them.
+ */
+ QListViewItem* i = processList->firstChild();
+ while (i != 0)
+ {
+ // advance before we reparent the item
+ QListViewItem* it = i;
+ i = i->nextSibling();
+ if (it->text(2) == m_line[m_pidCol]) {
+ processList->takeItem(it);
+ item->insertItem(it);
+ }
+ }
+ }
+ }
+}
+
+void ProcAttachPS::slotPSDone()
+{
+ filterEdited(filterEdit->text());
+}
+
+QString ProcAttachPS::text() const
+{
+ QListViewItem* item = processList->selectedItem();
+
+ if (item == 0)
+ return QString();
+
+ return item->text(1);
+}
+
+void ProcAttachPS::refresh()
+{
+ if (!m_ps->isRunning())
+ {
+ processList->clear();
+ buttonOk->setEnabled(false); // selection was cleared
+ runPS();
+ }
+}
+
+void ProcAttachPS::filterEdited(const QString& text)
+{
+ QListViewItem* i = processList->firstChild();
+ if (i) {
+ setVisibility(i, text);
+ }
+}
+
+/**
+ * Sets the visibility of \a i and
+ * returns whether it was made visible.
+ */
+bool ProcAttachPS::setVisibility(QListViewItem* i, const QString& text)
+{
+ bool visible = false;
+ for (QListViewItem* j = i->firstChild(); j; j = j->nextSibling())
+ {
+ if (setVisibility(j, text))
+ visible = true;
+ }
+ // look for text in the process name and in the PID
+ visible = visible || text.isEmpty() ||
+ i->text(0).find(text, 0, false) >= 0 ||
+ i->text(1).find(text) >= 0;
+
+ i->setVisible(visible);
+
+ // disable the OK button if the selected item becomes invisible
+ if (i->isSelected())
+ buttonOk->setEnabled(visible);
+
+ return visible;
+}
+
+void ProcAttachPS::selectedChanged()
+{
+ buttonOk->setEnabled(processList->selectedItem() != 0);
+}
+
+
+ProcAttach::ProcAttach(QWidget* parent) :
+ QDialog(parent, "procattach", true),
+ m_label(this, "label"),
+ m_processId(this, "procid"),
+ m_buttonOK(this, "ok"),
+ m_buttonCancel(this, "cancel"),
+ m_layout(this, 8),
+ m_buttons(4)
+{
+ QString title = kapp->caption();
+ title += i18n(": Attach to process");
+ setCaption(title);
+
+ m_label.setMinimumSize(330, 24);
+ m_label.setText(i18n("Specify the process number to attach to:"));
+
+ m_processId.setMinimumSize(330, 24);
+ m_processId.setMaxLength(100);
+ m_processId.setFrame(true);
+
+ m_buttonOK.setMinimumSize(100, 30);
+ connect(&m_buttonOK, SIGNAL(clicked()), SLOT(accept()));
+ m_buttonOK.setText(i18n("OK"));
+ m_buttonOK.setDefault(true);
+
+ m_buttonCancel.setMinimumSize(100, 30);
+ connect(&m_buttonCancel, SIGNAL(clicked()), SLOT(reject()));
+ m_buttonCancel.setText(i18n("Cancel"));
+
+ m_layout.addWidget(&m_label);
+ m_layout.addWidget(&m_processId);
+ m_layout.addLayout(&m_buttons);
+ m_layout.addStretch(10);
+ m_buttons.addStretch(10);
+ m_buttons.addWidget(&m_buttonOK);
+ m_buttons.addSpacing(40);
+ m_buttons.addWidget(&m_buttonCancel);
+ m_buttons.addStretch(10);
+
+ m_layout.activate();
+
+ m_processId.setFocus();
+ resize(350, 120);
+}
+
+ProcAttach::~ProcAttach()
+{
+}
diff --git a/kdbg/procattach.h b/kdbg/procattach.h
new file mode 100644
index 0000000..6ee1e42
--- /dev/null
+++ b/kdbg/procattach.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef ProcAttach_included
+#define ProcAttach_included
+
+#include "procattachbase.h"
+#include <qvaluevector.h>
+#include <qdialog.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+
+
+class KProcess;
+
+/*
+ * This is the full-featured version of the dialog. It is used when the
+ * system features a suitable ps command.
+ */
+
+class ProcAttachPS : public ProcAttachBase
+{
+ Q_OBJECT
+public:
+ ProcAttachPS(QWidget* parent);
+ ~ProcAttachPS();
+
+ QString text() const;
+
+protected:
+ void runPS();
+ virtual void refresh();
+ virtual void filterEdited(const QString& text);
+ virtual void selectedChanged();
+
+protected slots:
+ void slotTextReceived(KProcess* proc, char* buffer, int buflen);
+ void slotPSDone();
+
+protected:
+ void pushLine();
+ bool setVisibility(QListViewItem* i, const QString& text);
+
+ KProcess* m_ps;
+ // parse state
+ int m_pidCol; //!< The PID column in the ps output
+ int m_ppidCol; //!< The parent-PID column in the ps output
+ QCString m_token;
+ QValueVector<QString> m_line;
+};
+
+
+/*
+ * This is an extremely stripped down version of the dialog. It is used
+ * when there is no suitable ps command.
+ */
+
+class ProcAttach : public QDialog
+{
+public:
+ ProcAttach(QWidget* parent);
+ virtual ~ProcAttach();
+
+ void setText(const QString& text) { m_processId.setText(text); }
+ QString text() const { return m_processId.text(); }
+
+protected:
+ QLabel m_label;
+ QLineEdit m_processId;
+ QPushButton m_buttonOK;
+ QPushButton m_buttonCancel;
+ QVBoxLayout m_layout;
+ QHBoxLayout m_buttons;
+};
+
+#endif // ProcAttach_included
diff --git a/kdbg/procattachbase.cpp b/kdbg/procattachbase.cpp
new file mode 100644
index 0000000..b6f8293
--- /dev/null
+++ b/kdbg/procattachbase.cpp
@@ -0,0 +1,137 @@
+#include <kdialog.h>
+#include <klocale.h>
+/****************************************************************************
+** Form implementation generated from reading ui file '../../exper/kdbg/procattachbase.ui'
+**
+** Created: Sun Jun 6 14:57:15 2010
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+
+#include "procattachbase.h"
+
+#include <qvariant.h>
+#include <qpushbutton.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qtoolbutton.h>
+#include <qheader.h>
+#include <qlistview.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+
+/*
+ * Constructs a ProcAttachBase as 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.
+ */
+ProcAttachBase::ProcAttachBase( QWidget* parent, const char* name, bool modal, WFlags fl )
+ : QDialog( parent, name, modal, fl )
+{
+ if ( !name )
+ setName( "ProcAttachBase" );
+ setSizeGripEnabled( TRUE );
+ ProcAttachBaseLayout = new QHBoxLayout( this, 10, 6, "ProcAttachBaseLayout");
+
+ layout7 = new QVBoxLayout( 0, 0, 6, "layout7");
+
+ layout6 = new QHBoxLayout( 0, 0, 6, "layout6");
+
+ filterLabel = new QLabel( this, "filterLabel" );
+ layout6->addWidget( filterLabel );
+
+ filterEdit = new QLineEdit( this, "filterEdit" );
+ filterEdit->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)5, 0, 0, filterEdit->sizePolicy().hasHeightForWidth() ) );
+ filterEdit->setMaxLength( 20 );
+ layout6->addWidget( filterEdit );
+
+ filterClear = new QToolButton( this, "filterClear" );
+ layout6->addWidget( filterClear );
+ layout7->addLayout( layout6 );
+
+ processList = new QListView( this, "processList" );
+ processList->addColumn( tr2i18n( "Command" ) );
+ processList->addColumn( tr2i18n( "PID" ) );
+ processList->addColumn( tr2i18n( "PPID" ) );
+ processList->setMinimumSize( QSize( 300, 200 ) );
+ processList->setAllColumnsShowFocus( TRUE );
+ layout7->addWidget( processList );
+
+ layout3 = new QHBoxLayout( 0, 0, 6, "layout3");
+
+ buttonRefresh = new QPushButton( this, "buttonRefresh" );
+ buttonRefresh->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, buttonRefresh->sizePolicy().hasHeightForWidth() ) );
+ layout3->addWidget( buttonRefresh );
+ spacingBtns = new QSpacerItem( 242, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ layout3->addItem( spacingBtns );
+
+ buttonOk = new QPushButton( this, "buttonOk" );
+ buttonOk->setEnabled( FALSE );
+ buttonOk->setAutoDefault( TRUE );
+ buttonOk->setDefault( TRUE );
+ layout3->addWidget( buttonOk );
+
+ buttonCancel = new QPushButton( this, "buttonCancel" );
+ buttonCancel->setAutoDefault( TRUE );
+ layout3->addWidget( buttonCancel );
+ layout7->addLayout( layout3 );
+ ProcAttachBaseLayout->addLayout( layout7 );
+ languageChange();
+ resize( QSize(560, 416).expandedTo(minimumSizeHint()) );
+ clearWState( WState_Polished );
+
+ // signals and slots connections
+ connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) );
+ connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
+ connect( buttonRefresh, SIGNAL( clicked() ), this, SLOT( refresh() ) );
+ connect( filterEdit, SIGNAL( textChanged(const QString&) ), this, SLOT( filterEdited(const QString&) ) );
+ connect( filterClear, SIGNAL( clicked() ), filterEdit, SLOT( clear() ) );
+ connect( processList, SIGNAL( selectionChanged() ), this, SLOT( selectedChanged() ) );
+
+ // tab order
+ setTabOrder( filterEdit, processList );
+ setTabOrder( processList, buttonRefresh );
+ setTabOrder( buttonRefresh, buttonOk );
+ setTabOrder( buttonOk, buttonCancel );
+
+ // buddies
+ filterLabel->setBuddy( filterEdit );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+ProcAttachBase::~ProcAttachBase()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void ProcAttachBase::languageChange()
+{
+ setCaption( tr2i18n( "Attach to Process" ) );
+ filterLabel->setText( tr2i18n( "&Filter or PID:" ) );
+ QWhatsThis::add( filterEdit, tr2i18n( "Type the name of the process or its process ID (PID) here to reduce the number of entries in the list." ) );
+ filterClear->setText( tr2i18n( "..." ) );
+ QToolTip::add( filterClear, tr2i18n( "Clear filter" ) );
+ QWhatsThis::add( filterClear, tr2i18n( "Use this button to clear the filter text so that all processes are displayed." ) );
+ processList->header()->setLabel( 0, tr2i18n( "Command" ) );
+ processList->header()->setLabel( 1, tr2i18n( "PID" ) );
+ processList->header()->setLabel( 2, tr2i18n( "PPID" ) );
+ QWhatsThis::add( processList, tr2i18n( "<p>This list displays all processes that are currently running. You must select the process that you want KDbg to attach to. Use the <b>Filter or PID</b> edit box to reduce the number of entries in this list.<p>The text in the <i>Command</i> column is usually, but not always, the command that was used to start the process. The <i>PID</i> column shows the process ID. The <i>PPID</i> column shows the process ID of the parent process. Additional columns show more information about the processes that is also available via the system's <i>ps</i> command.</p><p>The list is not updated automatically. Use the <b>Refresh</b> button to update it.</p>" ) );
+ buttonRefresh->setText( tr2i18n( "&Refresh" ) );
+ QWhatsThis::add( buttonRefresh, tr2i18n( "This button updates the list of processes." ) );
+ buttonOk->setText( tr2i18n( "&OK" ) );
+ buttonOk->setAccel( QKeySequence( QString::null ) );
+ QWhatsThis::add( buttonOk, tr2i18n( "You must select a process from the list. Then click the <b>OK</b> button to attach to that process." ) );
+ buttonCancel->setText( tr2i18n( "&Cancel" ) );
+ buttonCancel->setAccel( QKeySequence( QString::null ) );
+}
+
+#include "procattachbase.moc"
diff --git a/kdbg/procattachbase.ui b/kdbg/procattachbase.ui
new file mode 100644
index 0000000..e44540d
--- /dev/null
+++ b/kdbg/procattachbase.ui
@@ -0,0 +1,276 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ProcAttachBase</class>
+<author>Johannes Sixt</author>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>ProcAttachBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>560</width>
+ <height>416</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Attach to Process</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>filterLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Filter or PID:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>filterEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>filterEdit</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maxLength">
+ <number>20</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Type the name of the process or its process ID (PID) here to reduce the number of entries in the list.</string>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>filterClear</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Clear filter</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Use this button to clear the filter text so that all processes are displayed.</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QListView">
+ <column>
+ <property name="text">
+ <string>Command</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>PID</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>PPID</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>processList</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>200</height>
+ </size>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;This list displays all processes that are currently running. You must select the process that you want KDbg to attach to. Use the &lt;b&gt;Filter or PID&lt;/b&gt; edit box to reduce the number of entries in this list.&lt;p&gt;The text in the &lt;i&gt;Command&lt;/i&gt; column is usually, but not always, the command that was used to start the process. The &lt;i&gt;PID&lt;/i&gt; column shows the process ID. The &lt;i&gt;PPID&lt;/i&gt; column shows the process ID of the parent process. Additional columns show more information about the processes that is also available via the system's &lt;i&gt;ps&lt;/i&gt; command.&lt;/p&gt;&lt;p&gt;The list is not updated automatically. Use the &lt;b&gt;Refresh&lt;/b&gt; button to update it.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonRefresh</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Refresh</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This button updates the list of processes.</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacingBtns</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>242</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonOk</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>You must select a process from the list. Then click the &lt;b&gt;OK&lt;/b&gt; button to attach to that process.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonCancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>ProcAttachBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>ProcAttachBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>buttonRefresh</sender>
+ <signal>clicked()</signal>
+ <receiver>ProcAttachBase</receiver>
+ <slot>refresh()</slot>
+ </connection>
+ <connection>
+ <sender>filterEdit</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>ProcAttachBase</receiver>
+ <slot>filterEdited(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>filterClear</sender>
+ <signal>clicked()</signal>
+ <receiver>filterEdit</receiver>
+ <slot>clear()</slot>
+ </connection>
+ <connection>
+ <sender>processList</sender>
+ <signal>selectionChanged()</signal>
+ <receiver>ProcAttachBase</receiver>
+ <slot>selectedChanged()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>filterEdit</tabstop>
+ <tabstop>processList</tabstop>
+ <tabstop>buttonRefresh</tabstop>
+ <tabstop>buttonOk</tabstop>
+ <tabstop>buttonCancel</tabstop>
+</tabstops>
+<slots>
+ <slot specifier="pure virtual">refresh()</slot>
+ <slot specifier="pure virtual">filterEdited(const QString&amp;)</slot>
+ <slot specifier="pure virtual">selectedChanged()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="10"/>
+</UI>
diff --git a/kdbg/programconfig.cpp b/kdbg/programconfig.cpp
new file mode 100644
index 0000000..28f837a
--- /dev/null
+++ b/kdbg/programconfig.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "programconfig.h"
+#include <kconfigbackend.h>
+#include <qfile.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+struct ProgramConfig::MyBackend : KConfigINIBackEnd
+{
+ MyBackend(KConfigBase* cfg, const QString& fn) :
+ KConfigINIBackEnd(cfg, fn, "", false)
+ { }
+ // need the following public
+ using KConfigINIBackEnd::parseSingleConfigFile;
+};
+
+ProgramConfig::ProgramConfig(const QString& fileName) :
+ m_fileName(fileName)
+{
+ m_iniBackend = new MyBackend(this, fileName);
+ backEnd = m_iniBackend;
+ reparseConfiguration();
+}
+
+QStringList ProgramConfig::groupList() const
+{
+ // unused
+ return QStringList();
+}
+
+QMap<QString, QString> ProgramConfig::entryMap(const QString&) const
+{
+ // unused
+ return QMap<QString, QString>();
+}
+
+void ProgramConfig::reparseConfiguration()
+{
+ m_entryMap.clear();
+
+ // add the "default group" marker to the map
+ KEntryKey groupKey("<default>", 0);
+ m_entryMap.insert(groupKey, KEntry());
+
+ QFile file(m_fileName);
+ bool readonly = true;
+ bool useit = true;
+ if (file.open(IO_ReadWrite)) { /* don't truncate! */
+ readonly = false;
+ // the file exists now
+ } else if (!file.open(IO_ReadOnly)) {
+ /* file does not exist and cannot be created: don't use it */
+ useit = false;
+ }
+
+ if (useit)
+ {
+ // Check ownership
+ // Important: This must be done using fstat on the opened file
+ // to avoid race conditions.
+ struct stat s;
+ memset(&s, 0, sizeof(s));
+ useit =
+ fstat(file.handle(), &s) == 0 &&
+ s.st_uid == getuid();
+ }
+
+ if (useit)
+ {
+ m_iniBackend->parseSingleConfigFile(file, 0, false, false);
+ }
+ else
+ {
+ /*
+ * The program specific config file is not ours, so we do not trust
+ * it for the following reason: Should the debuggee be located in a
+ * world-writable directory somebody else may have created it where
+ * the entry DebuggerCmdStr contains a malicious command, or may
+ * have created a (possibly huge) file containing nonsense, which
+ * leads to a DoS.
+ */
+ }
+
+ // don't write the file if we don't own it
+ setReadOnly(readonly || !useit);
+}
+
+KEntryMap ProgramConfig::internalEntryMap(const QString& group) const
+{
+ QCString group_utf = group.utf8();
+ KEntryMap tmpEntryMap;
+
+ // copy the whole group starting at the special group marker
+ KEntryKey key(group_utf, 0);
+ KEntryMapConstIterator it = m_entryMap.find(key);
+ for (; it != m_entryMap.end() && it.key().mGroup == group_utf; ++it)
+ {
+ tmpEntryMap.insert(it.key(), *it);
+ }
+
+ return tmpEntryMap;
+}
+
+KEntryMap ProgramConfig::internalEntryMap() const
+{
+ return m_entryMap;
+}
+
+void ProgramConfig::putData(const KEntryKey& key, const KEntry& data, bool checkGroup)
+{
+ if (checkGroup)
+ {
+ // make sure the special group marker is present
+ m_entryMap[KEntryKey(key.mGroup, 0)];
+ }
+ m_entryMap[key] = data;
+}
+
+KEntry ProgramConfig::lookupData(const KEntryKey& key) const
+{
+ KEntryMapConstIterator it;
+
+ it = m_entryMap.find(key);
+ if (it != m_entryMap.end())
+ {
+ const KEntry& entry = *it;
+ if (entry.bDeleted)
+ return KEntry();
+ else
+ return entry;
+ }
+ else {
+ return KEntry();
+ }
+}
+
+bool ProgramConfig::internalHasGroup(const QCString&) const
+{
+ // unused
+ return false;
+}
diff --git a/kdbg/programconfig.h b/kdbg/programconfig.h
new file mode 100644
index 0000000..325769d
--- /dev/null
+++ b/kdbg/programconfig.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include <kconfigbase.h>
+
+class KConfigINIBackEnd;
+
+class ProgramConfig : public KConfigBase
+{
+public:
+ ProgramConfig(const QString &fileName);
+ virtual QStringList groupList() const;
+ virtual QMap<QString, QString> entryMap(const QString &group) const;
+ virtual void reparseConfiguration();
+ virtual KEntryMap internalEntryMap( const QString& pGroup ) const;
+ virtual KEntryMap internalEntryMap() const;
+ virtual void putData(const KEntryKey &_key, const KEntry &_data, bool _checkGroup = true);
+ virtual KEntry lookupData(const KEntryKey &_key) const;
+ virtual bool internalHasGroup(const QCString &group) const;
+
+protected:
+ /**
+ * Contains all key,value entries, as well as some "special"
+ * keys which indicate the start of a group of entries.
+ *
+ * These special keys will have the .key portion of their @ref KEntryKey
+ * set to QString::null.
+ */
+ KEntryMap m_entryMap;
+ QString m_fileName;
+ // this is defined out-of-line
+ struct MyBackend;
+ MyBackend* m_iniBackend;
+};
diff --git a/kdbg/regwnd.cpp b/kdbg/regwnd.cpp
new file mode 100644
index 0000000..861b30a
--- /dev/null
+++ b/kdbg/regwnd.cpp
@@ -0,0 +1,613 @@
+/*
+ * Copyright Max Judin, Johannes Sixt, Daniel Kristjansson
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include <qheader.h>
+#include <kglobalsettings.h>
+#include <klocale.h> /* i18n */
+#include <kiconloader.h>
+#include <qfontdialog.h>
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+#include <stdlib.h> /* strtoul */
+#include "regwnd.h"
+#include "dbgdriver.h"
+
+/**
+ * Register display modes
+ */
+class RegisterDisplay {
+public:
+ enum BitSize {
+ bits8 = 0x10,
+ bits16 = 0x20,
+ bits32 = 0x30,
+ bits64 = 0x40,
+ bits80 = 0x50,
+ bits128 = 0x60,
+ bitsUnknown = 0x70
+ };
+
+ enum Format {
+ nada = 0x01,
+ binary = 0x02,
+ octal = 0x03,
+ decimal = 0x04,
+ hex = 0x05,
+ bcd = 0x06,
+ realE = 0x07,
+ realG = 0x08,
+ realF = 0x09
+ };
+ RegisterDisplay() : mode(bitsUnknown|nada) { }
+ RegisterDisplay(uint newMode) : mode(newMode) { }
+
+ bool contains(uint pmode) const {
+ bool val=((mode&0xf0)==pmode)||((mode&0x0f)==pmode);
+ return val;
+ }
+ uint bitsFlag() { return mode&0xf0; }
+ uint presentationFlag() const { return mode&0x0f; }
+ uint bits() const { return bitMap[(mode>>4)&0x07]; }
+ void changeFlag(uint code) {
+ uint mask=((code&0xf0)==code)?0x0f:0xf0;
+ mode = code | (mode & mask);
+ }
+private:
+ uint mode;
+ static uint bitMap[];
+};
+
+// helper struct
+struct MenuPair
+{
+ const char* name;
+ uint mode;
+ bool isSeparator() { return name == 0; }
+};
+
+static MenuPair menuitems[] = {
+ // treat as
+ { I18N_NOOP("&GDB default"), RegisterDisplay::nada },
+ { I18N_NOOP("&Binary"), RegisterDisplay::binary },
+ { I18N_NOOP("&Octal"), RegisterDisplay::octal },
+ { I18N_NOOP("&Decimal"), RegisterDisplay::decimal },
+ { I18N_NOOP("He&xadecimal"), RegisterDisplay::hex },
+ { I18N_NOOP("Real (&e)"), RegisterDisplay::realE },
+ { I18N_NOOP("Real (&f)"), RegisterDisplay::realF },
+ { I18N_NOOP("&Real (g)"), RegisterDisplay::realG },
+ { 0, 0 },
+ { "8 bits", RegisterDisplay::bits8 },
+ { "16 bits", RegisterDisplay::bits16 },
+ { "32 bits", RegisterDisplay::bits32 },
+ { "64 bits", RegisterDisplay::bits64 },
+ { "80 bits", RegisterDisplay::bits80 },
+ { "128 bits",RegisterDisplay::bits128 },
+};
+
+uint RegisterDisplay::bitMap[] = {
+ 0, 8, 16, 32,
+ 64, 80, 128, /*default*/32,
+};
+
+class ModeItem : public QListViewItem
+{
+public:
+ ModeItem(QListView* parent, const QString& name) : QListViewItem(parent, name) {}
+ ModeItem(QListViewItem* parent) : QListViewItem(parent) {}
+
+ virtual void setMode(RegisterDisplay mode) = 0;
+ virtual RegisterDisplay mode() = 0;
+};
+
+class GroupingViewItem : public ModeItem
+{
+public:
+ GroupingViewItem(RegisterView* parent,
+ const QString& name, const QString& pattern,
+ RegisterDisplay mode) :
+ ModeItem(parent, name), matcher(pattern), gmode(mode)
+ {
+ setExpandable(true);
+ setOpen(true);
+ }
+ bool matchName(const QString& str) const
+ {
+ return matcher.exactMatch(str);
+ }
+ virtual void setMode(RegisterDisplay mode)
+ {
+ gmode=mode;
+ QListViewItem *it=firstChild();
+ for (; 0!=it; it=it->nextSibling()) {
+ (static_cast<ModeItem*>(it))->setMode(gmode);
+ }
+ }
+ virtual RegisterDisplay mode() { return gmode; }
+
+private:
+ QRegExp matcher;
+ RegisterDisplay gmode;
+};
+
+class RegisterViewItem : public ModeItem
+{
+public:
+ RegisterViewItem(GroupingViewItem* parent,
+ const RegisterInfo& regInfo);
+ ~RegisterViewItem();
+
+ void setValue(const RegisterInfo& regInfo);
+ virtual void setMode(RegisterDisplay mode);
+ virtual RegisterDisplay mode() { return m_mode; }
+ RegisterInfo m_reg;
+ RegisterDisplay m_mode; /* display mode */
+ bool m_changes;
+ bool m_found;
+
+protected:
+ virtual void paintCell(QPainter*, const QColorGroup& cg,
+ int column, int width, int alignment);
+
+};
+
+
+RegisterViewItem::RegisterViewItem(GroupingViewItem* parent,
+ const RegisterInfo& regInfo) :
+ ModeItem(parent),
+ m_reg(regInfo),
+ m_changes(false),
+ m_found(true)
+{
+ setValue(m_reg);
+ setText(0, m_reg.regName);
+ setMode(parent->mode());
+}
+
+RegisterViewItem::~RegisterViewItem()
+{
+}
+
+/*
+ * We must be careful when converting the hex value because
+ * it may exceed this computer's long values.
+ */
+inline int hexCharToDigit(char h)
+{
+ if (h < '0')
+ return -1;
+ if (h <= '9')
+ return h - '0';
+ if (h < 'A')
+ return -1;
+ if (h <= 'F')
+ return h - ('A' - 10);
+ if (h < 'a')
+ return -1;
+ if (h <= 'f')
+ return h - ('a' - 10);
+ return -1;
+}
+
+static QString toBinary(QString hex)
+{
+ static const char digits[16][8] = {
+ "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
+ "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
+ };
+ QString result;
+
+ for (unsigned i = 2; i < hex.length(); i++) {
+ int idx = hexCharToDigit(hex[i].latin1());
+ if (idx < 0) {
+ // not a hex digit; no conversion
+ return hex;
+ }
+ const char* bindigits = digits[idx];
+ result += bindigits;
+ }
+ // remove leading zeros
+ switch (hexCharToDigit(hex[2].latin1())) {
+ case 0: case 1: result.remove(0, 3); break;
+ case 2: case 3: result.remove(0, 2); break;
+ case 4: case 5:
+ case 6: case 7: result.remove(0, 1); break;
+ }
+ return result;
+}
+
+static QString toOctal(QString hex)
+{
+ QString result;
+ int shift = 0;
+ unsigned v = 0;
+ for (int i = hex.length()-1; i >= 2; i--) {
+ int idx = hexCharToDigit(hex[i].latin1());
+ if (idx < 0)
+ return hex;
+ v += idx << shift;
+ result.insert(0, (v & 7) + '0');
+ v >>= 3;
+ shift++;
+ if (shift == 3) {
+ // an extra digit this round
+ result.insert(0, v + '0');
+ shift = v = 0;
+ }
+ }
+ if (v != 0) {
+ result.insert(0, v + '0');
+ }
+ return "0" + result;
+}
+
+static QString toDecimal(QString hex)
+{
+ /*
+ * We convert only numbers that are small enough for this computer's
+ * size of long integers.
+ */
+ if (hex.length() > sizeof(unsigned long)*2+2) /* count in leading "0x" */
+ return hex;
+
+ const char* start = hex.latin1();
+ char* end;
+ unsigned long val = strtoul(start, &end, 0);
+ if (start == end)
+ return hex;
+ else
+ return QString().setNum(val);
+}
+
+static QString toBCD(const QString& hex)
+{
+ return hex.right(2);
+}
+
+static char* toRaw(const QString& hex, uint& length)
+{
+ static uint testNum=1;
+ static void* testVoid=(void*)&testNum;
+ static char* testChar=(char*)testVoid;
+ static bool littleendian=(*testChar==1);
+
+ length=((hex.length()-2)%2)+((hex.length()-2)/2);
+ char* data=new char[length];
+
+ if (littleendian) {
+ uint j=0;
+ if (hex.length()<=2) return 0;
+ for (int i=hex.length()-1; i>=2; ) {
+ if (j%2==0) data[j/2]=hexCharToDigit(hex[i].latin1());
+ else data[j/2]|=(hexCharToDigit(hex[i].latin1())<<4);
+ i--;j++;
+ }
+ } else { // big endian
+ uint j=0;
+ if (hex.length()<=2) return 0;
+ for (uint i=2; i<hex.length(); ) {
+ if (j%2==0) data[j/2]=hexCharToDigit(hex[i].latin1())<<4;
+ else data[j/2]|=hexCharToDigit(hex[i].latin1());
+ i++;j++;
+ }
+ }
+ return data;
+}
+
+static long double extractNumber(const QString& hex)
+{
+ uint length;
+ char* data=toRaw(hex, length);
+ long double val;
+ if (length==4) { // float
+ val=*((float*)data);
+ } else if (length==8) { // double
+ val=*((double*)data);
+ } else if (length==10) { // long double
+ val=*((long double*)data);
+ } else {
+ val=*((float*)data);
+ }
+ delete[] data;
+
+ return val;
+}
+
+static QString toFloat(const QString& hex, char p)
+{
+ uint bits;
+ uint prec=6;
+ if (hex.length()<=10) { bits=32; prec=6; }
+ else if (hex.length()<=18) { bits=64; prec=17; }
+ else { bits=80; prec=20; }
+
+ QString cooked=QString::number(extractNumber(hex), p, prec);
+ if (p=='e') {
+ prec+=7;
+ while (cooked.length()<prec) cooked=cooked.prepend(" ");
+ }
+ return cooked;
+}
+
+static QString convertSingle(const QString& raw, const RegisterDisplay mode)
+{
+ switch (mode.presentationFlag()) {
+ case RegisterDisplay::binary: return toBinary(raw);
+ case RegisterDisplay::octal: return toOctal(raw);
+ case RegisterDisplay::decimal: return toDecimal(raw);
+ case RegisterDisplay::hex: return raw;
+ case RegisterDisplay::bcd: return toBCD(raw);
+ case RegisterDisplay::realE: return toFloat(raw, 'e');
+ case RegisterDisplay::realG: return toFloat(raw, 'g');
+ case RegisterDisplay::realF: return toFloat(raw, 'f');
+ default: return raw;
+ }
+}
+
+QString convertRaw(const RegisterInfo reg, RegisterDisplay mode)
+{
+ QString cooked;
+ uint totalNibles=0, nibles=mode.bits()>>2;
+ if (RegisterDisplay::nada!=mode.presentationFlag() &&
+ reg.rawValue.length() > 2 && reg.rawValue[0] == '0' && reg.rawValue[1] == 'x')
+ {
+ if ("uint128"==reg.type) totalNibles=32;
+ else if ("uint64"==reg.type) totalNibles=16;
+ else if (reg.type.isEmpty()) totalNibles=nibles;
+ else {
+ return "don't know how to handle vector type <"+reg.type+">";
+ }
+ if (0==nibles) nibles=8; // default to 4 byte, 32 bits values
+ if (nibles>totalNibles) totalNibles=nibles; // minimum one value
+
+ QString raw=reg.rawValue.right(reg.rawValue.length()-2); // clip off "0x"
+ while (raw.length()<totalNibles) raw.prepend("0"); // pad out to totalNibles
+
+ QString separator=","; // locale-specific?
+ for (int nib=totalNibles-nibles; nib>=0; nib-=nibles) {
+ QString qstr=convertSingle(raw.mid(nib, nibles).prepend("0x"), mode);
+
+ if (nib==int(totalNibles-nibles)) cooked=qstr+cooked;
+ else cooked=qstr+separator+cooked;
+ }
+ }
+ else
+ {
+ cooked = reg.cookedValue;
+ }
+ if (cooked.at(0)!=' ' && cooked.at(0)!='-' && cooked.at(0)!='+')
+ cooked.prepend(" ");
+ return cooked;
+}
+
+void RegisterViewItem::setValue(const RegisterInfo& reg)
+{
+ m_reg = reg;
+
+ setText(1, reg.rawValue);
+ QString cookedValue = convertRaw(reg, m_mode);
+ setText(2, cookedValue);
+}
+
+void RegisterViewItem::setMode(RegisterDisplay mode)
+{
+ m_mode = mode;
+
+ QString cookedValue = convertRaw(m_reg, mode);
+ setText(2, cookedValue);
+}
+
+void RegisterViewItem::paintCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int alignment)
+{
+ if (m_changes) {
+ QColorGroup newcg = cg;
+ newcg.setColor(QColorGroup::Text, red);
+ QListViewItem::paintCell(p, newcg, column, width, alignment);
+ } else {
+ QListViewItem::paintCell(p, cg, column, width, alignment);
+ }
+}
+
+
+RegisterView::RegisterView(QWidget* parent, const char* name) :
+ QListView(parent, name)
+{
+ setSorting(-1);
+ setFont(KGlobalSettings::fixedFont());
+
+ QPixmap iconRegs = UserIcon("regs.xpm");
+ QPixmap iconWatchcoded = UserIcon("watchcoded.xpm");
+ QPixmap iconWatch = UserIcon("watch.xpm");
+
+ addColumn(QIconSet(iconRegs), i18n("Register"));
+ addColumn(QIconSet(iconWatchcoded), i18n("Value"));
+ addColumn(QIconSet(iconWatch), i18n("Decoded value"));
+
+ setColumnAlignment(0,AlignLeft);
+ setColumnAlignment(1,AlignLeft);
+ setColumnAlignment(2,AlignLeft);
+
+ setAllColumnsShowFocus( true );
+ header()->setClickEnabled(false);
+
+ connect(this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)),
+ SLOT(rightButtonClicked(QListViewItem*,const QPoint&,int)));
+
+ m_modemenu = new QPopupMenu(this, "ERROR");
+ for (uint i=0; i<sizeof(menuitems)/sizeof(MenuPair); i++) {
+ if (menuitems[i].isSeparator())
+ m_modemenu->insertSeparator();
+ else
+ m_modemenu->insertItem(i18n(menuitems[i].name), menuitems[i].mode);
+ }
+ connect(m_modemenu,SIGNAL(activated(int)),SLOT(slotModeChange(int)));
+
+ new GroupingViewItem(this, "MIPS VU", "^vu.*",
+ RegisterDisplay::bits32|RegisterDisplay::realE);
+ new GroupingViewItem(this, "AltiVec", "^vr.*",
+ RegisterDisplay::bits32|RegisterDisplay::realE);
+ new GroupingViewItem(this, "POWER real", "^fpr.*",
+ RegisterDisplay::bits32|RegisterDisplay::realE);
+ new GroupingViewItem(this, "MMX", "^mm.*",
+ RegisterDisplay::bits32|RegisterDisplay::realE);
+ new GroupingViewItem(this, "SSE", "^xmm.*",
+ RegisterDisplay::bits32|RegisterDisplay::realE);
+ new GroupingViewItem(this, "x87", "^st.*",
+ RegisterDisplay::bits80|RegisterDisplay::realE);
+ new GroupingViewItem(this, i18n("x86/x87 segment"),
+ "(^cs$|^ss$|^ds$|^es$|^fs$|^gs$|^fiseg$|^foseg$)",
+ RegisterDisplay::nada);
+ new GroupingViewItem(this, i18n("Flags"),
+ "(^eflags$|^fctrl$|^mxcsr$|^cr$|^fpscr$|^vscr$|^ftag$|^fstat$)",
+ RegisterDisplay::bits32|RegisterDisplay::binary);
+ new GroupingViewItem(this, i18n("GP and others"), "^$",
+ RegisterDisplay::nada);
+
+ updateGroupVisibility();
+ setRootIsDecorated(true);
+
+ resize(200,300);
+}
+
+RegisterView::~RegisterView()
+{
+}
+
+GroupingViewItem* RegisterView::findMatchingGroup(const QString& regName)
+{
+ for (QListViewItem* it = firstChild(); it != 0; it = it->nextSibling())
+ {
+ GroupingViewItem* i = static_cast<GroupingViewItem*>(it);
+ if (i->matchName(regName))
+ return i;
+ }
+ // not better match found, so return "GP and others"
+ return static_cast<GroupingViewItem*>(firstChild());
+}
+
+GroupingViewItem* RegisterView::findGroup(const QString& groupName)
+{
+ for (QListViewItem* it = firstChild(); it != 0; it = it->nextSibling())
+ {
+ if (it->text(0) == groupName)
+ return static_cast<GroupingViewItem*>(it);
+ }
+ return 0;
+}
+
+void RegisterView::updateGroupVisibility()
+{
+ for (QListViewItem* it = firstChild(); it != 0; it = it->nextSibling())
+ {
+ it->setVisible(it->childCount() > 0);
+ }
+}
+
+void RegisterView::updateRegisters(const std::list<RegisterInfo>& regs)
+{
+ setUpdatesEnabled(false);
+
+ // mark all items as 'not found'
+ for (RegMap::iterator i = m_registers.begin(); i != m_registers.end(); ++i)
+ {
+ i->second->m_found = false;
+ }
+
+ // parse register values
+ // must iterate last to first, since QListView inserts at the top
+ for (std::list<RegisterInfo>::const_reverse_iterator reg = regs.rbegin(); reg != regs.rend(); ++reg)
+ {
+ // check if this is a new register
+ RegMap::iterator i = m_registers.find(reg->regName);
+
+ if (i != m_registers.end())
+ {
+ RegisterViewItem* it = i->second;
+ it->m_found = true;
+ if (it->m_reg.rawValue != reg->rawValue ||
+ it->m_reg.cookedValue != reg->cookedValue)
+ {
+ it->m_changes = true;
+ it->setValue(*reg);
+ repaintItem(it);
+ } else {
+ /*
+ * If there was a change last time, but not now, we
+ * must revert the color.
+ */
+ if (it->m_changes) {
+ it->m_changes = false;
+ repaintItem(it);
+ }
+ }
+ }
+ else
+ {
+ GroupingViewItem* group = findMatchingGroup(reg->regName);
+ m_registers[reg->regName] =
+ new RegisterViewItem(group, *reg);
+ }
+ }
+
+ // remove all 'not found' items;
+ QStringList del;
+ for (RegMap::iterator i = m_registers.begin(); i != m_registers.end(); ++i)
+ {
+ if (!i->second->m_found) {
+ del.push_back(i->first);
+ }
+ }
+ for (QStringList::Iterator i = del.begin(); i != del.end(); ++i)
+ {
+ RegMap::iterator it = m_registers.find(*i);
+ delete it->second;
+ m_registers.erase(it);
+ }
+
+ updateGroupVisibility();
+ setUpdatesEnabled(true);
+ triggerUpdate();
+}
+
+
+void RegisterView::rightButtonClicked(QListViewItem* item, const QPoint& p, int)
+{
+ if (item) {
+ RegisterDisplay mode=static_cast<ModeItem*>(item)->mode();
+ for (unsigned int i = 0; i<sizeof(menuitems)/sizeof(MenuPair); i++) {
+ m_modemenu->setItemChecked(menuitems[i].mode,
+ mode.contains(menuitems[i].mode));
+ }
+ m_modemenu->setCaption(item->text(0));
+ m_modemenu->popup(p);
+ }
+}
+
+void RegisterView::slotModeChange(int pcode)
+{
+ RegMap::iterator it=m_registers.find(m_modemenu->caption());
+ ModeItem* view;
+ if (it != m_registers.end())
+ view = it->second;
+ else
+ view = findGroup(m_modemenu->caption());
+
+ if (view) {
+ RegisterDisplay mode = view->mode();
+ mode.changeFlag(pcode);
+ view->setMode(mode);
+ }
+}
+
+void RegisterView::paletteChange(const QPalette& oldPal)
+{
+ setFont(KGlobalSettings::fixedFont());
+ QListView::paletteChange(oldPal);
+}
+
+#include "regwnd.moc"
diff --git a/kdbg/regwnd.h b/kdbg/regwnd.h
new file mode 100644
index 0000000..242064f
--- /dev/null
+++ b/kdbg/regwnd.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright Max Judin, Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef REGWND_H
+#define REGWND_H
+
+#include <qlistview.h>
+#include <list>
+#include <map>
+
+class QPopupMenu;
+class RegisterViewItem;
+class GroupingViewItem;
+struct RegisterInfo;
+
+
+class RegisterView : public QListView
+{
+ Q_OBJECT
+public:
+ RegisterView(QWidget* parent, const char *name = 0L);
+ ~RegisterView();
+
+protected slots:
+ void rightButtonClicked(QListViewItem*, const QPoint&, int);
+ void slotModeChange(int);
+ void updateRegisters(const std::list<RegisterInfo>&);
+
+private:
+ void paletteChange(const QPalette& oldPal);
+ void updateGroupVisibility();
+ GroupingViewItem* findMatchingGroup(const QString& regName);
+ GroupingViewItem* findGroup(const QString& groupName);
+ QPopupMenu* m_modemenu;
+ typedef std::map<QString,RegisterViewItem*> RegMap;
+ RegMap m_registers;
+
+friend class RegisterViewItem;
+};
+
+#endif // REGWND_H
diff --git a/kdbg/sourcewnd.cpp b/kdbg/sourcewnd.cpp
new file mode 100644
index 0000000..bef2e89
--- /dev/null
+++ b/kdbg/sourcewnd.cpp
@@ -0,0 +1,967 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "debugger.h"
+#include "sourcewnd.h"
+#include <qtextstream.h>
+#include <qpainter.h>
+#include <qbrush.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qkeycode.h>
+#include <qpopupmenu.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kglobalsettings.h>
+#include <kmainwindow.h>
+#include <algorithm>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "mydebug.h"
+
+
+SourceWindow::SourceWindow(const QString& fileName, QWidget* parent, const char* name) :
+ QTextEdit(parent, name),
+ m_fileName(fileName),
+ m_curRow(-1),
+ m_widthItems(16),
+ m_widthPlus(12),
+ m_widthLineNo(30)
+{
+ // load pixmaps
+ m_pcinner = UserIcon("pcinner");
+ m_pcup = UserIcon("pcup");
+ m_brkena = UserIcon("brkena");
+ m_brkdis = UserIcon("brkdis");
+ m_brktmp = UserIcon("brktmp");
+ m_brkcond = UserIcon("brkcond");
+ m_brkorph = UserIcon("brkorph");
+ setFont(KGlobalSettings::fixedFont());
+ setReadOnly(true);
+ setMargins(m_widthItems+m_widthPlus+m_widthLineNo, 0, 0 ,0);
+ setAutoFormatting(AutoNone);
+ setTextFormat(PlainText);
+ setWordWrap(NoWrap);
+ connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(update()));
+ connect(this, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(cursorChanged(int)));
+ viewport()->installEventFilter(this);
+
+ // add a syntax highlighter
+ if (QRegExp("\\.(c(pp|c|\\+\\+)?|CC?|h(\\+\\+|h)?|HH?)$").search(m_fileName) >= 0)
+ {
+ new HighlightCpp(this);
+ }
+}
+
+SourceWindow::~SourceWindow()
+{
+ delete syntaxHighlighter();
+}
+
+bool SourceWindow::loadFile()
+{
+ // first we load the code into QTextEdit
+ QFile f(m_fileName);
+ if (!f.open(IO_ReadOnly)) {
+ return false;
+ }
+
+ QTextStream t(&f);
+ setText(t.read());
+ f.close();
+
+ // then we copy it into our own m_sourceCode
+ int n = paragraphs();
+ m_sourceCode.resize(n);
+ m_rowToLine.resize(n);
+ for (int i = 0; i < n; i++) {
+ m_sourceCode[i].code = text(i);
+ m_rowToLine[i] = i;
+ }
+ m_lineItems.resize(n, 0);
+
+ // set a font for line numbers
+ m_lineNoFont = currentFont();
+ m_lineNoFont.setPixelSize(11);
+
+ return true;
+}
+
+void SourceWindow::reloadFile()
+{
+ QFile f(m_fileName);
+ if (!f.open(IO_ReadOnly)) {
+ // open failed; leave alone
+ return;
+ }
+
+ // read text into m_sourceCode
+ m_sourceCode.clear(); /* clear old text */
+
+ QTextStream t(&f);
+ setText(t.read());
+ f.close();
+
+ m_sourceCode.resize(paragraphs());
+ for (size_t i = 0; i < m_sourceCode.size(); i++) {
+ m_sourceCode[i].code = text(i);
+ }
+ // expanded lines are collapsed: move existing line items up
+ for (size_t i = 0; i < m_lineItems.size(); i++) {
+ if (m_rowToLine[i] != i) {
+ m_lineItems[m_rowToLine[i]] |= m_lineItems[i];
+ m_lineItems[i] = 0;
+ }
+ }
+ // allocate line items
+ m_lineItems.resize(m_sourceCode.size(), 0);
+
+ m_rowToLine.resize(m_sourceCode.size());
+ for (size_t i = 0; i < m_sourceCode.size(); i++)
+ m_rowToLine[i] = i;
+
+ // Highlighting was applied above when the text was inserted into widget,
+ // but at that time m_rowToLine was not corrected, yet, so that lines
+ // that previously were assembly were painted incorrectly.
+ if (syntaxHighlighter())
+ syntaxHighlighter()->rehighlight();
+ update(); // line numbers
+}
+
+void SourceWindow::scrollTo(int lineNo, const DbgAddr& address)
+{
+ if (lineNo < 0 || lineNo >= int(m_sourceCode.size()))
+ return;
+
+ int row = lineToRow(lineNo, address);
+ scrollToRow(row);
+}
+
+void SourceWindow::scrollToRow(int row)
+{
+ setCursorPosition(row, 0);
+ ensureCursorVisible();
+}
+
+void SourceWindow::drawFrame(QPainter* p)
+{
+ QTextEdit::drawFrame(p);
+
+ // and paragraph at the top is...
+ int top = paragraphAt(QPoint(0,contentsY()));
+ int bot = paragraphAt(QPoint(0,contentsY()+visibleHeight()-1));
+ if (bot < 0)
+ bot = paragraphs()-1;
+
+ p->save();
+
+ // set a clip rectangle
+ int fw = frameWidth();
+ QRect inside = rect();
+ inside.addCoords(fw,fw,-fw,-fw);
+ QRegion clip = p->clipRegion();
+ clip &= QRegion(inside);
+ p->setClipRegion(clip);
+
+ p->setFont(m_lineNoFont);
+ p->setPen(colorGroup().text());
+ p->eraseRect(inside);
+
+ for (int row = top; row <= bot; row++)
+ {
+ uchar item = m_lineItems[row];
+ p->save();
+
+ QRect r = paragraphRect(row);
+ QPoint pt = contentsToViewport(r.topLeft());
+ int h = r.height();
+ p->translate(fw, pt.y()+viewport()->y());
+
+ if (item & liBP) {
+ // enabled breakpoint
+ int y = (h - m_brkena.height())/2;
+ if (y < 0) y = 0;
+ p->drawPixmap(0,y,m_brkena);
+ }
+ if (item & liBPdisabled) {
+ // disabled breakpoint
+ int y = (h - m_brkdis.height())/2;
+ if (y < 0) y = 0;
+ p->drawPixmap(0,y,m_brkdis);
+ }
+ if (item & liBPtemporary) {
+ // temporary breakpoint marker
+ int y = (h - m_brktmp.height())/2;
+ if (y < 0) y = 0;
+ p->drawPixmap(0,y,m_brktmp);
+ }
+ if (item & liBPconditional) {
+ // conditional breakpoint marker
+ int y = (h - m_brkcond.height())/2;
+ if (y < 0) y = 0;
+ p->drawPixmap(0,y,m_brkcond);
+ }
+ if (item & liBPorphan) {
+ // orphaned breakpoint marker
+ int y = (h - m_brkcond.height())/2;
+ if (y < 0) y = 0;
+ p->drawPixmap(0,y,m_brkorph);
+ }
+ if (item & liPC) {
+ // program counter in innermost frame
+ int y = (h - m_pcinner.height())/2;
+ if (y < 0) y = 0;
+ p->drawPixmap(0,y,m_pcinner);
+ }
+ if (item & liPCup) {
+ // program counter somewhere up the stack
+ int y = (h - m_pcup.height())/2;
+ if (y < 0) y = 0;
+ p->drawPixmap(0,y,m_pcup);
+ }
+ p->translate(m_widthItems, 0);
+ if (!isRowDisassCode(row) && m_sourceCode[rowToLine(row)].canDisass) {
+ int w = m_widthPlus;
+ int x = w/2;
+ int y = h/2;
+ p->drawLine(x-2, y, x+2, y);
+ if (!isRowExpanded(row)) {
+ p->drawLine(x, y-2, x, y+2);
+ }
+ }
+ p->translate(m_widthPlus, 0);
+ if (!isRowDisassCode(row)) {
+ p->drawText(0, 0, m_widthLineNo, h, AlignRight|AlignVCenter,
+ QString().setNum(rowToLine(row)+1));
+ }
+ p->restore();
+ }
+ p->restore();
+}
+
+void SourceWindow::updateLineItems(const KDebugger* dbg)
+{
+ // clear outdated breakpoints
+ for (int i = m_lineItems.size()-1; i >= 0; i--) {
+ if (m_lineItems[i] & liBPany) {
+ // check if this breakpoint still exists
+ int line = rowToLine(i);
+ TRACE(QString().sprintf("checking for bp at %d", line));
+ KDebugger::BrkptROIterator bp = dbg->breakpointsBegin();
+ for (; bp != dbg->breakpointsEnd(); ++bp)
+ {
+ if (bp->lineNo == line &&
+ fileNameMatches(bp->fileName) &&
+ lineToRow(line, bp->address) == i)
+ {
+ // yes it exists; mode is changed below
+ break;
+ }
+ }
+ if (bp == dbg->breakpointsEnd()) {
+ /* doesn't exist anymore, remove it */
+ m_lineItems[i] &= ~liBPany;
+ update();
+ }
+ }
+ }
+
+ // add new breakpoints
+ for (KDebugger::BrkptROIterator bp = dbg->breakpointsBegin(); bp != dbg->breakpointsEnd(); ++bp)
+ {
+ if (fileNameMatches(bp->fileName)) {
+ TRACE(QString().sprintf("updating %s:%d", bp->fileName.data(), bp->lineNo));
+ int i = bp->lineNo;
+ if (i < 0 || i >= int(m_sourceCode.size()))
+ continue;
+ // compute new line item flags for breakpoint
+ uchar flags = bp->enabled ? liBP : liBPdisabled;
+ if (bp->temporary)
+ flags |= liBPtemporary;
+ if (!bp->condition.isEmpty() || bp->ignoreCount != 0)
+ flags |= liBPconditional;
+ if (bp->isOrphaned())
+ flags |= liBPorphan;
+ // update if changed
+ int row = lineToRow(i, bp->address);
+ if ((m_lineItems[row] & liBPany) != flags) {
+ m_lineItems[row] &= ~liBPany;
+ m_lineItems[row] |= flags;
+ update();
+ }
+ }
+ }
+}
+
+void SourceWindow::setPC(bool set, int lineNo, const DbgAddr& address, int frameNo)
+{
+ if (lineNo < 0 || lineNo >= int(m_sourceCode.size())) {
+ return;
+ }
+
+ int row = lineToRow(lineNo, address);
+
+ uchar flag = frameNo == 0 ? liPC : liPCup;
+ if (set) {
+ // set only if not already set
+ if ((m_lineItems[row] & flag) == 0) {
+ m_lineItems[row] |= flag;
+ update();
+ }
+ } else {
+ // clear only if not set
+ if ((m_lineItems[row] & flag) != 0) {
+ m_lineItems[row] &= ~flag;
+ update();
+ }
+ }
+}
+
+void SourceWindow::find(const QString& text, bool caseSensitive, FindDirection dir)
+{
+ ASSERT(dir == 1 || dir == -1);
+ if (QTextEdit::find(text, caseSensitive, false, dir > 0))
+ return;
+ // not found; wrap around
+ int para = dir > 0 ? 0 : paragraphs(), index = 0;
+ QTextEdit::find(text, caseSensitive, false, dir > 0, &para, &index);
+}
+
+void SourceWindow::mousePressEvent(QMouseEvent* ev)
+{
+ // we handle left and middle button
+ if (ev->button() != LeftButton && ev->button() != MidButton)
+ {
+ QTextEdit::mousePressEvent(ev);
+ return;
+ }
+
+ // get row
+ QPoint p = viewportToContents(QPoint(0, ev->y() - viewport()->y()));
+ int row = paragraphAt(p);
+ if (row < 0)
+ return;
+
+ if (ev->x() > m_widthItems+frameWidth())
+ {
+ if (isRowExpanded(row)) {
+ actionCollapseRow(row);
+ } else {
+ actionExpandRow(row);
+ }
+ return;
+ }
+
+ int sourceRow;
+ int line = rowToLine(row, &sourceRow);
+
+ // find address if row is disassembled code
+ DbgAddr address;
+ if (row > sourceRow) {
+ // get offset from source code line
+ int off = row - sourceRow;
+ address = m_sourceCode[line].disassAddr[off-1];
+ }
+
+ switch (ev->button()) {
+ case LeftButton:
+ TRACE(QString().sprintf("left-clicked line %d", line));
+ emit clickedLeft(m_fileName, line, address,
+ (ev->state() & ShiftButton) != 0);
+ break;
+ case MidButton:
+ TRACE(QString().sprintf("mid-clicked row %d", line));
+ emit clickedMid(m_fileName, line, address);
+ break;
+ default:;
+ }
+}
+
+void SourceWindow::keyPressEvent(QKeyEvent* ev)
+{
+ int top1, top2;
+ QPoint top;
+ switch (ev->key()) {
+ case Key_Plus:
+ actionExpandRow(m_curRow);
+ return;
+ case Key_Minus:
+ actionCollapseRow(m_curRow);
+ return;
+ case Key_Up:
+ if (m_curRow > 0) {
+ setCursorPosition(m_curRow-1, 0);
+ }
+ return;
+ case Key_Down:
+ if (m_curRow < paragraphs()-1) {
+ setCursorPosition(m_curRow+1, 0);
+ }
+ return;
+ case Key_Home:
+ setCursorPosition(0, 0);
+ return;
+ case Key_End:
+ setCursorPosition(paragraphs()-1, 0);
+ return;
+ case Key_Next:
+ case Key_Prior:
+ top = viewportToContents(QPoint(0,0));
+ top1 = paragraphAt(top);
+ }
+
+ QTextEdit::keyPressEvent(ev);
+
+ switch (ev->key()) {
+ case Key_Next:
+ case Key_Prior:
+ top = viewportToContents(QPoint(0,0));
+ top2 = paragraphAt(top);
+ setCursorPosition(m_curRow+(top2-top1), 0);
+ }
+}
+
+static inline bool isident(QChar c)
+{
+ return c.isLetterOrNumber() || c.latin1() == '_';
+}
+
+bool SourceWindow::wordAtPoint(const QPoint& p, QString& word, QRect& r)
+{
+ QPoint pv = viewportToContents(p - viewport()->pos());
+ int row, col = charAt(pv, &row);
+ if (row < 0 || col < 0)
+ return false;
+
+ // isolate the word at row, col
+ QString line = text(row);
+ if (!isident(line[col]))
+ return false;
+
+ int begin = col;
+ while (begin > 0 && isident(line[begin-1]))
+ --begin;
+ do
+ ++col;
+ while (col < int(line.length()) && isident(line[col]));
+
+ r = QRect(p, p);
+ r.addCoords(-5,-5,5,5);
+ word = line.mid(begin, col-begin);
+ return true;
+}
+
+void SourceWindow::paletteChange(const QPalette& oldPal)
+{
+ setFont(KGlobalSettings::fixedFont());
+ QTextEdit::paletteChange(oldPal);
+}
+
+/*
+ * Two file names (possibly full paths) match if the last parts - the file
+ * names - match.
+ */
+bool SourceWindow::fileNameMatches(const QString& other)
+{
+ return QFileInfo(other).fileName() == QFileInfo(m_fileName).fileName();
+}
+
+void SourceWindow::disassembled(int lineNo, const std::list<DisassembledCode>& disass)
+{
+ TRACE("disassembled line " + QString().setNum(lineNo));
+ if (lineNo < 0 || lineNo >= int(m_sourceCode.size()))
+ return;
+
+ SourceLine& sl = m_sourceCode[lineNo];
+
+ // copy disassembled code and its addresses
+ sl.disass.resize(disass.size());
+ sl.disassAddr.resize(disass.size());
+ sl.canDisass = !disass.empty();
+ int i = 0;
+ for (std::list<DisassembledCode>::const_iterator c = disass.begin(); c != disass.end(); ++c, ++i)
+ {
+ QString code = c->code;
+ while (code.endsWith("\n"))
+ code.truncate(code.length()-1);
+ sl.disass[i] = c->address.asString() + ' ' + code;
+ sl.disassAddr[i] = c->address;
+ }
+
+ int row = lineToRow(lineNo);
+ if (sl.canDisass) {
+ expandRow(row);
+ } else {
+ // clear expansion marker
+ update();
+ }
+}
+
+int SourceWindow::rowToLine(int row, int* sourceRow)
+{
+ int line = row >= 0 ? m_rowToLine[row] : -1;
+ if (sourceRow != 0) {
+ // search back until we hit the first entry with the current line number
+ while (row > 0 && m_rowToLine[row-1] == line)
+ row--;
+ *sourceRow = row;
+ }
+ return line;
+}
+
+/*
+ * Rows showing diassembled code have the same line number as the
+ * corresponding source code line number. Therefore, the line numbers in
+ * m_rowToLine are monotonically increasing with blocks of equal line
+ * numbers for a source line and its disassembled code that follows it.
+ *
+ * Hence, m_rowToLine always obeys the following condition:
+ *
+ * m_rowToLine[i] <= i
+ */
+
+int SourceWindow::lineToRow(int line)
+{
+ // line is zero-based!
+
+ assert(line < int(m_rowToLine.size()));
+
+ // quick test for common case
+ if (line < 0 || m_rowToLine[line] == line)
+ return line;
+
+ assert(m_rowToLine[line] < line);
+
+ /*
+ * Binary search between row == line and end of list. In the loop below
+ * we use the fact that the line numbers m_rowToLine do not contain
+ * holes.
+ */
+ int l = line;
+ int h = m_rowToLine.size();
+ while (l < h && m_rowToLine[l] != line)
+ {
+ assert(h == int(m_rowToLine.size()) || m_rowToLine[l] < m_rowToLine[h]);
+
+ /*
+ * We want to round down the midpoint so that we find the
+ * lowest row that belongs to the line we seek.
+ */
+ int mid = (l+h)/2;
+ if (m_rowToLine[mid] <= line)
+ l = mid;
+ else
+ h = mid;
+ }
+ // Found! Result is in l:
+ assert(m_rowToLine[l] == line);
+
+ /*
+ * We might not have hit the lowest index for the line.
+ */
+ while (l > 0 && m_rowToLine[l-1] == line)
+ --l;
+
+ return l;
+}
+
+int SourceWindow::lineToRow(int line, const DbgAddr& address)
+{
+ int row = lineToRow(line);
+ if (isRowExpanded(row)) {
+ row += m_sourceCode[line].findAddressRowOffset(address);
+ }
+ return row;
+}
+
+bool SourceWindow::isRowExpanded(int row)
+{
+ assert(row >= 0);
+ return row < int(m_rowToLine.size())-1 &&
+ m_rowToLine[row] == m_rowToLine[row+1];
+}
+
+bool SourceWindow::isRowDisassCode(int row)
+{
+ return row > 0 && row < int(m_rowToLine.size()) &&
+ m_rowToLine[row] == m_rowToLine[row-1];
+}
+
+void SourceWindow::expandRow(int row)
+{
+ TRACE("expanding row " + QString().setNum(row));
+ // get disassembled code
+ int line = rowToLine(row);
+ const std::vector<QString>& disass = m_sourceCode[line].disass;
+
+ // remove PC (must be set again in slot of signal expanded())
+ m_lineItems[row] &= ~(liPC|liPCup);
+
+ // adjust current row
+ if (m_curRow > row) {
+ m_curRow += disass.size();
+ // highlight is moved automatically
+ }
+
+ // insert new lines
+ setUpdatesEnabled(false);
+ ++row;
+ for (size_t i = 0; i < disass.size(); i++) {
+ m_rowToLine.insert(m_rowToLine.begin()+row, line);
+ m_lineItems.insert(m_lineItems.begin()+row, 0);
+ insertParagraph(disass[i], row++);
+ }
+ setUpdatesEnabled(true);
+ viewport()->update();
+ update(); // line items
+
+ emit expanded(line); /* must set PC */
+}
+
+void SourceWindow::collapseRow(int row)
+{
+ TRACE("collapsing row " + QString().setNum(row));
+ int line = rowToLine(row);
+
+ // find end of this block
+ int end = row+1;
+ while (end < int(m_rowToLine.size()) && m_rowToLine[end] == m_rowToLine[row]) {
+ end++;
+ }
+ ++row;
+ // adjust current row
+ if (m_curRow >= row) {
+ m_curRow -= end-row;
+ if (m_curRow < row) // was m_curRow in disassembled code?
+ m_curRow = -1;
+ }
+ setUpdatesEnabled(false);
+ while (--end >= row) {
+ m_rowToLine.erase(m_rowToLine.begin()+end);
+ m_lineItems.erase(m_lineItems.begin()+end);
+ removeParagraph(end);
+ }
+ setUpdatesEnabled(true);
+ viewport()->update();
+ update(); // line items
+
+ emit collapsed(line);
+}
+
+void SourceWindow::activeLine(int& line, DbgAddr& address)
+{
+ int row = m_curRow;
+
+ int sourceRow;
+ line = rowToLine(row, &sourceRow);
+ if (row > sourceRow) {
+ int off = row - sourceRow; /* offset from source line */
+ address = m_sourceCode[line].disassAddr[off-1];
+ }
+}
+
+/**
+ * Returns the offset from the line displaying the source code to
+ * the line containing the specified address. If the address is not
+ * found, 0 is returned.
+ */
+int SourceWindow::SourceLine::findAddressRowOffset(const DbgAddr& address) const
+{
+ if (address.isEmpty())
+ return 0;
+
+ for (size_t i = 0; i < disassAddr.size(); i++) {
+ if (disassAddr[i] == address) {
+ // found exact address
+ return i+1;
+ }
+ if (disassAddr[i] > address) {
+ /*
+ * We have already advanced too far; the address is before this
+ * index, but obviously we haven't found an exact match
+ * earlier. address is somewhere between the displayed
+ * addresses. We return the previous line.
+ */
+ return i;
+ }
+ }
+ // not found
+ return 0;
+}
+
+void SourceWindow::actionExpandRow(int row)
+{
+ if (row < 0 || isRowExpanded(row) || isRowDisassCode(row))
+ return;
+
+ // disassemble
+ int line = rowToLine(row);
+ const SourceLine& sl = m_sourceCode[line];
+ if (!sl.canDisass)
+ return;
+ if (sl.disass.size() == 0) {
+ emit disassemble(m_fileName, line);
+ } else {
+ expandRow(row);
+ }
+}
+
+void SourceWindow::actionCollapseRow(int row)
+{
+ if (row < 0 || !isRowExpanded(row) || isRowDisassCode(row))
+ return;
+
+ collapseRow(row);
+}
+
+void SourceWindow::setTabWidth(int numChars)
+{
+ if (numChars <= 0)
+ numChars = 8;
+ QFontMetrics fm(currentFont());
+ QString s;
+ int w = fm.width(s.fill('x', numChars));
+ setTabStopWidth(w);
+}
+
+void SourceWindow::cursorChanged(int row)
+{
+ if (row == m_curRow)
+ return;
+
+ if (m_curRow >= 0 && m_curRow < paragraphs())
+ clearParagraphBackground(m_curRow);
+ m_curRow = row;
+ setParagraphBackgroundColor(row, colorGroup().background());
+}
+
+/*
+ * We must override the context menu handling because QTextEdit's handling
+ * requires that it receives ownership of the popup menu; but the popup menu
+ * returned from the GUI factory is owned by the factory.
+ */
+
+void SourceWindow::contextMenuEvent(QContextMenuEvent* e)
+{
+ // get the context menu from the GUI factory
+ QWidget* top = this;
+ do
+ top = top->parentWidget();
+ while (!top->isTopLevel());
+ KMainWindow* mw = static_cast<KMainWindow*>(top);
+ QPopupMenu* m =
+ static_cast<QPopupMenu*>(mw->factory()->container("popup_files", mw));
+ m->exec(e->globalPos());
+}
+
+bool SourceWindow::eventFilter(QObject* watched, QEvent* e)
+{
+ if (e->type() == QEvent::ContextMenu && watched == viewport())
+ {
+ contextMenuEvent(static_cast<QContextMenuEvent*>(e));
+ return true;
+ }
+ return QTextEdit::eventFilter(watched, e);
+}
+
+HighlightCpp::HighlightCpp(SourceWindow* srcWnd) :
+ QSyntaxHighlighter(srcWnd),
+ m_srcWnd(srcWnd)
+{
+}
+
+enum HLState {
+ hlCommentLine = 1,
+ hlCommentBlock,
+ hlIdent,
+ hlString
+};
+
+static const QString ckw[] =
+{
+ "and",
+ "and_eq",
+ "asm",
+ "auto",
+ "bitand",
+ "bitor",
+ "bool",
+ "break",
+ "case",
+ "catch",
+ "char",
+ "class",
+ "compl",
+ "const",
+ "const_cast",
+ "continue",
+ "default",
+ "delete",
+ "do",
+ "double",
+ "dynamic_cast",
+ "else",
+ "enum",
+ "explicit",
+ "export",
+ "extern",
+ "false",
+ "float",
+ "for",
+ "friend",
+ "goto",
+ "if",
+ "inline",
+ "int",
+ "long",
+ "mutable",
+ "namespace",
+ "new",
+ "not",
+ "not_eq",
+ "operator",
+ "or",
+ "or_eq",
+ "private",
+ "protected",
+ "public",
+ "reinterpret_cast",
+ "register",
+ "return",
+ "short",
+ "signed",
+ "sizeof",
+ "static",
+ "static_cast",
+ "struct",
+ "switch",
+ "template",
+ "this",
+ "throw",
+ "true",
+ "try",
+ "typedef",
+ "typeid",
+ "typename",
+ "using",
+ "union",
+ "unsigned",
+ "virtual",
+ "void",
+ "volatile",
+ "wchar_t",
+ "while",
+ "xor",
+ "xor_eq"
+};
+
+int HighlightCpp::highlightParagraph(const QString& text, int state)
+{
+ int row = currentParagraph();
+ // highlight assembly lines
+ if (m_srcWnd->isRowDisassCode(row))
+ {
+ setFormat(0, text.length(), blue);
+ return state;
+ }
+
+ if (state == -2) // initial state
+ state = 0;
+
+ // check for preprocessor line
+ if (state == 0 && text.stripWhiteSpace().startsWith("#"))
+ {
+ setFormat(0, text.length(), QColor("dark green"));
+ return 0;
+ }
+
+ // a font for keywords
+ QFont identFont = textEdit()->currentFont();
+ identFont.setBold(!identFont.bold());
+
+ unsigned start = 0;
+ while (start < text.length())
+ {
+ int end;
+ switch (state) {
+ case hlCommentLine:
+ end = text.length();
+ state = 0;
+ setFormat(start, end-start, QColor("gray50"));
+ break;
+ case hlCommentBlock:
+ end = text.find("*/", start);
+ if (end >= 0)
+ end += 2, state = 0;
+ else
+ end = text.length();
+ setFormat(start, end-start, QColor("gray50"));
+ break;
+ case hlString:
+ for (end = start+1; end < int(text.length()); end++) {
+ if (text[end] == '\\') {
+ if (end < int(text.length()))
+ ++end;
+ } else if (text[end] == text[start]) {
+ ++end;
+ break;
+ }
+ }
+ state = 0;
+ setFormat(start, end-start, QColor("dark red"));
+ break;
+ case hlIdent:
+ for (end = start+1; end < int(text.length()); end++) {
+ if (!text[end].isLetterOrNumber() && text[end] != '_')
+ break;
+ }
+ state = 0;
+ if (std::binary_search(ckw, ckw + sizeof(ckw)/sizeof(ckw[0]),
+ text.mid(start, end-start)))
+ {
+ setFormat(start, end-start, identFont);
+ } else {
+ setFormat(start, end-start, m_srcWnd->colorGroup().text());
+ }
+ break;
+ default:
+ for (end = start; end < int(text.length()); end++)
+ {
+ if (text[end] == '/')
+ {
+ if (end+1 < int(text.length())) {
+ if (text[end+1] == '/') {
+ state = hlCommentLine;
+ break;
+ } else if (text[end+1] == '*') {
+ state = hlCommentBlock;
+ break;
+ }
+ }
+ }
+ else if (text[end] == '"' || text[end] == '\'')
+ {
+ state = hlString;
+ break;
+ }
+ else if (text[end] >= 'A' && text[end] <= 'Z' ||
+ text[end] >= 'a' && text[end] <= 'z' ||
+ text[end] == '_')
+ {
+ state = hlIdent;
+ break;
+ }
+ }
+ setFormat(start, end-start, m_srcWnd->colorGroup().text());
+ }
+ start = end;
+ }
+ return state;
+}
+
+#include "sourcewnd.moc"
diff --git a/kdbg/sourcewnd.h b/kdbg/sourcewnd.h
new file mode 100644
index 0000000..bab0b5a
--- /dev/null
+++ b/kdbg/sourcewnd.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef SOURCEWND_H
+#define SOURCEWND_H
+
+#include <qpixmap.h>
+#include <qtextedit.h>
+#include <qsyntaxhighlighter.h>
+#include <vector>
+#include "dbgdriver.h"
+
+// forward declarations
+class KDebugger;
+struct DbgAddr;
+
+class SourceWindow : public QTextEdit
+{
+ Q_OBJECT
+public:
+ SourceWindow(const QString& fileName, QWidget* parent, const char* name);
+ ~SourceWindow();
+
+ bool loadFile();
+ void reloadFile();
+ bool fileNameMatches(const QString& other);
+ void scrollTo(int lineNo, const DbgAddr& address);
+ const QString& fileName() const { return m_fileName; }
+ void updateLineItems(const KDebugger* dbg);
+ void setPC(bool set, int lineNo, const DbgAddr& address, int frameNo);
+ enum FindDirection { findForward = 1, findBackward = -1 };
+ void find(const QString& text, bool caseSensitive, FindDirection dir);
+ bool wordAtPoint(const QPoint& p, QString& word, QRect& r);
+ /**
+ * Translates row number (zero-based) to zero-based source line number.
+ * If sourceRow is non-zero, it is filled with the source code row
+ * belonging to the line number.
+ */
+ int rowToLine(int row, int* sourceRow = 0);
+ /** Translates zero-based source line number to row number (zero-based) */
+ int lineToRow(int line);
+ /** Is the row disassembled? */
+ bool isRowExpanded(int row);
+ /** Does the row show disassembled code? */
+ bool isRowDisassCode(int row);
+
+ /** lineNo is zero-based */
+ void disassembled(int lineNo, const std::list<DisassembledCode>& disass);
+
+ void activeLine(int& lineNo, DbgAddr& address);
+
+protected:
+ virtual void drawFrame(QPainter* p);
+ virtual bool eventFilter(QObject* watched, QEvent* e);
+ virtual void contextMenuEvent(QContextMenuEvent* e);
+ virtual void mousePressEvent(QMouseEvent* ev);
+ virtual void keyPressEvent(QKeyEvent* ev);
+ virtual void paletteChange(const QPalette&);
+ void expandRow(int row);
+ void collapseRow(int row);
+ void scrollToRow(int row);
+ /** translates (0-based) line number plus a code address into a row number */
+ int lineToRow(int row, const DbgAddr& address);
+
+ void actionExpandRow(int row);
+ void actionCollapseRow(int row);
+
+signals:
+ void clickedLeft(const QString&, int, const DbgAddr& address, bool);
+ void clickedMid(const QString&, int, const DbgAddr& address);
+ void disassemble(const QString&, int);
+ void expanded(int lineNo); /* source lineNo has been expanded */
+ void collapsed(int lineNo); /* source lineNo has been collapsed */
+public slots:
+ void setTabWidth(int numChars);
+ void cursorChanged(int row);
+
+protected:
+ QString m_fileName;
+ enum LineItem { liPC = 1, liPCup = 2,
+ liBP = 4, liBPdisabled = 8, liBPtemporary = 16,
+ liBPconditional = 32, liBPorphan = 64,
+ liBPany = liBP|liBPdisabled|liBPtemporary|liBPconditional|liBPorphan
+ };
+
+ struct SourceLine {
+ QString code; /* a line of text */
+ std::vector<QString> disass; /* its disassembled code */
+ std::vector<DbgAddr> disassAddr; /* the addresses thereof */
+ bool canDisass; /* if line can be disassembled */
+ SourceLine() : canDisass(true) { }
+ int findAddressRowOffset(const DbgAddr& address) const;
+ };
+ std::vector<SourceLine> m_sourceCode;
+
+ std::vector<int> m_rowToLine; //!< The source line number for each row
+ std::vector<uchar> m_lineItems; //!< Icons displayed on the line
+ QPixmap m_pcinner; /* PC at innermost frame */
+ QPixmap m_pcup; /* PC at frame up the stack */
+ QPixmap m_brkena; /* enabled breakpoint */
+ QPixmap m_brkdis; /* disabled breakpoint */
+ QPixmap m_brktmp; /* temporary breakpoint marker */
+ QPixmap m_brkcond; /* conditional breakpoint marker */
+ QPixmap m_brkorph; /* orphaned breakpoint marker */
+ QFont m_lineNoFont; //!< The font used to draw line numbers
+ int m_curRow; //!< The highlighted row
+ int m_widthItems; //!< The width of the item column
+ int m_widthPlus; //!< The width of the expander column
+ int m_widthLineNo; //!< The width of the line number columns
+};
+
+class HighlightCpp : public QSyntaxHighlighter
+{
+ SourceWindow* m_srcWnd;
+
+public:
+ HighlightCpp(SourceWindow* srcWnd);
+ virtual int highlightParagraph(const QString& text, int state);
+};
+
+#endif // SOURCEWND_H
diff --git a/kdbg/testprogs/Makefile.am b/kdbg/testprogs/Makefile.am
new file mode 100644
index 0000000..b5a35f1
--- /dev/null
+++ b/kdbg/testprogs/Makefile.am
@@ -0,0 +1,62 @@
+## This is the example XSL and XML files for debugging with xsldbg
+EXTRA_DIST = xsldoc.xsl xsldoc.xml
+
+# set the include path for X, qt and KDE
+INCLUDES= $(all_includes)
+# always compile with debugging info switched on
+AM_CXXFLAGS = -g
+
+# Disable optimization to ensure that variables are not hidden by the
+# compiler
+CXXFLAGS:=$(patsubst -O%,,$(CXXFLAGS))
+
+if BUILDTESTPROGS
+PROGS = \
+ anonstruct \
+ locals \
+ maths \
+ nestedclass \
+ qt \
+ repeats \
+ std \
+ templates \
+ testfile \
+ widechar
+else
+PROGS =
+endif
+
+noinst_PROGRAMS = $(PROGS)
+
+testfile_SOURCES = testfile.cpp
+testfile_LDFLAGS = -g $(all_libraries) $(KDE_RPATH)
+testfile_LDADD = $(LIB_QT)
+
+locals_SOURCES = locals.cpp
+locals_LDFLAGS = -g
+
+maths_SOURCES = maths.cpp
+maths_LDFLAGS = -g
+
+qt_SOURCES = qt.cpp
+qt_LDFLAGS = -g $(all_libraries) $(KDE_RPATH)
+qt_LDADD = $(LIB_QT)
+
+repeats_SOURCES = repeats.cpp
+repeats_LDFLAGS = -g $(all_libraries) $(KDE_RPATH)
+repeats_LDADD = $(LIB_QT)
+
+std_SOURCES = std.cpp
+std_LDFLAGS = -g
+
+templates_SOURCES = templates.cpp
+templates_LDFLAGS = -g
+
+anonstruct_SOURCES = anonstruct.cpp
+anonstruct_LDFLAGS = -g
+
+nestedclass_SOURCES = nestedclass.cpp
+nestedclass_LDFLAGS = -g
+
+widechar_SOURCES = widechar.cpp
+widechar_LDFLAGS = -g
diff --git a/kdbg/testprogs/Makefile.in b/kdbg/testprogs/Makefile.in
new file mode 100644
index 0000000..6f0236e
--- /dev/null
+++ b/kdbg/testprogs/Makefile.in
@@ -0,0 +1,885 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 483858 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+noinst_PROGRAMS = $(am__EXEEXT_1)
+subdir = kdbg/testprogs
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+@BUILDTESTPROGS_TRUE@am__EXEEXT_1 = anonstruct$(EXEEXT) \
+@BUILDTESTPROGS_TRUE@ locals$(EXEEXT) maths$(EXEEXT) \
+@BUILDTESTPROGS_TRUE@ nestedclass$(EXEEXT) qt$(EXEEXT) \
+@BUILDTESTPROGS_TRUE@ repeats$(EXEEXT) std$(EXEEXT) \
+@BUILDTESTPROGS_TRUE@ templates$(EXEEXT) testfile$(EXEEXT) \
+@BUILDTESTPROGS_TRUE@ widechar$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+am_anonstruct_OBJECTS = anonstruct.$(OBJEXT)
+#>- anonstruct_OBJECTS = $(am_anonstruct_OBJECTS)
+#>+ 1
+anonstruct_OBJECTS = anonstruct.$(OBJEXT)
+anonstruct_LDADD = $(LDADD)
+#>- anonstruct_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+#>- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+#>- $(CXXFLAGS) $(anonstruct_LDFLAGS) $(LDFLAGS) -o $@
+#>+ 3
+anonstruct_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(KDE_CXXFLAGS) $(anonstruct_LDFLAGS) $(LDFLAGS) -o $@
+am_locals_OBJECTS = locals.$(OBJEXT)
+#>- locals_OBJECTS = $(am_locals_OBJECTS)
+#>+ 1
+locals_OBJECTS = locals.$(OBJEXT)
+locals_LDADD = $(LDADD)
+#>- locals_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
+#>- $(locals_LDFLAGS) $(LDFLAGS) -o $@
+#>+ 3
+locals_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
+ $(locals_LDFLAGS) $(LDFLAGS) -o $@
+am_maths_OBJECTS = maths.$(OBJEXT)
+#>- maths_OBJECTS = $(am_maths_OBJECTS)
+#>+ 1
+maths_OBJECTS = maths.$(OBJEXT)
+maths_LDADD = $(LDADD)
+#>- maths_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
+#>- $(maths_LDFLAGS) $(LDFLAGS) -o $@
+#>+ 3
+maths_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
+ $(maths_LDFLAGS) $(LDFLAGS) -o $@
+am_nestedclass_OBJECTS = nestedclass.$(OBJEXT)
+#>- nestedclass_OBJECTS = $(am_nestedclass_OBJECTS)
+#>+ 1
+nestedclass_OBJECTS = nestedclass.$(OBJEXT)
+nestedclass_LDADD = $(LDADD)
+#>- nestedclass_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+#>- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+#>- $(CXXFLAGS) $(nestedclass_LDFLAGS) $(LDFLAGS) -o $@
+#>+ 3
+nestedclass_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(KDE_CXXFLAGS) $(nestedclass_LDFLAGS) $(LDFLAGS) -o $@
+am_qt_OBJECTS = qt.$(OBJEXT)
+#>- qt_OBJECTS = $(am_qt_OBJECTS)
+#>+ 1
+qt_OBJECTS = qt.$(OBJEXT)
+am__DEPENDENCIES_1 =
+qt_DEPENDENCIES = $(am__DEPENDENCIES_1)
+#>- qt_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(qt_LDFLAGS) \
+#>- $(LDFLAGS) -o $@
+#>+ 3
+qt_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) $(qt_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am_repeats_OBJECTS = repeats.$(OBJEXT)
+#>- repeats_OBJECTS = $(am_repeats_OBJECTS)
+#>+ 1
+repeats_OBJECTS = repeats.$(OBJEXT)
+repeats_DEPENDENCIES = $(am__DEPENDENCIES_1)
+#>- repeats_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
+#>- $(repeats_LDFLAGS) $(LDFLAGS) -o $@
+#>+ 3
+repeats_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
+ $(repeats_LDFLAGS) $(LDFLAGS) -o $@
+am_std_OBJECTS = std.$(OBJEXT)
+#>- std_OBJECTS = $(am_std_OBJECTS)
+#>+ 1
+std_OBJECTS = std.$(OBJEXT)
+std_LDADD = $(LDADD)
+#>- std_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(std_LDFLAGS) \
+#>- $(LDFLAGS) -o $@
+#>+ 3
+std_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) $(std_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am_templates_OBJECTS = templates.$(OBJEXT)
+#>- templates_OBJECTS = $(am_templates_OBJECTS)
+#>+ 1
+templates_OBJECTS = templates.$(OBJEXT)
+templates_LDADD = $(LDADD)
+#>- templates_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+#>- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+#>- $(CXXFLAGS) $(templates_LDFLAGS) $(LDFLAGS) -o $@
+#>+ 3
+templates_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(KDE_CXXFLAGS) $(templates_LDFLAGS) $(LDFLAGS) -o $@
+am_testfile_OBJECTS = testfile.$(OBJEXT)
+#>- testfile_OBJECTS = $(am_testfile_OBJECTS)
+#>+ 1
+testfile_OBJECTS = testfile.$(OBJEXT)
+testfile_DEPENDENCIES = $(am__DEPENDENCIES_1)
+#>- testfile_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+#>- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+#>- $(CXXFLAGS) $(testfile_LDFLAGS) $(LDFLAGS) -o $@
+#>+ 3
+testfile_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(KDE_CXXFLAGS) $(testfile_LDFLAGS) $(LDFLAGS) -o $@
+am_widechar_OBJECTS = widechar.$(OBJEXT)
+#>- widechar_OBJECTS = $(am_widechar_OBJECTS)
+#>+ 1
+widechar_OBJECTS = widechar.$(OBJEXT)
+widechar_LDADD = $(LDADD)
+#>- widechar_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+#>- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+#>- $(CXXFLAGS) $(widechar_LDFLAGS) $(LDFLAGS) -o $@
+#>+ 3
+widechar_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(KDE_CXXFLAGS) $(widechar_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
+am__depfiles_maybe = depfiles
+#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 2
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+#>- LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 3
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+CXXLD = $(CXX)
+#>- CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+#>- $(LDFLAGS) -o $@
+#>+ 3
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(anonstruct_SOURCES) $(locals_SOURCES) $(maths_SOURCES) \
+ $(nestedclass_SOURCES) $(qt_SOURCES) $(repeats_SOURCES) \
+ $(std_SOURCES) $(templates_SOURCES) $(testfile_SOURCES) \
+ $(widechar_SOURCES)
+DIST_SOURCES = $(anonstruct_SOURCES) $(locals_SOURCES) \
+ $(maths_SOURCES) $(nestedclass_SOURCES) $(qt_SOURCES) \
+ $(repeats_SOURCES) $(std_SOURCES) $(templates_SOURCES) \
+ $(testfile_SOURCES) $(widechar_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARTSCCONFIG = @ARTSCCONFIG@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+
+# Disable optimization to ensure that variables are not hidden by the
+# compiler
+#>- CXXFLAGS := $(patsubst -O%,,$(CXXFLAGS))
+#>+ 1
+CXXFLAGS := $(patsubst -O%,,$(CXXFLAGS) $(KDE_CXXFLAGS))
+CYGPATH_W = @CYGPATH_W@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOPIDLNG = @DCOPIDLNG@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
+KCONFIG_COMPILER = @KCONFIG_COMPILER@
+KDECONFIG = @KDECONFIG@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
+KDE_MT_LIBS = @KDE_MT_LIBS@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_FPIE = @KDE_USE_FPIE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+KDE_USE_PIE = @KDE_USE_PIE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPTHREAD = @LIBPTHREAD@
+LIBRESOLV = @LIBRESOLV@
+LIBS = @LIBS@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBZ = @LIBZ@
+LIB_KAB = @LIB_KAB@
+LIB_KABC = @LIB_KABC@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDED = @LIB_KDED@
+LIB_KDEPIM = @LIB_KDEPIM@
+LIB_KDEPRINT = @LIB_KDEPRINT@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KDNSSD = @LIB_KDNSSD@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMPROXY = @LIB_KIMPROXY@
+LIB_KIO = @LIB_KIO@
+LIB_KJS = @LIB_KJS@
+LIB_KNEWSTUFF = @LIB_KNEWSTUFF@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KUNITTEST = @LIB_KUNITTEST@
+LIB_KUTILS = @LIB_KUTILS@
+LIB_POLL = @LIB_POLL@
+LIB_QPE = @LIB_QPE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_X11 = @LIB_X11@
+LIB_XEXT = @LIB_XEXT@
+LIB_XRENDER = @LIB_XRENDER@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKEKDEWIDGETS = @MAKEKDEWIDGETS@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MKDIR_P = @MKDIR_P@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PS_COMMAND = @PS_COMMAND@
+QTE_NORTTI = @QTE_NORTTI@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+UIC_TR = @UIC_TR@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+XGETTEXT = @XGETTEXT@
+XMKMF = @XMKMF@
+XMLLINT = @XMLLINT@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+X_RPATH = @X_RPATH@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_kcfgdir = @kde_kcfgdir@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_qtver = @kde_qtver@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_styledir = @kde_styledir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+kde_widgetdir = @kde_widgetdir@
+kdeinitdir = @kdeinitdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+xdg_appsdir = @xdg_appsdir@
+xdg_directorydir = @xdg_directorydir@
+xdg_menudir = @xdg_menudir@
+EXTRA_DIST = xsldoc.xsl xsldoc.xml
+
+# set the include path for X, qt and KDE
+INCLUDES = $(all_includes)
+# always compile with debugging info switched on
+AM_CXXFLAGS = -g
+@BUILDTESTPROGS_FALSE@PROGS =
+@BUILDTESTPROGS_TRUE@PROGS = \
+@BUILDTESTPROGS_TRUE@ anonstruct \
+@BUILDTESTPROGS_TRUE@ locals \
+@BUILDTESTPROGS_TRUE@ maths \
+@BUILDTESTPROGS_TRUE@ nestedclass \
+@BUILDTESTPROGS_TRUE@ qt \
+@BUILDTESTPROGS_TRUE@ repeats \
+@BUILDTESTPROGS_TRUE@ std \
+@BUILDTESTPROGS_TRUE@ templates \
+@BUILDTESTPROGS_TRUE@ testfile \
+@BUILDTESTPROGS_TRUE@ widechar
+
+testfile_SOURCES = testfile.cpp
+testfile_LDFLAGS = -g $(all_libraries) $(KDE_RPATH)
+testfile_LDADD = $(LIB_QT)
+locals_SOURCES = locals.cpp
+locals_LDFLAGS = -g
+maths_SOURCES = maths.cpp
+maths_LDFLAGS = -g
+qt_SOURCES = qt.cpp
+qt_LDFLAGS = -g $(all_libraries) $(KDE_RPATH)
+qt_LDADD = $(LIB_QT)
+repeats_SOURCES = repeats.cpp
+repeats_LDFLAGS = -g $(all_libraries) $(KDE_RPATH)
+repeats_LDADD = $(LIB_QT)
+std_SOURCES = std.cpp
+std_LDFLAGS = -g
+templates_SOURCES = templates.cpp
+templates_LDFLAGS = -g
+anonstruct_SOURCES = anonstruct.cpp
+anonstruct_LDFLAGS = -g
+nestedclass_SOURCES = nestedclass.cpp
+nestedclass_LDFLAGS = -g
+widechar_SOURCES = widechar.cpp
+widechar_LDFLAGS = -g
+#>- all: all-am
+#>+ 1
+all: docs-am all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/testprogs/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu kdbg/testprogs/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/testprogs/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/testprogs/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/testprogs/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+anonstruct$(EXEEXT): $(anonstruct_OBJECTS) $(anonstruct_DEPENDENCIES)
+ @rm -f anonstruct$(EXEEXT)
+ $(anonstruct_LINK) $(anonstruct_OBJECTS) $(anonstruct_LDADD) $(LIBS)
+locals$(EXEEXT): $(locals_OBJECTS) $(locals_DEPENDENCIES)
+ @rm -f locals$(EXEEXT)
+ $(locals_LINK) $(locals_OBJECTS) $(locals_LDADD) $(LIBS)
+maths$(EXEEXT): $(maths_OBJECTS) $(maths_DEPENDENCIES)
+ @rm -f maths$(EXEEXT)
+ $(maths_LINK) $(maths_OBJECTS) $(maths_LDADD) $(LIBS)
+nestedclass$(EXEEXT): $(nestedclass_OBJECTS) $(nestedclass_DEPENDENCIES)
+ @rm -f nestedclass$(EXEEXT)
+ $(nestedclass_LINK) $(nestedclass_OBJECTS) $(nestedclass_LDADD) $(LIBS)
+qt$(EXEEXT): $(qt_OBJECTS) $(qt_DEPENDENCIES)
+ @rm -f qt$(EXEEXT)
+ $(qt_LINK) $(qt_OBJECTS) $(qt_LDADD) $(LIBS)
+repeats$(EXEEXT): $(repeats_OBJECTS) $(repeats_DEPENDENCIES)
+ @rm -f repeats$(EXEEXT)
+ $(repeats_LINK) $(repeats_OBJECTS) $(repeats_LDADD) $(LIBS)
+std$(EXEEXT): $(std_OBJECTS) $(std_DEPENDENCIES)
+ @rm -f std$(EXEEXT)
+ $(std_LINK) $(std_OBJECTS) $(std_LDADD) $(LIBS)
+templates$(EXEEXT): $(templates_OBJECTS) $(templates_DEPENDENCIES)
+ @rm -f templates$(EXEEXT)
+ $(templates_LINK) $(templates_OBJECTS) $(templates_LDADD) $(LIBS)
+testfile$(EXEEXT): $(testfile_OBJECTS) $(testfile_DEPENDENCIES)
+ @rm -f testfile$(EXEEXT)
+ $(testfile_LINK) $(testfile_OBJECTS) $(testfile_LDADD) $(LIBS)
+widechar$(EXEEXT): $(widechar_OBJECTS) $(widechar_DEPENDENCIES)
+ @rm -f widechar$(EXEEXT)
+ $(widechar_LINK) $(widechar_OBJECTS) $(widechar_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/anonstruct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/locals.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maths.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nestedclass.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repeats.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/std.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/templates.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/widechar.Po@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-am
+#>+ 1
+clean: kde-rpo-clean clean-am
+
+#>- clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+#>- mostlyclean-am
+#>+ 2
+clean-am: clean-bcheck clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstPROGRAMS ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+
+#>+ 2
+KDE_DIST=test1.xsl test1.xml Makefile.in Makefile.am
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/testprogs/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/testprogs/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/testprogs/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-am
+
+bcheck-am:
+ @for i in ; do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXXCOMPILE) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 3
+final:
+ $(MAKE) all-am
+
+#>+ 3
+final-install:
+ $(MAKE) install-am
+
+#>+ 3
+no-final:
+ $(MAKE) all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/kdbg/testprogs/anonstruct.cpp b/kdbg/testprogs/anonstruct.cpp
new file mode 100644
index 0000000..591a15e
--- /dev/null
+++ b/kdbg/testprogs/anonstruct.cpp
@@ -0,0 +1,32 @@
+// test anonymous structs and unions
+
+#include <cstdio>
+#include <pthread.h>
+
+struct T {
+ pthread_mutex_t mutex; // contains anonymous union on Linux
+ struct {
+ int a;
+ };
+ union {
+ int b;
+ long c;
+ };
+ int TestPopup()
+ {
+ return a ? b : c;
+ }
+};
+
+int main()
+{
+ pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ T t;
+ union {
+ char a;
+ int b;
+ };
+ a = 'X';
+ b = t.TestPopup();
+ std::fprintf(stderr, "%d, %d, a=%d, b=%d\n", sizeof(mutex), sizeof(t), a, b);
+}
diff --git a/kdbg/testprogs/locals.cpp b/kdbg/testprogs/locals.cpp
new file mode 100644
index 0000000..ed2cf1e
--- /dev/null
+++ b/kdbg/testprogs/locals.cpp
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+
+// a function that has args but no locals
+
+static int nolocals(int argc, char** argv)
+{
+ printf("argc=%d, argv[0]=%s\n", argc, argv[0]);
+}
+
+
+// a function that has no args but locals
+
+static int noargs()
+{
+ int c = 1;
+ char* pgm[] = { "foo", 0 };
+ nolocals(c, pgm);
+}
+
+
+int main(int argc, char** argv)
+{
+ noargs();
+ nolocals(argc, argv);
+}
diff --git a/kdbg/testprogs/maths.cpp b/kdbg/testprogs/maths.cpp
new file mode 100644
index 0000000..c69e98d
--- /dev/null
+++ b/kdbg/testprogs/maths.cpp
@@ -0,0 +1,30 @@
+// do some floatingpoint computations
+#include <math.h>
+#include <stdio.h>
+
+double deg2rad(double a)
+{
+ double result;
+ result = a * 3.141592653589793 / 180.0;
+ return result;
+}
+
+#define pi 3.1415926535897932384626433832795028841971693993750
+
+void longdouble(long double ld)
+{
+ long double x = 1000000.0 * ld*ld*pi;
+ printf("long double: %Lf\n", x);
+}
+
+int main(int argc, char** argv)
+{
+ double a = 17.4;
+ double b = deg2rad(a);
+ double sine = sin(b);
+
+ printf("angle=%f degrees (%f radians), sine is %f\n",
+ a, b, sine);
+
+ longdouble(17.0);
+}
diff --git a/kdbg/testprogs/nestedclass.cpp b/kdbg/testprogs/nestedclass.cpp
new file mode 100644
index 0000000..41bcbd5
--- /dev/null
+++ b/kdbg/testprogs/nestedclass.cpp
@@ -0,0 +1,31 @@
+#include <iostream>
+
+void foo()
+{
+ struct Whiz
+ {
+ Whiz()
+ {
+ std::cerr << __PRETTY_FUNCTION__ << std::endl;
+ }
+ void inner(Whiz*)
+ {
+ struct Inner
+ {
+ void bar()
+ {
+ std::cerr << __PRETTY_FUNCTION__ << std::endl;
+ }
+ };
+ Inner z;
+ z.bar();
+ }
+ };
+ Whiz w;
+ w.inner(&w);
+}
+
+int main()
+{
+ foo();
+}
diff --git a/kdbg/testprogs/qt.cpp b/kdbg/testprogs/qt.cpp
new file mode 100644
index 0000000..2e04330
--- /dev/null
+++ b/kdbg/testprogs/qt.cpp
@@ -0,0 +1,41 @@
+#include <qmap.h>
+#include <qvaluelist.h>
+#include <qvaluevector.h>
+#include <qstring.h>
+#include <qrect.h>
+#include <iostream>
+
+template<typename T>
+void test_sharing(const T& input)
+{
+ // a copy should increase the share counter
+ T copy = input;
+
+ // a const interator should not detach the copy
+ typename T::const_iterator cit = copy.constBegin();
+ std::cout << *cit << std::endl;
+
+ // a non-const iterator should detach the copy
+ typename T::iterator it = copy.begin();
+ std::cout << *it << std::endl;
+}
+
+int main()
+{
+ QMap<QString,int> str2int;
+ str2int["foo"] = 42;
+ test_sharing(str2int);
+
+ QValueList<int> ints;
+ ints.push_back(42);
+ test_sharing(ints);
+
+ QValueVector<double> vals(6, 47.11);
+ vals.push_back(42);
+ test_sharing(vals);
+
+ QRect r(10,20, 130, 240);
+ QPoint p = r.topLeft();
+ QPoint q = r.bottomRight();
+ std::cout << r.width() << r.height() << p.x() << q.y() << std::endl;
+}
diff --git a/kdbg/testprogs/repeats.cpp b/kdbg/testprogs/repeats.cpp
new file mode 100644
index 0000000..a7998df
--- /dev/null
+++ b/kdbg/testprogs/repeats.cpp
@@ -0,0 +1,41 @@
+// test <repeats 30 times> in arrays
+
+#include <qstring.h>
+
+struct Big {
+ struct bog {
+ short b[40];
+ } a[40];
+ short c[40][40];
+};
+
+static void f(int)
+{
+}
+
+
+int main()
+{
+ struct Big big = {{{ 2,}}};
+ big.a[0].b[39]=7;
+ big.a[38].b[39]=6;
+
+ // array of pointer to function
+ void (*apf[30])(int);
+
+ for (int i = 1; i < 29; i++)
+ apf[i] = f;
+
+ QString s[300];
+
+ for (int i = 0; i < 300; i++)
+ s[i].sprintf("String %d", i);
+
+ s[21] = s[48];
+
+ int many[300];
+ for (int i = 0; i < 300; i++)
+ many[i] = i;
+
+ return 0;
+}
diff --git a/kdbg/testprogs/std.cpp b/kdbg/testprogs/std.cpp
new file mode 100644
index 0000000..af37a3a
--- /dev/null
+++ b/kdbg/testprogs/std.cpp
@@ -0,0 +1,58 @@
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include <iterator>
+
+template<typename T>
+struct V : std::vector<T>
+{
+ V(const T& v) : std::vector<T>(10, v) {}
+ void anotherone(const T& v)
+ {
+ push_back(v);
+ }
+};
+
+template<typename C, typename T>
+void test_container(C& v, T x)
+{
+ v.push_back(x);
+};
+
+void test_sstream(std::basic_ostringstream<char>& str)
+{
+ str << "Example:\n ";
+}
+
+int main()
+{
+ std::string s = "abc";
+ V<std::string> v(s);
+ test_container(v, "xyz");
+ v.anotherone("ABC");
+
+ std::vector<bool> vb;
+ vb.push_back(true);
+ test_container(vb, false);
+ vb[0] = vb[1];
+ std::cout << vb.size() << std::endl;
+
+ std::list<int> l;
+ l.push_front(-88);
+ test_container(l, 42);
+ std::cout << l.size() << std::endl;
+
+ std::map<std::string,double> m;
+ m["example"] = 47.11;
+ m.insert(std::make_pair("kdbg", 3.14));
+ std::cout << m.size() << std::endl;
+
+ std::ostringstream dump;
+ test_sstream(dump);
+ std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(dump, "\n "));
+ std::cout << dump.str() << std::endl;
+}
diff --git a/kdbg/testprogs/templates.cpp b/kdbg/testprogs/templates.cpp
new file mode 100644
index 0000000..a667463
--- /dev/null
+++ b/kdbg/testprogs/templates.cpp
@@ -0,0 +1,117 @@
+// This file test stack parsing capabilities of KDbg.
+// Parsing function names can be quite tricky ;)
+#include <iostream>
+using namespace std;
+
+struct S {
+ void operator>>(int)
+ {
+ cout << __PRETTY_FUNCTION__ << endl;
+ }
+};
+
+template<typename T>
+struct templS {
+ void operator>(T)
+ {
+ cout << __PRETTY_FUNCTION__ << endl;
+ }
+ void operator<(T)
+ {
+ cout << __PRETTY_FUNCTION__ << endl;
+ }
+};
+
+
+namespace A {
+namespace {
+namespace B {
+namespace {
+namespace {
+void g()
+{
+ cout << __PRETTY_FUNCTION__ << endl;
+}
+} // namespace
+void Banong() { g(); }
+} // namespace
+void g() { Banong(); }
+} // namespace B
+void Aanong() { B::g(); }
+} // namespace
+void g() { Aanong(); }
+
+void operator<<(int, S)
+{
+ cout << __PRETTY_FUNCTION__ << endl;
+}
+
+template<typename T>
+void operator<(T, S)
+{
+ cout << __PRETTY_FUNCTION__ << endl;
+}
+} // namespace A
+
+void operator<<(struct S&, int)
+{
+ cout << __PRETTY_FUNCTION__ << endl;
+}
+
+template<typename T, typename U>
+void operator<<(T&, U)
+{
+ cout << __PRETTY_FUNCTION__ << endl;
+}
+
+void operator<(struct S&, int)
+{
+ cout << __PRETTY_FUNCTION__ << endl;
+}
+
+template<typename T, typename U>
+void operator<(T&, U)
+{
+ cout << __PRETTY_FUNCTION__ << endl;
+}
+
+void f(const char* s)
+{
+ A::g();
+ cout << s << endl;
+}
+
+template<typename T>
+void indirect(T f, const char* s)
+{
+ f(s);
+}
+
+int main()
+{
+ S s1, s2;
+ f("direct");
+ s1 << 1;
+ s1 << s2;
+ s1 < 1;
+ s1 < s2;
+
+ A::operator<<(1, s1);
+ A::operator<(1, s1);
+
+ // the next lines test a templated function that accepts
+ // as one of its parameters a templated function pointer
+ void (*op1)(S&, S*) = operator<<;
+ operator<<(op1, s2);
+ void (*op2)(S&, S*) = operator<;
+ operator<(op2, s2);
+ indirect(f, "indirect");
+
+ // pointer to member function
+ void (S::*pm1)(int) = &S::operator>>;
+ (s1.*pm1)(1);
+ void (templS<int>::*pm2)(int) = &templS<int>::operator>;
+ templS<int> tSi;
+ (tSi.*pm2)(1);
+ tSi.operator<(1);
+}
diff --git a/kdbg/testprogs/test1.xml b/kdbg/testprogs/test1.xml
new file mode 100644
index 0000000..c177744
--- /dev/null
+++ b/kdbg/testprogs/test1.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" ?>
+<!--
+ File : test1.xml
+ Author: Keith Isdale <k_isdale@tpg.com.au>
+ Description: xml data for stylesheet for test "test1"
+ Copyright Reserved Under GPL
+-->
+<html>
+<head>
+</head>
+<body>
+ <h1>test1</h1>
+ <p>text1</p>
+</body>
+</html> \ No newline at end of file
diff --git a/kdbg/testprogs/test1.xsl b/kdbg/testprogs/test1.xsl
new file mode 100644
index 0000000..b939f82
--- /dev/null
+++ b/kdbg/testprogs/test1.xsl
@@ -0,0 +1,113 @@
+<?xml version="1.0" ?>
+<!--
+ File : test1.xsl
+ Author: Keith Isdale <k_isdale@tpg.com.au>
+ Description: stylesheet for test "test1"
+ Copyright Reserved Under GPL
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+ <xsl:template match="/">
+ <xsl:apply-templates/>
+ <xsl:apply-templates mode="testMode"/>
+ <xsl:apply-templates mode="xsl:testMode"/>
+ <xsl:call-template name="test1"/>
+ <xsl:call-template name="test2"/>
+ <xsl:call-template name="xsl:test1"/>
+ <xsl:call-template name="xsl:test2"/>
+ </xsl:template>
+
+ <xsl:template match="html">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="head">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="body">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="h1">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="para">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+
+ <xsl:template match="head" mode="testMode">
+ <xsl:apply-templates mode="testMode"/>
+ </xsl:template>
+
+ <xsl:template match="body" mode="testMode">
+ <xsl:apply-templates mode="testMode"/>
+ </xsl:template>
+
+ <xsl:template match="h1" mode="testMode">
+ <xsl:apply-templates mode="testMode"/>
+ </xsl:template>
+
+ <xsl:template match="para" mode="testMode">
+ <xsl:apply-templates mode="testMode"/>
+ </xsl:template>
+
+ <xsl:template match="html" mode="testMode">
+ <xsl:apply-templates mode="testMode"/>
+ </xsl:template>
+
+
+ <xsl:template match="head" mode="xsl:testMode">
+ <xsl:apply-templates mode="xsl:testMode"/>
+ </xsl:template>
+
+ <xsl:template match="body" mode="xsl:testMode">
+ <xsl:apply-templates mode="xsl:testMode"/>
+ </xsl:template>
+
+ <xsl:template match="h1" mode="xsl:testMode">
+ <xsl:value-of select="'test2'"/>
+ <xsl:apply-templates select="."/>
+ <xsl:apply-templates mode="xsl:testMode"/>
+ </xsl:template>
+
+ <xsl:template match="para" mode="xsl:testMode">
+ <xsl:apply-templates mode="xsl:testMode"/>
+ </xsl:template>
+
+ <xsl:template match="html" mode="xsl:testMode">
+ <xsl:apply-templates mode="xsl:testMode"/>
+ </xsl:template>
+
+ <xsl:template name="test1">
+ <outputtest/>
+ </xsl:template>
+
+ <xsl:template name="test2">
+ <outputtest/>
+ </xsl:template>
+
+ <xsl:template name="xsl:test1">
+ <outputtest/>
+ </xsl:template>
+
+ <xsl:template name="xsl:test2">
+ <outputtest/>
+ </xsl:template>
+
+ <xsl:template match="*">
+ <outputtest/>
+ </xsl:template>
+
+ <xsl:template match="*" mode="testMode">
+ <outputtest/>
+ </xsl:template>
+
+ <xsl:template match="*" mode="xsl:testMode">
+ <outputtest/>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/kdbg/testprogs/testfile.cpp b/kdbg/testprogs/testfile.cpp
new file mode 100644
index 0000000..847ad3e
--- /dev/null
+++ b/kdbg/testprogs/testfile.cpp
@@ -0,0 +1,202 @@
+#include <iostream>
+#include <qstring.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <math.h>
+
+enum E { red, green, blue, yellow };
+struct S { int x, y; S* s; };
+
+struct emptyBase { };
+struct emptyDerived : S { };
+struct emptyNested : emptyBase { };
+struct emptyVBase { virtual ~emptyVBase(){} };
+struct emptyVDerived : S { virtual ~emptyVDerived(){} };
+struct emptyVNested : emptyVBase { };
+
+int globalvar = 1234;
+
+class Cl
+{
+ int k;
+ double l;
+public:
+ Cl(int r);
+ virtual ~Cl();
+ virtual int f(int x);
+};
+
+typedef void (*PtrFunc)(E*, char);
+
+class Dl : public Cl
+{
+public:
+ Dl(int r);
+ virtual int f(int x);
+ int operator()(const QString& x, int& y) const;
+ operator const char*() { return 0; }
+ operator PtrFunc*();
+};
+
+namespace A {
+namespace {
+namespace B {
+namespace {
+namespace {
+void g()
+{
+ S s1, s2;
+ s1.x = 85;
+ s2.y = 17;
+ s1.s = &s2;
+ s2.s = &s1;
+}
+} // namespace
+void Banong() { g(); }
+} // namespace
+void g() { Banong(); }
+} // namespace B
+void Aanong() { B::g(); }
+} // namespace
+void g() { Aanong(); }
+} // namespace A
+
+void f(E e[3], char c)
+{
+ E x = e[2];
+ S y[2];
+ E* pe = e;
+ E* pea[3] = { pe, };
+ {
+ int x = 17;
+ x;
+ }
+ A::g();
+ char buffer[300];
+ memset(buffer, 1, 300);
+ for (int i = 0; i < sizeof(buffer); i +=15) buffer[i] = '\02';
+ QDir dir;
+ QFile file;
+ QFileInfo fi;
+ x = red;
+ emptyBase eb;
+ emptyDerived ed;
+ emptyNested en;
+ int ea[3];
+ emptyVBase evb;
+ emptyVDerived evd;
+ emptyVNested evn;
+}
+
+void strtest(const char* t)
+{
+ const char* s = t;
+ const char*& s2 = s;
+ if (t == 0)
+ strtest(s2);
+ std::cout << s2 << std::endl;
+}
+
+template<typename F>
+void templated_strtest(F f, const char* t)
+{
+ f(t);
+}
+
+void segFault()
+{
+ *(char*)0 = 's';
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc > 1) {
+ if (*argv[1] == 's') {
+ segFault();
+ } else if (*argv[1] == 'a') {
+ // let debugger attach
+ int junk;
+ std::cin >> junk;
+ }
+ }
+
+ char a[6] = { 'a', 'B', '\'', '\"' };
+ char a1[1] = { '1' };
+ E e[3] = { red, green, blue };
+ E e1[1] = { yellow };
+
+ a[0] = '5';
+ void (*pf[2])(E*, char) = {f};
+ {
+ double d[1] = { -1.234e123 };
+ int i = 10;
+ sin(i);
+ }
+ (*pf[0])(e, '\n');
+
+ QString s;
+
+ s = "Hi, there!\r\n\t\"\'\\";
+
+ const QString& strref = s;
+
+ templated_strtest(strtest, s);
+ s = "asbcxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+ strtest(s);
+ s += "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiii";
+ strtest(s);
+ s += "rst";
+ strtest(s);
+ s = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";
+ strtest(s);
+ s += "rst";
+ strtest(s);
+ s = "";
+
+ Cl c1(13);
+ Dl d1(3214);
+ d1.f(17);
+ int n = 83;
+ d1(strref, n);
+ PtrFunc* ppf = d1;
+}
+
+Cl::Cl(int r) :
+ k(r),
+ l(sin(r))
+{
+ std::cout << l << std::endl;
+}
+
+Cl::~Cl()
+{
+}
+
+int Cl::f(int x)
+{
+ int y = 2*x;
+ return y;
+}
+
+Dl::Dl(int r) :
+ Cl(r)
+{
+}
+
+int Dl::f(int x)
+{
+ int y = Cl::f(x);
+ return y+3;
+}
+
+int Dl::operator()(const QString& x, int& y) const
+{
+ std::cerr << "ha! I know!" << std::endl;
+ return 1;
+}
+
+Dl::operator PtrFunc*()
+{
+ return 0;
+}
diff --git a/kdbg/testprogs/widechar.cpp b/kdbg/testprogs/widechar.cpp
new file mode 100644
index 0000000..ae0725a
--- /dev/null
+++ b/kdbg/testprogs/widechar.cpp
@@ -0,0 +1,31 @@
+#include <wchar.h>
+#include <stdio.h>
+#include <string>
+
+struct WChar {
+ const wchar_t* cwstr;
+ wchar_t* wstr;
+};
+
+int main()
+{
+ int j=3;
+ const wchar_t* nullPtr = 0;
+ const wchar_t* uninitializedPtr = (const wchar_t*)0xdeadbeef;
+ const wchar_t* str = L"abc";
+ wchar_t* str2 = L"def";
+ const char* shortStr = "12345";
+
+ WChar s = { 0, L"Some string" };
+ s.cwstr = s.wstr;
+
+ wchar_t wstr[64], *wstrPtr = wstr;
+
+ wprintf(L"wide string: %S\n", str);
+
+ for (int i=0; i<j; ++i)
+ {
+ swprintf(wstr, 63, L"%d. wide string: %S\n", i+1, str);
+ wprintf(L"%S\n", wstr);
+ }
+}
diff --git a/kdbg/testprogs/xsldoc.xml b/kdbg/testprogs/xsldoc.xml
new file mode 100644
index 0000000..8ea9f48
--- /dev/null
+++ b/kdbg/testprogs/xsldoc.xml
@@ -0,0 +1,667 @@
+<?xml version="1.0"?>
+<!DOCTYPE xsldoc SYSTEM "xsldoc.dtd">
+<!--
+ File : xsldoc.xml
+ Author: Keith Isdale <k_isdale@tpg.com.au>
+ Description: Xml Data to be processed generate help text and other
+ documentation
+ Copyright Reserved Under GPL
+-->
+<xsldoc>
+<overview>
+<header>xsldbg help</header>
+<body>
+<para>xsldbg is similar to gdb. It has three modes of execution
+of stylesheets.
+<list>
+<li>Run the whole stylesheet</li>
+<li>Step to next xsl instruction</li>
+<li>Continue to next break point is found</li>
+</list>
+</para>
+<para title="xsldbg command line">
+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 &lt;ENTER&gt; key.
+</para>
+<para title="Legend :">
+<list><li>TEMPLATENAME : a valid template name</li>
+<li>FILENAME : a valid URL for a stylesheet</li>
+<li>LINENO : a valid line number in associated FILENAME</li>
+<li>NUMBER_OF_FRAMES : a valid line number frames to change position by</li>
+<li>BREAKPOINT_ID : a valid break point number</li>
+<li>SPEED: speed to walk through code at, between 0 to 9</li>
+<li><comment>(Comment)</comment>: a comment about command meaning or usage</li>
+<li>{ opt1 | opt2 | opt2 .. etc} : Choose one of the opt's</li>
+<li>XPATH : a xpath selection of node(s)</li>
+<li>PARAM_ID : a valid parameter number as indicated by showparam command</li>
+<li>PATH : a path to change working directory to</li>
+<li>TEXT : free form text <comment>(no restricttions)</comment></li>
+<li>COMMAND : a valid command for the xsdbg</li>
+<li>QNAME : a valid variable/parameter name</li>
+<li>SOURCE : the stylesheet being/tobe executed</li>
+<li>DATA : the xml data being/tobe processed by the stylesheet
+</li>
+</list>
+</para>
+
+<!-- - - - - Start help summary - - - - - -->
+<para title="Within xsldbg these commands are available:">
+<list>
+
+<li>Help related : help</li>
+
+<li>Running related : {<link href="bye">bye</link>|<link href="exit">exit</link>|
+<link href="quit">quit</link>}, <link href="step">step</link>,
+<link href="stepup">stepup</link>, <link href="stepdown">stepdown</link>,
+<link href="continue">continue</link>, <link href="run">run</link>,
+<link href="trace">trace</link>
+</li>
+
+<li>Libxslt parameter related :
+<link href="addparam">addparam</link>,<link href="delparam">delparam</link>,
+<link href="showparam">showparam</link>
+</li>
+
+<li>Template related : <link href="templates">templates</link>,
+<link href="where">where</link>, <link href="frame">frame</link>
+</li>
+
+<li>Break point related : <link href="break">break</link>,
+<link href="showbreak">showbreak</link>,
+<link href="delete">delete</link>, <link href="enable">enable</link>
+</li>
+
+<li>Expression viewing(xpath) : <link href="cat">cat</link></li>
+<li>Node viewing : <link href="ls">ls</link>, <link href="dir">dir</link>,
+<link href="du">du</link>, <link href="cat">cat</link>, <link href="pwd">pwd</link></li>
+<li>Variable viewing : <link href="globals">globals</link>,
+<link href="locals">locals</link>,
+<link href="cat">cat</link>
+</li>
+
+<li>Node selection : <link href="source">source</link>,
+<link href="data">data</link>,
+<link href="cd">cd</link>
+</li>
+
+<li>Searching :<link href="search">search</link>
+</li>
+
+<li>Operating system related :
+<link href="chdir">chdir</link>,
+<link href="shell">shell</link>
+</li>
+
+<li>File related :
+<link href="validate">validate</link>, <link href="load">load</link>,
+<link href="save">save</link>, <link href="write">write</link>,
+<link href="free">free</link>
+</li>
+</list>
+</para>
+<para>nb: At the moment the file related commands as disabled because
+they are not completed.</para>
+</body>
+
+<footer></footer>
+</overview>
+
+<!-- - - - - - Help related commands - - - - - - - - - - -->
+<cmd name="help" title="Help">
+<summary>Display help on command or overiew</summary>
+<usage>
+<li>help <comment>(Show overview of product)</comment></li>
+<li>help &lt;COMMAND&gt; <comment>(Show help about a command)</comment></li>
+</usage>
+</cmd>
+
+<!-- - - - - - - Running related commands - - - - - - - - -->
+<cmd name="bye" title="Bye">
+<summary>Exit processing stylesheet as soon as possible.</summary>
+<usage>
+<li>
+<text>bye</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="quit" title="Quit">
+<summary>Exit processing stylesheet as soon as possible.</summary>
+<para>Shortcut name: q</para>
+<usage>
+<li>
+<text>quit</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="exit" title="Exit">
+<summary>Exit processing stylesheet as soon as possible.</summary>
+<usage>
+<li>
+<text>exit</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="step" title="Step">
+<summary>Step until next stylesheet instruction.</summary>
+<body>
+<para>Shortcut name: s</para>
+</body>
+<usage>
+<li>
+<text>step</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="stepup" title="Stepup">
+<summary>Step up to a older "call frame". </summary>
+<body>
+<para>Shortcut name: up</para>
+</body>
+ <usage>
+ <li>
+ <text>stepup </text>
+ <comment>(step up one frame)</comment></li>
+ <li>
+ <text>stepup &lt;NUMBER_OF_FRAMES&gt; </text>
+ <comment>(step up specified number of frames)</comment>
+ </li>
+ </usage>
+</cmd>
+
+<cmd name="stepdown" title="Stepdown">
+<summary>Step down to a newer "call frame". </summary>
+<body>
+<para>Shortcut name: down</para>
+</body>
+ <usage>
+ <li>
+ <text>stepdown </text>
+ <comment>(step down one frame)</comment>
+ </li>
+ <li>
+ <text>stepdown &lt;NUMBER_OF_FRAMES&gt;</text>
+ <comment>(step down specified number of frames)</comment>
+ </li>
+ </usage>
+</cmd>
+
+<cmd name="continue" title="Continue">
+<summary>Continue running stylesheet, stopping at any break points found.</summary>
+<para>Shortcut name: c</para>
+<usage>
+<li>
+<text>continue</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="run" title="Run">
+<summary>Restart the stylesheet.</summary>
+<para>Shortcut name: r</para>
+<usage>
+<li>
+<text>run</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="trace" title="Trace">
+<summary>Trace one execution of the stylesheet</summary>
+<usage>
+<li>
+<text>trace</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="walk" title="Walk">
+<summary>Walk through code using a range of speeds</summary>
+<usage>
+<li>
+<text>walk &lt;SPEED&gt;</text>
+<comment>(Use Ctrl-c to stop execution, &lt;SPEED&gt; is a value between 0 and 9. Where 0 means stop, 1 is very fast, 9 is very slow)</comment>
+</li>
+</usage>
+</cmd>
+
+<!-- - - - - - - - libxslt Parameter related - - - - -->
+<cmd name="addparam" title="Addparam">
+<summary>Add a libxslt parameter</summary>
+<usage>
+<li>
+<text>addparam &lt;QNAME&gt; &lt;XPATH&gt;</text>
+<comment>(No error checking done on the validity of &lt;QNAME&gt; nor &lt;XPATH&gt;. This is equivalent to providing --param &lt;QNAME&gt; &lt;XPATH&gt; via command line)</comment>
+</li>
+</usage>
+</cmd>
+
+<cmd name="delparam" title="Delparam">
+<summary>Delete a libxslt parameter</summary>
+<usage>
+<li>
+<text>delparam</text>
+<comment>(Delete all parameters present)</comment>
+</li>
+<li>
+<text>delparam &lt;PARAM_ID&gt;</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="showparam" title="Showparam">
+<summary>Print the libxslt parameters present</summary>
+<usage>
+<li>
+<text>showparam</text>
+</li>
+</usage>
+</cmd>
+
+<!-- - - - - - - Template related commands - - - - - - - -->
+<cmd name="templates" title="Templates">
+<summary>Print a list of available templates. Search for a template</summary>
+<para>Shortcut name: t</para>
+<usage>
+<li>
+<text>templates</text>
+</li>
+<li>
+<text>templates &lt;TEMPLATE&gt;</text>
+<comment>(Print details of template named &lt;TEMPLATE&gt; if it can be found)</comment>
+</li>
+</usage>
+</cmd>
+
+<cmd name="where" title="Where">
+<summary>Print a trace of templates calls (frame stack) and print the working directory.</summary>
+<para>Shortcut name: w</para>
+<usage>
+<li>
+<text>where</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="frame" title="Frame">
+<summary>Print the stack frame at a given depth</summary>
+<para>Shortcut name: f</para>
+<usage>
+<li>
+<text>frame &lt;FRAME_DEPTH&gt;</text>
+<comment>(Depth is a number from 0 to the current depth of call stack)</comment>
+
+</li>
+</usage>
+</cmd>
+
+<cmd name="stylesheets" title="Stylesheets">
+<summary>Print out a list of stylesheets loaded</summary>
+<body>
+<para>Shortcut name: style</para>
+</body>
+<usage>
+<li>
+<text>stylesheets</text>
+</li>
+</usage>
+</cmd>
+
+<!-- - - - - Break point related commands - - - - - - - -->
+<cmd name="break" title="Break">
+<summary>Break at a template, at a location in any file loaded, or at the current node. </summary>
+<body>
+<para>Shortcut name: b</para>
+<para>xsldbg will try to guess the complete URL given a
+<list>
+<li>file name without a path specified.</li>
+<li>a file name in the same directory as the &quot;top&quot; stylesheet loaded</li>
+<li>a file name relative to the current working directory of xsldbg</li>
+</list>
+Ie if you have loaded a stylsheet file of ../en/xsldoc.xsl you can do this
+</para>
+<para> break -l xsldoc.xsl 26
+</para>
+</body>
+<usage>
+<li>
+ <text>break -l &lt;FILENAME&gt; &lt;LINENO&gt;</text>
+</li>
+<li>
+ <text>break &lt;TEMPLATENAME&gt;</text>
+ <comment>(To break at named template.)</comment>
+</li>
+<li>
+ <text>break *</text>
+ <comment>(To break at any template found.)</comment>
+</li>
+<li>
+ <text>break </text>
+ <comment>(To break point at current node. Yes that includes xml data nodes!)</comment>
+</li>
+</usage>
+</cmd>
+
+<cmd name="showbreak" title="Showbreak">
+<summary>To display list of template break points.</summary>
+<para>Shortcut name: show</para>
+<usage>
+<li>
+<text>showbreak</text>
+</li>
+</usage>
+</cmd>
+
+
+<cmd name="delete" title="Delete">
+<summary>Delete a template breakpoint</summary>
+<body>
+<para>Shortcut name: d</para>
+</body>
+<usage>
+<li>
+ <text>delete</text>
+ <comment>(To delete breakpoint at current node)</comment>
+</li>
+<li>
+ <text>delete &lt;BREAKPOINT_ID&gt;</text>
+ <comment>(To delete breakpoint at specified break point number)</comment>
+</li>
+<li>
+ <text>delete -l &lt;FILENAME&gt; &lt;LINENO&gt;</text>
+ <comment>(Delete at specifed file, line number)</comment>
+</li>
+<li>
+ <text>delete &lt;TEMMPLATENAME&gt;</text>
+ <comment>(To delete break point at named template.)</comment>
+</li>
+<li>
+ <text>delete *</text>
+ <comment>(To delete all break points.)</comment>
+</li>
+</usage>
+</cmd>
+
+<cmd name="enable" title="Enable">
+<summary>Enable or disable a breakpoint (Toggle enable/disable/)</summary>
+<body>
+<para>Shortcut name: e</para>
+</body>
+<usage>
+<li>
+ <text>enable</text>
+ <comment>(To enable/disable breakpoint at current node)</comment>
+</li>
+<li>
+ <text>enable &lt;BREAKPOINT_ID&gt;</text>
+ <comment>(To enable/disable breakpoint at specified break point number</comment>
+</li>
+<li>
+ <text>enable -l &lt;FILENAME&gt; &lt;LINENO&gt;</text>
+ <comment>(Enable/disable breakpoint at specifed file, line number)</comment>
+</li>
+</usage>
+</cmd>
+
+<cmd name="disable" title="Disable">
+<summary>Disable a breakpoint</summary>
+<usage>
+<li>
+ <text>disable</text>
+ <comment>(To disable breakpoint at current node)</comment>
+</li>
+<li>
+ <text>disable &lt;BREAKPOINT_ID&gt;</text>
+ <comment>(To disable breakpoint at specified break point number</comment>
+</li>
+<li>
+ <text>disable -l &lt;FILENAME&gt; &lt;LINENO&gt;</text>
+ <comment>(Disable breakpoint at specifed file, line number)</comment>
+</li>
+</usage>
+</cmd>
+
+
+<!-- - - - - - - Node view related commands - - - - - - - - -->
+<cmd name="ls" title="Ls">
+<summary>List nodes in a brief format</summary>
+<usage>
+<li>
+<text>ls</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="dir" title="Dir">
+<summary>Print list of nodes in a similary way to the dir shell command.</summary>
+<body>
+<para></para>
+</body>
+<usage>
+<li>
+<text>dir</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="du" title="Du">
+<summary>Print a summary of child nodes in a tree format.</summary>
+<usage>
+<li>
+<text>du</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="cat" title="Cat">
+<summary>Print the result of a xpath expression on relative current node.</summary>
+<body>
+<para>Usage : cat &lt;XPATH&gt;</para>
+<para>Usage : cat $&lt;QNAME&gt; (To view a varaible or parameter)</para>
+</body>
+</cmd>
+
+<cmd name="pwd" title="Pwd">
+<summary>Print the current working directory.</summary>
+<usage>
+<li>
+<text>pwd</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="base" title="Base">
+<summary>Print the base for this node</summary>
+<usage>
+<li>
+<text>base</text>
+</li>
+</usage>
+</cmd>
+
+<cmd name="dump" title="Dump">
+<summary>Dump the gory details of this node</summary>
+<usage>
+<li>
+<text>dump</text>
+</li>
+</usage>
+</cmd>
+
+<!-- - - - - - - Variable related commands - - - - - - - - - -->
+<cmd name="globals" title="Globals">
+<summary>Print a list of global stylesheet variables or parameters. Print the value of a global variable</summary>
+<usage>
+<li>
+ <text>globals</text>
+ <comment>(Print list of all globaly available variables)</comment>
+</li>
+<li>
+ <text>globals &lt;QNAME&gt;</text>
+ <comment>(Print the value of variable specified)</comment>
+</li>
+</usage>
+</cmd>
+
+<cmd name="locals" title="Locals">
+<summary>Print a list of local stylesheet variables or parameters. Print the value of a local variable</summary>
+<usage>
+<li>
+ <text>locals</text>
+ <comment>(Print list of all locally available variables)</comment>
+</li>
+<li>
+ <text>locals &lt;QNAME&gt;</text>
+ <comment>(Print the value of variable specified)</comment>
+</li>
+</usage>
+</cmd>
+
+<!-- - - - - - - Node selection related commands - - - - - - - -->
+<cmd name="source" title="Source">
+<summary>Switch to displaying the current node in stylesheet. Or change stylesheet used</summary>
+<usage>
+<li>
+<text>source</text>
+<comment>(Switch to the current node in stylesheet.)</comment>
+</li>
+<li>
+<text>source &lt;SOURCE&gt;</text>
+<comment>(To change to a new source file. A leading '~' is replaced by the $HOME environment variable value. May need to use run command to execute it)</comment>
+</li>
+</usage>
+</cmd>
+
+<cmd name="data" title="Data">
+<summary>Switch to displaying the current node in xml data. Or change xml data used</summary>
+<usage>
+<li>
+<text>data</text>
+<comment>(Switch to the current document node.)</comment>
+</li>
+<li>
+<text>data &lt;DATA&gt;</text>
+<comment>(To change to a new xml data file. A leading '~' is replaced by the $HOME environment variable value. May need to use run command to process it)</comment>
+</li>
+</usage>
+</cmd>
+
+<cmd name="cd" title="Cd">
+<summary>Change to the path specified by a xpath.</summary>
+<usage>
+<li>
+ <text>cd &lt;XPATH&gt;</text>
+</li>
+<li>
+ <text>cd -t&lt;TEMPLATENAME&gt;</text>
+ <comment>(To changes current SOURCE node to a be xsl template with name &lt;NAME&gt;, but does execute source command)</comment>
+</li>
+<li>
+ <text>cd -s&lt;XPATH&gt;</text>
+ <comment>(An absolute xPath to node within stylesheet)</comment>
+</li>
+<li>
+ <text>cd &lt;SHORTCUT&gt; &lt;XPATH&gt;</text>
+</li>
+<li>
+ <text> Where SHORTCUT can be either</text>
+</li>
+<li>
+<list>
+<li><text>&lt;&lt; = preceding-sibling::node()</text>
+</li>
+<li><text>&gt;&gt; = following-sibling::node()</text>
+</li>
+<li><text>&lt;- = ancestor::node()</text>
+</li>
+<li><text>-&gt; = decendant::node()</text>
+</li>
+</list>
+</li>
+</usage>
+</cmd>
+
+
+<!-- - - - - - File related commands - - - - - - -->
+<cmd name="validate" title="Validate">
+<summary>Validate the output file generated by stylesheet (Disabled)</summary>
+</cmd>
+
+<cmd name="load" title="Load">
+<summary>Reload stylesheet and data file(s) (Disabled see run)</summary>
+</cmd>
+
+<cmd name="save" title="Save">
+<summary>Save the generated data file (Disabled)</summary>
+</cmd>
+
+<cmd name="write" title="Write">
+<summary>To be completed</summary>
+</cmd>
+
+<cmd name="free" title="Free">
+<summary>Free stylesheet and data (Disabled see run)</summary>
+</cmd>
+
+<!-- - - - - - - Searching related - - - - - -->
+<cmd name="search" title="Search">
+<summary>Search a database of all information gathered from styleets loaded</summary>
+<body>
+<para>When the search command is issued a file (search.data) will be created in the current directory. You can then process this file with your own stylessheet to present data in a other ways than displayed by default.
+</para>
+<para>Depending on the amount of data collected it might take a while to compled this command.
+</para>
+<para>At the moment breakpoints are not being sorted properly. Which is being looked at.
+</para>
+</body>
+<usage>
+<li>
+<text>search &lt;XPATH&gt;</text><comment>(See what xpath can be used see search.dtd)</comment>
+</li>
+<li>
+<text>search -sort &lt;XPATH&gt;</text><comment>(Enable tell search.xsl to sort the result before outputing it)</comment>
+</li>
+</usage>
+</cmd>
+
+<!-- - - - - Operating system related - - - - -->
+<cmd name="chdir" title="Chdir">
+<summary>Change the working directory</summary>
+<usage>
+<li>
+<text>chdir &lt;PATH&gt;</text>
+<comment>(A relative or absolute path for operating system)</comment>
+</li>
+</usage>
+</cmd>
+
+<cmd name="shell" title="Shell">
+<summary>Execute shell command</summary>
+<usage>
+<li>
+<text>shell &lt;TEXT&gt;</text>
+<comment>(&lt;TEXT&gt; is the text to be passed to operating system for execution)</comment>
+</li>
+</usage>
+</cmd>
+
+</xsldoc>
+
+
+<!-- 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/kdbg/testprogs/xsldoc.xsl b/kdbg/testprogs/xsldoc.xsl
new file mode 100644
index 0000000..eb49ca3
--- /dev/null
+++ b/kdbg/testprogs/xsldoc.xsl
@@ -0,0 +1,114 @@
+<?xml version="1.0" ?>
+<!--
+ File : xsldoc.xsl
+ Author: Keith Isdale <k_isdale@tpg.com.au>
+ Description: Stylesheet to process xsldoc.xml and generate help text
+ Copyright Reserved Under GPL
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+ <xsl:output method="text"/>
+ <xsl:strip-space elements="text"/>
+ <xsl:variable name="overview_node" select="/xsldoc/overview"/>
+ <xsl:variable name="command_nodes" select="/xsldoc/cmd"/>
+ <xsl:variable name="doc_version" select="'0.5'"/>
+ <xsl:param name="xsldbg_version" select="'0.5.9'"/>
+ <!-- We want help to point to a invalid command if stylesheet
+ user has not provided a value for 'help' param-->
+ <xsl:param name="help" select="'_#_'"/>
+
+
+ <xsl:template match="/">
+ <xsl:variable name="help_cmd" select="$command_nodes[@name=$help]"/>
+ xsldbg version <xsl:value-of select="$xsldbg_version"/>
+ ====================
+
+ <xsl:choose>
+ <xsl:when test="count($help_cmd) > 0" >
+ <xsl:apply-templates select="$help_cmd" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="$help !='_#_'">
+ <xsl:text>Help about </xsl:text>
+ <xsl:value-of select="$help"/>
+ <xsl:text> was not found.
+ </xsl:text>
+ </xsl:if>
+ <xsl:apply-templates select="$overview_node"/>
+ </xsl:otherwise>
+ </xsl:choose>
+<xsl:text>
+</xsl:text>
+ Help document version <xsl:value-of select="$doc_version"/><xsl:text>
+</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="header">
+<xsl:value-of select="."/>
+<xsl:text>
+ </xsl:text>
+<xsl:value-of
+ select="substring('____________________________________________________________',
+ 1, string-length())" />
+<xsl:text>
+</xsl:text>
+ </xsl:template>
+
+
+ <xsl:template match="text()">
+ <xsl:value-of select="normalize-space()"/>
+ </xsl:template>
+
+ <xsl:template match="para">
+ <xsl:text>
+</xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="list | usage">
+ <xsl:text>
+</xsl:text>
+ <xsl:for-each select="li">
+ <xsl:text> </xsl:text><xsl:apply-templates />
+ <xsl:text>
+</xsl:text>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="comment">
+ <xsl:text> </xsl:text><xsl:value-of select="."/>
+ </xsl:template>
+
+ <xsl:template name="cmd-summary" match="cmd-summary">
+ <xsl:text > Command summary
+</xsl:text>
+ <xsl:apply-templates select="cmd"/>
+ </xsl:template>
+
+ <xsl:template match="cmd">
+Command : <xsl:value-of select="@title"/><xsl:text >
+</xsl:text>Summary : <xsl:value-of select="summary"/><xsl:text>
+</xsl:text>
+ <xsl:if test="body">
+ <xsl:apply-templates select="body"/><xsl:text >
+</xsl:text>
+ </xsl:if>
+ <xsl:text>Usage:
+</xsl:text>
+ <xsl:apply-templates select="usage"/>
+ </xsl:template>
+
+
+</xsl:stylesheet>
+
+
+<!-- initialization code for xemacs -->
+<!--
+Local Variables:
+mode: xsl
+sgml-minimize-attributes:nil
+sgml-general-insert-case:lower
+sgml-indent-step:2
+sgml-indent-data:nil
+End:
+--> \ No newline at end of file
diff --git a/kdbg/threadlist.cpp b/kdbg/threadlist.cpp
new file mode 100644
index 0000000..7c60bc3
--- /dev/null
+++ b/kdbg/threadlist.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "threadlist.h"
+#include "dbgdriver.h"
+#include <klocale.h>
+#include <kiconloader.h>
+#include <qbitmap.h>
+#include <qpainter.h>
+
+
+class ThreadEntry : public QListViewItem, public ThreadInfo
+{
+public:
+ ThreadEntry(QListView* parent, const ThreadInfo& thread);
+ void setFunction(const QString& func);
+
+ bool m_delete; /* used for updating the list */
+};
+
+ThreadEntry::ThreadEntry(QListView* parent, const ThreadInfo& thread) :
+ QListViewItem(parent, thread.threadName, thread.function),
+ ThreadInfo(thread),
+ m_delete(false)
+{
+}
+
+void ThreadEntry::setFunction(const QString& func)
+{
+ function = func;
+ setText(1, function);
+}
+
+
+ThreadList::ThreadList(QWidget* parent, const char* name) :
+ QListView(parent, name)
+{
+ addColumn(i18n("Thread ID"), 150);
+ addColumn(i18n("Location"));
+
+ // load pixmaps
+ m_focusIcon = UserIcon("pcinner");
+ makeNoFocusIcon();
+
+ connect(this, SIGNAL(currentChanged(QListViewItem*)),
+ this, SLOT(slotCurrentChanged(QListViewItem*)));
+}
+
+ThreadList::~ThreadList()
+{
+}
+
+void ThreadList::updateThreads(const std::list<ThreadInfo>& threads)
+{
+ // reset flag in all items
+ for (QListViewItem* e = firstChild(); e != 0; e = e->nextSibling()) {
+ static_cast<ThreadEntry*>(e)->m_delete = true;
+ }
+
+ for (std::list<ThreadInfo>::const_iterator i = threads.begin(); i != threads.end(); ++i)
+ {
+ // look up this thread by id
+ ThreadEntry* te = threadById(i->id);
+ if (te == 0) {
+ te = new ThreadEntry(this, *i);
+ } else {
+ te->m_delete = false;
+ te->setFunction(i->function);
+ }
+ // set focus icon
+ te->hasFocus = i->hasFocus;
+ te->setPixmap(0, i->hasFocus ? m_focusIcon : m_noFocusIcon);
+ }
+
+ // delete all entries that have not been seen
+ for (QListViewItem* e = firstChild(); e != 0;) {
+ ThreadEntry* te = static_cast<ThreadEntry*>(e);
+ e = e->nextSibling(); /* step ahead before deleting it ;-) */
+ if (te->m_delete) {
+ delete te;
+ }
+ }
+}
+
+ThreadEntry* ThreadList::threadById(int id)
+{
+ for (QListViewItem* e = firstChild(); e != 0; e = e->nextSibling()) {
+ ThreadEntry* te = static_cast<ThreadEntry*>(e);
+ if (te->id == id) {
+ return te;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Creates an icon of the same size as the m_focusIcon, but which is
+ * totally transparent.
+ */
+void ThreadList::makeNoFocusIcon()
+{
+ m_noFocusIcon = m_focusIcon;
+ {
+ QPainter p(&m_noFocusIcon);
+ p.fillRect(0,0, m_noFocusIcon.width(),m_noFocusIcon.height(), QColor(white));
+ }
+ m_noFocusIcon.setMask(m_noFocusIcon.createHeuristicMask());
+}
+
+void ThreadList::slotCurrentChanged(QListViewItem* newItem)
+{
+ if (newItem == 0)
+ return;
+
+ ThreadEntry* te = static_cast<ThreadEntry*>(newItem);
+
+ // change the focused thread
+ if (te->hasFocus)
+ return;
+
+ emit setThread(te->id);
+}
+
+
+#include "threadlist.moc"
diff --git a/kdbg/threadlist.h b/kdbg/threadlist.h
new file mode 100644
index 0000000..e936d89
--- /dev/null
+++ b/kdbg/threadlist.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef THREADLIST_H
+#define THREADLIST_H
+
+#include <qlistview.h>
+#include <qpixmap.h>
+#include <list>
+
+class ThreadInfo;
+class ThreadEntry;
+
+class ThreadList : public QListView
+{
+ Q_OBJECT
+public:
+ ThreadList(QWidget* parent, const char* name);
+ ~ThreadList();
+
+public slots:
+ void updateThreads(const std::list<ThreadInfo>&);
+ void slotCurrentChanged(QListViewItem*);
+
+signals:
+ void setThread(int);
+
+protected:
+ ThreadEntry* threadById(int id);
+ void makeNoFocusIcon();
+
+ QPixmap m_focusIcon;
+ QPixmap m_noFocusIcon;
+};
+
+#endif // THREADLIST_H
diff --git a/kdbg/ttywnd.cpp b/kdbg/ttywnd.cpp
new file mode 100644
index 0000000..b23f2f4
--- /dev/null
+++ b/kdbg/ttywnd.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include <qsocketnotifier.h>
+#include <qpopupmenu.h>
+#include "ttywnd.h"
+#include <kglobalsettings.h>
+#include <klocale.h>
+
+#include "config.h"
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* open, close, etc. */
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_PTY_H
+#include <pty.h> /* openpty on Linux */
+#endif
+#ifdef HAVE_LIBUTIL_H
+#include <libutil.h> /* openpty on FreeBSD */
+#endif
+#ifdef HAVE_UTIL_H /* openpty on NetBSD, OpenBSD */
+#include <util.h>
+#endif
+#include <errno.h>
+
+#include "mydebug.h"
+
+
+STTY::STTY() :
+ QObject(),
+ m_masterfd(-1),
+ m_slavefd(-1),
+ m_outNotifier(0)
+{
+ if (findTTY())
+ {
+ ::fcntl(m_masterfd, F_SETFL, O_NDELAY);
+ m_outNotifier = new QSocketNotifier(m_masterfd, QSocketNotifier::Read);
+ connect(m_outNotifier, SIGNAL(activated(int)), SLOT(outReceived(int)));
+ } else {
+ m_slavetty = QString();
+ }
+}
+
+STTY::~STTY()
+{
+ if (m_outNotifier) {
+ ::close(m_masterfd);
+ if (m_slavefd >= 0)
+ ::close(m_slavefd);
+ delete m_outNotifier;
+ }
+}
+
+bool STTY::findTTY()
+{
+ m_masterfd = -1;
+
+#ifdef HAVE_FUNC_OPENPTY
+ /* use glibc2's openpty */
+ if (m_masterfd < 0)
+ {
+ if (::openpty(&m_masterfd, &m_slavefd, 0, 0, 0) == 0) {
+ const char* tname = ::ttyname(m_slavefd);
+ if (tname != 0) {
+ m_slavetty = tname;
+ } else {
+ ::close(m_slavefd);
+ ::close(m_masterfd);
+ m_masterfd = m_slavefd = -1;
+ }
+ }
+ }
+#endif
+
+ // resort to BSD-style terminals
+ if (m_masterfd < 0)
+ {
+ const char* s3;
+ const char* s4;
+
+ char ptynam[] = "/dev/ptyxx";
+ char ttynam[] = "/dev/ttyxx";
+ static const char ptyc3[] = "pqrstuvwxyzabcde";
+ static const char ptyc4[] = "0123456789abcdef";
+
+ // Find a master pty that we can open
+ for (s3 = ptyc3; *s3 != 0 && m_masterfd < 0; s3++)
+ {
+ for (s4 = ptyc4; *s4 != 0; s4++)
+ {
+ ptynam[8] = ttynam[8] = *s3;
+ ptynam[9] = ttynam[9] = *s4;
+ if ((m_masterfd = ::open(ptynam,O_RDWR)) >= 0)
+ {
+ if (::geteuid() == 0 || ::access(ttynam,R_OK|W_OK) == 0)
+ {
+ m_slavetty = ttynam;
+ break;
+ }
+ ::close(m_masterfd);
+ m_masterfd = -1;
+ }
+ }
+ }
+ }
+
+ return m_masterfd >= 0;
+}
+
+void STTY::outReceived(int f)
+{
+ for (;;) {
+ char buf[1024];
+ int n = ::read(f, buf, sizeof(buf));
+ if (n < 0) {
+ if (errno != EAGAIN) { /* this is not an error */
+ // ugh! error! somebody disconnect this signal please!
+ }
+ break;
+ }
+ emit output(buf, n);
+ if (n == 0)
+ break;
+ }
+}
+
+
+
+TTYWindow::TTYWindow(QWidget* parent, const char* name) :
+ QTextEdit(parent, name),
+ m_tty(0),
+ m_hPos(0)
+{
+ setFont(KGlobalSettings::fixedFont());
+ setReadOnly(true);
+ setAutoFormatting(AutoNone);
+ setTextFormat(PlainText);
+ setWordWrap(NoWrap);
+}
+
+TTYWindow::~TTYWindow()
+{
+ if (m_tty)
+ deactivate();
+}
+
+
+QString TTYWindow::activate()
+{
+ // allocate a pseudo terminal
+ m_tty = new STTY;
+
+ QString ttyName = m_tty->slaveTTY();
+ if (ttyName.isEmpty()) {
+ // failed to allocate terminal
+ delete m_tty;
+ m_tty = 0;
+ return QString();
+ } else {
+ connect(m_tty, SIGNAL(output(char*,int)), SLOT(slotAppend(char*,int)));
+ return ttyName;
+ }
+}
+
+void TTYWindow::deactivate()
+{
+ delete m_tty;
+ m_tty = 0;
+}
+
+/**
+ * Note that it is necessary to track the horizontal position explicitly
+ * since if the user modifies the selected text in the window, the cursor
+ * position changes, too.
+ */
+void TTYWindow::slotAppend(char* buffer, int count)
+{
+ // parse off lines
+ char* start = buffer;
+ while (count > 0) {
+ int len = 0;
+ while (count > 0 && start[len] != '\n' && start[len] != '\r') {
+ --count;
+ ++len;
+ }
+ if (len > 0) {
+ QString str = QString::fromLatin1(start, len);
+ // replace text in the last line
+ int para = paragraphs()-1;
+ // this selection is non-empty only after a '\r' that was not
+ // followed by a '\n'
+ setSelection(para, m_hPos, para, m_hPos+len, 1);
+ removeSelectedText(1);
+ insertAt(str, para, m_hPos);
+ m_hPos += len;
+ start += len;
+ len = 0;
+ }
+ if (count > 0 && *start == '\r') {
+ ++start;
+ --count;
+ m_hPos = 0;
+ }
+ if (count > 0 && *start == '\n') {
+ ++start;
+ --count;
+ append(QString());
+ m_hPos = 0;
+ }
+ }
+}
+
+QPopupMenu* TTYWindow::createPopupMenu(const QPoint& pos)
+{
+ QPopupMenu* menu = QTextEdit::createPopupMenu(pos);
+ menu->insertSeparator();
+ menu->insertItem(i18n("&Clear"), this, SLOT(slotClear()));
+ return menu;
+}
+
+void TTYWindow::slotClear()
+{
+ clear();
+ m_hPos = 0;
+}
+
+#include "ttywnd.moc"
diff --git a/kdbg/ttywnd.h b/kdbg/ttywnd.h
new file mode 100644
index 0000000..3995ffc
--- /dev/null
+++ b/kdbg/ttywnd.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef TTYWND_H
+#define TTYWND_H
+
+#include <qtextedit.h>
+
+class QSocketNotifier;
+class QPopupMenu;
+
+/**
+ * This class is cortesy Judin Max <novaprint@mtu-net.ru>.
+ *
+ * The master side of the TTY is the emulator.
+ *
+ * The slave side is where a client process can write output and can read
+ * input. For this purpose, it must open the file (terminal device) whose
+ * name is returned by @ref slaveTTY for both reading and writing. To
+ * establish the stdin, stdout, and stderr channels the file descriptor
+ * obtained by this must be dup'd to file descriptors 0, 1, and 2, resp.
+ */
+class STTY : public QObject
+{
+ Q_OBJECT
+public:
+ STTY();
+ ~STTY();
+
+ QString slaveTTY(){ return m_slavetty; };
+
+protected slots:
+ void outReceived(int);
+
+signals:
+ void output(char* buffer, int charlen);
+
+protected:
+ int m_masterfd;
+ int m_slavefd;
+ QSocketNotifier* m_outNotifier;
+ QString m_slavetty;
+ bool findTTY();
+};
+
+class TTYWindow : public QTextEdit
+{
+ Q_OBJECT
+public:
+ TTYWindow(QWidget* parent, const char* name);
+ ~TTYWindow();
+
+ QString activate();
+ void deactivate();
+
+protected:
+ STTY* m_tty;
+ virtual QPopupMenu* createPopupMenu(const QPoint& pos);
+ int m_hPos; //!< tracks horizontal cursor position
+
+protected slots:
+ void slotAppend(char* buffer, int count);
+ void slotClear();
+};
+
+#endif // TTYWND_H
diff --git a/kdbg/typetable.cpp b/kdbg/typetable.cpp
new file mode 100644
index 0000000..3136a61
--- /dev/null
+++ b/kdbg/typetable.cpp
@@ -0,0 +1,409 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include <qdir.h>
+#include <qptrlist.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <ksimpleconfig.h>
+#include <list>
+#include <algorithm>
+#include <iterator>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "typetable.h"
+#include "mydebug.h"
+
+//! the TypeTables of all known libraries
+static std::list<TypeTable> typeTables;
+bool typeTablesInited = false;
+
+
+//! an indentifier for wchar_t
+TypeInfo TypeInfo::m_wchartType("");
+//! the unknown type
+TypeInfo TypeInfo::m_unknownType("");
+
+
+void TypeTable::initTypeLibraries()
+{
+ if (!typeTablesInited) {
+ TypeTable::loadTypeTables();
+ }
+}
+
+void TypeTable::loadTypeTables()
+{
+ typeTablesInited = true;
+
+ const QStringList files = KGlobal::dirs()->findAllResources("types", "*.kdbgtt",
+ false, true);
+
+ if (files.isEmpty()) {
+ TRACE("no type tables found");
+ return;
+ }
+
+ for (QValueListConstIterator<QString> p = files.begin(); p != files.end(); ++p) {
+ typeTables.push_back(TypeTable());
+ typeTables.back().loadFromFile(*p);
+ }
+}
+
+
+TypeTable::TypeTable() :
+ m_printQStringDataCmd(0)
+{
+ m_typeDict.setAutoDelete(true);
+ // aliasDict keeps only pointers to items into typeDict
+ m_aliasDict.setAutoDelete(false);
+}
+
+TypeTable::~TypeTable()
+{
+ delete[] m_printQStringDataCmd;
+ while (!m_templates.empty()) {
+ delete m_templates.begin()->second;
+ m_templates.erase(m_templates.begin());
+ }
+}
+
+
+static const char TypeTableGroup[] = "Type Table";
+static const char LibDisplayName[] = "LibDisplayName";
+static const char ShlibRE[] = "ShlibRE";
+static const char EnableBuiltin[] = "EnableBuiltin";
+static const char PrintQStringCmd[] = "PrintQStringCmd";
+static const char TypesEntryFmt[] = "Types%d";
+static const char DisplayEntry[] = "Display";
+static const char AliasEntry[] = "Alias";
+static const char TemplateEntry[] = "Template";
+static const char ExprEntryFmt[] = "Expr%d";
+static const char FunctionGuardEntryFmt[] = "FunctionGuard%d";
+
+
+void TypeTable::loadFromFile(const QString& fileName)
+{
+ TRACE("reading file " + fileName);
+ KSimpleConfig cf(fileName, true); /* read-only */
+
+ /*
+ * Read library name and properties.
+ */
+ cf.setGroup(TypeTableGroup);
+ m_displayName = cf.readEntry(LibDisplayName);
+ if (m_displayName.isEmpty()) {
+ // use file name instead
+ QFileInfo fi(fileName);
+ m_displayName = fi.baseName(true);
+ }
+
+ m_shlibNameRE = QRegExp(cf.readEntry(ShlibRE));
+ m_enabledBuiltins = cf.readListEntry(EnableBuiltin);
+
+ QString printQString = cf.readEntry(PrintQStringCmd);
+ const char* ascii = printQString.ascii();
+ if (ascii == 0)
+ ascii = "";
+ m_printQStringDataCmd = new char[strlen(ascii)+1];
+ strcpy(m_printQStringDataCmd, ascii);
+
+ /*
+ * Get the types. We search for entries of kind Types1, Types2, etc.
+ * because a single entry Types could get rather long for large
+ * libraries.
+ */
+ QString typesEntry;
+ for (int i = 1; ; i++) {
+ // next bunch of types
+ cf.setGroup(TypeTableGroup);
+ typesEntry.sprintf(TypesEntryFmt, i);
+ if (!cf.hasKey(typesEntry))
+ break;
+
+ QStringList typeNames = cf.readListEntry(typesEntry, ',');
+
+ // now read them
+ QString alias;
+ for (QStringList::iterator it = typeNames.begin(); it != typeNames.end(); ++it)
+ {
+ cf.setGroup(*it);
+ // check if this is an alias
+ alias = cf.readEntry(AliasEntry);
+ if (alias.isEmpty()) {
+ readType(cf, *it);
+ } else {
+ // look up the alias type and insert it
+ TypeInfo* info = m_typeDict[alias];
+ if (info == 0) {
+ TRACE(*it + ": alias " + alias + " not found");
+ } else {
+ m_aliasDict.insert(alias, info);
+ TRACE(*it + ": alias " + alias);
+ }
+ }
+ }
+ } // for all Types%d
+}
+
+void TypeTable::readType(KConfigBase& cf, const QString& type)
+{
+ // the display string
+ QString expr = cf.readEntry(DisplayEntry);
+
+ TypeInfo* info = new TypeInfo(expr);
+ if (info->m_numExprs == 0) {
+ TRACE("bogus type " + type + ": no %% in Display: " + expr);
+ delete info;
+ return;
+ }
+
+ info->m_templatePattern = cf.readEntry(TemplateEntry);
+
+ // Expr1, Expr2, etc...
+ QString exprEntry;
+ QString funcGuardEntry;
+ for (int j = 0; j < info->m_numExprs; j++) {
+ exprEntry.sprintf(ExprEntryFmt, j+1);
+ expr = cf.readEntry(exprEntry);
+ info->m_exprStrings[j] = expr;
+
+ funcGuardEntry.sprintf(FunctionGuardEntryFmt, j+1);
+ expr = cf.readEntry(funcGuardEntry);
+ info->m_guardStrings[j] = expr;
+ }
+
+ // add the new type
+ if (info->m_templatePattern.find('<') < 0)
+ m_typeDict.insert(type, info);
+ else
+ m_templates[type] = info;
+ TRACE(type + QString().sprintf(": %d exprs", info->m_numExprs));
+}
+
+void TypeTable::copyTypes(QDict<TypeInfo>& dict)
+{
+ for (QDictIterator<TypeInfo> it = m_typeDict; it != 0; ++it) {
+ dict.insert(it.currentKey(), it);
+ }
+ for (QDictIterator<TypeInfo> it = m_aliasDict; it != 0; ++it) {
+ dict.insert(it.currentKey(), it);
+ }
+}
+
+bool TypeTable::isEnabledBuiltin(const QString& feature) const
+{
+ return m_enabledBuiltins.find(feature) != m_enabledBuiltins.end();
+}
+
+TypeInfo::TypeInfo(const QString& displayString)
+{
+ // decompose the input into the parts
+ int i = 0;
+ int startIdx = 0;
+ int idx;
+ while (i < typeInfoMaxExpr &&
+ (idx = displayString.find('%', startIdx)) >= 0)
+ {
+ m_displayString[i] = displayString.mid(startIdx, idx-startIdx);
+ startIdx = idx+1;
+ i++;
+ }
+ m_numExprs = i;
+ /*
+ * Remaining string; note that there's one more display string than
+ * sub-expressions.
+ */
+ m_displayString[i] = displayString.right(displayString.length()-startIdx);
+}
+
+TypeInfo::~TypeInfo()
+{
+}
+
+
+ProgramTypeTable::ProgramTypeTable() :
+ m_parseQt2QStrings(false),
+ m_QCharIsShort(false),
+ m_printQStringDataCmd(0)
+{
+ m_types.setAutoDelete(false); /* paranoia */
+ m_aliasDict.setAutoDelete(false); /* paranoia */
+}
+
+ProgramTypeTable::~ProgramTypeTable()
+{
+}
+
+void ProgramTypeTable::loadTypeTable(TypeTable* table)
+{
+ table->copyTypes(m_types);
+
+ // add templates
+ const TypeTable::TypeMap& t = table->templates();
+ std::transform(t.begin(), t.end(),
+ std::inserter(m_templates, m_templates.begin()),
+ std::ptr_fun(template2Info));
+
+ // check whether to enable builtin QString support
+ if (!m_parseQt2QStrings) {
+ m_parseQt2QStrings = table->isEnabledBuiltin("QString::Data");
+ }
+ if (!m_QCharIsShort) {
+ m_QCharIsShort = table->isEnabledBuiltin("QCharIsShort");
+ }
+ if (!m_printQStringDataCmd && *table->printQStringDataCmd()) {
+ m_printQStringDataCmd = table->printQStringDataCmd();
+ }
+}
+
+ProgramTypeTable::TemplateMap::value_type
+ ProgramTypeTable::template2Info(const TypeTable::TypeMap::value_type& tt)
+{
+ QStringList args = splitTemplateArgs(tt.second->m_templatePattern);
+
+ TemplateMap::value_type result(args.front(), TemplateInfo());
+ result.second.type = tt.second;
+ args.pop_front();
+ result.second.templateArgs = args;
+ return result;
+}
+
+/**
+ * Splits the name \a t into the template name and its arguments.
+ * The first entry of the returned list is the template name, the remaining
+ * entries are the arguments.
+ */
+QStringList ProgramTypeTable::splitTemplateArgs(const QString& t)
+{
+ QStringList result;
+ result.push_back(t);
+
+ int i = t.find('<');
+ if (i < 0)
+ return result;
+
+ // split off the template name
+ result.front().truncate(i);
+
+ i++; // skip '<'
+ // look for the next comma or the closing '>', skipping nested '<>'
+ int nest = 0;
+ int start = i;
+ for (; unsigned(i) < t.length() && nest >= 0; i++)
+ {
+ if (t[i] == '<')
+ nest++;
+ else if (t[i] == '>')
+ nest--;
+ else if (nest == 0 && t[i] == ',') {
+ // found end of argument
+ QString arg = t.mid(start, i-start);
+ result.push_back(arg);
+ start = i+1; // skip ','
+ }
+ }
+ // accept the template only if the closing '>' is the last character
+ if (nest < 0 && unsigned(i) == t.length()) {
+ QString arg = t.mid(start, i-start-1);
+ result.push_back(arg);
+ } else {
+ result.clear();
+ result.push_back(t);
+ }
+ return result;
+}
+
+TypeInfo* ProgramTypeTable::lookup(QString type)
+{
+ /*
+ * Registered aliases contain the complete template parameter list.
+ * Check for an alias first so that this case is out of the way.
+ */
+ if (TypeInfo* result = m_aliasDict[type])
+ return result;
+
+ /*
+ * Check for a normal type. Even if type is a template instance,
+ * it could have been registered as a normal type instead of a pattern.
+ */
+ if (TypeInfo* result = m_types[type])
+ return result;
+
+ /*
+ * The hard part: Look up a template.
+ */
+ QStringList parts = splitTemplateArgs(type);
+ if (parts.size() == 1)
+ return 0; // not a template
+
+ // We can have several patterns for the same template name.
+ std::pair<TemplateMap::const_iterator, TemplateMap::const_iterator> range =
+ m_templates.equal_range(parts.front());
+ // We pick the one that has the wildcards in the later parameters.
+ unsigned minPenalty = ~0U;
+ TypeInfo* result = 0;
+ parts.pop_front();
+
+ for (TemplateMap::const_iterator i = range.first; i != range.second; ++i)
+ {
+ const QStringList& pat = i->second.templateArgs;
+ if (parts.size() < pat.size())
+ continue; // too few arguments
+
+ // a "*" in the last position of the pattern matches all arguments
+ // at the end of the template's arguments
+ if (parts.size() > pat.size() && pat.back() != "*")
+ continue; // too many arguments and no wildcard
+
+ QStringList::const_iterator t = parts.begin();
+ QStringList::const_iterator p = pat.begin();
+ unsigned accumPenalty = 0;
+ bool equal = true;
+ unsigned penalty = ~(~0U>>1); // 1 in the leading bit
+ while (equal && p != pat.end())
+ {
+ if (*p == "*")
+ accumPenalty |= penalty; // penalize wildcards
+ else
+ equal = *p == *t;
+ ++p, ++t, penalty >>= 1;
+ }
+ if (equal)
+ {
+ if (accumPenalty == 0)
+ return i->second.type;
+ if (accumPenalty < minPenalty) {
+ result = i->second.type;
+ minPenalty = accumPenalty;
+ }
+ }
+ }
+ return result;
+}
+
+void ProgramTypeTable::registerAlias(const QString& name, TypeInfo* type)
+{
+ ASSERT(lookup(name) == 0 || lookup(name) == type);
+ m_aliasDict.insert(name, type);
+}
+
+void ProgramTypeTable::loadLibTypes(const QStringList& libs)
+{
+ for (QStringList::const_iterator it = libs.begin(); it != libs.end(); ++it)
+ {
+ // look up the library
+ for (std::list<TypeTable>::iterator t = typeTables.begin(); t != typeTables.end(); ++t)
+ {
+ if (t->matchFileName(*it))
+ {
+ TRACE("adding types for " + *it);
+ loadTypeTable(&*t);
+ }
+ }
+ }
+}
diff --git a/kdbg/typetable.h b/kdbg/typetable.h
new file mode 100644
index 0000000..5cef561
--- /dev/null
+++ b/kdbg/typetable.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include <qdict.h>
+#include <qstring.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+#include <map>
+
+class KConfigBase;
+
+/**
+ * The maximum number of sub-expressions that may appear in a single struct
+ * value.
+ */
+const int typeInfoMaxExpr = 5;
+
+
+struct TypeInfo
+{
+ TypeInfo(const QString& displayString);
+ ~TypeInfo();
+
+ /**
+ * The number of sub-expressions that need to be evaluated to get the
+ * struct value.
+ */
+ int m_numExprs;
+ /**
+ * This array contains the various parts which glue together the
+ * sub-expressions. The entries in this array are the parts that appear
+ * between the percent signs '%' of the display expression; hence,
+ * there is one part more than there are sub-expressions.
+ */
+ QString m_displayString[typeInfoMaxExpr+1];
+ /**
+ * This is a list of partial expressions. Each contains one or more \%s,
+ * which will be replaced by the parent expression. The results are
+ * substituted for the percent signs in m_displayString.
+ */
+ QString m_exprStrings[typeInfoMaxExpr];
+ /**
+ * This is a list of guard expressions. Each contains one or more \%s,
+ * which will be replaced by the parent expression, or is empty. If the
+ * evaluation of the resulting expression returns an error, the
+ * corresponding expression from m_exprStrings is not evaluated. (This
+ * is used to guard function calls.)
+ */
+ QString m_guardStrings[typeInfoMaxExpr];
+ /**
+ * This is the type name including template arguments that contain a
+ * pattern: A single '*' as template parameter matches one template
+ * argument, except that a '*' as the last template parameter matches
+ * all remaining template argument.
+ */
+ QString m_templatePattern;
+ /**
+ * Returns a pointer to a TypeInfo that identifies wchar_t
+ */
+ static TypeInfo* wchartType() { return &m_wchartType; }
+ /**
+ * Gets a pointer to a TypeInfo that means: "I don't know the type"
+ */
+ static TypeInfo* unknownType() { return &m_unknownType; }
+
+protected:
+ static TypeInfo m_wchartType;
+ static TypeInfo m_unknownType;
+};
+
+class TypeTable
+{
+public:
+ TypeTable();
+ ~TypeTable();
+
+ typedef std::map<QString,TypeInfo*> TypeMap;
+
+ /**
+ * Load all known type libraries.
+ */
+ static void initTypeLibraries();
+
+ /**
+ * Copy type infos to the specified dictionary.
+ */
+ void copyTypes(QDict<TypeInfo>& dict);
+
+ /**
+ * Returns the template types
+ */
+ const TypeMap& templates() const { return m_templates; }
+
+ /**
+ * Does the file name match this library?
+ */
+ bool matchFileName(const QString& fileName) const {
+ return m_shlibNameRE.match(fileName) >= 0;
+ }
+
+ /**
+ * Is the specified builtin feature enabled in this type library?
+ */
+ bool isEnabledBuiltin(const QString& feature) const;
+
+ /**
+ * Returns the command to print the QString data.
+ */
+ const char* printQStringDataCmd() const { return m_printQStringDataCmd; }
+
+protected:
+ /**
+ * Loads the structure type information from the configuration files.
+ */
+ static void loadTypeTables();
+ void loadFromFile(const QString& fileName);
+ void readType(KConfigBase& cf, const QString& type);
+ QDict<TypeInfo> m_typeDict;
+ QDict<TypeInfo> m_aliasDict;
+ TypeMap m_templates;
+ QString m_displayName;
+ QRegExp m_shlibNameRE;
+ QStringList m_enabledBuiltins;
+ char* m_printQStringDataCmd;
+};
+
+
+/**
+ * This table keeps only references to the global type table. It is set up
+ * once per program.
+ */
+class ProgramTypeTable
+{
+public:
+ ProgramTypeTable();
+ ~ProgramTypeTable();
+
+ /**
+ * Load types belonging to the specified libraries.
+ */
+ void loadLibTypes(const QStringList& libs);
+
+ /**
+ * Load types belonging to the specified type table
+ */
+ void loadTypeTable(TypeTable* table);
+
+ /**
+ * Lookup a structure type.
+ *
+ * If the type is unknown, 0 is returned.
+ */
+ TypeInfo* lookup(QString type);
+
+ /**
+ * Adds a new alias for a type name.
+ */
+ void registerAlias(const QString& name, TypeInfo* type);
+
+ /**
+ * Tells whether we use built-in support to understand QStrings.
+ */
+ bool parseQt2QStrings() const { return m_parseQt2QStrings; }
+
+ /**
+ * Tells whether QChar are defined like in Qt3.
+ */
+ bool qCharIsShort() const { return m_QCharIsShort; }
+
+ /**
+ * Returns the command to print the QString data.
+ */
+ const char* printQStringDataCmd() const { return m_printQStringDataCmd; }
+
+protected:
+ QDict<TypeInfo> m_types;
+ QDict<TypeInfo> m_aliasDict;
+ struct TemplateInfo {
+ QStringList templateArgs;
+ TypeInfo* type;
+ };
+ typedef std::multimap<QString, TemplateInfo> TemplateMap;
+ TemplateMap m_templates; //!< one or more template patterns per template name
+ static TemplateMap::value_type
+ template2Info(const TypeTable::TypeMap::value_type& tt);
+ static QStringList splitTemplateArgs(const QString& t);
+ bool m_parseQt2QStrings;
+ bool m_QCharIsShort;
+ const char* m_printQStringDataCmd;
+};
diff --git a/kdbg/typetables/Makefile.am b/kdbg/typetables/Makefile.am
new file mode 100644
index 0000000..4b8c958
--- /dev/null
+++ b/kdbg/typetables/Makefile.am
@@ -0,0 +1,16 @@
+# types in libraries that we understand
+typesdir = $(kde_datadir)/kdbg/types
+types_DATA = \
+ qt.kdbgtt \
+ qt2.kdbgtt \
+ qt3.kdbgtt \
+ qt4core.kdbgtt \
+ kdecore.kdbgtt \
+ kdecore3.kdbgtt \
+ glib.kdbgtt \
+ gtk+.kdbgtt \
+ stdc++.kdbgtt \
+ stdc++6.kdbgtt \
+ X11.kdbgtt
+
+EXTRA_DIST = $(types_DATA)
diff --git a/kdbg/typetables/Makefile.in b/kdbg/typetables/Makefile.in
new file mode 100644
index 0000000..5686895
--- /dev/null
+++ b/kdbg/typetables/Makefile.in
@@ -0,0 +1,600 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 483858 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = kdbg/typetables
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(typesdir)"
+typesDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(types_DATA)
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+ARTSCCONFIG = @ARTSCCONFIG@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOPIDLNG = @DCOPIDLNG@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
+KCONFIG_COMPILER = @KCONFIG_COMPILER@
+KDECONFIG = @KDECONFIG@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
+KDE_MT_LIBS = @KDE_MT_LIBS@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_FPIE = @KDE_USE_FPIE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+KDE_USE_PIE = @KDE_USE_PIE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPTHREAD = @LIBPTHREAD@
+LIBRESOLV = @LIBRESOLV@
+LIBS = @LIBS@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBZ = @LIBZ@
+LIB_KAB = @LIB_KAB@
+LIB_KABC = @LIB_KABC@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDED = @LIB_KDED@
+LIB_KDEPIM = @LIB_KDEPIM@
+LIB_KDEPRINT = @LIB_KDEPRINT@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KDNSSD = @LIB_KDNSSD@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMPROXY = @LIB_KIMPROXY@
+LIB_KIO = @LIB_KIO@
+LIB_KJS = @LIB_KJS@
+LIB_KNEWSTUFF = @LIB_KNEWSTUFF@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KUNITTEST = @LIB_KUNITTEST@
+LIB_KUTILS = @LIB_KUTILS@
+LIB_POLL = @LIB_POLL@
+LIB_QPE = @LIB_QPE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_X11 = @LIB_X11@
+LIB_XEXT = @LIB_XEXT@
+LIB_XRENDER = @LIB_XRENDER@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKEKDEWIDGETS = @MAKEKDEWIDGETS@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MKDIR_P = @MKDIR_P@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PS_COMMAND = @PS_COMMAND@
+QTE_NORTTI = @QTE_NORTTI@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+UIC_TR = @UIC_TR@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+XGETTEXT = @XGETTEXT@
+XMKMF = @XMKMF@
+XMLLINT = @XMLLINT@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+X_RPATH = @X_RPATH@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_kcfgdir = @kde_kcfgdir@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_qtver = @kde_qtver@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_styledir = @kde_styledir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+kde_widgetdir = @kde_widgetdir@
+kdeinitdir = @kdeinitdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+xdg_appsdir = @xdg_appsdir@
+xdg_directorydir = @xdg_directorydir@
+xdg_menudir = @xdg_menudir@
+
+# types in libraries that we understand
+typesdir = $(kde_datadir)/kdbg/types
+types_DATA = \
+ qt.kdbgtt \
+ qt2.kdbgtt \
+ qt3.kdbgtt \
+ qt4core.kdbgtt \
+ kdecore.kdbgtt \
+ kdecore3.kdbgtt \
+ glib.kdbgtt \
+ gtk+.kdbgtt \
+ stdc++.kdbgtt \
+ stdc++6.kdbgtt \
+ X11.kdbgtt
+
+EXTRA_DIST = $(types_DATA)
+#>- all: all-am
+#>+ 1
+all: docs-am all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/typetables/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu kdbg/typetables/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/typetables/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/typetables/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/typetables/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-typesDATA: $(types_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(typesdir)" || $(MKDIR_P) "$(DESTDIR)$(typesdir)"
+ @list='$(types_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(typesDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(typesdir)/$$f'"; \
+ $(typesDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(typesdir)/$$f"; \
+ done
+
+uninstall-typesDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(types_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(typesdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(typesdir)/$$f"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(typesdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-am
+#>+ 1
+clean: kde-rpo-clean clean-am
+
+#>- clean-am: clean-generic clean-libtool mostlyclean-am
+#>+ 1
+clean-am: clean-bcheck clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-typesDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-typesDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ install-typesDATA installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-am uninstall-typesDATA
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+
+#>+ 2
+KDE_DIST=stdc++6.kdbgtt qt.kdbgtt gtk+.kdbgtt kdecore3.kdbgtt stdc++.kdbgtt qt4core.kdbgtt glib.kdbgtt X11.kdbgtt qt3.kdbgtt qt2.kdbgtt kdecore.kdbgtt Makefile.in Makefile.am
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kdbg/typetables/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu kdbg/typetables/Makefile
+ cd $(top_srcdir) && perl admin/am_edit -padmin kdbg/typetables/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-am
+
+bcheck-am:
+ @for i in ; do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXX) $(DEFS) -I. -I$(srcdir) -I$(top_builddir) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 3
+final:
+ $(MAKE) all-am
+
+#>+ 3
+final-install:
+ $(MAKE) install-am
+
+#>+ 3
+no-final:
+ $(MAKE) all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/kdbg/typetables/X11.kdbgtt b/kdbg/typetables/X11.kdbgtt
new file mode 100644
index 0000000..19947f8
--- /dev/null
+++ b/kdbg/typetables/X11.kdbgtt
@@ -0,0 +1,9 @@
+[Type Table]
+Types1=_XDisplay,Display
+LibDisplayName=libX11 (all versions)
+ShlibRE=libX11\.so
+[_XDisplay]
+Display={ name=% }
+Expr1=(%1).display_name
+[Display]
+Alias=_XDisplay
diff --git a/kdbg/typetables/glib.kdbgtt b/kdbg/typetables/glib.kdbgtt
new file mode 100644
index 0000000..7927467
--- /dev/null
+++ b/kdbg/typetables/glib.kdbgtt
@@ -0,0 +1,7 @@
+[Type Table]
+Types1=GString
+LibDisplayName=libglib
+ShlibRE=libglib.*\.so\.[0-9]+$
+[GString]
+Display={ % }
+Expr1=(%s).str
diff --git a/kdbg/typetables/gtk+.kdbgtt b/kdbg/typetables/gtk+.kdbgtt
new file mode 100644
index 0000000..7cc34e0
--- /dev/null
+++ b/kdbg/typetables/gtk+.kdbgtt
@@ -0,0 +1,7 @@
+[Type Table]
+Types1=GtkWidget
+LibDisplayName=libgtk+
+ShlibRE=libgtk.*\.so\.[0-9]+$
+[GtkWidget]
+Display={ name=% }
+Expr1=(%s).name
diff --git a/kdbg/typetables/kdecore.kdbgtt b/kdbg/typetables/kdecore.kdbgtt
new file mode 100644
index 0000000..d68226d
--- /dev/null
+++ b/kdbg/typetables/kdecore.kdbgtt
@@ -0,0 +1,7 @@
+[Type Table]
+Types1=KSimpleConfig
+LibDisplayName=kdecore (KDE 1.0 and 1.1)
+ShlibRE=libkdecore\.so\.[12]$
+[KSimpleConfig]
+Display={ global=% }
+Expr1=(%s).pData->aGlobalAppFile.shd->data
diff --git a/kdbg/typetables/kdecore3.kdbgtt b/kdbg/typetables/kdecore3.kdbgtt
new file mode 100644
index 0000000..dc16bf0
--- /dev/null
+++ b/kdbg/typetables/kdecore3.kdbgtt
@@ -0,0 +1,7 @@
+[Type Table]
+Types1=KSimpleConfig
+LibDisplayName=kdecore (KDE post-1.1)
+ShlibRE=libkdecore\.so\.3$
+[KSimpleConfig]
+Display={ global=% }
+Expr1=(*(%s).pData->aGlobalAppFile.shd->data)
diff --git a/kdbg/typetables/qt.kdbgtt b/kdbg/typetables/qt.kdbgtt
new file mode 100644
index 0000000..b6db99c
--- /dev/null
+++ b/kdbg/typetables/qt.kdbgtt
@@ -0,0 +1,23 @@
+[Type Table]
+Types1=QString,QDir,QFileInfo,QFile
+Types2=QObject,QTableView
+LibDisplayName=libqt 1.x
+ShlibRE=libqt\.so\.1$
+[QString]
+Display={ % }
+Expr1=(%s).shd->data
+[QObject]
+Display={ name=% }
+Expr1=(%s).objname
+[QTableView]
+Alias=QObject
+[QDir]
+Display={ path=% filter=% }
+Expr1=((%s).dPath.shd->data)
+Expr2=((%s).nameFilt.shd->data)
+[QFileInfo]
+Display={ name=% }
+Expr1=((%s).fn.shd->data)
+[QFile]
+Display={ name=% }
+Expr1=((%s).fn.shd->data)
diff --git a/kdbg/typetables/qt2.kdbgtt b/kdbg/typetables/qt2.kdbgtt
new file mode 100644
index 0000000..a7a5d65
--- /dev/null
+++ b/kdbg/typetables/qt2.kdbgtt
@@ -0,0 +1,28 @@
+[Type Table]
+Types1=QString,QCString,QDir,QFileInfo,QFile
+Types2=QObject,QTableView
+LibDisplayName=libqt 2.x
+ShlibRE=libqt\.so\.2$
+EnableBuiltin=QString::Data
+PrintQStringCmd=print ($qstrunicode=($qstrdata=(%s))->unicode)?(*(unsigned short*)$qstrunicode)@(($qstrlen=(unsigned int)($qstrdata->len))>100?100:$qstrlen):1==0\n
+[QString]
+Display={ % }
+Expr1=/QString::Data (%s).d
+[QCString]
+Display={ % }
+Expr1=(%s).shd->data
+[QObject]
+Display={ name=% }
+Expr1=(%s).objname
+[QTableView]
+Alias=QObject
+[QDir]
+Display={ path=% filter=% }
+Expr1=/QString::Data (%s).dPath.d
+Expr2=/QString::Data (%s).nameFilt.d
+[QFileInfo]
+Display={ name=% }
+Expr1=/QString::Data (%s).fn.d
+[QFile]
+Display={ name=% }
+Expr1=/QString::Data (%s).fn.d
diff --git a/kdbg/typetables/qt3.kdbgtt b/kdbg/typetables/qt3.kdbgtt
new file mode 100644
index 0000000..f568fb3
--- /dev/null
+++ b/kdbg/typetables/qt3.kdbgtt
@@ -0,0 +1,65 @@
+[Type Table]
+Types1=QString,QCString,QDir,QFileInfo,QFile
+Types2=QObject
+Types3=QMap,QValueList,QValueVector
+Types4=QPoint,QRect
+LibDisplayName=libqt 3.x
+ShlibRE=libqt-mt\.so\.3$
+EnableBuiltin=QString::Data,QCharIsShort
+PrintQStringCmd=print ($qstrunicode=($qstrdata=(%s))->unicode)?(*(unsigned short*)$qstrunicode)@(($qstrlen=(unsigned int)($qstrdata->len))>100?100:$qstrlen):1==0\n
+
+[QString]
+Display={ % }
+Expr1=/QString::Data (%s).d
+
+[QCString]
+Display={ % }
+Expr1=(%s).shd->data
+
+[QObject]
+Display={ name=% }
+Expr1=(%s).objname
+
+[QDir]
+Display={ path=% filter=% }
+Expr1=/QString::Data (%s).dPath.d
+Expr2=/QString::Data (%s).nameFilt.d
+
+[QFileInfo]
+Display={ name=% }
+Expr1=/QString::Data (%s).fn.d
+
+[QFile]
+Display={ name=% }
+Expr1=/QString::Data (%s).fn.d
+
+[QMap]
+Template=QMap<*>
+Display={ size=% shared=% }
+Expr1=(%s).sh->node_count
+Expr2=(%s).sh->count
+
+[QValueList]
+Template=QValueList<*>
+Display={ size=% shared=% }
+Expr1=*((unsigned int*)((%s).sh)+1+sizeof(char*)/sizeof(int))
+Expr2=((QShared*)((%s).sh))->count
+
+[QValueVector]
+Template=QValueVector<*>
+Display={ size=% shared=% capacity=% }
+Expr1=($tmp=(%s).sh)->finish-$tmp->start
+Expr2=(%s).sh->count
+Expr3=($tmp=(%s).sh)->end-$tmp->start
+
+[QPoint]
+Display={ %,% }
+Expr1=(%s).xp
+Expr2=(%s).yp
+
+[QRect]
+Display={ tl=(%,%) br=(%,%) }
+Expr1=(%s).x1
+Expr2=(%s).y1
+Expr3=(%s).x2
+Expr4=(%s).y2
diff --git a/kdbg/typetables/qt4core.kdbgtt b/kdbg/typetables/qt4core.kdbgtt
new file mode 100644
index 0000000..f144f6e
--- /dev/null
+++ b/kdbg/typetables/qt4core.kdbgtt
@@ -0,0 +1,9 @@
+[Type Table]
+Types1=QString
+LibDisplayName=libQtCore 4.x
+ShlibRE=libQtCore(_debug)?\.so\.4$
+EnableBuiltin=QString::Data,QCharIsShort
+PrintQStringCmd=print ($qstrunicode=($qstrdata=(%s))->data)?(*(unsigned short*)$qstrunicode)@(($qstrlen=(unsigned int)($qstrdata->size))>100?100:$qstrlen):1==0\n
+[QString]
+Display={ % }
+Expr1=/QString::Data (%s).d
diff --git a/kdbg/typetables/stdc++.kdbgtt b/kdbg/typetables/stdc++.kdbgtt
new file mode 100644
index 0000000..089ff77
--- /dev/null
+++ b/kdbg/typetables/stdc++.kdbgtt
@@ -0,0 +1,7 @@
+[Type Table]
+Types1=string
+LibDisplayName=libstdc++
+ShlibRE=libstdc\+\+-libc6\..*\.so\.[0-9]+$
+[string]
+Display={ % }
+Expr1=(%s).dat
diff --git a/kdbg/typetables/stdc++6.kdbgtt b/kdbg/typetables/stdc++6.kdbgtt
new file mode 100644
index 0000000..2792a33
--- /dev/null
+++ b/kdbg/typetables/stdc++6.kdbgtt
@@ -0,0 +1,45 @@
+[Type Table]
+Types1=string,basic_string<char>,ostringstream,basic_ostringstream<char>
+Types2=std::vector,std::vector<bool>,std::list,std::map
+LibDisplayName=libstdc++6
+ShlibRE=libstdc\+\+\.so\.6$
+
+[string]
+Display={ % }
+Expr1=(%s)._M_dataplus._M_p
+
+[basic_string<char>]
+Template=std::basic_string<char,*>
+Display={ % }
+Expr1=(%s)._M_dataplus._M_p
+
+[ostringstream]
+Display={ % }
+Expr1=(%s)._M_stringbuf._M_string._M_dataplus._M_p
+
+[basic_ostringstream<char>]
+Template=std::basic_ostringstream<char,*>
+Display={ % }
+Expr1=(%s)._M_stringbuf._M_string._M_dataplus._M_p
+
+[std::vector]
+Template=std::vector<*>
+Display={ size=% capcity=% }
+Expr1=($vec=(%s)._M_impl)._M_finish-$vec._M_start
+Expr2=($vec=(%s)._M_impl)._M_end_of_storage-$vec._M_start
+
+[std::vector<bool>]
+Template=std::vector<bool,*>
+Display={ size=% capcity=% }
+Expr1=(($vec=(%s)._M_impl)._M_finish._M_p-$vec._M_start._M_p)*sizeof(*$vec._M_end_of_storage)*8+$vec._M_finish._M_offset
+Expr2=(($vec=(%s)._M_impl)._M_end_of_storage-$vec._M_start._M_p)*sizeof(*$vec._M_end_of_storage)*8
+
+[std::list]
+Template=std::list<*>
+Display={ size=% }
+Expr1=(%s).size()
+
+[std::map]
+Template=std::map<*>
+Display={ size=% }
+Expr1=(%s)._M_t._M_impl._M_node_count
diff --git a/kdbg/winstack.cpp b/kdbg/winstack.cpp
new file mode 100644
index 0000000..dde80e9
--- /dev/null
+++ b/kdbg/winstack.cpp
@@ -0,0 +1,449 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "winstack.h"
+#include "sourcewnd.h"
+#include <qbrush.h>
+#include <qfileinfo.h>
+#include <qpopupmenu.h>
+#include <kapplication.h>
+#include <kmainwindow.h>
+#include <klocale.h> /* i18n */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "mydebug.h"
+
+
+
+WinStack::WinStack(QWidget* parent, const char* name) :
+ KTabWidget(parent, name),
+ m_pcLine(-1),
+ m_valueTip(this),
+ m_tipLocation(1,1,10,10),
+ m_tabWidth(0)
+{
+ connect(&m_findDlg.m_buttonForward,
+ SIGNAL(clicked()), SLOT(slotFindForward()));
+ connect(&m_findDlg.m_buttonBackward,
+ SIGNAL(clicked()), SLOT(slotFindBackward()));
+
+ connect(this, SIGNAL(setTabWidth(int)), this, SLOT(slotSetTabWidth(int)));
+}
+
+WinStack::~WinStack()
+{
+}
+
+void WinStack::contextMenuEvent(QContextMenuEvent* e)
+{
+ // get the context menu from the GUI factory
+ QWidget* top = this;
+ do
+ top = top->parentWidget();
+ while (!top->isTopLevel());
+ KMainWindow* mw = static_cast<KMainWindow*>(top);
+ QPopupMenu* m =
+ static_cast<QPopupMenu*>(mw->factory()->container("popup_files_empty", mw));
+ m->exec(e->globalPos());
+}
+
+
+void WinStack::reloadAllFiles()
+{
+ for (int i = count()-1; i >= 0; i--) {
+ windowAt(i)->reloadFile();
+ }
+}
+
+QSize WinStack::sizeHint() const
+{
+ return QSize(640, 480);
+}
+
+void WinStack::activate(const QString& fileName, int lineNo, const DbgAddr& address)
+{
+ QFileInfo fi(fileName);
+
+ if (!fi.isFile()) {
+ /*
+ * We didn't find that file. Now check if it is a relative path and
+ * try m_lastOpenDir as prefix.
+ */
+ TRACE(fi.filePath() + (" not found, looking in " + m_lastOpenDir));
+ if (!fi.isRelative() || m_lastOpenDir.isEmpty()) {
+ return;
+ }
+ fi.setFile(m_lastOpenDir + "/" + fi.filePath());
+ if (!fi.isFile()) {
+ return;
+ }
+ }
+ // if this is not an absolute path name, make it one
+ activatePath(fi.absFilePath(), lineNo, address);
+}
+
+void WinStack::activateFile(const QString& fileName)
+{
+ activatePath(fileName, 0, DbgAddr());
+}
+
+bool WinStack::activatePath(QString pathName, int lineNo, const DbgAddr& address)
+{
+ // check whether the file is already open
+ SourceWindow* fw = 0;
+ for (int i = count()-1; i >= 0; i--) {
+ if (windowAt(i)->fileName() == pathName) {
+ fw = windowAt(i);
+ break;
+ }
+ }
+ if (fw == 0) {
+ // not found, load it
+ fw = new SourceWindow(pathName, this, "fileWindow");
+
+ // slurp the file in
+ if (!fw->loadFile()) {
+ // read failed
+ delete fw;
+ return false;
+ }
+
+ addTab(fw, QFileInfo(pathName).fileName());
+ setTabToolTip(fw, pathName);
+
+ connect(fw, SIGNAL(clickedLeft(const QString&,int,const DbgAddr&,bool)),
+ SIGNAL(toggleBreak(const QString&,int,const DbgAddr&,bool)));
+ connect(fw, SIGNAL(clickedMid(const QString&,int,const DbgAddr&)),
+ SIGNAL(enadisBreak(const QString&,int,const DbgAddr&)));
+
+ // disassemble code
+ connect(fw, SIGNAL(disassemble(const QString&, int)),
+ SIGNAL(disassemble(const QString&, int)));
+ connect(fw, SIGNAL(expanded(int)), SLOT(slotExpandCollapse(int)));
+ connect(fw, SIGNAL(collapsed(int)), SLOT(slotExpandCollapse(int)));
+
+ // tab width
+ connect(this, SIGNAL(setTabWidth(int)), fw, SLOT(setTabWidth(int)));
+ fw->setTabWidth(m_tabWidth);
+ fw->setFocusPolicy(QWidget::WheelFocus);
+
+ // set PC if there is one
+ emit newFileLoaded();
+ if (m_pcLine >= 0) {
+ setPC(true, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
+ }
+ }
+ return activateWindow(fw, lineNo, address);
+}
+
+bool WinStack::activateWindow(SourceWindow* fw, int lineNo, const DbgAddr& address)
+{
+ // make the line visible
+ if (lineNo >= 0) {
+ fw->scrollTo(lineNo, address);
+ }
+
+ showPage(fw);
+ fw->setFocus();
+
+ return true;
+}
+
+bool WinStack::activeLine(QString& fileName, int& lineNo)
+{
+ DbgAddr dummy;
+ return activeLine(fileName, lineNo, dummy);
+}
+
+bool WinStack::activeLine(QString& fileName, int& lineNo, DbgAddr& address)
+{
+ if (activeWindow() == 0) {
+ return false;
+ }
+
+ fileName = activeFileName();
+ activeWindow()->activeLine(lineNo, address);
+ return true;
+}
+
+void WinStack::updateLineItems(const KDebugger* dbg)
+{
+ for (int i = count()-1; i >= 0; i--) {
+ windowAt(i)->updateLineItems(dbg);
+ }
+}
+
+void WinStack::updatePC(const QString& fileName, int lineNo, const DbgAddr& address, int frameNo)
+{
+ if (m_pcLine >= 0) {
+ setPC(false, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
+ }
+ m_pcFile = fileName;
+ m_pcLine = lineNo;
+ m_pcAddress = address.asString();
+ m_pcFrame = frameNo;
+ if (lineNo >= 0) {
+ setPC(true, fileName, lineNo, address, frameNo);
+ }
+}
+
+SourceWindow* WinStack::findByFileName(const QString& fileName) const
+{
+ for (int i = count()-1; i >= 0; i--) {
+ if (windowAt(i)->fileNameMatches(fileName)) {
+ return windowAt(i);
+ }
+ }
+ return 0;
+}
+
+void WinStack::setPC(bool set, const QString& fileName, int lineNo,
+ const DbgAddr& address, int frameNo)
+{
+ TRACE((set ? "set PC: " : "clear PC: ") + fileName +
+ QString().sprintf(":%d#%d ", lineNo, frameNo) + address.asString());
+ SourceWindow* fw = findByFileName(fileName);
+ if (fw)
+ fw->setPC(set, lineNo, address, frameNo);
+}
+
+SourceWindow* WinStack::windowAt(int i) const
+{
+ return static_cast<SourceWindow*>(page(i));
+}
+
+SourceWindow* WinStack::activeWindow() const
+{
+ return static_cast<SourceWindow*>(currentPage());
+}
+
+QString WinStack::activeFileName() const
+{
+ QString f;
+ if (activeWindow() != 0)
+ f = activeWindow()->fileName();
+ return f;
+}
+
+void WinStack::slotFindForward()
+{
+ if (activeWindow() != 0)
+ activeWindow()->find(m_findDlg.searchText(), m_findDlg.caseSensitive(),
+ SourceWindow::findForward);
+}
+
+void WinStack::slotFindBackward()
+{
+ if (activeWindow() != 0)
+ activeWindow()->find(m_findDlg.searchText(), m_findDlg.caseSensitive(),
+ SourceWindow::findBackward);
+}
+
+void WinStack::maybeTip(const QPoint& p)
+{
+ SourceWindow* w = activeWindow();
+ if (w == 0)
+ return;
+
+ // get the word at the point
+ QString word;
+ QRect r;
+ if (!w->wordAtPoint(w->mapFrom(this, p), word, r))
+ return;
+
+ // must be valid
+ assert(!word.isEmpty());
+ assert(r.isValid());
+
+ // remember the location
+ m_tipLocation = QRect(w->mapTo(this, r.topLeft()), r.size());
+
+ emit initiateValuePopup(word);
+}
+
+void WinStack::slotShowValueTip(const QString& tipText)
+{
+ m_valueTip.tip(m_tipLocation, tipText);
+}
+
+void WinStack::slotDisassembled(const QString& fileName, int lineNo,
+ const std::list<DisassembledCode>& disass)
+{
+ SourceWindow* fw = findByFileName(fileName);
+ if (fw == 0) {
+ // not found: ignore
+ return;
+ }
+
+ fw->disassembled(lineNo, disass);
+}
+
+void WinStack::slotExpandCollapse(int)
+{
+ // update line items after expanding or collapsing disassembled code
+
+ // HACK: we know that this will result in updateLineItems
+ // should be done more cleanly with a separate signal
+ emit newFileLoaded();
+
+ if (m_pcLine >= 0) {
+ setPC(true, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
+ }
+}
+
+
+void WinStack::slotSetTabWidth(int numChars)
+{
+ m_tabWidth = numChars;
+}
+
+void WinStack::slotFileReload()
+{
+ if (activeWindow() != 0) {
+ TRACE("reloading one file");
+ activeWindow()->reloadFile();
+ }
+}
+
+void WinStack::slotViewFind()
+{
+ if (m_findDlg.isVisible()) {
+ m_findDlg.done(0);
+ } else {
+ m_findDlg.show();
+ }
+}
+
+void WinStack::slotBrkptSet()
+{
+ QString file;
+ int lineNo;
+ DbgAddr address;
+ if (activeLine(file, lineNo, address))
+ emit toggleBreak(file, lineNo, address, false);
+}
+
+void WinStack::slotBrkptSetTemp()
+{
+ QString file;
+ int lineNo;
+ DbgAddr address;
+ if (activeLine(file, lineNo, address))
+ emit toggleBreak(file, lineNo, address, true);
+}
+
+void WinStack::slotBrkptEnable()
+{
+ QString file;
+ int lineNo;
+ DbgAddr address;
+ if (activeLine(file, lineNo, address))
+ emit enadisBreak(file, lineNo, address);
+}
+
+void WinStack::slotMoveProgramCounter()
+{
+ QString file;
+ int lineNo;
+ DbgAddr address;
+ if (activeLine(file, lineNo, address))
+ emit moveProgramCounter(file, lineNo, address);
+}
+
+void WinStack::slotClose()
+{
+ QWidget* w = activeWindow();
+ if (!w)
+ return;
+
+ removePage(w);
+ delete w;
+}
+
+
+ValueTip::ValueTip(WinStack* parent) :
+ QToolTip(parent)
+{
+}
+
+void ValueTip::maybeTip(const QPoint& p)
+{
+ WinStack* w = static_cast<WinStack*>(parentWidget());
+ w->maybeTip(p);
+}
+
+
+FindDialog::FindDialog() :
+ QDialog(0, "find", false),
+ m_searchText(this, "text"),
+ m_caseCheck(this, "case"),
+ m_buttonForward(this, "forward"),
+ m_buttonBackward(this, "backward"),
+ m_buttonClose(this, "close"),
+ m_layout(this, 8),
+ m_buttons(4)
+{
+ setCaption(QString(kapp->caption()) + i18n(": Search"));
+
+ m_searchText.setMinimumSize(330, 24);
+ m_searchText.setMaxLength(10000);
+ m_searchText.setFrame(true);
+
+ m_caseCheck.setText(i18n("&Case sensitive"));
+ m_caseCheck.setChecked(true);
+ m_buttonForward.setText(i18n("&Forward"));
+ m_buttonForward.setDefault(true);
+ m_buttonBackward.setText(i18n("&Backward"));
+ m_buttonClose.setText(i18n("Close"));
+
+ m_caseCheck.setMinimumSize(330, 24);
+
+ // get maximum size of buttons
+ QSize maxSize(80,30);
+ maxSize.expandedTo(m_buttonForward.sizeHint());
+ maxSize.expandedTo(m_buttonBackward.sizeHint());
+ maxSize.expandedTo(m_buttonClose.sizeHint());
+
+ m_buttonForward.setMinimumSize(maxSize);
+ m_buttonBackward.setMinimumSize(maxSize);
+ m_buttonClose.setMinimumSize(maxSize);
+
+ connect(&m_buttonClose, SIGNAL(clicked()), SLOT(reject()));
+
+ m_layout.addWidget(&m_searchText);
+ m_layout.addWidget(&m_caseCheck);
+ m_layout.addLayout(&m_buttons);
+ m_layout.addStretch(10);
+ m_buttons.addWidget(&m_buttonForward);
+ m_buttons.addStretch(10);
+ m_buttons.addWidget(&m_buttonBackward);
+ m_buttons.addStretch(10);
+ m_buttons.addWidget(&m_buttonClose);
+
+ m_layout.activate();
+
+ m_searchText.setFocus();
+ resize( 350, 120 );
+}
+
+FindDialog::~FindDialog()
+{
+}
+
+void FindDialog::closeEvent(QCloseEvent* ev)
+{
+ QDialog::closeEvent(ev);
+ emit closed();
+}
+
+void FindDialog::done(int result)
+{
+ QDialog::done(result);
+ emit closed();
+}
+
+#include "winstack.moc"
diff --git a/kdbg/winstack.h b/kdbg/winstack.h
new file mode 100644
index 0000000..22d1470
--- /dev/null
+++ b/kdbg/winstack.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright Johannes Sixt
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef WINSTACK_H
+#define WINSTACK_H
+
+#include <qdialog.h>
+#include <qlineedit.h>
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#include <qtooltip.h>
+#include <ktabwidget.h>
+#include <list>
+
+// forward declarations
+class KDebugger;
+class WinStack;
+class SourceWindow;
+class DisassembledCode;
+struct DbgAddr;
+
+class FindDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ FindDialog();
+ ~FindDialog();
+
+ bool caseSensitive() const { return m_caseCheck.isChecked(); }
+ QString searchText() const { return m_searchText.text(); }
+ virtual void done(int result);
+
+ QLineEdit m_searchText;
+ QCheckBox m_caseCheck;
+ QPushButton m_buttonForward;
+ QPushButton m_buttonBackward;
+ QPushButton m_buttonClose;
+
+signals:
+ void closed();
+
+protected:
+ virtual void closeEvent(QCloseEvent* ev);
+ QVBoxLayout m_layout;
+ QHBoxLayout m_buttons;
+};
+
+
+class ValueTip : public QToolTip
+{
+public:
+ ValueTip(WinStack* parent);
+ virtual ~ValueTip() {} // Qt3's QToolTip lacks virtual dtor!
+ virtual void maybeTip(const QPoint& p);
+ void tip(const QRect& r, const QString& s) { QToolTip::tip(r, s); }
+};
+
+
+class WinStack : public KTabWidget
+{
+ Q_OBJECT
+public:
+ WinStack(QWidget* parent, const char* name);
+ virtual ~WinStack();
+
+ /**
+ * Slot activate also looks in this directory when the specified file is
+ * a relative path.
+ */
+ void setExtraDirectory(const QString& dir) { m_lastOpenDir = dir; }
+ void activateFile(const QString& fileName);
+ bool activeLine(QString& filename, int& lineNo);
+ bool activeLine(QString& filename, int& lineNo, DbgAddr& address);
+ void maybeTip(const QPoint& p);
+ bool hasWindows() const { return count() > 0; }
+ QString activeFileName() const;
+ SourceWindow* activeWindow() const;
+ SourceWindow* windowAt(int i) const;
+
+ virtual QSize sizeHint() const;
+
+signals:
+ void toggleBreak(const QString&, int, const DbgAddr&, bool);
+ void enadisBreak(const QString&, int, const DbgAddr&);
+ void newFileLoaded();
+ void initiateValuePopup(const QString&);
+ void disassemble(const QString&, int);
+ void setTabWidth(int numChars);
+ void moveProgramCounter(const QString&, int, const DbgAddr&);
+
+public slots:
+ virtual void slotFindForward();
+ virtual void slotFindBackward();
+ virtual void activate(const QString& filename, int lineNo, const DbgAddr& address);
+ void updatePC(const QString& filename, int lineNo, const DbgAddr& address, int frameNo);
+ void reloadAllFiles();
+ void updateLineItems(const KDebugger* deb);
+ void slotSetTabWidth(int numChars);
+
+ void slotFileReload();
+ void slotViewFind();
+ void slotBrkptSet();
+ void slotBrkptSetTemp();
+ void slotBrkptEnable();
+ void slotMoveProgramCounter();
+ void slotClose();
+
+ // Displays the value tip at m_tipLocation
+ void slotShowValueTip(const QString& tipText);
+
+ // Shows the disassembled code at the location given by file and lineNo
+ void slotDisassembled(const QString& fileName, int lineNo,
+ const std::list<DisassembledCode>& disass);
+
+ // Updates line items after expanding/collapsing disassembled code
+ void slotExpandCollapse(int lineNo);
+
+protected:
+ bool activatePath(QString pathname, int lineNo, const DbgAddr& address);
+ virtual bool activateWindow(SourceWindow* fw, int lineNo, const DbgAddr& address); /* -1 doesnt change line */
+ virtual void contextMenuEvent(QContextMenuEvent* e);
+ void setPC(bool set, const QString& fileName, int lineNo,
+ const DbgAddr& address, int frameNo);
+ SourceWindow* findByFileName(const QString& fileName) const;
+ QString m_lastOpenDir; /* where user opened last file */
+
+ // program counter
+ QString m_pcFile;
+ int m_pcLine; /* -1 if no PC */
+ QString m_pcAddress; /* exact address of PC */
+ int m_pcFrame;
+
+ ValueTip m_valueTip;
+ QRect m_tipLocation; /* where tip should appear */
+
+ int m_tabWidth; /* number of chars */
+
+public:
+ // find dialog
+ FindDialog m_findDlg;
+};
+
+#endif // WINSTACK_H
diff --git a/kdbg/xsldbgdriver.cpp b/kdbg/xsldbgdriver.cpp
new file mode 100644
index 0000000..7248697
--- /dev/null
+++ b/kdbg/xsldbgdriver.cpp
@@ -0,0 +1,1452 @@
+/*
+ * Copyright Johannes Sixt, Keith Isdale
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#include "xsldbgdriver.h"
+#include "exprwnd.h"
+#include <qstringlist.h>
+#include <klocale.h> /* i18n */
+#include <ctype.h>
+#include <stdlib.h> /* strtol, atoi */
+#include <string.h> /* strcpy */
+#include <kmessagebox.h>
+
+#include "assert.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "mydebug.h"
+
+
+static ExprValue *parseVar(const char *&s);
+static bool parseName(const char *&s, QString & name,
+ VarTree::NameKind & kind);
+static bool parseValue(const char *&s, ExprValue * variable);
+static bool isErrorExpr(const char *output);
+
+#define TERM_IO_ALLOWED 1
+
+// TODO: make this cmd info stuff non-static to allow multiple
+// simultaneous gdbs to run!
+
+struct XsldbgCmdInfo {
+ DbgCommand cmd;
+ const char *fmt; /* format string */
+ enum Args {
+ argNone, argString, argNum,
+ argStringNum, argNumString,
+ argString2, argNum2
+ } argsNeeded;
+};
+
+/*
+ * The following array of commands must be sorted by the DC* values,
+ * because they are used as indices.
+ */
+static XsldbgCmdInfo cmds[] = {
+ {DCinitialize, "init\n", XsldbgCmdInfo::argNone},
+ {DCtty, "tty %s\n", XsldbgCmdInfo::argString},
+ {DCexecutable, "source %s\n", XsldbgCmdInfo::argString}, /* force a restart */
+ {DCtargetremote, "print 'target remote %s'\n", XsldbgCmdInfo::argString},
+ {DCcorefile, "data %s\n", XsldbgCmdInfo::argString}, /* force a restart */
+ {DCattach, "print 'attach %s'\n", XsldbgCmdInfo::argString},
+ {DCinfolinemain, "print 'info main line'\n", XsldbgCmdInfo::argNone},
+ {DCinfolocals, "locals -f\n", XsldbgCmdInfo::argNone},
+ {DCinforegisters, "print 'info reg'\n", XsldbgCmdInfo::argNone},
+ {DCexamine, "print 'x %s %s'\n", XsldbgCmdInfo::argString2},
+ {DCinfoline, "print 'templates %s:%d'\n", XsldbgCmdInfo::argStringNum},
+ {DCdisassemble, "print 'disassemble %s %s'\n", XsldbgCmdInfo::argString2},
+ {DCsetargs, "data %s\n", XsldbgCmdInfo::argString},
+ {DCsetenv, "addparam %s %s\n", XsldbgCmdInfo::argString2},
+ {DCunsetenv, "unset env %s\n", XsldbgCmdInfo::argString},
+ {DCsetoption, "setoption %s %d\n", XsldbgCmdInfo::argStringNum},
+ {DCcd, "chdir %s\n", XsldbgCmdInfo::argString},
+ {DCbt, "where\n", XsldbgCmdInfo::argNone},
+ {DCrun, "run\nsource\n", XsldbgCmdInfo::argNone}, /* Ensure that at the start
+ of executing XSLT we show the XSLT file */
+ {DCcont, "continue\n", XsldbgCmdInfo::argNone},
+ {DCstep, "step\n", XsldbgCmdInfo::argNone},
+ {DCstepi, "step\n", XsldbgCmdInfo::argNone},
+ {DCnext, "next\n", XsldbgCmdInfo::argNone},
+ {DCnexti, "next\n", XsldbgCmdInfo::argNone},
+ {DCfinish, "stepup\n", XsldbgCmdInfo::argNone},
+ {DCuntil, "continue %s:%d\n", XsldbgCmdInfo::argStringNum},
+ {DCkill, "quit\n", XsldbgCmdInfo::argNone},
+ {DCbreaktext, "break %s\n", XsldbgCmdInfo::argString},
+ {DCbreakline, "break -l %s %d\n", XsldbgCmdInfo::argStringNum},
+ {DCtbreakline, "break -l %s %d\n", XsldbgCmdInfo::argStringNum },
+ {DCbreakaddr, "print `break *%s`\n", XsldbgCmdInfo::argString },
+ {DCtbreakaddr, "print `tbreak *%s`\n", XsldbgCmdInfo::argString },
+ {DCwatchpoint, "print 'watch %s'\n", XsldbgCmdInfo::argString},
+ {DCdelete, "delete %d\n", XsldbgCmdInfo::argNum},
+ {DCenable, "enable %d\n", XsldbgCmdInfo::argNum},
+ {DCdisable, "disable %d\n", XsldbgCmdInfo::argNum},
+ {DCprint, "print %s\n", XsldbgCmdInfo::argString},
+ {DCprintDeref, "print 'print (*%s)'\n", XsldbgCmdInfo::argString},
+ {DCprintStruct, "print 'print %s'\n", XsldbgCmdInfo::argString},
+ {DCprintQStringStruct, "print 'print %s'\n", XsldbgCmdInfo::argString},
+ {DCframe, "frame %d\n", XsldbgCmdInfo::argNum},
+ {DCfindType, "print 'whatis %s'\n", XsldbgCmdInfo::argString},
+ {DCinfosharedlib, "stylesheets\n", XsldbgCmdInfo::argNone},
+ {DCthread, "print 'thread %d'\n", XsldbgCmdInfo::argNum},
+ {DCinfothreads, "print 'info threads'\n", XsldbgCmdInfo::argNone},
+ {DCinfobreak, "show\n", XsldbgCmdInfo::argNone},
+ {DCcondition, "print 'condition %d %s'\n", XsldbgCmdInfo::argNumString},
+ {DCsetpc, "print 'set variable $pc=%s'\n", XsldbgCmdInfo::argString},
+ {DCignore, "print 'ignore %d %d'\n", XsldbgCmdInfo::argNum2},
+ {DCprintWChar, "print 'ignore %s'\n", XsldbgCmdInfo::argString},
+ {DCsetvariable, "set %s %s\n", XsldbgCmdInfo::argString2},
+};
+
+#define NUM_CMDS (int(sizeof(cmds)/sizeof(cmds[0])))
+#define MAX_FMTLEN 200
+
+XsldbgDriver::XsldbgDriver():
+DebuggerDriver(), m_gdbMajor(2), m_gdbMinor(0)
+{
+ m_promptRE.setPattern("\\(xsldbg\\) .*> ");
+ m_promptMinLen = 11;
+ m_promptLastChar = ' ';
+
+ m_markerRE.setPattern("^Breakpoint for file ");
+ m_haveDataFile = FALSE;
+
+#ifndef NDEBUG
+ // check command info array
+ const char *perc;
+
+ for (int i = 0; i < NUM_CMDS; i++) {
+ // must be indexable by DbgCommand values, i.e. sorted by DbgCommand values
+ assert(i == cmds[i].cmd);
+ // a format string must be associated
+ assert(cmds[i].fmt != 0);
+ assert(strlen(cmds[i].fmt) <= MAX_FMTLEN);
+ // format string must match arg specification
+ switch (cmds[i].argsNeeded) {
+ case XsldbgCmdInfo::argNone:
+ assert(strchr(cmds[i].fmt, '%') == 0);
+ break;
+ case XsldbgCmdInfo::argString:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 's');
+ assert(strchr(perc + 2, '%') == 0);
+ break;
+ case XsldbgCmdInfo::argNum:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 'd');
+ assert(strchr(perc + 2, '%') == 0);
+ break;
+ case XsldbgCmdInfo::argStringNum:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 's');
+ perc = strchr(perc + 2, '%');
+ assert(perc != 0 && perc[1] == 'd');
+ assert(strchr(perc + 2, '%') == 0);
+ break;
+ case XsldbgCmdInfo::argNumString:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 'd');
+ perc = strchr(perc + 2, '%');
+ assert(perc != 0 && perc[1] == 's');
+ assert(strchr(perc + 2, '%') == 0);
+ break;
+ case XsldbgCmdInfo::argString2:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 's');
+ perc = strchr(perc + 2, '%');
+ assert(perc != 0 && perc[1] == 's');
+ assert(strchr(perc + 2, '%') == 0);
+ break;
+ case XsldbgCmdInfo::argNum2:
+ perc = strchr(cmds[i].fmt, '%');
+ assert(perc != 0 && perc[1] == 'd');
+ perc = strchr(perc + 2, '%');
+ assert(perc != 0 && perc[1] == 'd');
+ assert(strchr(perc + 2, '%') == 0);
+ break;
+ }
+ }
+#endif
+}
+
+XsldbgDriver::~XsldbgDriver()
+{
+}
+
+
+QString
+XsldbgDriver::driverName() const
+{
+ return "XSLDBG";
+}
+
+QString
+XsldbgDriver::defaultXsldbg()
+{
+ return "xsldbg --lang en --shell --gdb";
+}
+
+QString
+XsldbgDriver::defaultInvocation() const
+{
+ return defaultXsldbg();
+}
+
+QStringList XsldbgDriver::boolOptionList() const
+{
+ QStringList allOptions;
+ allOptions.append("verbose");
+ allOptions.append("repeat");
+ allOptions.append("debug");
+ allOptions.append("novalid");
+ allOptions.append("noout");
+ allOptions.append("html");
+ allOptions.append("docbook");
+ allOptions.append("nonet");
+ allOptions.append("catalogs");
+ allOptions.append("xinclude");
+ allOptions.append("profile");
+ return allOptions;
+}
+
+
+void
+XsldbgDriver::slotReceiveOutput(KProcess * process, char *buffer,
+ int buflen)
+{
+ //TRACE(buffer);
+ if (m_state != DSidle) {
+ // TRACE(buffer);
+ DebuggerDriver::slotReceiveOutput(process, buffer, buflen);
+ } else {
+ if (strncmp(buffer, "quit", 4) == 0) {
+ TRACE("Ignoring text when xsldbg is quiting");
+ } else {
+ TRACE
+ ("Stray output received by XsldbgDriver::slotReceiveOutput");
+ TRACE(buffer);
+ }
+ }
+}
+
+bool
+XsldbgDriver::startup(QString cmdStr)
+{
+ if (!DebuggerDriver::startup(cmdStr))
+ return false;
+
+ static const char xsldbgInitialize[] = "pwd\nsetoption gdb 2\n"; /* don't need to do anything else */
+
+ executeCmdString(DCinitialize, xsldbgInitialize, false);
+
+ return true;
+}
+
+void
+XsldbgDriver::commandFinished(CmdQueueItem * cmd)
+{
+
+ TRACE(__PRETTY_FUNCTION__);
+ // command string must be committed
+ if (!cmd->m_committed) {
+ // not commited!
+ TRACE("calling " +
+ (__PRETTY_FUNCTION__ +
+ (" with uncommited command:\n\t" + cmd->m_cmdString)));
+ return;
+ }
+
+ switch (cmd->m_cmd) {
+ case DCinitialize:
+ // get version number from preamble
+ {
+ int len;
+ QRegExp xsldbgVersion("^XSLDBG [0-9]+\\.[0-9]+\\.[0-9]+");
+ int offset = xsldbgVersion.match(m_output, 0, &len);
+
+ if (offset >= 0) {
+ char *start = m_output + offset + 7; // skip "^XSLDBG "
+ char *end;
+
+ TRACE("Reading version");
+ TRACE(start);
+ m_gdbMajor = strtol(start, &end, 10);
+ m_gdbMinor = strtol(end + 1, 0, 10); // skip "."
+ if (start == end) {
+ // nothing was parsed
+ m_gdbMajor = 0;
+ m_gdbMinor = 7;
+ }
+ } else {
+ // assume some default version (what would make sense?)
+ m_gdbMajor = 0;
+ m_gdbMinor = 7;
+ }
+ TRACE(QString("Got version ") +
+ QString::number(m_gdbMajor) + "." +
+ QString::number(m_gdbMinor));
+ break;
+ }
+ default:;
+ }
+ /* ok, the command is ready */
+ emit commandReceived(cmd, m_output);
+
+ switch (cmd->m_cmd) {
+ case DCbt:
+ case DCinfolocals:
+ case DCrun:
+ case DCcont:
+ case DCstep:
+ case DCnext:
+ case DCfinish:{
+ if (!::isErrorExpr(m_output))
+ parseMarker();
+ else{
+ // This only shows an error for DCinfolocals
+ // need to update KDebugger::handleRunCommand ?
+ KMessageBox::sorry(0L, m_output);
+ }
+ }
+ break;
+
+ case DCinfolinemain:
+ if (!m_xslFile.isEmpty())
+ emit activateFileLine(m_xslFile, 0, DbgAddr());
+ break;
+
+ default:;
+ }
+}
+
+void
+XsldbgDriver::parseMarker()
+{
+
+ // TRACE("parseMarker : xsldbg");
+ // TRACE(m_output);
+ int len, markerStart = -1;
+ char *p = m_output;
+
+ while (markerStart == -1) {
+ if ((p == 0) || (*p == '\0')) {
+ m_output[0] = '\0';
+ return;
+ }
+ //TRACE(QString("parseMarker is looking at :") + p);
+ markerStart = m_markerRE.match(p, 0, &len);
+ if (markerStart == -1) {
+ // try to marker on next line !
+ p = strchr(p, '\n');
+ if ((p != 0) && (*p != '\0'))
+ p++;
+ }
+ }
+
+
+ // extract the marker
+ char *startMarker = p + markerStart + len;
+
+ //TRACE(QString("found marker:") + startMarker);
+ char *endMarker = strchr(startMarker, '\n');
+
+ if (endMarker == 0)
+ return;
+
+ *endMarker = '\0';
+
+ // extract filename and line number
+ static QRegExp MarkerRE(" at line [0-9]+");
+
+ int lineNoStart = MarkerRE.match(startMarker, 0, &len);
+
+ if (lineNoStart >= 0) {
+ int lineNo = atoi(startMarker + lineNoStart + 8);
+
+ DbgAddr address;
+
+ // now show the window
+ startMarker[lineNoStart-1] = '\0'; /* split off file name */
+ TRACE("Got file and line number");
+ startMarker++;
+ TRACE(QString(startMarker) + ": " + QString::number(lineNo));
+ emit activateFileLine(startMarker, lineNo - 1, address);
+ }
+}
+
+
+/*
+ * Escapes characters that might lead to problems when they appear on gdb's
+ * command line.
+ */
+static void
+normalizeStringArg(QString & arg)
+{
+ /*
+ * Remove trailing backslashes. This approach is a little simplistic,
+ * but we know that there is at the moment no case where a trailing
+ * backslash would make sense.
+ */
+ while (!arg.isEmpty() && arg[arg.length() - 1] == '\\') {
+ arg = arg.left(arg.length() - 1);
+ }
+}
+
+
+QString
+XsldbgDriver::makeCmdString(DbgCommand cmd, QString strArg)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == XsldbgCmdInfo::argString);
+
+ normalizeStringArg(strArg);
+
+ if (cmd == DCcd) {
+ // need the working directory when parsing the output
+ m_programWD = strArg;
+ } else if (cmd == DCexecutable) {
+ // want to display the XSL file
+ m_xslFile = strArg;
+ }
+
+ QString cmdString;
+ cmdString.sprintf(cmds[cmd].fmt, strArg.latin1());
+ return cmdString;
+}
+
+QString
+XsldbgDriver::makeCmdString(DbgCommand cmd, int intArg)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == XsldbgCmdInfo::argNum);
+
+ QString cmdString;
+ cmdString.sprintf(cmds[cmd].fmt, intArg);
+ return cmdString;
+}
+
+QString
+XsldbgDriver::makeCmdString(DbgCommand cmd, QString strArg, int intArg)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == XsldbgCmdInfo::argStringNum ||
+ cmds[cmd].argsNeeded == XsldbgCmdInfo::argNumString ||
+ cmd == DCexamine || cmd == DCtty);
+
+ normalizeStringArg(strArg);
+
+ QString cmdString;
+
+ if (cmd == DCtty) {
+ /*
+ * intArg specifies which channels should be redirected to
+ * /dev/null. It is a value or'ed together from RDNstdin,
+ * RDNstdout, RDNstderr.
+ */
+ static const char *const runRedir[8] = {
+ "",
+ " </dev/null",
+ " >/dev/null",
+ " </dev/null >/dev/null",
+ " 2>/dev/null",
+ " </dev/null 2>/dev/null",
+ " >/dev/null 2>&1",
+ " </dev/null >/dev/null 2>&1"
+ };
+
+ if (strArg.isEmpty())
+ intArg = 7; /* failsafe if no tty */
+ m_redirect = runRedir[intArg & 7];
+
+ return makeCmdString(DCtty, strArg); /* note: no problem if strArg empty */
+ }
+
+ if (cmd == DCexamine) {
+ // make a format specifier from the intArg
+ static const char size[16] = {
+ '\0', 'b', 'h', 'w', 'g'
+ };
+ static const char format[16] = {
+ '\0', 'x', 'd', 'u', 'o', 't',
+ 'a', 'c', 'f', 's', 'i'
+ };
+
+ assert(MDTsizemask == 0xf); /* lowest 4 bits */
+ assert(MDTformatmask == 0xf0); /* next 4 bits */
+ int count = 16; /* number of entities to print */
+ char sizeSpec = size[intArg & MDTsizemask];
+ char formatSpec = format[(intArg & MDTformatmask) >> 4];
+
+ assert(sizeSpec != '\0');
+ assert(formatSpec != '\0');
+ // adjust count such that 16 lines are printed
+ switch (intArg & MDTformatmask) {
+ case MDTstring:
+ case MDTinsn:
+ break; /* no modification needed */
+ default:
+ // all cases drop through:
+ switch (intArg & MDTsizemask) {
+ case MDTbyte:
+ case MDThalfword:
+ count *= 2;
+ case MDTword:
+ count *= 2;
+ case MDTgiantword:
+ count *= 2;
+ }
+ break;
+ }
+ QString spec;
+
+ spec.sprintf("/%d%c%c", count, sizeSpec, formatSpec);
+
+ return makeCmdString(DCexamine, spec, strArg);
+ }
+
+ if (cmds[cmd].argsNeeded == XsldbgCmdInfo::argStringNum) {
+ // line numbers are zero-based
+ if (cmd == DCuntil || cmd == DCbreakline ||
+ cmd == DCtbreakline || cmd == DCinfoline) {
+ intArg++;
+ }
+ if (cmd == DCinfoline) {
+ // must split off file name part
+ int slash = strArg.findRev('/');
+
+ if (slash >= 0)
+ strArg = strArg.right(strArg.length() - slash - 1);
+ }
+ cmdString.sprintf(cmds[cmd].fmt, strArg.latin1(), intArg);
+ } else {
+ cmdString.sprintf(cmds[cmd].fmt, intArg, strArg.latin1());
+ }
+ return cmdString;
+}
+
+QString
+XsldbgDriver::makeCmdString(DbgCommand cmd, QString strArg1,
+ QString strArg2)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == XsldbgCmdInfo::argString2);
+
+ normalizeStringArg(strArg1);
+ normalizeStringArg(strArg2);
+
+ QString cmdString;
+ cmdString.sprintf(cmds[cmd].fmt, strArg1.latin1(), strArg2.latin1());
+ return cmdString;
+}
+
+QString
+XsldbgDriver::makeCmdString(DbgCommand cmd, int intArg1, int intArg2)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == XsldbgCmdInfo::argNum2);
+
+ QString cmdString;
+ cmdString.sprintf(cmds[cmd].fmt, intArg1, intArg2);
+ return cmdString;
+}
+
+CmdQueueItem *
+XsldbgDriver::executeCmd(DbgCommand cmd, bool clearLow)
+{
+ assert(cmd >= 0 && cmd < NUM_CMDS);
+ assert(cmds[cmd].argsNeeded == XsldbgCmdInfo::argNone);
+
+ if (cmd == DCrun) {
+ m_haveCoreFile = false;
+ }
+
+ return executeCmdString(cmd, cmds[cmd].fmt, clearLow);
+}
+
+CmdQueueItem *
+XsldbgDriver::executeCmd(DbgCommand cmd, QString strArg, bool clearLow)
+{
+ return executeCmdString(cmd, makeCmdString(cmd, strArg), clearLow);
+}
+
+CmdQueueItem *
+XsldbgDriver::executeCmd(DbgCommand cmd, int intArg, bool clearLow)
+{
+
+ return executeCmdString(cmd, makeCmdString(cmd, intArg), clearLow);
+}
+
+CmdQueueItem *
+XsldbgDriver::executeCmd(DbgCommand cmd, QString strArg, int intArg,
+ bool clearLow)
+{
+ return executeCmdString(cmd, makeCmdString(cmd, strArg, intArg),
+ clearLow);
+}
+
+CmdQueueItem *
+XsldbgDriver::executeCmd(DbgCommand cmd, QString strArg1, QString strArg2,
+ bool clearLow)
+{
+ return executeCmdString(cmd, makeCmdString(cmd, strArg1, strArg2),
+ clearLow);
+}
+
+CmdQueueItem *
+XsldbgDriver::executeCmd(DbgCommand cmd, int intArg1, int intArg2,
+ bool clearLow)
+{
+ return executeCmdString(cmd, makeCmdString(cmd, intArg1, intArg2),
+ clearLow);
+}
+
+CmdQueueItem *
+XsldbgDriver::queueCmd(DbgCommand cmd, QueueMode mode)
+{
+ return queueCmdString(cmd, cmds[cmd].fmt, mode);
+}
+
+CmdQueueItem *
+XsldbgDriver::queueCmd(DbgCommand cmd, QString strArg, QueueMode mode)
+{
+ return queueCmdString(cmd, makeCmdString(cmd, strArg), mode);
+}
+
+CmdQueueItem *
+XsldbgDriver::queueCmd(DbgCommand cmd, int intArg, QueueMode mode)
+{
+ return queueCmdString(cmd, makeCmdString(cmd, intArg), mode);
+}
+
+CmdQueueItem *
+XsldbgDriver::queueCmd(DbgCommand cmd, QString strArg, int intArg,
+ QueueMode mode)
+{
+ return queueCmdString(cmd, makeCmdString(cmd, strArg, intArg), mode);
+}
+
+CmdQueueItem *
+XsldbgDriver::queueCmd(DbgCommand cmd, QString strArg1, QString strArg2,
+ QueueMode mode)
+{
+ return queueCmdString(cmd, makeCmdString(cmd, strArg1, strArg2), mode);
+}
+
+void
+XsldbgDriver::terminate()
+{
+ qDebug("XsldbgDriver::Terminate");
+ flushCommands();
+ executeCmdString(DCinitialize, "quit\n", true);
+ kill(SIGTERM);
+ m_state = DSidle;
+}
+
+void
+XsldbgDriver::detachAndTerminate()
+{
+ qDebug("XsldbgDriver::detachAndTerminate");
+ flushCommands();
+ executeCmdString(DCinitialize, "quit\n", true);
+ kill(SIGINT);
+}
+
+void
+XsldbgDriver::interruptInferior()
+{
+ // remove accidentally queued commands
+ qDebug("interruptInferior");
+ flushHiPriQueue();
+ kill(SIGINT);
+}
+
+static bool
+isErrorExpr(const char *output)
+{
+ int wordIndex;
+ bool result = false;
+#define ERROR_WORD_COUNT 6
+ static const char *errorWords[ERROR_WORD_COUNT] = {
+ "Error:",
+ "error:", // libxslt error
+ "Unknown command",
+ "Warning:",
+ "warning:", // libxslt warning
+ "Information:" // xsldbg information
+ };
+ static int errorWordLength[ERROR_WORD_COUNT] = {
+ 6, /* Error */
+ 6, /* rror */
+ 15, /* Unknown command*/
+ 8, /* Warning */
+ 8, /* warning */
+ 12 /* Information */
+ };
+
+ for (wordIndex = 0; wordIndex < ERROR_WORD_COUNT; wordIndex++){
+ // ignore any warnings relating to local variables not being available
+ if (strncmp(output,
+ errorWords[wordIndex],
+ errorWordLength[wordIndex]) == 0 &&
+ (wordIndex == 0 && strstr(output, "try stepping past the xsl:param") == 0) ) {
+ result = true;
+ TRACE(QString("Error/Warning/Information from xsldbg ") + output);
+ break;
+ }
+ }
+
+ return result;
+}
+
+/**
+ * Returns true if the output is an error message. If wantErrorValue is
+ * true, a new ExprValue object is created and filled with the error message.
+ */
+static bool
+parseErrorMessage(const char *output,
+ ExprValue * &variable, bool wantErrorValue)
+{
+ if (isErrorExpr(output)) {
+ if (wantErrorValue) {
+ // put the error message as value in the variable
+ variable = new ExprValue(QString(), VarTree::NKplain);
+ const char *endMsg = strchr(output, '\n');
+
+ if (endMsg == 0)
+ endMsg = output + strlen(output);
+ variable->m_value = QString::fromLatin1(output, endMsg - output);
+ } else {
+ variable = 0;
+ }
+ return true;
+ }
+ return false;
+}
+
+
+void
+XsldbgDriver::setPrintQStringDataCmd(const char* /*cmd*/)
+{
+}
+
+ExprValue *
+XsldbgDriver::parseQCharArray(const char */*output*/, bool /*wantErrorValue*/,
+ bool /*qt3like*/)
+{
+ ExprValue *variable = 0;
+
+ TRACE("XsldbgDriver::parseQCharArray not implmented");
+ return variable;
+}
+
+static ExprValue *
+parseVar(const char *&s)
+{
+ const char *p = s;
+ bool foundLocalVar = false;
+ ExprValue *variable = 0L;
+ QString name;
+
+ VarTree::NameKind kind;
+
+ TRACE(__PRETTY_FUNCTION__);
+ TRACE(p);
+
+ if (parseErrorMessage(p, variable, false) == true) {
+ TRACE("Found error message");
+ return variable;
+ }
+
+ if (strncmp(p, " Local", 6) == 0) {
+ foundLocalVar = true;
+ /* skip " Local" */
+ p = p + 6;
+ TRACE("Found local variable");
+ } else if (strncmp(p, " Global", 7) == 0) {
+ /* skip " Global" */
+ p = p + 7;
+ TRACE("Found global variable");
+ } else if (strncmp(p, "= ", 2) == 0) {
+ /* we're processing the result of a "print command" */
+ /* find next line */
+ const char *nextLine = strchr(p, '\n');
+
+ TRACE("Found print expr");
+ if (nextLine) {
+ p = p + 2; /* skip the "= " */
+ name = QString::fromLatin1(p, nextLine - p);
+ kind = VarTree::NKplain;
+ p = nextLine + 1;
+ variable = new ExprValue(name, kind);
+ variable->m_varKind = VarTree::VKsimple;
+ parseValue(p, variable);
+ return variable;
+ }
+ } else
+ return variable; /* don't know what to do this this data abort!! */
+
+ // skip whitespace
+ while (isspace(*p))
+ p++;
+
+ if (*p != '='){
+ // No value provided just a name
+ TRACE(QString("Parse var: name") + p);
+ if (!parseName(p, name, kind)) {
+ return 0;
+ }
+ variable = new ExprValue(name, kind);
+ if (variable != 0L) {
+ variable->m_varKind = VarTree::VKsimple;
+ }
+ }else{
+ p++;
+ // skip whitespace
+ while (isspace(*p))
+ p++;
+ TRACE(QString("Parse var: name") + p);
+ if (!parseName(p, name, kind)) {
+ return 0;
+ }
+ variable = new ExprValue(name, kind);
+ if (variable != 0L) {
+ variable->m_varKind = VarTree::VKsimple;
+ }
+ if (*p == '\n')
+ p++;
+ if (!parseValue(p, variable)) {
+ delete variable;
+ return 0;
+ }
+ }
+
+ if (*p == '\n')
+ p++;
+
+ s = p;
+ return variable;
+}
+
+
+inline void
+skipName(const char *&p)
+{
+ // allow : (for enumeration values) and $ and . (for _vtbl.)
+ while (isalnum(*p) || *p == '_' || *p == ':' || *p == '$' || *p == '.')
+ p++;
+}
+
+static bool
+parseName(const char *&s, QString & name, VarTree::NameKind & kind)
+{
+ /* qDebug(__PRETTY_FUNCTION__); */
+ kind = VarTree::NKplain;
+
+ const char *p = s;
+ int len = 0;
+
+ // examples of names:
+ // help_cmd
+
+ while ((*p != '\n') && (*p != '\0')) {
+ len++;
+ p++;
+ }
+
+
+ name = QString::fromLatin1(s, len);
+ /* XSL variables will have a $ prefix to be evaluated
+ * properly */
+ //TRACE(QString("parseName got name" ) + name);
+
+ // return the new position
+ s = p;
+ return true;
+}
+
+static bool
+parseValue(const char *&s, ExprValue * variable)
+{
+ const char *start = s, *end = s;
+ ExprValue * childValue;
+ #define VALUE_END_MARKER_INDEX 0
+
+ /* This mark the end of a value */
+ static const char *marker[] = {
+ "\032\032", /* value end marker*/
+ "(xsldbg) ",
+ "Breakpoint at", /* stepped to next location */
+ "Breakpoint in", /* reached a set breakpoint */
+ "Reached ", /* reached template */
+ "Error:",
+ "Warning:",
+ "Information:",
+ "runtime error",
+ "xmlXPathEval:",
+ 0
+ };
+ static char valueBuffer[2048];
+ int markerIndex = 0, foundEnd = 0;
+ size_t copySize;
+
+ if (variable == 0L)
+ return false; /* should never happen but .. */
+
+ while (start && (*start != '\0')) {
+ /* look for the next marker */
+ for (markerIndex = 0; marker[markerIndex] != 0; markerIndex++) {
+ foundEnd =
+ strncmp(start, marker[markerIndex],
+ strlen(marker[markerIndex])) == 0;
+ if (foundEnd)
+ break;
+ }
+
+ if (foundEnd)
+ break;
+
+
+ end = strchr(start, '\n');
+ if (end)
+ copySize = end - start;
+ else
+ copySize = strlen(start);
+ if (copySize >= sizeof(valueBuffer))
+ copySize = sizeof(valueBuffer)-1;
+
+ strncpy(valueBuffer, start, copySize);
+ valueBuffer[copySize] = '\0';
+ TRACE("Got value :");
+ TRACE(valueBuffer);
+ if ((variable->m_varKind == VarTree::VKsimple)) {
+ if (!variable->m_value.isEmpty()){
+ variable->m_varKind = VarTree::VKarray;
+ childValue = new ExprValue(variable->m_value, VarTree::NKplain);
+ variable->appendChild(childValue);
+ childValue = new ExprValue(valueBuffer, VarTree::NKplain);
+ variable->appendChild(childValue);
+ variable->m_value = "";
+ }else{
+ variable->m_value = valueBuffer;
+ }
+ }else{
+ childValue = new ExprValue(valueBuffer, VarTree::NKplain);
+ variable->appendChild(childValue);
+ }
+
+ if (*end =='\n'){
+ start = end + 1;
+ }else{
+ start = end + 1;
+ break;
+ }
+ }
+
+ if (foundEnd == 0)
+ TRACE(QString("Unable to find end on value near :") + start);
+
+ // If we've got something otherthan a end of value marker then
+ // advance to the end of this buffer
+ if (markerIndex != VALUE_END_MARKER_INDEX){
+ while (start && *start != '\0')
+ start++;
+ }else{
+ start = start + strlen(marker[0]);
+ }
+
+ s = start;
+
+ return true;
+}
+
+
+/**
+ * Parses a stack frame.
+ */
+static void
+parseFrameInfo(const char *&s, QString & func,
+ QString & file, int &lineNo, DbgAddr & /*address*/)
+{
+ const char *p = s, *endPos = s + strlen(s);
+ QString lineNoString;
+
+ TRACE("parseFrameInfo");
+
+ lineNo = -1;
+
+ /* skip 'template :\" */
+ p = p + 11;
+ // TRACE(p);
+ func = "";
+ while ((*p != '\"') && (*p != '\0')) {
+ func.append(*p);
+ p++;
+ }
+ while ((*p != '\0') && *p != '"')
+ p++;
+ if (*p != '\0')
+ p++;
+ ASSERT(p <= endPos);
+ if (p >= endPos) {
+ /* panic */
+ return;
+ }
+
+ /* skip mode :".*" */
+ while ((*p != '\0') && *p != '"')
+ p++;
+ if (*p != '\0')
+ p++;
+ while ((*p != '\0') && *p != '"')
+ p++;
+
+ /* skip '" in file ' */
+ p = p + 10;
+ if(*p == '"')
+ p++;
+ // TRACE(p);
+ file = "";
+ while (!isspace(*p) && (*p != '\"') && (*p != '\0')) {
+ file.append(*p);
+ p++;
+ }
+ if(*p == '"')
+ p++;
+ ASSERT(p <= endPos);
+ if (p >= endPos) {
+ /* panic */
+ return;
+ }
+
+ // TRACE(p);
+ /* skip ' : line '" */
+ p = p + 9;
+ // TRACE(p);
+ ASSERT(p <= endPos);
+ if (p >= endPos) {
+ /* panic */
+ return;
+ }
+ // TRACE(p);
+ if (isdigit(*p)) {
+ /* KDbg uses an offset of +1 for its line numbers */
+ lineNo = atoi(p) - 1;
+ lineNoString = QString::number(lineNo);
+ }
+ /* convert func into format needed */
+ func.append(" at ");
+ func.append(file);
+ func.append(':');
+ func.append(lineNoString);
+
+ /*advance to next line */
+ p = strchr(p, '\n');
+ if (p)
+ p++;
+ s = p;
+
+}
+
+#undef ISSPACE
+
+/**
+ * Parses a stack frame including its frame number
+ */
+static bool
+parseFrame(const char *&s, int &frameNo, QString & func,
+ QString & file, int &lineNo, DbgAddr & address)
+{
+
+ // TRACE("XsldbgDriver ::parseFrame");
+ /* skip leading 'where' or 'frame <frame_no>' */
+ if ((strncmp(s, "where", 5) == 0) || (strncmp(s, "frame", 5) == 0)) {
+ s = strchr(s, '\n');
+ if ((*s != '\0') && (*s != '#'))
+ s++;
+ }
+ // TRACE(s);
+
+ // Example:
+ //#1 template :"/" in file /home/keith/anon_CVS/xsldbg/docs/en/xsldoc.xsl : line 21
+ // must start with a hash mark followed by number
+ if (s[0] != '#' || !isdigit(s[1]))
+ return false;
+
+ //TRACE("XsldbgDriver ::parseFrame got #");
+ s++; /* skip the hash mark */
+ // frame number
+ frameNo = atoi(s);
+ while (isdigit(*s))
+ s++;
+
+ //TRACE(QString("Got frame ").append(QString::number(frameNo)));
+ // space
+ while (isspace(*s))
+ s++;
+ parseFrameInfo(s, func, file, lineNo, address);
+ // TRACE("Will next look at ");
+ // TRACE(s);
+ return true;
+}
+
+void
+XsldbgDriver::parseBackTrace(const char *output,
+ std::list < StackFrame > &stack)
+{
+ QString func, file;
+ int lineNo, frameNo;
+ DbgAddr address;
+
+ while (::parseFrame(output, frameNo, func, file, lineNo, address)) {
+ stack.push_back(StackFrame());
+ StackFrame* frm = &stack.back();
+
+ frm->frameNo = frameNo;
+ frm->fileName = file;
+ frm->lineNo = lineNo;
+ frm->address = address;
+ frm->var = new ExprValue(func, VarTree::NKplain);
+ }
+}
+
+bool
+XsldbgDriver::parseFrameChange(const char *output, int &frameNo,
+ QString & file, int &lineNo,
+ DbgAddr & address)
+{
+ QString func;
+
+ return::parseFrame(output, frameNo, func, file, lineNo, address);
+}
+
+
+bool
+XsldbgDriver::parseBreakList(const char *output,
+ std::list < Breakpoint > &brks)
+{
+ TRACE("parseBreakList");
+ /* skip the first blank line */
+ const char *p;
+
+ // split up a line
+ Breakpoint bp;
+ char *dummy;
+ p = strchr(output, '\n');/* skip the first blank line*/
+
+ while ((p != 0) && (*p != '\0')) {
+ if (*p == '\n')
+ p++;
+ QString templateName;
+ //qDebug("Looking at :%s", p);
+ if (strncmp(p, " Breakpoint", 11) != 0)
+ break;
+ p = p + 11;
+ if (*p == '\0')
+ break;
+
+ //TRACE(p);
+ // get Num
+ bp.id = strtol(p, &dummy, 10); /* don't care about overflows */
+
+ p = dummy;
+ if ((p == 0) || (p[1] == '\0'))
+ break;
+ p++;
+
+ //TRACE(p);
+ // Get breakpoint state ie enabled/disabled
+ if (strncmp(p, "enabled", 7) == 0) {
+ bp.enabled = true;
+ p = p + 7;
+ } else {
+ if (strncmp(p, "disabled", 8) == 0) {
+ p = p + 8;
+ bp.enabled = false;
+ } else{
+ TRACE("Parse error in breakpoint list");
+ TRACE(p);
+ return false;
+ }
+ }
+
+ //TRACE("Looking for template");
+ //TRACE(p);
+ if (strncmp(p, " for template: \"", 16) == 0){
+ p = p + 16;
+ //TRACE("Looking for template name near");
+ //TRACE(p);
+ /* get the template name */
+ while (p && (*p != '\0') && (*p != '\"')){
+ templateName.append(*p);
+ p++;
+ }
+ if (*p == '\"'){
+ p++;
+ }else{
+ TRACE("Error missed \" near");
+ TRACE(p);
+ }
+ }
+
+ //TRACE("Looking for mode near");
+ //TRACE(p);
+ if (strncmp(p, " mode: \"", 8) == 0){
+ p = p + 8;
+ while (p && *p != '\"')
+ p++;
+ if (p)
+ p++;
+ }
+
+ if (strncmp(p, " in file ", 9) != 0){
+ TRACE("Parse error in breakpoint list");
+ TRACE(p);
+ return false;
+ }
+
+
+ /* skip ' in file ' */
+ p = p + 9;
+ // TRACE(p);
+
+ if (*p == '\"')
+ p++;
+ /* grab file name */
+ QString file;
+ while ((*p != '\"') && !isspace(*p)) {
+ file.append(*p);
+ p++;
+ }
+ if (*p == '\"')
+ p++;
+ if (*p == '\0')
+ break;
+
+ /* skip ' : line ' */
+ p = p + 8;
+ while (isspace(*p)) {
+ p++;
+ }
+ //TRACE(p);
+ QString lineNo;
+ while (isdigit(*p)) {
+ lineNo.append(*p);
+ p++;
+ }
+
+ // bp.lineNo is zero-based
+ bp.lineNo = lineNo.toInt() - 1;
+ bp.location = QString("in %1 at %2:%3").arg(templateName, file, lineNo);
+ bp.fileName = file;
+ brks.push_back(bp);
+
+ if (p != 0) {
+ p = strchr(p, '\n');
+ if (p)
+ p++;
+ }
+ }
+ return true;
+}
+
+std::list<ThreadInfo>
+XsldbgDriver::parseThreadList(const char */*output*/)
+{
+ return std::list<ThreadInfo>();
+}
+
+bool
+XsldbgDriver::parseBreakpoint(const char *output, int &id,
+ QString &file, int &lineNo, QString &address)
+{
+ // check for errors
+ if ( strncmp(output, "Error:", 6) == 0) {
+ return false;
+ }
+
+ char *dummy;
+ if (strncmp(output, "Breakpoint ", 11) != 0)
+ return false;
+
+ output += 11;
+ if (!isdigit(*output))
+ return false;
+
+ // get Num
+ id = strtol(output, &dummy, 10); /* don't care about overflows */
+ if (output == dummy)
+ return false;
+
+ // the file name + lineNo will be filled in later from the breakpoint list
+ file = address = QString();
+ lineNo = 0;
+ return true;
+}
+
+void
+XsldbgDriver::parseLocals(const char *output, std::list < ExprValue* > &newVars)
+{
+
+ /* keep going until error or xsldbg prompt is found */
+ while (*output != '\0') {
+ ExprValue *variable = parseVar(output);
+
+ if (variable == 0) {
+ break;
+ }
+ // do not add duplicates
+ for (std::list<ExprValue*>::iterator o = newVars.begin(); o != newVars.end(); ++o) {
+ if ((*o)->m_name == variable->m_name) {
+ delete variable;
+
+ goto skipDuplicate;
+ }
+ }
+ newVars.push_back(variable);
+ skipDuplicate:;
+ }
+}
+
+
+ExprValue *
+XsldbgDriver::parsePrintExpr(const char *output, bool wantErrorValue)
+{
+ ExprValue* var = 0;
+ // check for error conditions
+ if (!parseErrorMessage(output, var, wantErrorValue)) {
+ // parse the variable
+ var = parseVar(output);
+ }
+ return var;
+}
+
+bool
+XsldbgDriver::parseChangeWD(const char *output, QString & message)
+{
+ bool isGood = false;
+
+ if (strncmp(output, "Change to directory", 20) == 0) {
+ output = output + 20; /* skip 'Change to directory' */
+ message = QString(output).simplifyWhiteSpace();
+ if (message.isEmpty()) {
+ message = i18n("New working directory: ") + m_programWD;
+ isGood = true;
+ }
+ }
+ return isGood;
+}
+
+bool
+XsldbgDriver::parseChangeExecutable(const char *output, QString & message)
+{
+ message = output;
+ TRACE(QString("XsldbgDriver::parseChangeExecutable :") + output);
+ m_haveCoreFile = false;
+
+ /*
+ * The command is successful if there is no output or the single
+ * message (no debugging symbols found)...
+ */
+ QRegExp exp(".*Load of source deferred. Use the run command.*");
+ int len, index = exp.match(output, 0, &len);
+
+ if (index != -1) {
+ TRACE("Parsed stylesheet executable");
+ message = "";
+ }
+ return (output[0] == '\0') || (index != -1);
+}
+
+bool
+XsldbgDriver::parseCoreFile(const char *output)
+{
+ TRACE("XsldbgDriver::parseCoreFile");
+ TRACE(output);
+ QRegExp exp(".*Load of data file deferred. Use the run command.*");
+ int len, index = exp.match(output, 0, &len);
+
+ if (index != -1) {
+ m_haveCoreFile = true;
+ TRACE("Parsed data file name");
+ }
+
+ return m_haveCoreFile;
+}
+
+uint
+XsldbgDriver::parseProgramStopped(const char *output, QString & message)
+{
+ /* Not sure about this function leave it here for the moment */
+ /*
+ * return DebuggerDriver::SFrefreshBreak & DebuggerDriver::SFprogramActive;
+ */
+
+ // go through the output, line by line, checking what we have
+ const char *start = output - 1;
+ uint flags = SFprogramActive;
+
+ message = QString();
+ do {
+ start++; /* skip '\n' */
+
+ if (strncmp(start, "Finished stylesheet\n\032\032\n", 21) == 0){
+ // flags &= ~SFprogramActive;
+ break;
+ }
+
+ // next line, please
+ start = strchr(start, '\n');
+ } while (start != 0);
+
+ return flags;
+}
+
+QStringList
+XsldbgDriver::parseSharedLibs(const char */*output*/)
+{
+ return QStringList();
+}
+
+bool
+XsldbgDriver::parseFindType(const char */*output*/, QString & /*type*/)
+{
+ return true;
+}
+
+std::list<RegisterInfo>
+XsldbgDriver::parseRegisters(const char */*output*/)
+{
+ return std::list<RegisterInfo>();
+}
+
+bool
+XsldbgDriver::parseInfoLine(const char */*output*/, QString & /*addrFrom*/,
+ QString & /*addrTo*/)
+{
+ return false;
+}
+
+std::list<DisassembledCode>
+XsldbgDriver::parseDisassemble(const char */*output*/)
+{
+ return std::list<DisassembledCode>();
+}
+
+QString
+XsldbgDriver::parseMemoryDump(const char */*output*/,
+ std::list < MemoryDump > &/*memdump*/)
+{
+ return i18n("No memory dump available");
+}
+
+QString
+XsldbgDriver::parseSetVariable(const char */*output*/)
+{
+ QString msg;
+ return msg;
+}
+
+
+#include "xsldbgdriver.moc"
diff --git a/kdbg/xsldbgdriver.h b/kdbg/xsldbgdriver.h
new file mode 100644
index 0000000..f27b09d
--- /dev/null
+++ b/kdbg/xsldbgdriver.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright Johannes Sixt, Keith Isdale
+ * This file is licensed under the GNU General Public License Version 2.
+ * See the file COPYING in the toplevel directory of the source directory.
+ */
+
+#ifndef XSLDBGDRIVER_H
+#define XSLDBGDRIVER_H
+
+#include "dbgdriver.h"
+#include "qregexp.h"
+
+
+class XsldbgDriver:public DebuggerDriver {
+ Q_OBJECT public:
+ XsldbgDriver();
+ ~XsldbgDriver();
+
+ virtual QString driverName() const;
+ virtual QString defaultInvocation() const;
+ virtual QStringList boolOptionList() const;
+ static QString defaultXsldbg();
+ virtual bool startup(QString cmdStr);
+ virtual void commandFinished(CmdQueueItem * cmd);
+ void slotReceiveOutput(KProcess * process, char *buffer, int buflen);
+
+ virtual CmdQueueItem *executeCmd(DbgCommand, bool clearLow = false);
+ virtual CmdQueueItem *executeCmd(DbgCommand, QString strArg,
+ bool clearLow = false);
+ virtual CmdQueueItem *executeCmd(DbgCommand, int intArg,
+ bool clearLow = false);
+ virtual CmdQueueItem *executeCmd(DbgCommand, QString strArg,
+ int intArg, bool clearLow = false);
+ virtual CmdQueueItem *executeCmd(DbgCommand, QString strArg1,
+ QString strArg2, bool clearLow =
+ false);
+ virtual CmdQueueItem *executeCmd(DbgCommand, int intArg1, int intArg2,
+ bool clearLow = false);
+ virtual CmdQueueItem *queueCmd(DbgCommand, QueueMode mode);
+ virtual CmdQueueItem *queueCmd(DbgCommand, QString strArg,
+ QueueMode mode);
+ virtual CmdQueueItem *queueCmd(DbgCommand, int intArg, QueueMode mode);
+ virtual CmdQueueItem *queueCmd(DbgCommand, QString strArg, int intArg,
+ QueueMode mode);
+ virtual CmdQueueItem *queueCmd(DbgCommand, QString strArg1,
+ QString strArg2, QueueMode mode);
+
+ virtual void terminate();
+ virtual void detachAndTerminate();
+ virtual void interruptInferior();
+
+ virtual void setPrintQStringDataCmd(const char* cmd);
+ /**
+ * Parses the output as an array of QChars.
+ */
+ virtual ExprValue *parseQCharArray(const char *output,
+ bool wantErrorValue, bool qt3like);
+
+ virtual void parseBackTrace(const char *output,
+ std::list < StackFrame > &stack);
+ virtual bool parseFrameChange(const char *output, int &frameNo,
+ QString & file, int &lineNo,
+ DbgAddr & address);
+ virtual bool parseBreakList(const char *output,
+ std::list < Breakpoint > &brks);
+ virtual std::list<ThreadInfo> parseThreadList(const char *output);
+ virtual bool parseBreakpoint(const char *output, int &id,
+ QString & file, int &lineNo, QString& address);
+ virtual void parseLocals(const char *output,
+ std::list < ExprValue* > &newVars);
+ virtual ExprValue * parsePrintExpr(const char *output, bool wantErrorValue);
+ virtual bool parseChangeWD(const char *output, QString & message);
+ virtual bool parseChangeExecutable(const char *output,
+ QString & message);
+ virtual bool parseCoreFile(const char *output);
+ virtual uint parseProgramStopped(const char *output,
+ QString & message);
+ virtual QStringList parseSharedLibs(const char *output);
+ virtual bool parseFindType(const char *output, QString & type);
+ virtual std::list<RegisterInfo> parseRegisters(const char *output);
+ virtual bool parseInfoLine(const char *output, QString & addrFrom,
+ QString & addrTo);
+ virtual std::list<DisassembledCode> parseDisassemble(const char *output);
+ virtual QString parseMemoryDump(const char *output,
+ std::list < MemoryDump > &memdump);
+ virtual QString parseSetVariable(const char* output);
+
+ protected:
+ int m_gdbMajor, m_gdbMinor;
+ QString m_programWD; /* just an intermediate storage */
+ QString m_xslFile; /* needed to display it initially */
+ bool m_haveDataFile; /* have we set the XML data file to use? */
+ QString m_redirect; /* redirection to /dev/null */
+ bool m_haveCoreFile;
+ QRegExp m_markerRE;
+
+ QString makeCmdString(DbgCommand cmd, QString strArg);
+ QString makeCmdString(DbgCommand cmd, int intArg);
+ QString makeCmdString(DbgCommand cmd, QString strArg, int intArg);
+ QString makeCmdString(DbgCommand cmd, QString strArg1,
+ QString strArg2);
+ QString makeCmdString(DbgCommand cmd, int intArg1, int intArg2);
+ void parseMarker();
+};
+
+#endif // XSLDBGDRIVER_H