1 //===-- SBCommandReturnObject.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/API/SBCommandReturnObject.h" 10 #include "Utils.h" 11 #include "lldb/API/SBError.h" 12 #include "lldb/API/SBStream.h" 13 #include "lldb/Interpreter/CommandReturnObject.h" 14 #include "lldb/Utility/ConstString.h" 15 #include "lldb/Utility/Log.h" 16 #include "lldb/Utility/Status.h" 17 18 using namespace lldb; 19 using namespace lldb_private; 20 21 SBCommandReturnObject::SBCommandReturnObject() 22 : m_opaque_up(new CommandReturnObject()) {} 23 24 SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs) 25 : m_opaque_up() { 26 m_opaque_up = clone(rhs.m_opaque_up); 27 } 28 29 SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject *ptr) 30 : m_opaque_up(ptr) {} 31 32 SBCommandReturnObject::~SBCommandReturnObject() = default; 33 34 CommandReturnObject *SBCommandReturnObject::Release() { 35 return m_opaque_up.release(); 36 } 37 38 const SBCommandReturnObject &SBCommandReturnObject:: 39 operator=(const SBCommandReturnObject &rhs) { 40 if (this != &rhs) 41 m_opaque_up = clone(rhs.m_opaque_up); 42 return *this; 43 } 44 45 bool SBCommandReturnObject::IsValid() const { return m_opaque_up != nullptr; } 46 47 const char *SBCommandReturnObject::GetOutput() { 48 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 49 50 if (m_opaque_up) { 51 llvm::StringRef output = m_opaque_up->GetOutputData(); 52 ConstString result(output.empty() ? llvm::StringRef("") : output); 53 54 if (log) 55 log->Printf("SBCommandReturnObject(%p)::GetOutput () => \"%s\"", 56 static_cast<void *>(m_opaque_up.get()), result.AsCString()); 57 58 return result.AsCString(); 59 } 60 61 if (log) 62 log->Printf("SBCommandReturnObject(%p)::GetOutput () => nullptr", 63 static_cast<void *>(m_opaque_up.get())); 64 65 return nullptr; 66 } 67 68 const char *SBCommandReturnObject::GetError() { 69 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 70 71 if (m_opaque_up) { 72 llvm::StringRef output = m_opaque_up->GetErrorData(); 73 ConstString result(output.empty() ? llvm::StringRef("") : output); 74 if (log) 75 log->Printf("SBCommandReturnObject(%p)::GetError () => \"%s\"", 76 static_cast<void *>(m_opaque_up.get()), result.AsCString()); 77 78 return result.AsCString(); 79 } 80 81 if (log) 82 log->Printf("SBCommandReturnObject(%p)::GetError () => nullptr", 83 static_cast<void *>(m_opaque_up.get())); 84 85 return nullptr; 86 } 87 88 size_t SBCommandReturnObject::GetOutputSize() { 89 return (m_opaque_up ? m_opaque_up->GetOutputData().size() : 0); 90 } 91 92 size_t SBCommandReturnObject::GetErrorSize() { 93 return (m_opaque_up ? m_opaque_up->GetErrorData().size() : 0); 94 } 95 96 size_t SBCommandReturnObject::PutOutput(FILE *fh) { 97 if (fh) { 98 size_t num_bytes = GetOutputSize(); 99 if (num_bytes) 100 return ::fprintf(fh, "%s", GetOutput()); 101 } 102 return 0; 103 } 104 105 size_t SBCommandReturnObject::PutError(FILE *fh) { 106 if (fh) { 107 size_t num_bytes = GetErrorSize(); 108 if (num_bytes) 109 return ::fprintf(fh, "%s", GetError()); 110 } 111 return 0; 112 } 113 114 void SBCommandReturnObject::Clear() { 115 if (m_opaque_up) 116 m_opaque_up->Clear(); 117 } 118 119 lldb::ReturnStatus SBCommandReturnObject::GetStatus() { 120 return (m_opaque_up ? m_opaque_up->GetStatus() : lldb::eReturnStatusInvalid); 121 } 122 123 void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) { 124 if (m_opaque_up) 125 m_opaque_up->SetStatus(status); 126 } 127 128 bool SBCommandReturnObject::Succeeded() { 129 return (m_opaque_up ? m_opaque_up->Succeeded() : false); 130 } 131 132 bool SBCommandReturnObject::HasResult() { 133 return (m_opaque_up ? m_opaque_up->HasResult() : false); 134 } 135 136 void SBCommandReturnObject::AppendMessage(const char *message) { 137 if (m_opaque_up) 138 m_opaque_up->AppendMessage(message); 139 } 140 141 void SBCommandReturnObject::AppendWarning(const char *message) { 142 if (m_opaque_up) 143 m_opaque_up->AppendWarning(message); 144 } 145 146 CommandReturnObject *SBCommandReturnObject::operator->() const { 147 return m_opaque_up.get(); 148 } 149 150 CommandReturnObject *SBCommandReturnObject::get() const { 151 return m_opaque_up.get(); 152 } 153 154 CommandReturnObject &SBCommandReturnObject::operator*() const { 155 assert(m_opaque_up.get()); 156 return *(m_opaque_up.get()); 157 } 158 159 CommandReturnObject &SBCommandReturnObject::ref() const { 160 assert(m_opaque_up.get()); 161 return *(m_opaque_up.get()); 162 } 163 164 void SBCommandReturnObject::SetLLDBObjectPtr(CommandReturnObject *ptr) { 165 if (m_opaque_up) 166 m_opaque_up.reset(ptr); 167 } 168 169 bool SBCommandReturnObject::GetDescription(SBStream &description) { 170 Stream &strm = description.ref(); 171 172 if (m_opaque_up) { 173 description.Printf("Error: "); 174 lldb::ReturnStatus status = m_opaque_up->GetStatus(); 175 if (status == lldb::eReturnStatusStarted) 176 strm.PutCString("Started"); 177 else if (status == lldb::eReturnStatusInvalid) 178 strm.PutCString("Invalid"); 179 else if (m_opaque_up->Succeeded()) 180 strm.PutCString("Success"); 181 else 182 strm.PutCString("Fail"); 183 184 if (GetOutputSize() > 0) 185 strm.Printf("\nOutput Message:\n%s", GetOutput()); 186 187 if (GetErrorSize() > 0) 188 strm.Printf("\nError Message:\n%s", GetError()); 189 } else 190 strm.PutCString("No value"); 191 192 return true; 193 } 194 195 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) { 196 SetImmediateOutputFile(fh, false); 197 } 198 199 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) { 200 SetImmediateErrorFile(fh, false); 201 } 202 203 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh, 204 bool transfer_ownership) { 205 if (m_opaque_up) 206 m_opaque_up->SetImmediateOutputFile(fh, transfer_ownership); 207 } 208 209 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh, 210 bool transfer_ownership) { 211 if (m_opaque_up) 212 m_opaque_up->SetImmediateErrorFile(fh, transfer_ownership); 213 } 214 215 void SBCommandReturnObject::PutCString(const char *string, int len) { 216 if (m_opaque_up) { 217 if (len == 0 || string == nullptr || *string == 0) { 218 return; 219 } else if (len > 0) { 220 std::string buffer(string, len); 221 m_opaque_up->AppendMessage(buffer.c_str()); 222 } else 223 m_opaque_up->AppendMessage(string); 224 } 225 } 226 227 const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate) { 228 if (!m_opaque_up) 229 return nullptr; 230 if (!only_if_no_immediate || 231 m_opaque_up->GetImmediateOutputStream().get() == nullptr) 232 return GetOutput(); 233 return nullptr; 234 } 235 236 const char *SBCommandReturnObject::GetError(bool only_if_no_immediate) { 237 if (!m_opaque_up) 238 return nullptr; 239 if (!only_if_no_immediate || 240 m_opaque_up->GetImmediateErrorStream().get() == nullptr) 241 return GetError(); 242 return nullptr; 243 } 244 245 size_t SBCommandReturnObject::Printf(const char *format, ...) { 246 if (m_opaque_up) { 247 va_list args; 248 va_start(args, format); 249 size_t result = m_opaque_up->GetOutputStream().PrintfVarArg(format, args); 250 va_end(args); 251 return result; 252 } 253 return 0; 254 } 255 256 void SBCommandReturnObject::SetError(lldb::SBError &error, 257 const char *fallback_error_cstr) { 258 if (m_opaque_up) { 259 if (error.IsValid()) 260 m_opaque_up->SetError(error.ref(), fallback_error_cstr); 261 else if (fallback_error_cstr) 262 m_opaque_up->SetError(Status(), fallback_error_cstr); 263 } 264 } 265 266 void SBCommandReturnObject::SetError(const char *error_cstr) { 267 if (m_opaque_up && error_cstr) 268 m_opaque_up->SetError(error_cstr); 269 } 270