1 //===-- CommandReturnObject.cpp -------------------------------------------===// 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 #include "lldb/Interpreter/CommandReturnObject.h" 10 11 #include "lldb/Utility/Status.h" 12 #include "lldb/Utility/StreamString.h" 13 14 using namespace lldb; 15 using namespace lldb_private; 16 17 static llvm::raw_ostream &error(Stream &strm) { 18 return llvm::WithColor(strm.AsRawOstream(), llvm::HighlightColor::Error, 19 llvm::ColorMode::Enable) 20 << "error: "; 21 } 22 23 static llvm::raw_ostream &warning(Stream &strm) { 24 return llvm::WithColor(strm.AsRawOstream(), llvm::HighlightColor::Warning, 25 llvm::ColorMode::Enable) 26 << "warning: "; 27 } 28 29 static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s) { 30 bool add_newline = false; 31 if (!s.empty()) { 32 // We already checked for empty above, now make sure there is a newline in 33 // the error, and if there isn't one, add one. 34 strm.Write(s.c_str(), s.size()); 35 36 const char last_char = *s.rbegin(); 37 add_newline = last_char != '\n' && last_char != '\r'; 38 } 39 if (add_newline) 40 strm.EOL(); 41 } 42 43 CommandReturnObject::CommandReturnObject(bool colors) 44 : m_out_stream(colors), m_err_stream(colors) {} 45 46 void CommandReturnObject::AppendErrorWithFormat(const char *format, ...) { 47 if (!format) 48 return; 49 va_list args; 50 va_start(args, format); 51 StreamString sstrm; 52 sstrm.PrintfVarArg(format, args); 53 va_end(args); 54 55 const std::string &s = std::string(sstrm.GetString()); 56 if (!s.empty()) { 57 error(GetErrorStream()); 58 DumpStringToStreamWithNewline(GetErrorStream(), s); 59 } 60 } 61 62 void CommandReturnObject::AppendMessageWithFormat(const char *format, ...) { 63 if (!format) 64 return; 65 va_list args; 66 va_start(args, format); 67 StreamString sstrm; 68 sstrm.PrintfVarArg(format, args); 69 va_end(args); 70 71 GetOutputStream() << sstrm.GetString(); 72 } 73 74 void CommandReturnObject::AppendWarningWithFormat(const char *format, ...) { 75 if (!format) 76 return; 77 va_list args; 78 va_start(args, format); 79 StreamString sstrm; 80 sstrm.PrintfVarArg(format, args); 81 va_end(args); 82 83 warning(GetErrorStream()) << sstrm.GetString(); 84 } 85 86 void CommandReturnObject::AppendMessage(llvm::StringRef in_string) { 87 if (in_string.empty()) 88 return; 89 GetOutputStream() << in_string.rtrim() << '\n'; 90 } 91 92 void CommandReturnObject::AppendWarning(llvm::StringRef in_string) { 93 if (in_string.empty()) 94 return; 95 warning(GetErrorStream()) << in_string.rtrim() << '\n'; 96 } 97 98 void CommandReturnObject::AppendError(llvm::StringRef in_string) { 99 if (in_string.empty()) 100 return; 101 error(GetErrorStream()) << in_string.rtrim() << '\n'; 102 } 103 104 void CommandReturnObject::SetError(const Status &error, 105 const char *fallback_error_cstr) { 106 const char *error_cstr = error.AsCString(); 107 if (error_cstr == nullptr) 108 error_cstr = fallback_error_cstr; 109 SetError(error_cstr); 110 } 111 112 void CommandReturnObject::SetError(llvm::StringRef error_str) { 113 if (error_str.empty()) 114 return; 115 116 AppendError(error_str); 117 SetStatus(eReturnStatusFailed); 118 } 119 120 // Similar to AppendError, but do not prepend 'Status: ' to message, and don't 121 // append "\n" to the end of it. 122 123 void CommandReturnObject::AppendRawError(llvm::StringRef in_string) { 124 if (in_string.empty()) 125 return; 126 GetErrorStream() << in_string; 127 } 128 129 void CommandReturnObject::SetStatus(ReturnStatus status) { m_status = status; } 130 131 ReturnStatus CommandReturnObject::GetStatus() { return m_status; } 132 133 bool CommandReturnObject::Succeeded() { 134 return m_status <= eReturnStatusSuccessContinuingResult; 135 } 136 137 bool CommandReturnObject::HasResult() { 138 return (m_status == eReturnStatusSuccessFinishResult || 139 m_status == eReturnStatusSuccessContinuingResult); 140 } 141 142 void CommandReturnObject::Clear() { 143 lldb::StreamSP stream_sp; 144 stream_sp = m_out_stream.GetStreamAtIndex(eStreamStringIndex); 145 if (stream_sp) 146 static_cast<StreamString *>(stream_sp.get())->Clear(); 147 stream_sp = m_err_stream.GetStreamAtIndex(eStreamStringIndex); 148 if (stream_sp) 149 static_cast<StreamString *>(stream_sp.get())->Clear(); 150 m_status = eReturnStatusStarted; 151 m_did_change_process_state = false; 152 m_suppress_immediate_output = false; 153 m_interactive = true; 154 } 155 156 bool CommandReturnObject::GetDidChangeProcessState() { 157 return m_did_change_process_state; 158 } 159 160 void CommandReturnObject::SetDidChangeProcessState(bool b) { 161 m_did_change_process_state = b; 162 } 163 164 bool CommandReturnObject::GetInteractive() const { return m_interactive; } 165 166 void CommandReturnObject::SetInteractive(bool b) { m_interactive = b; } 167 168 bool CommandReturnObject::GetSuppressImmediateOutput() const { 169 return m_suppress_immediate_output; 170 } 171 172 void CommandReturnObject::SetSuppressImmediateOutput(bool b) { 173 m_suppress_immediate_output = b; 174 } 175