|
11 | 11 |
|
12 | 12 | namespace lldb_dap {
|
13 | 13 |
|
14 |
| -void RunLLDBCommands(llvm::StringRef prefix, |
| 14 | +bool RunLLDBCommands(llvm::StringRef prefix, |
15 | 15 | const llvm::ArrayRef<std::string> &commands,
|
16 |
| - llvm::raw_ostream &strm) { |
| 16 | + llvm::raw_ostream &strm, bool parse_command_directives) { |
17 | 17 | if (commands.empty())
|
18 |
| - return; |
| 18 | + return true; |
| 19 | + |
| 20 | + bool did_print_prefix = false; |
| 21 | + |
19 | 22 | lldb::SBCommandInterpreter interp = g_dap.debugger.GetCommandInterpreter();
|
20 |
| - if (!prefix.empty()) |
21 |
| - strm << prefix << "\n"; |
22 |
| - for (const auto &command : commands) { |
| 23 | + for (llvm::StringRef command : commands) { |
23 | 24 | lldb::SBCommandReturnObject result;
|
24 |
| - strm << "(lldb) " << command << "\n"; |
25 |
| - interp.HandleCommand(command.c_str(), result); |
26 |
| - auto output_len = result.GetOutputSize(); |
27 |
| - if (output_len) { |
28 |
| - const char *output = result.GetOutput(); |
29 |
| - strm << output; |
| 25 | + bool quiet_on_success = false; |
| 26 | + bool check_error = false; |
| 27 | + |
| 28 | + while (parse_command_directives) { |
| 29 | + if (command.starts_with("?")) { |
| 30 | + command = command.drop_front(); |
| 31 | + quiet_on_success = true; |
| 32 | + } else if (command.starts_with("!")) { |
| 33 | + command = command.drop_front(); |
| 34 | + check_error = true; |
| 35 | + } else { |
| 36 | + break; |
| 37 | + } |
30 | 38 | }
|
31 |
| - auto error_len = result.GetErrorSize(); |
32 |
| - if (error_len) { |
33 |
| - const char *error = result.GetError(); |
34 |
| - strm << error; |
| 39 | + |
| 40 | + interp.HandleCommand(command.str().c_str(), result); |
| 41 | + const bool got_error = !result.Succeeded(); |
| 42 | + // The if statement below is assuming we always print out `!` prefixed |
| 43 | + // lines. The only time we don't print is when we have `quiet_on_success == |
| 44 | + // true` and we don't have an error. |
| 45 | + if (quiet_on_success ? got_error : true) { |
| 46 | + if (!did_print_prefix && !prefix.empty()) { |
| 47 | + strm << prefix << "\n"; |
| 48 | + did_print_prefix = true; |
| 49 | + } |
| 50 | + strm << "(lldb) " << command << "\n"; |
| 51 | + auto output_len = result.GetOutputSize(); |
| 52 | + if (output_len) { |
| 53 | + const char *output = result.GetOutput(); |
| 54 | + strm << output; |
| 55 | + } |
| 56 | + auto error_len = result.GetErrorSize(); |
| 57 | + if (error_len) { |
| 58 | + const char *error = result.GetError(); |
| 59 | + strm << error; |
| 60 | + } |
35 | 61 | }
|
| 62 | + if (check_error && got_error) |
| 63 | + return false; // Stop running commands. |
36 | 64 | }
|
| 65 | + return true; |
37 | 66 | }
|
38 | 67 |
|
39 | 68 | std::string RunLLDBCommands(llvm::StringRef prefix,
|
40 |
| - const llvm::ArrayRef<std::string> &commands) { |
| 69 | + const llvm::ArrayRef<std::string> &commands, |
| 70 | + bool &required_command_failed, |
| 71 | + bool parse_command_directives) { |
| 72 | + required_command_failed = false; |
41 | 73 | std::string s;
|
42 | 74 | llvm::raw_string_ostream strm(s);
|
43 |
| - RunLLDBCommands(prefix, commands, strm); |
| 75 | + required_command_failed = |
| 76 | + !RunLLDBCommands(prefix, commands, strm, parse_command_directives); |
44 | 77 | strm.flush();
|
45 | 78 | return s;
|
46 | 79 | }
|
47 | 80 |
|
| 81 | +std::string |
| 82 | +RunLLDBCommandsVerbatim(llvm::StringRef prefix, |
| 83 | + const llvm::ArrayRef<std::string> &commands) { |
| 84 | + bool required_command_failed = false; |
| 85 | + return RunLLDBCommands(prefix, commands, required_command_failed, |
| 86 | + /*parse_command_directives=*/false); |
| 87 | +} |
| 88 | + |
48 | 89 | bool ThreadHasStopReason(lldb::SBThread &thread) {
|
49 | 90 | switch (thread.GetStopReason()) {
|
50 | 91 | case lldb::eStopReasonTrace:
|
|
0 commit comments