forked from eranif/codelite
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDapLocator.cpp
More file actions
166 lines (146 loc) · 4.77 KB
/
Copy pathDapLocator.cpp
File metadata and controls
166 lines (146 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include "DapLocator.hpp"
#include "Platform/Platform.hpp"
#include "StdToWX.h"
#include "file_logger.h"
#include "globals.h"
#include "procutils.h"
DapLocator::DapLocator() {}
DapLocator::~DapLocator() {}
size_t DapLocator::Locate(std::vector<DapEntry>* entries)
{
find_lldb_dap(entries);
find_debugpy(entries);
find_gdb(entries);
return entries->size();
}
namespace
{
wxString wrap_string(const wxString& str)
{
wxString s = str;
if (s.Contains(" ")) {
s.Prepend("\"").Append("\"");
}
return s;
}
DapEntry create_entry(const wxString& name, int port, const std::vector<wxString>& cmd, DapLaunchType launch_type)
{
DapEntry entry;
entry.SetName(name);
#ifdef __WXMSW__
entry.SetUseForwardSlash(true);
entry.SetUseVolume(false);
entry.SetUseRelativePath(false);
#else
entry.SetUseNativePath();
#endif
wxString connection_string;
connection_string << "tcp://127.0.0.1:" << port;
entry.SetConnectionString(connection_string);
wxString command;
for (const wxString& c : cmd) {
command << wrap_string(c) << " ";
}
command.RemoveLast();
entry.SetCommand(command);
entry.SetLaunchType(launch_type);
entry.SetEnvFormat(dap::EnvFormat::DICTIONARY);
return entry;
}
DapEntry create_entry_stdio(const wxString& name, const std::vector<wxString>& cmd, DapLaunchType launch_type)
{
DapEntry entry;
entry.SetName(name);
#ifdef __WXMSW__
entry.SetUseForwardSlash(true);
entry.SetUseVolume(false);
entry.SetUseRelativePath(false);
#else
entry.SetUseNativePath();
#endif
entry.SetConnectionString("stdio");
wxString command;
for (const wxString& c : cmd) {
command << wrap_string(c) << " ";
}
command.RemoveLast();
entry.SetCommand(command);
entry.SetLaunchType(launch_type);
entry.SetEnvFormat(dap::EnvFormat::DICTIONARY);
return entry;
}
} // namespace
void DapLocator::find_lldb_dap(std::vector<DapEntry>* entries)
{
// Since LLVM-18, lldb-vscode was renamed to lldb-dap, try to find it as well
const wxArrayString names = StdToWX::ToArrayString({ "lldb-dap", "lldb-vscode" });
const auto lldb_debugger = ThePlatform->AnyWhich(names);
if (!lldb_debugger) {
return;
}
const wxString entry_name = wxFileName(*lldb_debugger).GetName();
#ifdef __WXMAC__
auto entry = create_entry(entry_name, 12345, { *lldb_debugger, "--port", "12345" }, DapLaunchType::LAUNCH);
entry.SetEnvFormat(dap::EnvFormat::LIST);
entries->push_back(entry);
#else
auto entry = create_entry_stdio(entry_name, { *lldb_debugger }, DapLaunchType::LAUNCH);
entry.SetEnvFormat(dap::EnvFormat::LIST);
entries->push_back(entry);
#endif
}
void DapLocator::find_debugpy(std::vector<DapEntry>* entries)
{
// locate python3
const auto python = ThePlatform->AnyWhich(StdToWX::ToArrayString({"python", "python3"}));
if (!python) {
return;
}
// we got pip
wxString line = ProcUtils::GrepCommandOutput({ *python, "-m", "pip", "list" }, "debugpy");
if (line.empty())
return;
// we have a match
auto entry =
create_entry("debugpy", 12345,
{ *python, "-m", "debugpy", "--listen", "12345", "--wait-for-client", "$(CurrentFileFullPath)" },
DapLaunchType::ATTACH);
entry.SetUseNativePath();
entries->push_back(entry);
}
void DapLocator::find_gdb(std::vector<DapEntry>* entries)
{
// gdb, since version 14.0, supports the dap protocol
wxArrayString paths;
// locate gdb
const auto gdb = ThePlatform->Which("gdb");
if (!gdb) {
return;
}
clDEBUG() << "Found gdb at:" << *gdb << endl;
// Check the version. An example version:
// GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1
// GNU gdb (GDB) 15.2
static wxRegEx re_version(R"(GNU gdb \(.*?\) ([0-9\.]+))");
unsigned long major_version = 0;
ProcUtils::GrepCommandOutputWithCallback({ *gdb, "-v" }, [&](const wxString& line) {
clDEBUG() << "Checking line..." << line << endl;
if (re_version.IsValid() && re_version.Matches(line)) {
// Got the version line, extract its major version
auto major_version_string = re_version.GetMatch(line, 1).BeforeFirst('.');
clDEBUG() << "Found gdb line version:" << line << endl;
clDEBUG() << "Version:" << major_version_string << endl;
major_version_string.ToCULong(&major_version);
// We can stop processing lines
return true;
}
return false;
});
if (major_version >= 14) {
// we have a match
auto entry = create_entry_stdio("gdb-dap", { *gdb, "-i=dap" }, DapLaunchType::LAUNCH);
entry.SetUseForwardSlash(true);
entry.SetUseVolume(true);
entries->push_back(entry);
}
}