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 CommandReturnObject::~CommandReturnObject() {} 49 50 void CommandReturnObject::AppendErrorWithFormat(const char *format, ...) { 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 << "\n"; 94 } 95 96 void CommandReturnObject::AppendWarning(llvm::StringRef in_string) { 97 if (in_string.empty()) 98 return; 99 warning(GetErrorStream()) << in_string << '\n'; 100 } 101 102 // Similar to AppendWarning, but do not prepend 'warning: ' to message, and 103 // don't append "\n" to the end of it. 104 105 void CommandReturnObject::AppendRawWarning(llvm::StringRef in_string) { 106 if (in_string.empty()) 107 return; 108 GetErrorStream() << in_string; 109 } 110 111 void CommandReturnObject::AppendError(llvm::StringRef in_string) { 112 if (in_string.empty()) 113 return; 114 error(GetErrorStream()) << in_string << '\n'; 115 } 116 117 void CommandReturnObject::SetError(const Status &error, 118 const char *fallback_error_cstr) { 119 const char *error_cstr = error.AsCString(); 120 if (error_cstr == nullptr) 121 error_cstr = fallback_error_cstr; 122 SetError(error_cstr); 123 } 124 125 void CommandReturnObject::SetError(llvm::StringRef error_str) { 126 if (error_str.empty()) 127 return; 128 129 AppendError(error_str); 130 SetStatus(eReturnStatusFailed); 131 } 132 133 // Similar to AppendError, but do not prepend 'Status: ' to message, and don't 134 // append "\n" to the end of it. 135 136 void CommandReturnObject::AppendRawError(llvm::StringRef in_string) { 137 if (in_string.empty()) 138 return; 139 GetErrorStream() << in_string; 140 } 141 142 void CommandReturnObject::SetStatus(ReturnStatus status) { m_status = status; } 143 144 ReturnStatus CommandReturnObject::GetStatus() { return m_status; } 145 146 bool CommandReturnObject::Succeeded() { 147 return m_status <= eReturnStatusSuccessContinuingResult; 148 } 149 150 bool CommandReturnObject::HasResult() { 151 return (m_status == eReturnStatusSuccessFinishResult || 152 m_status == eReturnStatusSuccessContinuingResult); 153 } 154 155 void CommandReturnObject::Clear() { 156 lldb::StreamSP stream_sp; 157 stream_sp = m_out_stream.GetStreamAtIndex(eStreamStringIndex); 158 if (stream_sp) 159 static_cast<StreamString *>(stream_sp.get())->Clear(); 160 stream_sp = m_err_stream.GetStreamAtIndex(eStreamStringIndex); 161 if (stream_sp) 162 static_cast<StreamString *>(stream_sp.get())->Clear(); 163 m_status = eReturnStatusStarted; 164 m_did_change_process_state = false; 165 m_interactive = true; 166 } 167 168 bool CommandReturnObject::GetDidChangeProcessState() { 169 return m_did_change_process_state; 170 } 171 172 void CommandReturnObject::SetDidChangeProcessState(bool b) { 173 m_did_change_process_state = b; 174 } 175 176 bool CommandReturnObject::GetInteractive() const { return m_interactive; } 177 178 void CommandReturnObject::SetInteractive(bool b) { m_interactive = b; } 179