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