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