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