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 |
30 | QList<Debugger> Debugger::availableInternalDebuggers(const QString & backend) |
31 | { |
32 | return availableDebuggers("debuggers/internal/*" , backend); |
33 | } |
34 | |
35 | //static |
36 | QList<Debugger> Debugger::availableExternalDebuggers(const QString & backend) |
37 | { |
38 | return availableDebuggers("debuggers/external/*" , backend); |
39 | } |
40 | |
41 | bool Debugger::isValid() const |
42 | { |
43 | return !m_config.isNull(); |
44 | } |
45 | |
46 | bool Debugger::isInstalled() const |
47 | { |
48 | QString tryexec = tryExec(); |
49 | return !tryexec.isEmpty() && !KStandardDirs::findExe(tryexec).isEmpty(); |
50 | } |
51 | |
52 | QString Debugger::name() const |
53 | { |
54 | return isValid() ? m_config->group("General" ).readEntry("Name" ) : QString(); |
55 | } |
56 | |
57 | QString 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 | |
64 | QString Debugger::tryExec() const |
65 | { |
66 | return isValid() ? m_config->group("General" ).readEntry("TryExec" ) : QString(); |
67 | } |
68 | |
69 | QStringList Debugger::supportedBackends() const |
70 | { |
71 | return isValid() ? m_config->group("General" ).readEntry("Backends" ) |
72 | .split('|', QString::SkipEmptyParts) : QStringList(); |
73 | } |
74 | |
75 | void Debugger::setUsedBackend(const QString & backendName) |
76 | { |
77 | if (supportedBackends().contains(backendName)) { |
78 | m_backend = backendName; |
79 | } |
80 | } |
81 | |
82 | QString 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 | |
91 | QString 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 | |
100 | bool 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 |
110 | void 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 |
131 | QList<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 | |