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