1 //===-- SBCommandInterpreter.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/lldb-types.h" 11 #include "lldb/Interpreter/Args.h" 12 #include "lldb/Core/SourceManager.h" 13 #include "lldb/Core/Listener.h" 14 #include "lldb/Interpreter/CommandInterpreter.h" 15 #include "lldb/Interpreter/CommandReturnObject.h" 16 #include "lldb/Target/Target.h" 17 18 #include "lldb/API/SBBroadcaster.h" 19 #include "lldb/API/SBDebugger.h" 20 #include "lldb/API/SBCommandReturnObject.h" 21 #include "lldb/API/SBCommandInterpreter.h" 22 #include "lldb/API/SBProcess.h" 23 #include "lldb/API/SBTarget.h" 24 #include "lldb/API/SBListener.h" 25 #include "lldb/API/SBStream.h" 26 #include "lldb/API/SBStringList.h" 27 28 using namespace lldb; 29 using namespace lldb_private; 30 31 32 SBCommandInterpreter::SBCommandInterpreter (CommandInterpreter *interpreter) : 33 m_opaque_ptr (interpreter) 34 { 35 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 36 37 if (log) 38 log->Printf ("SBCommandInterpreter::SBCommandInterpreter (interpreter=%p)" 39 " => SBCommandInterpreter(%p)", interpreter, m_opaque_ptr); 40 } 41 42 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) : 43 m_opaque_ptr (rhs.m_opaque_ptr) 44 { 45 } 46 47 const SBCommandInterpreter & 48 SBCommandInterpreter::operator = (const SBCommandInterpreter &rhs) 49 { 50 m_opaque_ptr = rhs.m_opaque_ptr; 51 return *this; 52 } 53 54 SBCommandInterpreter::~SBCommandInterpreter () 55 { 56 } 57 58 bool 59 SBCommandInterpreter::IsValid() const 60 { 61 return m_opaque_ptr != NULL; 62 } 63 64 65 bool 66 SBCommandInterpreter::CommandExists (const char *cmd) 67 { 68 if (m_opaque_ptr) 69 return m_opaque_ptr->CommandExists (cmd); 70 return false; 71 } 72 73 bool 74 SBCommandInterpreter::AliasExists (const char *cmd) 75 { 76 if (m_opaque_ptr) 77 return m_opaque_ptr->AliasExists (cmd); 78 return false; 79 } 80 81 lldb::ReturnStatus 82 SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history) 83 { 84 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 85 86 if (log) 87 log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p), add_to_history=%i)", 88 m_opaque_ptr, command_line, result.get(), add_to_history); 89 90 result.Clear(); 91 if (m_opaque_ptr) 92 { 93 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 94 Mutex::Locker api_locker; 95 if (target_sp) 96 api_locker.Reset(target_sp->GetAPIMutex().GetMutex()); 97 m_opaque_ptr->HandleCommand (command_line, add_to_history, result.ref()); 98 } 99 else 100 { 101 result->AppendError ("SBCommandInterpreter is not valid"); 102 result->SetStatus (eReturnStatusFailed); 103 } 104 105 // We need to get the value again, in case the command disabled the log! 106 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 107 if (log) 108 { 109 SBStream sstr; 110 result.GetDescription (sstr); 111 log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p): %s, add_to_history=%i) => %i", 112 m_opaque_ptr, command_line, result.get(), sstr.GetData(), add_to_history, result.GetStatus()); 113 } 114 115 return result.GetStatus(); 116 } 117 118 int 119 SBCommandInterpreter::HandleCompletion (const char *current_line, 120 const char *cursor, 121 const char *last_char, 122 int match_start_point, 123 int max_return_elements, 124 SBStringList &matches) 125 { 126 int num_completions = 0; 127 if (m_opaque_ptr) 128 { 129 lldb_private::StringList lldb_matches; 130 num_completions = m_opaque_ptr->HandleCompletion (current_line, cursor, last_char, match_start_point, 131 max_return_elements, lldb_matches); 132 133 SBStringList temp_list (&lldb_matches); 134 matches.AppendList (temp_list); 135 } 136 return num_completions; 137 } 138 139 int 140 SBCommandInterpreter::HandleCompletion (const char *current_line, 141 uint32_t cursor_pos, 142 int match_start_point, 143 int max_return_elements, 144 lldb::SBStringList &matches) 145 { 146 const char *cursor = current_line + cursor_pos; 147 const char *last_char = current_line + strlen (current_line); 148 return HandleCompletion (current_line, cursor, last_char, match_start_point, max_return_elements, matches); 149 } 150 151 bool 152 SBCommandInterpreter::HasCommands () 153 { 154 if (m_opaque_ptr) 155 return m_opaque_ptr->HasCommands(); 156 return false; 157 } 158 159 bool 160 SBCommandInterpreter::HasAliases () 161 { 162 if (m_opaque_ptr) 163 return m_opaque_ptr->HasAliases(); 164 return false; 165 } 166 167 bool 168 SBCommandInterpreter::HasAliasOptions () 169 { 170 if (m_opaque_ptr) 171 return m_opaque_ptr->HasAliasOptions (); 172 return false; 173 } 174 175 SBProcess 176 SBCommandInterpreter::GetProcess () 177 { 178 SBProcess process; 179 if (m_opaque_ptr) 180 { 181 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 182 if (target_sp) 183 { 184 Mutex::Locker api_locker(target_sp->GetAPIMutex()); 185 process.SetProcess(target_sp->GetProcessSP()); 186 } 187 } 188 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 189 190 if (log) 191 log->Printf ("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)", 192 m_opaque_ptr, process.get()); 193 194 195 return process; 196 } 197 198 ssize_t 199 SBCommandInterpreter::WriteToScriptInterpreter (const char *src) 200 { 201 return WriteToScriptInterpreter (src, strlen(src)); 202 } 203 204 ssize_t 205 SBCommandInterpreter::WriteToScriptInterpreter (const char *src, size_t src_len) 206 { 207 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 208 209 ssize_t bytes_written = 0; 210 if (m_opaque_ptr && src && src[0]) 211 { 212 ScriptInterpreter *script_interpreter = m_opaque_ptr->GetScriptInterpreter(); 213 if (script_interpreter) 214 bytes_written = ::write (script_interpreter->GetMasterFileDescriptor(), src, src_len); 215 } 216 if (log) 217 log->Printf ("SBCommandInterpreter(%p)::WriteToScriptInterpreter (src=\"%s\", src_len=%zu) => %zi", 218 m_opaque_ptr, src, src_len, bytes_written); 219 220 return bytes_written; 221 } 222 223 224 CommandInterpreter * 225 SBCommandInterpreter::get () 226 { 227 return m_opaque_ptr; 228 } 229 230 CommandInterpreter & 231 SBCommandInterpreter::ref () 232 { 233 assert (m_opaque_ptr); 234 return *m_opaque_ptr; 235 } 236 237 void 238 SBCommandInterpreter::reset (lldb_private::CommandInterpreter *interpreter) 239 { 240 m_opaque_ptr = interpreter; 241 } 242 243 void 244 SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &result) 245 { 246 result.Clear(); 247 if (m_opaque_ptr) 248 { 249 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 250 Mutex::Locker api_locker; 251 if (target_sp) 252 api_locker.Reset(target_sp->GetAPIMutex().GetMutex()); 253 m_opaque_ptr->SourceInitFile (false, result.ref()); 254 } 255 else 256 { 257 result->AppendError ("SBCommandInterpreter is not valid"); 258 result->SetStatus (eReturnStatusFailed); 259 } 260 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 261 262 if (log) 263 log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory (&SBCommandReturnObject(%p))", 264 m_opaque_ptr, result.get()); 265 266 } 267 268 void 269 SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnObject &result) 270 { 271 result.Clear(); 272 if (m_opaque_ptr) 273 { 274 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 275 Mutex::Locker api_locker; 276 if (target_sp) 277 api_locker.Reset(target_sp->GetAPIMutex().GetMutex()); 278 m_opaque_ptr->SourceInitFile (true, result.ref()); 279 } 280 else 281 { 282 result->AppendError ("SBCommandInterpreter is not valid"); 283 result->SetStatus (eReturnStatusFailed); 284 } 285 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 286 287 if (log) 288 log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory (&SBCommandReturnObject(%p))", 289 m_opaque_ptr, result.get()); 290 } 291 292 SBBroadcaster 293 SBCommandInterpreter::GetBroadcaster () 294 { 295 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 296 297 SBBroadcaster broadcaster (m_opaque_ptr, false); 298 299 if (log) 300 log->Printf ("SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)", 301 m_opaque_ptr, broadcaster.get()); 302 303 return broadcaster; 304 } 305 306 const char * 307 SBCommandInterpreter::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type) 308 { 309 return CommandObject::GetArgumentTypeAsCString (arg_type); 310 } 311 312 const char * 313 SBCommandInterpreter::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type) 314 { 315 return CommandObject::GetArgumentDescriptionAsCString (arg_type); 316 } 317 318 319 extern "C" bool 320 LLDBSwigPythonBreakpointCallbackFunction 321 ( 322 const char *python_function_name, 323 const char *session_dictionary_name, 324 const lldb::StackFrameSP& sb_frame, 325 const lldb::BreakpointLocationSP& sb_bp_loc 326 ); 327 328 extern "C" std::string 329 LLDBSwigPythonCallTypeScript 330 ( 331 const char *python_function_name, 332 const char *session_dictionary_name, 333 const lldb::ValueObjectSP& valobj_sp 334 ); 335 336 extern "C" void* 337 LLDBSwigPythonCreateSyntheticProvider 338 ( 339 const std::string python_class_name, 340 const char *session_dictionary_name, 341 const lldb::ValueObjectSP& valobj_sp 342 ); 343 344 345 extern "C" uint32_t LLDBSwigPython_CalculateNumChildren (void *implementor); 346 extern "C" void* LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx); 347 extern "C" int LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name); 348 extern "C" void* LLDBSWIGPython_CastPyObjectToSBValue (void* data); 349 extern "C" void LLDBSwigPython_UpdateSynthProviderInstance (void* implementor); 350 351 extern "C" bool LLDBSwigPythonCallCommand 352 ( 353 const char *python_function_name, 354 const char *session_dictionary_name, 355 lldb::DebuggerSP& debugger, 356 const char* args, 357 std::string& err_msg, 358 lldb_private::CommandReturnObject& cmd_retobj 359 ); 360 361 362 extern "C" void init_lldb(void); 363 364 void 365 SBCommandInterpreter::InitializeSWIG () 366 { 367 static bool g_initialized = false; 368 if (!g_initialized) 369 { 370 g_initialized = true; 371 ScriptInterpreter::InitializeInterpreter (init_lldb, 372 LLDBSwigPythonBreakpointCallbackFunction, 373 LLDBSwigPythonCallTypeScript, 374 LLDBSwigPythonCreateSyntheticProvider, 375 LLDBSwigPython_CalculateNumChildren, 376 LLDBSwigPython_GetChildAtIndex, 377 LLDBSwigPython_GetIndexOfChildWithName, 378 LLDBSWIGPython_CastPyObjectToSBValue, 379 LLDBSwigPython_UpdateSynthProviderInstance, 380 LLDBSwigPythonCallCommand); 381 } 382 } 383