1 //===-- CommandReturnObject.cpp ---------------------------------*- 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 #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 void DumpStringToStreamWithNewline(Stream &strm, const std::string &s, 18 bool add_newline_if_empty) { 19 bool add_newline = false; 20 if (s.empty()) { 21 add_newline = add_newline_if_empty; 22 } else { 23 // We already checked for empty above, now make sure there is a newline in 24 // the error, and if there isn't one, add one. 25 strm.Write(s.c_str(), s.size()); 26 27 const char last_char = *s.rbegin(); 28 add_newline = last_char != '\n' && last_char != '\r'; 29 } 30 if (add_newline) 31 strm.EOL(); 32 } 33 34 CommandReturnObject::CommandReturnObject() 35 : m_out_stream(), m_err_stream(), m_status(eReturnStatusStarted), 36 m_did_change_process_state(false), m_interactive(true), 37 m_abnormal_stop_was_expected(false) {} 38 39 CommandReturnObject::~CommandReturnObject() {} 40 41 void CommandReturnObject::AppendErrorWithFormat(const char *format, ...) { 42 if (!format) 43 return; 44 va_list args; 45 va_start(args, format); 46 StreamString sstrm; 47 sstrm.PrintfVarArg(format, args); 48 va_end(args); 49 50 const std::string &s = sstrm.GetString(); 51 if (!s.empty()) { 52 Stream &error_strm = GetErrorStream(); 53 error_strm.PutCString("error: "); 54 DumpStringToStreamWithNewline(error_strm, s, false); 55 } 56 } 57 58 void CommandReturnObject::AppendMessageWithFormat(const char *format, ...) { 59 if (!format) 60 return; 61 va_list args; 62 va_start(args, format); 63 StreamString sstrm; 64 sstrm.PrintfVarArg(format, args); 65 va_end(args); 66 67 GetOutputStream() << sstrm.GetString(); 68 } 69 70 void CommandReturnObject::AppendWarningWithFormat(const char *format, ...) { 71 if (!format) 72 return; 73 va_list args; 74 va_start(args, format); 75 StreamString sstrm; 76 sstrm.PrintfVarArg(format, args); 77 va_end(args); 78 79 GetErrorStream() << "warning: " << sstrm.GetString(); 80 } 81 82 void CommandReturnObject::AppendMessage(llvm::StringRef in_string) { 83 if (in_string.empty()) 84 return; 85 GetOutputStream() << in_string << "\n"; 86 } 87 88 void CommandReturnObject::AppendWarning(llvm::StringRef in_string) { 89 if (in_string.empty()) 90 return; 91 GetErrorStream() << "warning: " << in_string << "\n"; 92 } 93 94 // Similar to AppendWarning, but do not prepend 'warning: ' to message, and 95 // don't append "\n" to the end of it. 96 97 void CommandReturnObject::AppendRawWarning(llvm::StringRef in_string) { 98 if (in_string.empty()) 99 return; 100 GetErrorStream() << in_string; 101 } 102 103 void CommandReturnObject::AppendError(llvm::StringRef in_string) { 104 if (in_string.empty()) 105 return; 106 GetErrorStream() << "error: " << in_string << "\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 SetStatus(eReturnStatusFailed); 123 } 124 125 // Similar to AppendError, but do not prepend 'Status: ' to message, and don't 126 // append "\n" to the end of it. 127 128 void CommandReturnObject::AppendRawError(llvm::StringRef in_string) { 129 if (in_string.empty()) 130 return; 131 GetErrorStream() << in_string; 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