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 liblldb_CommandReturnObject_h_
10 #define liblldb_CommandReturnObject_h_
11 
12 #include "lldb/Core/StreamFile.h"
13 #include "lldb/Utility/StreamString.h"
14 #include "lldb/Utility/StreamTee.h"
15 #include "lldb/lldb-private.h"
16 
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/FormatVariadic.h"
19 
20 #include <memory>
21 
22 namespace lldb_private {
23 
24 class CommandReturnObject {
25 public:
26   CommandReturnObject();
27 
28   ~CommandReturnObject();
29 
30   llvm::StringRef GetOutputData() {
31     lldb::StreamSP stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex));
32     if (stream_sp)
33       return static_pointer_cast<StreamString>(stream_sp)->GetString();
34     return llvm::StringRef();
35   }
36 
37   llvm::StringRef GetErrorData() {
38     lldb::StreamSP stream_sp(m_err_stream.GetStreamAtIndex(eStreamStringIndex));
39     if (stream_sp)
40       return static_pointer_cast<StreamString>(stream_sp)->GetString();
41     return llvm::StringRef();
42   }
43 
44   Stream &GetOutputStream() {
45     // Make sure we at least have our normal string stream output stream
46     lldb::StreamSP stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex));
47     if (!stream_sp) {
48       stream_sp.reset(new StreamString());
49       m_out_stream.SetStreamAtIndex(eStreamStringIndex, stream_sp);
50     }
51     return m_out_stream;
52   }
53 
54   Stream &GetErrorStream() {
55     // Make sure we at least have our normal string stream output stream
56     lldb::StreamSP stream_sp(m_err_stream.GetStreamAtIndex(eStreamStringIndex));
57     if (!stream_sp) {
58       stream_sp.reset(new StreamString());
59       m_err_stream.SetStreamAtIndex(eStreamStringIndex, stream_sp);
60     }
61     return m_err_stream;
62   }
63 
64   void SetImmediateOutputFile(lldb::FileSP file_sp) {
65     lldb::StreamSP stream_sp(new StreamFile(file_sp));
66     m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
67   }
68 
69   void SetImmediateErrorFile(lldb::FileSP file_sp) {
70     lldb::StreamSP stream_sp(new StreamFile(file_sp));
71     m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
72   }
73 
74   void SetImmediateOutputStream(const lldb::StreamSP &stream_sp) {
75     m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
76   }
77 
78   void SetImmediateErrorStream(const lldb::StreamSP &stream_sp) {
79     m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
80   }
81 
82   lldb::StreamSP GetImmediateOutputStream() {
83     return m_out_stream.GetStreamAtIndex(eImmediateStreamIndex);
84   }
85 
86   lldb::StreamSP GetImmediateErrorStream() {
87     return m_err_stream.GetStreamAtIndex(eImmediateStreamIndex);
88   }
89 
90   void Clear();
91 
92   void AppendMessage(llvm::StringRef in_string);
93 
94   void AppendMessageWithFormat(const char *format, ...)
95       __attribute__((format(printf, 2, 3)));
96 
97   void AppendRawWarning(llvm::StringRef in_string);
98 
99   void AppendWarning(llvm::StringRef in_string);
100 
101   void AppendWarningWithFormat(const char *format, ...)
102       __attribute__((format(printf, 2, 3)));
103 
104   void AppendError(llvm::StringRef in_string);
105 
106   void AppendRawError(llvm::StringRef in_string);
107 
108   void AppendErrorWithFormat(const char *format, ...)
109       __attribute__((format(printf, 2, 3)));
110 
111   template <typename... Args>
112   void AppendMessageWithFormatv(const char *format, Args &&... args) {
113     AppendMessage(llvm::formatv(format, std::forward<Args>(args)...).str());
114   }
115 
116   template <typename... Args>
117   void AppendWarningWithFormatv(const char *format, Args &&... args) {
118     AppendWarning(llvm::formatv(format, std::forward<Args>(args)...).str());
119   }
120 
121   template <typename... Args>
122   void AppendErrorWithFormatv(const char *format, Args &&... args) {
123     AppendError(llvm::formatv(format, std::forward<Args>(args)...).str());
124   }
125 
126   void SetError(const Status &error, const char *fallback_error_cstr = nullptr);
127 
128   void SetError(llvm::StringRef error_cstr);
129 
130   lldb::ReturnStatus GetStatus();
131 
132   void SetStatus(lldb::ReturnStatus status);
133 
134   bool Succeeded();
135 
136   bool HasResult();
137 
138   bool GetDidChangeProcessState();
139 
140   void SetDidChangeProcessState(bool b);
141 
142   bool GetInteractive() const;
143 
144   void SetInteractive(bool b);
145 
146 private:
147   enum { eStreamStringIndex = 0, eImmediateStreamIndex = 1 };
148 
149   StreamTee m_out_stream;
150   StreamTee m_err_stream;
151 
152   lldb::ReturnStatus m_status;
153   bool m_did_change_process_state;
154   bool m_interactive; // If true, then the input handle from the debugger will
155                       // be hooked up
156 };
157 
158 } // namespace lldb_private
159 
160 #endif // liblldb_CommandReturnObject_h_
161