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