1
|
#include "ide.h"
|
2
|
|
3
|
void Ide::RunArgs() {
|
4
|
WithRunLayout<TopWindow> dlg;
|
5
|
CtrlLayoutOKCancel(dlg, "Run options");
|
6
|
|
7
|
#ifndef PLATFORM_POSIX
|
8
|
dlg.consolemode.Hide();
|
9
|
dlg.console_lable.Hide();
|
10
|
#endif
|
11
|
|
12
|
SelectDirButton dir_browse("Run in folder");
|
13
|
dir_browse.Attach(dlg.dir);
|
14
|
dlg.dir = rundir.ToWString();
|
15
|
|
16
|
dlg.arg <<= runarg;
|
17
|
|
18
|
{
|
19
|
StringStream ss(recent_runarg);
|
20
|
dlg.arg.SerializeList(ss);
|
21
|
}
|
22
|
|
23
|
SaveFileButton stdout_browse("Save STDOUT as");
|
24
|
stdout_browse.Type("Text files (*.txt)", "*.txt").AllFilesType();
|
25
|
stdout_browse.Attach(dlg.stdout_file);
|
26
|
|
27
|
{
|
28
|
StringStream ss(recent_stdout_file);
|
29
|
dlg.stdout_file.SerializeList(ss);
|
30
|
dlg.stdout_file <<= stdout_file;
|
31
|
}
|
32
|
|
33
|
dlg.runmode <<= runmode;
|
34
|
dlg.external = runexternal;
|
35
|
dlg.consolemode = consolemode;
|
36
|
dlg.runmode <<= dlg.Breaker(222);
|
37
|
|
38
|
for(;;) {
|
39
|
int rm = ~dlg.runmode;
|
40
|
dlg.stdout_file.Enable(rm == RUN_FILE || rm == RUN_FILE_CONSOLE);
|
41
|
switch(dlg.Run()) {
|
42
|
case IDOK:
|
43
|
rundir = dlg.dir;
|
44
|
runarg = ~dlg.arg;
|
45
|
runmode = ~dlg.runmode;
|
46
|
runexternal = dlg.external;
|
47
|
consolemode = dlg.consolemode;
|
48
|
stdout_file = ~dlg.stdout_file;
|
49
|
dlg.arg.AddHistory();
|
50
|
{
|
51
|
StringStream ss;
|
52
|
dlg.arg.SerializeList(ss);
|
53
|
recent_runarg = ss;
|
54
|
}
|
55
|
{
|
56
|
StringStream ss;
|
57
|
dlg.stdout_file.SerializeList(ss);
|
58
|
recent_stdout_file = ss;
|
59
|
}
|
60
|
return;
|
61
|
|
62
|
case IDCANCEL:
|
63
|
return;
|
64
|
}
|
65
|
}
|
66
|
}
|
67
|
|
68
|
One<Host> Ide::CreateHostRunDir()
|
69
|
{
|
70
|
One<Host> h = CreateHost(false);
|
71
|
if(IsNull(rundir))
|
72
|
h->ChDir(GetFileFolder(target));
|
73
|
else
|
74
|
h->ChDir(rundir);
|
75
|
return h;
|
76
|
}
|
77
|
|
78
|
bool Ide::ShouldHaveConsole()
|
79
|
{
|
80
|
return decode(consolemode, 0, FindIndex(SplitFlags(mainconfigparam, true), "GUI") < 0,
|
81
|
1, true, false);
|
82
|
}
|
83
|
|
84
|
void Ide::BuildAndExecute()
|
85
|
{
|
86
|
if(Build()) {
|
87
|
int time = msecs();
|
88
|
One<Host> h = CreateHostRunDir();
|
89
|
h->ChDir(Nvl(rundir, GetFileFolder(target)));
|
90
|
String cmdline;
|
91
|
if(!runexternal)
|
92
|
cmdline << '\"' << h->GetHostPath(target) << "\" ";
|
93
|
cmdline << ToSystemCharset(runarg);
|
94
|
int exitcode;
|
95
|
switch(runmode) {
|
96
|
case RUN_WINDOW:
|
97
|
HideBottom();
|
98
|
h->Launch(cmdline, ShouldHaveConsole());
|
99
|
break;
|
100
|
case RUN_CONSOLE:
|
101
|
ShowConsole();
|
102
|
PutConsole(String().Cat() << "Executing: " << cmdline);
|
103
|
console.Sync();
|
104
|
exitcode = h->ExecuteWithInput(cmdline);
|
105
|
PutConsole("Finished in " + GetPrintTime(time) + ", exit code: " + AsString(exitcode));
|
106
|
break;
|
107
|
case RUN_FILE: {
|
108
|
HideBottom();
|
109
|
String fn;
|
110
|
if(IsNull(stdout_file))
|
111
|
fn = ForceExt(target, ".ol");
|
112
|
else
|
113
|
fn = stdout_file;
|
114
|
FileOut out(fn);
|
115
|
if(!out) {
|
116
|
PromptOK("Unable to open output file [* " + DeQtf(stdout_file) + "] !");
|
117
|
return;
|
118
|
}
|
119
|
if(h->Execute(cmdline, out) >= 0) {
|
120
|
out.Close();
|
121
|
EditFile(fn);
|
122
|
}
|
123
|
}
|
124
|
}
|
125
|
}
|
126
|
}
|
127
|
|
128
|
void Ide::BuildAndDebug0(const String& srcfile)
|
129
|
{
|
130
|
if(Build()) {
|
131
|
One<Host> h = CreateHostRunDir();
|
132
|
h->ChDir(GetFileFolder(target));
|
133
|
VectorMap<String, String> bm = GetMethodVars(method);
|
134
|
String dbg = bm.Get("DEBUGGER", Null);
|
135
|
if(IsNull(dbg)) {
|
136
|
if(bm.Get("BUILDER", Null) == "MSC71") {
|
137
|
String sln = ForceExt(target, ".sln");
|
138
|
if(GetFileLength(sln) > 0)
|
139
|
h->Launch("devenv \"" + h->GetHostPath(sln) + "\" "
|
140
|
|
141
|
);
|
142
|
else
|
143
|
h->Launch("devenv \"" + h->GetHostPath(target)
|
144
|
|
145
|
+ "\" /debugexe "
|
146
|
);
|
147
|
return;
|
148
|
}
|
149
|
dbg = "gdb";
|
150
|
}
|
151
|
else
|
152
|
h->Launch('\"' + dbg + "\" \""
|
153
|
|
154
|
+ h->GetHostPath(target) + "\"", true);
|
155
|
}
|
156
|
}
|
157
|
|
158
|
void Ide::BuildAndExtDebug()
|
159
|
{
|
160
|
BuildAndDebug0(Null);
|
161
|
}
|
162
|
|
163
|
void Ide::BuildAndExtDebugFile()
|
164
|
{
|
165
|
BuildAndDebug0(editfile);
|
166
|
}
|
167
|
|
168
|
One<Debugger> GdbCreate(One<Host> rval_ host, const String& exefile, const String& cmdline, bool console);
|
169
|
One<Debugger> Gdb_MI2Create(One<Host> rval_ host, const String& exefile, const String& cmdline, bool console);
|
170
|
#ifdef PLATFORM_WIN32
|
171
|
One<Debugger> CdbCreate(One<Host> rval_ host, const String& exefile, const String& cmdline);
|
172
|
One<Debugger> PdbCreate(One<Host> rval_ host, const String& exefile, const String& cmdline);
|
173
|
#endif
|
174
|
|
175
|
void Ide::BuildAndDebug(bool runto)
|
176
|
{
|
177
|
VectorMap<String, String> bm = GetMethodVars(method);
|
178
|
String builder = bm.Get("BUILDER", "");
|
179
|
if(!Build())
|
180
|
return;
|
181
|
if(!FileExists(target))
|
182
|
return;
|
183
|
if(designer)
|
184
|
EditAsText();
|
185
|
One<Host> host = CreateHostRunDir();
|
186
|
host->ChDir(Nvl(rundir, GetFileFolder(target)));
|
187
|
HideBottom();
|
188
|
editor.Disable();
|
189
|
|
190
|
bool console = ShouldHaveConsole();
|
191
|
#ifdef COMPILER_MSC
|
192
|
if(builder == "GCC")
|
193
|
if(gdbSelector)
|
194
|
debugger = Gdb_MI2Create(host, target, runarg, console);
|
195
|
else
|
196
|
debugger = GdbCreate(host, target, runarg, console);
|
197
|
else
|
198
|
debugger = PdbCreate(host, target, runarg);
|
199
|
#else
|
200
|
if(gdbSelector)
|
201
|
debugger = Gdb_MI2Create(pick(host), target, runarg, console);
|
202
|
else
|
203
|
debugger = GdbCreate(pick(host), target, runarg, console);
|
204
|
#endif
|
205
|
if(!debugger) {
|
206
|
IdeEndDebug();
|
207
|
SetBar();
|
208
|
editor.Enable();
|
209
|
return;
|
210
|
}
|
211
|
debuglock = 0;
|
212
|
const Workspace& wspc = IdeWorkspace();
|
213
|
for(int i = 0; i < wspc.GetCount(); i++) {
|
214
|
const Package& pk = wspc.GetPackage(i);
|
215
|
String n = wspc[i];
|
216
|
for(int i = 0; i < pk.file.GetCount(); i++) {
|
217
|
String file = SourcePath(n, pk.file[i]);
|
218
|
LineInfo& ln = Filedata(file).lineinfo;
|
219
|
for(int i = 0; i < ln.GetCount(); i++) {
|
220
|
LineInfoRecord& lr = ln[i];
|
221
|
if(!lr.breakpoint.IsEmpty())
|
222
|
if(!debugger->SetBreakpoint(file, lr.lineno, lr.breakpoint)) {
|
223
|
lr.breakpoint = "\xe";
|
224
|
if(PathIsEqual(file, editfile))
|
225
|
editor.SetBreakpoint(lr.lineno, "\xe");
|
226
|
}
|
227
|
}
|
228
|
}
|
229
|
}
|
230
|
SetBar();
|
231
|
editor.Enable();
|
232
|
if(runto) {
|
233
|
if(!debugger->RunTo())
|
234
|
IdeEndDebug();
|
235
|
}
|
236
|
else
|
237
|
debugger->Run();
|
238
|
}
|
239
|
|
240
|
void Ide::DebugClearBreakpoints()
|
241
|
{
|
242
|
const Workspace& wspc = IdeWorkspace();
|
243
|
for(int i = 0; i < wspc.GetCount(); i++) {
|
244
|
const Package& pk = wspc.GetPackage(i);
|
245
|
String n = wspc[i];
|
246
|
for(int i = 0; i < pk.file.GetCount(); i++) {
|
247
|
String file = SourcePath(n, pk.file[i]);
|
248
|
LineInfo& ln = Filedata(file).lineinfo;
|
249
|
if(debugger)
|
250
|
for(int i = 0; i < ln.GetCount(); i++) {
|
251
|
const LineInfoRecord& lr = ln[i];
|
252
|
if(!lr.breakpoint.IsEmpty())
|
253
|
debugger->SetBreakpoint(file, lr.lineno, "");
|
254
|
}
|
255
|
ClearBreakpoints(ln);
|
256
|
}
|
257
|
}
|
258
|
editor.ClearBreakpoints();
|
259
|
}
|
260
|
|
261
|
void Ide::OnBreakpoint(int i)
|
262
|
{
|
263
|
if(!editfile.IsEmpty() && !designer && debugger) {
|
264
|
String q = editor.GetBreakpoint(i);
|
265
|
if(q[0] != 0xe && !debugger->SetBreakpoint(editfile, i, q))
|
266
|
if(!q.IsEmpty())
|
267
|
editor.SetBreakpoint(i, "\xe");
|
268
|
}
|
269
|
}
|
270
|
|
271
|
void Ide::DebugToggleBreak()
|
272
|
{
|
273
|
if(editfile.IsEmpty() || designer)
|
274
|
return;
|
275
|
int ln = editor.GetCursorLine();
|
276
|
String brk = editor.GetBreakpoint(ln);
|
277
|
if(!brk.IsEmpty())
|
278
|
editor.SetBreakpoint(ln, Null);
|
279
|
else
|
280
|
editor.SetBreakpoint(ln, "1");
|
281
|
editor.RefreshFrame();
|
282
|
}
|
283
|
|
284
|
void Ide::ConditionalBreak()
|
285
|
{
|
286
|
if(editfile.IsEmpty() || designer)
|
287
|
return;
|
288
|
int ln = editor.GetCursorLine();
|
289
|
String brk = editor.GetBreakpoint(ln);
|
290
|
if(EditText(brk, "Conditional breakpoint", "Condition"))
|
291
|
editor.SetBreakpoint(ln, brk);
|
292
|
editor.RefreshFrame();
|
293
|
}
|
294
|
|
295
|
void Ide::StopDebug()
|
296
|
{
|
297
|
if(debugger)
|
298
|
debugger->Stop();
|
299
|
console.Kill();
|
300
|
PosSync();
|
301
|
}
|
302
|
|
303
|
String Ide::GetLogPath()
|
304
|
{
|
305
|
if(target.GetCount() == 0)
|
306
|
return Null;
|
307
|
#ifdef PLATFORM_WIN32
|
308
|
return ForceExt(target, ".log");
|
309
|
#else
|
310
|
String p = GetFileTitle(target);
|
311
|
return GetHomeDirFile(".upp/" + p + "/" + p + ".log");
|
312
|
#endif
|
313
|
}
|
314
|
|
315
|
void Ide::OpenLog()
|
316
|
{
|
317
|
String p = GetLogPath();
|
318
|
if(FileExists(p))
|
319
|
EditFile(p);
|
320
|
}
|
321
|
|
322
|
bool Ide::EditorTip(CodeEditor::MouseTip& mt)
|
323
|
{
|
324
|
return debugger && debugger->Tip(editor.ReadIdBack(mt.pos), mt);
|
325
|
}
|