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