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() = default; 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 if (m_suppress_immediate_output) 67 return; 68 lldb::StreamSP stream_sp(new StreamFile(file_sp)); 69 m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); 70 } 71 72 void SetImmediateErrorFile(lldb::FileSP file_sp) { 73 if (m_suppress_immediate_output) 74 return; 75 lldb::StreamSP stream_sp(new StreamFile(file_sp)); 76 m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); 77 } 78 79 void SetImmediateOutputStream(const lldb::StreamSP &stream_sp) { 80 if (m_suppress_immediate_output) 81 return; 82 m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); 83 } 84 85 void SetImmediateErrorStream(const lldb::StreamSP &stream_sp) { 86 if (m_suppress_immediate_output) 87 return; 88 m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); 89 } 90 91 lldb::StreamSP GetImmediateOutputStream() { 92 return m_out_stream.GetStreamAtIndex(eImmediateStreamIndex); 93 } 94 95 lldb::StreamSP GetImmediateErrorStream() { 96 return m_err_stream.GetStreamAtIndex(eImmediateStreamIndex); 97 } 98 99 void Clear(); 100 101 void AppendMessage(llvm::StringRef in_string); 102 103 void AppendMessageWithFormat(const char *format, ...) 104 __attribute__((format(printf, 2, 3))); 105 106 void AppendWarning(llvm::StringRef in_string); 107 108 void AppendWarningWithFormat(const char *format, ...) 109 __attribute__((format(printf, 2, 3))); 110 111 void AppendError(llvm::StringRef in_string); 112 113 void AppendRawError(llvm::StringRef in_string); 114 115 void AppendErrorWithFormat(const char *format, ...) 116 __attribute__((format(printf, 2, 3))); 117 118 template <typename... Args> 119 void AppendMessageWithFormatv(const char *format, Args &&... args) { 120 AppendMessage(llvm::formatv(format, std::forward<Args>(args)...).str()); 121 } 122 123 template <typename... Args> 124 void AppendWarningWithFormatv(const char *format, Args &&... args) { 125 AppendWarning(llvm::formatv(format, std::forward<Args>(args)...).str()); 126 } 127 128 template <typename... Args> 129 void AppendErrorWithFormatv(const char *format, Args &&... args) { 130 AppendError(llvm::formatv(format, std::forward<Args>(args)...).str()); 131 } 132 133 void SetError(const Status &error, const char *fallback_error_cstr = nullptr); 134 135 lldb::ReturnStatus GetStatus(); 136 137 void SetStatus(lldb::ReturnStatus status); 138 139 bool Succeeded(); 140 141 bool HasResult(); 142 143 bool GetDidChangeProcessState(); 144 145 void SetDidChangeProcessState(bool b); 146 147 bool GetInteractive() const; 148 149 void SetInteractive(bool b); 150 151 bool GetSuppressImmediateOutput() const; 152 153 void SetSuppressImmediateOutput(bool b); 154 155 private: 156 enum { eStreamStringIndex = 0, eImmediateStreamIndex = 1 }; 157 158 StreamTee m_out_stream; 159 StreamTee m_err_stream; 160 161 lldb::ReturnStatus m_status = lldb::eReturnStatusStarted; 162 163 bool m_did_change_process_state = false; 164 bool m_suppress_immediate_output = false; 165 166 /// If true, then the input handle from the debugger will be hooked up. 167 bool m_interactive = true; 168 }; 169 170 } // namespace lldb_private 171 172 #endif // LLDB_INTERPRETER_COMMANDRETURNOBJECT_H 173