xref: /llvm-project/lldb/include/lldb/Interpreter/CommandReturnObject.h (revision 79178ca689a8259d19d93320a6299e3d31383ac4)
1 //===-- CommandReturnObject.h -----------------------------------*- C++ -*-===//
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 #ifndef LLDB_INTERPRETER_COMMANDRETURNOBJECT_H
10 #define LLDB_INTERPRETER_COMMANDRETURNOBJECT_H
11 
12 #include "lldb/Host/StreamFile.h"
13 #include "lldb/Utility/DiagnosticsRendering.h"
14 #include "lldb/Utility/StreamString.h"
15 #include "lldb/Utility/StreamTee.h"
16 #include "lldb/Utility/StructuredData.h"
17 #include "lldb/lldb-private.h"
18 
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Support/Error.h"
21 #include "llvm/Support/FormatVariadic.h"
22 #include "llvm/Support/WithColor.h"
23 
24 #include <memory>
25 
26 namespace lldb_private {
27 
28 class CommandReturnObject {
29 public:
30   CommandReturnObject(bool colors);
31 
32   ~CommandReturnObject() = default;
33 
34   /// Format any inline diagnostics with an indentation of \c indent.
35   std::string GetInlineDiagnosticString(unsigned indent);
36 
37   llvm::StringRef GetOutputString() {
38     lldb::StreamSP stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex));
39     if (stream_sp)
40       return std::static_pointer_cast<StreamString>(stream_sp)->GetString();
41     return llvm::StringRef();
42   }
43 
44   /// Return the errors as a string.
45   ///
46   /// If \c with_diagnostics is true, all diagnostics are also
47   /// rendered into the string. Otherwise the expectation is that they
48   /// are fetched with \ref GetInlineDiagnosticString().
49   std::string GetErrorString(bool with_diagnostics = true);
50   StructuredData::ObjectSP GetErrorData();
51 
52   Stream &GetOutputStream() {
53     // Make sure we at least have our normal string stream output stream
54     lldb::StreamSP stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex));
55     if (!stream_sp) {
56       stream_sp = std::make_shared<StreamString>();
57       m_out_stream.SetStreamAtIndex(eStreamStringIndex, stream_sp);
58     }
59     return m_out_stream;
60   }
61 
62   Stream &GetErrorStream() {
63     // Make sure we at least have our normal string stream output stream
64     lldb::StreamSP stream_sp(m_err_stream.GetStreamAtIndex(eStreamStringIndex));
65     if (!stream_sp) {
66       stream_sp = std::make_shared<StreamString>();
67       m_err_stream.SetStreamAtIndex(eStreamStringIndex, stream_sp);
68     }
69     return m_err_stream;
70   }
71 
72   void SetImmediateOutputFile(lldb::FileSP file_sp) {
73     if (m_suppress_immediate_output)
74       return;
75     lldb::StreamSP stream_sp(new StreamFile(file_sp));
76     m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
77   }
78 
79   void SetImmediateErrorFile(lldb::FileSP file_sp) {
80     if (m_suppress_immediate_output)
81       return;
82     lldb::StreamSP stream_sp(new StreamFile(file_sp));
83     m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
84   }
85 
86   void SetImmediateOutputStream(const lldb::StreamSP &stream_sp) {
87     if (m_suppress_immediate_output)
88       return;
89     m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
90   }
91 
92   void SetImmediateErrorStream(const lldb::StreamSP &stream_sp) {
93     if (m_suppress_immediate_output)
94       return;
95     m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
96   }
97 
98   lldb::StreamSP GetImmediateOutputStream() {
99     return m_out_stream.GetStreamAtIndex(eImmediateStreamIndex);
100   }
101 
102   lldb::StreamSP GetImmediateErrorStream() {
103     return m_err_stream.GetStreamAtIndex(eImmediateStreamIndex);
104   }
105 
106   void Clear();
107 
108   void AppendMessage(llvm::StringRef in_string);
109 
110   void AppendMessageWithFormat(const char *format, ...)
111       __attribute__((format(printf, 2, 3)));
112 
113   void AppendNote(llvm::StringRef in_string);
114 
115   void AppendNoteWithFormat(const char *format, ...)
116       __attribute__((format(printf, 2, 3)));
117 
118   void AppendWarning(llvm::StringRef in_string);
119 
120   void AppendWarningWithFormat(const char *format, ...)
121       __attribute__((format(printf, 2, 3)));
122 
123   void AppendError(llvm::StringRef in_string);
124 
125   void AppendRawError(llvm::StringRef in_string);
126 
127   void AppendErrorWithFormat(const char *format, ...)
128       __attribute__((format(printf, 2, 3)));
129 
130   template <typename... Args>
131   void AppendMessageWithFormatv(const char *format, Args &&... args) {
132     AppendMessage(llvm::formatv(format, std::forward<Args>(args)...).str());
133   }
134 
135   template <typename... Args>
136   void AppendNoteWithFormatv(const char *format, Args &&...args) {
137     AppendNote(llvm::formatv(format, std::forward<Args>(args)...).str());
138   }
139 
140   template <typename... Args>
141   void AppendWarningWithFormatv(const char *format, Args &&... args) {
142     AppendWarning(llvm::formatv(format, std::forward<Args>(args)...).str());
143   }
144 
145   template <typename... Args>
146   void AppendErrorWithFormatv(const char *format, Args &&... args) {
147     AppendError(llvm::formatv(format, std::forward<Args>(args)...).str());
148   }
149 
150   void SetError(Status error);
151 
152   void SetError(llvm::Error error);
153 
154   void SetDiagnosticIndent(std::optional<uint16_t> indent) {
155     m_diagnostic_indent = indent;
156   }
157 
158   std::optional<uint16_t> GetDiagnosticIndent() const {
159     return m_diagnostic_indent;
160   }
161 
162   lldb::ReturnStatus GetStatus() const;
163 
164   void SetStatus(lldb::ReturnStatus status);
165 
166   bool Succeeded() const;
167 
168   bool HasResult() const;
169 
170   bool GetDidChangeProcessState() const;
171 
172   void SetDidChangeProcessState(bool b);
173 
174   bool GetInteractive() const;
175 
176   void SetInteractive(bool b);
177 
178   bool GetSuppressImmediateOutput() const;
179 
180   void SetSuppressImmediateOutput(bool b);
181 
182 private:
183   enum { eStreamStringIndex = 0, eImmediateStreamIndex = 1 };
184 
185   StreamTee m_out_stream;
186   StreamTee m_err_stream;
187   std::vector<DiagnosticDetail> m_diagnostics;
188   std::optional<uint16_t> m_diagnostic_indent;
189 
190   lldb::ReturnStatus m_status = lldb::eReturnStatusStarted;
191 
192   bool m_did_change_process_state = false;
193   bool m_suppress_immediate_output = false;
194 
195   /// If true, then the input handle from the debugger will be hooked up.
196   bool m_interactive = true;
197   bool m_colors;
198 };
199 
200 } // namespace lldb_private
201 
202 #endif // LLDB_INTERPRETER_COMMANDRETURNOBJECT_H
203