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