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 m_status(eReturnStatusStarted), m_did_change_process_state(false), 46 m_interactive(true) {} 47 48 void CommandReturnObject::AppendErrorWithFormat(const char *format, ...) { 49 SetStatus(eReturnStatusFailed); 50 51 if (!format) 52 return; 53 va_list args; 54 va_start(args, format); 55 StreamString sstrm; 56 sstrm.PrintfVarArg(format, args); 57 va_end(args); 58 59 const std::string &s = std::string(sstrm.GetString()); 60 if (!s.empty()) { 61 error(GetErrorStream()); 62 DumpStringToStreamWithNewline(GetErrorStream(), s); 63 } 64 } 65 66 void CommandReturnObject::AppendMessageWithFormat(const char *format, ...) { 67 if (!format) 68 return; 69 va_list args; 70 va_start(args, format); 71 StreamString sstrm; 72 sstrm.PrintfVarArg(format, args); 73 va_end(args); 74 75 GetOutputStream() << sstrm.GetString(); 76 } 77 78 void CommandReturnObject::AppendWarningWithFormat(const char *format, ...) { 79 if (!format) 80 return; 81 va_list args; 82 va_start(args, format); 83 StreamString sstrm; 84 sstrm.PrintfVarArg(format, args); 85 va_end(args); 86 87 warning(GetErrorStream()) << sstrm.GetString(); 88 } 89 90 void CommandReturnObject::AppendMessage(llvm::StringRef in_string) { 91 if (in_string.empty()) 92 return; 93 GetOutputStream() << in_string.rtrim() << '\n'; 94 } 95 96 void CommandReturnObject::AppendWarning(llvm::StringRef in_string) { 97 if (in_string.empty()) 98 return; 99 warning(GetErrorStream()) << in_string.rtrim() << '\n'; 100 } 101 102 void CommandReturnObject::AppendError(llvm::StringRef in_string) { 103 if (in_string.empty()) 104 return; 105 SetStatus(eReturnStatusFailed); 106 error(GetErrorStream()) << in_string.rtrim() << '\n'; 107 } 108 109 void CommandReturnObject::SetError(const Status &error, 110 const char *fallback_error_cstr) { 111 const char *error_cstr = error.AsCString(); 112 if (error_cstr == nullptr) 113 error_cstr = fallback_error_cstr; 114 SetError(error_cstr); 115 } 116 117 void CommandReturnObject::SetError(llvm::StringRef error_str) { 118 if (error_str.empty()) 119 return; 120 121 AppendError(error_str); 122 } 123 124 // Similar to AppendError, but do not prepend 'Status: ' to message, and don't 125 // append "\n" to the end of it. 126 127 void CommandReturnObject::AppendRawError(llvm::StringRef in_string) { 128 if (in_string.empty()) 129 return; 130 GetErrorStream() << in_string; 131 SetStatus(eReturnStatusFailed); 132 } 133 134 void CommandReturnObject::SetStatus(ReturnStatus status) { m_status = status; } 135 136 ReturnStatus CommandReturnObject::GetStatus() { return m_status; } 137 138 bool CommandReturnObject::Succeeded() { 139 return m_status <= eReturnStatusSuccessContinuingResult; 140 } 141 142 bool CommandReturnObject::HasResult() { 143 return (m_status == eReturnStatusSuccessFinishResult || 144 m_status == eReturnStatusSuccessContinuingResult); 145 } 146 147 void CommandReturnObject::Clear() { 148 lldb::StreamSP stream_sp; 149 stream_sp = m_out_stream.GetStreamAtIndex(eStreamStringIndex); 150 if (stream_sp) 151 static_cast<StreamString *>(stream_sp.get())->Clear(); 152 stream_sp = m_err_stream.GetStreamAtIndex(eStreamStringIndex); 153 if (stream_sp) 154 static_cast<StreamString *>(stream_sp.get())->Clear(); 155 m_status = eReturnStatusStarted; 156 m_did_change_process_state = false; 157 m_interactive = true; 158 } 159 160 bool CommandReturnObject::GetDidChangeProcessState() { 161 return m_did_change_process_state; 162 } 163 164 void CommandReturnObject::SetDidChangeProcessState(bool b) { 165 m_did_change_process_state = b; 166 } 167 168 bool CommandReturnObject::GetInteractive() const { return m_interactive; } 169 170 void CommandReturnObject::SetInteractive(bool b) { m_interactive = b; } 171