1 | //===-- CommandReturnObject.cpp -------------------------------------------===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "lldb/Interpreter/CommandReturnObject.h" |
10 | |
11 | #include "lldb/Utility/DiagnosticsRendering.h" |
12 | #include "lldb/Utility/Status.h" |
13 | #include "lldb/Utility/StreamString.h" |
14 | |
15 | using namespace lldb; |
16 | using namespace lldb_private; |
17 | |
18 | static llvm::raw_ostream &error(Stream &strm) { |
19 | return llvm::WithColor(strm.AsRawOstream(), llvm::HighlightColor::Error, |
20 | llvm::ColorMode::Enable) |
21 | << "error: "; |
22 | } |
23 | |
24 | static llvm::raw_ostream &warning(Stream &strm) { |
25 | return llvm::WithColor(strm.AsRawOstream(), llvm::HighlightColor::Warning, |
26 | llvm::ColorMode::Enable) |
27 | << "warning: "; |
28 | } |
29 | |
30 | static llvm::raw_ostream ¬e(Stream &strm) { |
31 | return llvm::WithColor(strm.AsRawOstream(), llvm::HighlightColor::Note, |
32 | llvm::ColorMode::Enable) |
33 | << "note: "; |
34 | } |
35 | |
36 | static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s) { |
37 | bool add_newline = false; |
38 | if (!s.empty()) { |
39 | // We already checked for empty above, now make sure there is a newline in |
40 | // the error, and if there isn't one, add one. |
41 | strm.Write(src: s.c_str(), src_len: s.size()); |
42 | |
43 | const char last_char = *s.rbegin(); |
44 | add_newline = last_char != '\n' && last_char != '\r'; |
45 | } |
46 | if (add_newline) |
47 | strm.EOL(); |
48 | } |
49 | |
50 | CommandReturnObject::CommandReturnObject(bool colors) |
51 | : m_out_stream(colors), m_err_stream(colors), m_colors(colors) {} |
52 | |
53 | void CommandReturnObject::AppendErrorWithFormat(const char *format, ...) { |
54 | SetStatus(eReturnStatusFailed); |
55 | |
56 | if (!format) |
57 | return; |
58 | va_list args; |
59 | va_start(args, format); |
60 | StreamString sstrm; |
61 | sstrm.PrintfVarArg(format, args); |
62 | va_end(args); |
63 | |
64 | const std::string &s = std::string(sstrm.GetString()); |
65 | if (!s.empty()) { |
66 | error(strm&: GetErrorStream()); |
67 | DumpStringToStreamWithNewline(strm&: GetErrorStream(), s); |
68 | } |
69 | } |
70 | |
71 | void CommandReturnObject::AppendMessageWithFormat(const char *format, ...) { |
72 | if (!format) |
73 | return; |
74 | va_list args; |
75 | va_start(args, format); |
76 | StreamString sstrm; |
77 | sstrm.PrintfVarArg(format, args); |
78 | va_end(args); |
79 | |
80 | GetOutputStream() << sstrm.GetString(); |
81 | } |
82 | |
83 | void CommandReturnObject::AppendNoteWithFormat(const char *format, ...) { |
84 | if (!format) |
85 | return; |
86 | va_list args; |
87 | va_start(args, format); |
88 | StreamString sstrm; |
89 | sstrm.PrintfVarArg(format, args); |
90 | va_end(args); |
91 | |
92 | note(strm&: GetOutputStream()) << sstrm.GetString(); |
93 | } |
94 | |
95 | void CommandReturnObject::AppendWarningWithFormat(const char *format, ...) { |
96 | if (!format) |
97 | return; |
98 | va_list args; |
99 | va_start(args, format); |
100 | StreamString sstrm; |
101 | sstrm.PrintfVarArg(format, args); |
102 | va_end(args); |
103 | |
104 | warning(strm&: GetErrorStream()) << sstrm.GetString(); |
105 | } |
106 | |
107 | void CommandReturnObject::AppendMessage(llvm::StringRef in_string) { |
108 | if (in_string.empty()) |
109 | return; |
110 | GetOutputStream() << in_string.rtrim() << '\n'; |
111 | } |
112 | |
113 | void CommandReturnObject::AppendNote(llvm::StringRef in_string) { |
114 | if (in_string.empty()) |
115 | return; |
116 | note(strm&: GetOutputStream()) << in_string.rtrim() << '\n'; |
117 | } |
118 | |
119 | void CommandReturnObject::AppendWarning(llvm::StringRef in_string) { |
120 | if (in_string.empty()) |
121 | return; |
122 | warning(strm&: GetErrorStream()) << in_string.rtrim() << '\n'; |
123 | } |
124 | |
125 | void CommandReturnObject::AppendError(llvm::StringRef in_string) { |
126 | SetStatus(eReturnStatusFailed); |
127 | if (in_string.empty()) |
128 | return; |
129 | // Workaround to deal with already fully formatted compiler diagnostics. |
130 | llvm::StringRef msg(in_string.rtrim()); |
131 | msg.consume_front(Prefix: "error: "); |
132 | error(strm&: GetErrorStream()) << msg << '\n'; |
133 | } |
134 | |
135 | void CommandReturnObject::SetError(Status error) { |
136 | SetError(error.takeError()); |
137 | } |
138 | |
139 | void CommandReturnObject::SetError(llvm::Error error) { |
140 | // Retrieve any diagnostics. |
141 | error = llvm::handleErrors(E: std::move(error), Hs: [&](DiagnosticError &error) { |
142 | SetStatus(eReturnStatusFailed); |
143 | m_diagnostics = error.GetDetails(); |
144 | }); |
145 | if (error) { |
146 | AppendError(in_string: llvm::toString(E: std::move(error))); |
147 | } |
148 | } |
149 | |
150 | std::string |
151 | CommandReturnObject::GetInlineDiagnosticString(unsigned indent) const { |
152 | StreamString diag_stream(m_colors); |
153 | RenderDiagnosticDetails(stream&: diag_stream, offset_in_command: indent, show_inline: true, details: m_diagnostics); |
154 | // Duplex the diagnostics to the secondary stream (but not inlined). |
155 | if (auto stream_sp = m_err_stream.GetStreamAtIndex(idx: eImmediateStreamIndex)) |
156 | RenderDiagnosticDetails(stream&: *stream_sp, offset_in_command: std::nullopt, show_inline: false, details: m_diagnostics); |
157 | |
158 | return diag_stream.GetString().str(); |
159 | } |
160 | |
161 | std::string CommandReturnObject::GetErrorString(bool with_diagnostics) const { |
162 | StreamString stream(m_colors); |
163 | if (with_diagnostics) |
164 | RenderDiagnosticDetails(stream, offset_in_command: std::nullopt, show_inline: false, details: m_diagnostics); |
165 | |
166 | lldb::StreamSP stream_sp(m_err_stream.GetStreamAtIndex(idx: eStreamStringIndex)); |
167 | if (stream_sp) |
168 | stream << std::static_pointer_cast<StreamString>(r: stream_sp)->GetString(); |
169 | return stream.GetString().str(); |
170 | } |
171 | |
172 | StructuredData::ObjectSP CommandReturnObject::GetErrorData() { |
173 | return Serialize(details: m_diagnostics); |
174 | } |
175 | |
176 | // Similar to AppendError, but do not prepend 'Status: ' to message, and don't |
177 | // append "\n" to the end of it. |
178 | |
179 | void CommandReturnObject::AppendRawError(llvm::StringRef in_string) { |
180 | SetStatus(eReturnStatusFailed); |
181 | assert(!in_string.empty() && "Expected a non-empty error message"); |
182 | GetErrorStream() << in_string; |
183 | } |
184 | |
185 | void CommandReturnObject::SetStatus(ReturnStatus status) { m_status = status; } |
186 | |
187 | ReturnStatus CommandReturnObject::GetStatus() const { return m_status; } |
188 | |
189 | bool CommandReturnObject::Succeeded() const { |
190 | return m_status <= eReturnStatusSuccessContinuingResult; |
191 | } |
192 | |
193 | bool CommandReturnObject::HasResult() const { |
194 | return (m_status == eReturnStatusSuccessFinishResult || |
195 | m_status == eReturnStatusSuccessContinuingResult); |
196 | } |
197 | |
198 | void CommandReturnObject::Clear() { |
199 | lldb::StreamSP stream_sp; |
200 | stream_sp = m_out_stream.GetStreamAtIndex(idx: eStreamStringIndex); |
201 | if (stream_sp) |
202 | static_cast<StreamString *>(stream_sp.get())->Clear(); |
203 | stream_sp = m_err_stream.GetStreamAtIndex(idx: eStreamStringIndex); |
204 | if (stream_sp) |
205 | static_cast<StreamString *>(stream_sp.get())->Clear(); |
206 | m_diagnostics.clear(); |
207 | m_status = eReturnStatusStarted; |
208 | m_did_change_process_state = false; |
209 | m_suppress_immediate_output = false; |
210 | m_interactive = true; |
211 | } |
212 | |
213 | bool CommandReturnObject::GetDidChangeProcessState() const { |
214 | return m_did_change_process_state; |
215 | } |
216 | |
217 | void CommandReturnObject::SetDidChangeProcessState(bool b) { |
218 | m_did_change_process_state = b; |
219 | } |
220 | |
221 | bool CommandReturnObject::GetInteractive() const { return m_interactive; } |
222 | |
223 | void CommandReturnObject::SetInteractive(bool b) { m_interactive = b; } |
224 | |
225 | bool CommandReturnObject::GetSuppressImmediateOutput() const { |
226 | return m_suppress_immediate_output; |
227 | } |
228 | |
229 | void CommandReturnObject::SetSuppressImmediateOutput(bool b) { |
230 | m_suppress_immediate_output = b; |
231 | } |
232 |
Definitions
- error
- warning
- note
- DumpStringToStreamWithNewline
- CommandReturnObject
- AppendErrorWithFormat
- AppendMessageWithFormat
- AppendNoteWithFormat
- AppendWarningWithFormat
- AppendMessage
- AppendNote
- AppendWarning
- AppendError
- SetError
- SetError
- GetInlineDiagnosticString
- GetErrorString
- GetErrorData
- AppendRawError
- SetStatus
- GetStatus
- Succeeded
- HasResult
- Clear
- GetDidChangeProcessState
- SetDidChangeProcessState
- GetInteractive
- SetInteractive
- GetSuppressImmediateOutput
Learn to use CMake with our Intro Training
Find out more