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