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 assert(ptr != nullptr); 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 LLDB_RECORD_RESULT(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 LLDB_RECORD_RESULT(*this); 60 } 61 62 bool SBCommandReturnObject::IsValid() const { 63 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, IsValid); 64 return this->operator bool(); 65 } 66 SBCommandReturnObject::operator bool() const { 67 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, operator bool); 68 69 // This method is not useful but it needs to stay to keep SB API stable. 70 return true; 71 } 72 73 const char *SBCommandReturnObject::GetOutput() { 74 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetOutput); 75 76 ConstString output(m_opaque_up->GetOutputData()); 77 return output.AsCString(/*value_if_empty*/ ""); 78 } 79 80 const char *SBCommandReturnObject::GetError() { 81 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetError); 82 83 ConstString output(m_opaque_up->GetErrorData()); 84 return output.AsCString(/*value_if_empty*/ ""); 85 } 86 87 size_t SBCommandReturnObject::GetOutputSize() { 88 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetOutputSize); 89 90 return m_opaque_up->GetOutputData().size(); 91 } 92 93 size_t SBCommandReturnObject::GetErrorSize() { 94 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetErrorSize); 95 96 return m_opaque_up->GetErrorData().size(); 97 } 98 99 size_t SBCommandReturnObject::PutOutput(FILE *fh) { 100 LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *), fh); 101 102 if (fh) { 103 size_t num_bytes = GetOutputSize(); 104 if (num_bytes) 105 return ::fprintf(fh, "%s", GetOutput()); 106 } 107 return 0; 108 } 109 110 size_t SBCommandReturnObject::PutError(FILE *fh) { 111 LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *), fh); 112 113 if (fh) { 114 size_t num_bytes = GetErrorSize(); 115 if (num_bytes) 116 return ::fprintf(fh, "%s", GetError()); 117 } 118 return 0; 119 } 120 121 void SBCommandReturnObject::Clear() { 122 LLDB_RECORD_METHOD_NO_ARGS(void, SBCommandReturnObject, Clear); 123 124 m_opaque_up->Clear(); 125 } 126 127 lldb::ReturnStatus SBCommandReturnObject::GetStatus() { 128 LLDB_RECORD_METHOD_NO_ARGS(lldb::ReturnStatus, SBCommandReturnObject, 129 GetStatus); 130 131 return m_opaque_up->GetStatus(); 132 } 133 134 void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) { 135 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetStatus, 136 (lldb::ReturnStatus), status); 137 138 m_opaque_up->SetStatus(status); 139 } 140 141 bool SBCommandReturnObject::Succeeded() { 142 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, Succeeded); 143 144 return m_opaque_up->Succeeded(); 145 } 146 147 bool SBCommandReturnObject::HasResult() { 148 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, HasResult); 149 150 return m_opaque_up->HasResult(); 151 } 152 153 void SBCommandReturnObject::AppendMessage(const char *message) { 154 LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendMessage, (const char *), 155 message); 156 157 m_opaque_up->AppendMessage(message); 158 } 159 160 void SBCommandReturnObject::AppendWarning(const char *message) { 161 LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendWarning, (const char *), 162 message); 163 164 m_opaque_up->AppendWarning(message); 165 } 166 167 CommandReturnObject *SBCommandReturnObject::operator->() const { 168 return m_opaque_up.get(); 169 } 170 171 CommandReturnObject *SBCommandReturnObject::get() const { 172 return m_opaque_up.get(); 173 } 174 175 CommandReturnObject &SBCommandReturnObject::operator*() const { 176 assert(m_opaque_up.get()); 177 return *(m_opaque_up.get()); 178 } 179 180 CommandReturnObject &SBCommandReturnObject::ref() const { 181 assert(m_opaque_up.get()); 182 return *(m_opaque_up.get()); 183 } 184 185 bool SBCommandReturnObject::GetDescription(SBStream &description) { 186 LLDB_RECORD_METHOD(bool, SBCommandReturnObject, GetDescription, 187 (lldb::SBStream &), description); 188 189 Stream &strm = description.ref(); 190 191 description.Printf("Error: "); 192 lldb::ReturnStatus status = m_opaque_up->GetStatus(); 193 if (status == lldb::eReturnStatusStarted) 194 strm.PutCString("Started"); 195 else if (status == lldb::eReturnStatusInvalid) 196 strm.PutCString("Invalid"); 197 else if (m_opaque_up->Succeeded()) 198 strm.PutCString("Success"); 199 else 200 strm.PutCString("Fail"); 201 202 if (GetOutputSize() > 0) 203 strm.Printf("\nOutput Message:\n%s", GetOutput()); 204 205 if (GetErrorSize() > 0) 206 strm.Printf("\nError Message:\n%s", GetError()); 207 208 return true; 209 } 210 211 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) { 212 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, 213 (FILE *), fh); 214 215 SetImmediateOutputFile(fh, false); 216 } 217 218 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) { 219 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, 220 (FILE *), fh); 221 222 SetImmediateErrorFile(fh, false); 223 } 224 225 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh, 226 bool transfer_ownership) { 227 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, 228 (FILE *, bool), fh, transfer_ownership); 229 230 m_opaque_up->SetImmediateOutputFile(fh, transfer_ownership); 231 } 232 233 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh, 234 bool transfer_ownership) { 235 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, 236 (FILE *, bool), fh, transfer_ownership); 237 238 m_opaque_up->SetImmediateErrorFile(fh, transfer_ownership); 239 } 240 241 void SBCommandReturnObject::PutCString(const char *string, int len) { 242 LLDB_RECORD_METHOD(void, SBCommandReturnObject, PutCString, 243 (const char *, int), string, len); 244 245 if (len == 0 || string == nullptr || *string == 0) { 246 return; 247 } else if (len > 0) { 248 std::string buffer(string, len); 249 m_opaque_up->AppendMessage(buffer.c_str()); 250 } else 251 m_opaque_up->AppendMessage(string); 252 } 253 254 const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate) { 255 LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetOutput, (bool), 256 only_if_no_immediate); 257 258 if (!only_if_no_immediate || 259 m_opaque_up->GetImmediateOutputStream().get() == nullptr) 260 return GetOutput(); 261 return nullptr; 262 } 263 264 const char *SBCommandReturnObject::GetError(bool only_if_no_immediate) { 265 LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetError, (bool), 266 only_if_no_immediate); 267 268 if (!only_if_no_immediate || 269 m_opaque_up->GetImmediateErrorStream().get() == nullptr) 270 return GetError(); 271 return nullptr; 272 } 273 274 size_t SBCommandReturnObject::Printf(const char *format, ...) { 275 va_list args; 276 va_start(args, format); 277 size_t result = m_opaque_up->GetOutputStream().PrintfVarArg(format, args); 278 va_end(args); 279 return result; 280 } 281 282 void SBCommandReturnObject::SetError(lldb::SBError &error, 283 const char *fallback_error_cstr) { 284 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetError, 285 (lldb::SBError &, const char *), error, 286 fallback_error_cstr); 287 288 if (error.IsValid()) 289 m_opaque_up->SetError(error.ref(), fallback_error_cstr); 290 else if (fallback_error_cstr) 291 m_opaque_up->SetError(Status(), fallback_error_cstr); 292 } 293 294 void SBCommandReturnObject::SetError(const char *error_cstr) { 295 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetError, (const char *), 296 error_cstr); 297 298 if (error_cstr) 299 m_opaque_up->SetError(error_cstr); 300 } 301 302 namespace lldb_private { 303 namespace repro { 304 305 template <> 306 void RegisterMethods<SBCommandReturnObject>(Registry &R) { 307 LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, ()); 308 LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, 309 (const lldb::SBCommandReturnObject &)); 310 LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, 311 (lldb_private::CommandReturnObject *)); 312 LLDB_REGISTER_METHOD(lldb_private::CommandReturnObject *, 313 SBCommandReturnObject, Release, ()); 314 LLDB_REGISTER_METHOD( 315 const lldb::SBCommandReturnObject &, 316 SBCommandReturnObject, operator=,(const lldb::SBCommandReturnObject &)); 317 LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, IsValid, ()); 318 LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, operator bool, ()); 319 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetOutput, ()); 320 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetError, ()); 321 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, GetOutputSize, ()); 322 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, GetErrorSize, ()); 323 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *)); 324 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *)); 325 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, Clear, ()); 326 LLDB_REGISTER_METHOD(lldb::ReturnStatus, SBCommandReturnObject, GetStatus, 327 ()); 328 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetStatus, 329 (lldb::ReturnStatus)); 330 LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, Succeeded, ()); 331 LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, HasResult, ()); 332 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, AppendMessage, 333 (const char *)); 334 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, AppendWarning, 335 (const char *)); 336 LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, GetDescription, 337 (lldb::SBStream &)); 338 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, 339 (FILE *)); 340 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, 341 (FILE *)); 342 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, 343 (FILE *, bool)); 344 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, 345 (FILE *, bool)); 346 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, PutCString, 347 (const char *, int)); 348 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetOutput, 349 (bool)); 350 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetError, (bool)); 351 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetError, 352 (lldb::SBError &, const char *)); 353 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetError, (const char *)); 354 } 355 356 } 357 } 358