1/*
2 Copyright (C) 2009 George Kiagiadakis <gkiagia@users.sourceforge.net>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "debugger.h"
18
19#include <KConfig>
20#include <KConfigGroup>
21#include <KGlobal>
22#include <KStandardDirs>
23#include <KMacroExpanderBase>
24#include <KDebug>
25
26#include "crashedapplication.h"
27#include "drkonqi.h"
28
29//static
30QList<Debugger> Debugger::availableInternalDebuggers(const QString & backend)
31{
32 return availableDebuggers("debuggers/internal/*", backend);
33}
34
35//static
36QList<Debugger> Debugger::availableExternalDebuggers(const QString & backend)
37{
38 return availableDebuggers("debuggers/external/*", backend);
39}
40
41bool Debugger::isValid() const
42{
43 return !m_config.isNull();
44}
45
46bool Debugger::isInstalled() const
47{
48 QString tryexec = tryExec();
49 return !tryexec.isEmpty() && !KStandardDirs::findExe(tryexec).isEmpty();
50}
51
52QString Debugger::name() const
53{
54 return isValid() ? m_config->group("General").readEntry("Name") : QString();
55}
56
57QString Debugger::codeName() const
58{
59 //fall back to the "TryExec" string if "CodeName" is not specified.
60 //for most debuggers those strings should be the same
61 return isValid() ? m_config->group("General").readEntry("CodeName", tryExec()) : QString();
62}
63
64QString Debugger::tryExec() const
65{
66 return isValid() ? m_config->group("General").readEntry("TryExec") : QString();
67}
68
69QStringList Debugger::supportedBackends() const
70{
71 return isValid() ? m_config->group("General").readEntry("Backends")
72 .split('|', QString::SkipEmptyParts) : QStringList();
73}
74
75void Debugger::setUsedBackend(const QString & backendName)
76{
77 if (supportedBackends().contains(backendName)) {
78 m_backend = backendName;
79 }
80}
81
82QString Debugger::command() const
83{
84 if (!isValid() || !m_config->hasGroup(m_backend)) {
85 return QString();
86 } else {
87 return m_config->group(m_backend).readPathEntry("Exec", QString());
88 }
89}
90
91QString Debugger::backtraceBatchCommands() const
92{
93 if (!isValid() || !m_config->hasGroup(m_backend)) {
94 return QString();
95 } else {
96 return m_config->group(m_backend).readEntry("BatchCommands");
97 }
98}
99
100bool Debugger::runInTerminal() const
101{
102 if (!isValid() || !m_config->hasGroup(m_backend)) {
103 return false;
104 } else {
105 return m_config->group(m_backend).readEntry("Terminal", false);
106 }
107}
108
109//static
110void Debugger::expandString(QString & str, ExpandStringUsage usage, const QString & tempFile)
111{
112 const CrashedApplication *appInfo = DrKonqi::crashedApplication();
113 QHash<QString, QString> map;
114 map[QLatin1String("progname")] = appInfo->name();
115 map[QLatin1String("execname")] = appInfo->fakeExecutableBaseName();
116 map[QLatin1String("execpath")] = appInfo->executable().absoluteFilePath();
117 map[QLatin1String("signum")] = QString::number(appInfo->signalNumber());
118 map[QLatin1String("signame")] = appInfo->signalName();
119 map[QLatin1String("pid")] = QString::number(appInfo->pid());
120 map[QLatin1String("tempfile")] = tempFile;
121 map[QLatin1String("thread")] = QString::number(appInfo->thread());
122
123 if (usage == ExpansionUsageShell) {
124 str = KMacroExpander::expandMacrosShellQuote(str, map);
125 } else {
126 str = KMacroExpander::expandMacros(str, map);
127 }
128}
129
130//static
131QList<Debugger> Debugger::availableDebuggers(const char *regexp, const QString & backend)
132{
133 KStandardDirs *dirs = KGlobal::dirs();
134 QStringList debuggers = dirs->findAllResources("appdata", QLatin1String(regexp),
135 KStandardDirs::NoDuplicates);
136
137 QList<Debugger> result;
138 foreach (const QString & debuggerFile, debuggers) {
139 Debugger debugger;
140 debugger.m_config = KSharedConfig::openConfig(debuggerFile);
141 if (debugger.supportedBackends().contains(backend)) {
142 debugger.setUsedBackend(backend);
143 result.append(debugger);
144 }
145 }
146 return result;
147}
148