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-python.h" 11 12 #include "lldb/lldb-types.h" 13 #include "lldb/Core/SourceManager.h" 14 #include "lldb/Core/Listener.h" 15 #include "lldb/Interpreter/CommandInterpreter.h" 16 #include "lldb/Interpreter/CommandObjectMultiword.h" 17 #include "lldb/Interpreter/CommandReturnObject.h" 18 #include "lldb/Target/Target.h" 19 20 #include "lldb/API/SBBroadcaster.h" 21 #include "lldb/API/SBCommandReturnObject.h" 22 #include "lldb/API/SBCommandInterpreter.h" 23 #include "lldb/API/SBProcess.h" 24 #include "lldb/API/SBTarget.h" 25 #include "lldb/API/SBListener.h" 26 #include "lldb/API/SBStream.h" 27 #include "lldb/API/SBStringList.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 class CommandPluginInterfaceImplementation : public CommandObjectParsed 33 { 34 public: 35 CommandPluginInterfaceImplementation (CommandInterpreter &interpreter, 36 const char *name, 37 lldb::SBCommandPluginInterface* backend, 38 const char *help = NULL, 39 const char *syntax = NULL, 40 uint32_t flags = 0) : 41 CommandObjectParsed (interpreter, name, help, syntax, flags), 42 m_backend(backend) {} 43 44 virtual bool 45 IsRemovable() const { return true; } 46 47 protected: 48 virtual bool 49 DoExecute (Args& command, CommandReturnObject &result) 50 { 51 SBCommandReturnObject sb_return(&result); 52 SBCommandInterpreter sb_interpreter(&m_interpreter); 53 SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this()); 54 bool ret = m_backend->DoExecute (debugger_sb,(char**)command.GetArgumentVector(), sb_return); 55 sb_return.Release(); 56 return ret; 57 } 58 lldb::SBCommandPluginInterface* m_backend; 59 }; 60 61 SBCommandInterpreter::SBCommandInterpreter (CommandInterpreter *interpreter) : 62 m_opaque_ptr (interpreter) 63 { 64 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 65 66 if (log) 67 log->Printf ("SBCommandInterpreter::SBCommandInterpreter (interpreter=%p)" 68 " => SBCommandInterpreter(%p)", interpreter, m_opaque_ptr); 69 } 70 71 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) : 72 m_opaque_ptr (rhs.m_opaque_ptr) 73 { 74 } 75 76 const SBCommandInterpreter & 77 SBCommandInterpreter::operator = (const SBCommandInterpreter &rhs) 78 { 79 m_opaque_ptr = rhs.m_opaque_ptr; 80 return *this; 81 } 82 83 SBCommandInterpreter::~SBCommandInterpreter () 84 { 85 } 86 87 bool 88 SBCommandInterpreter::IsValid() const 89 { 90 return m_opaque_ptr != NULL; 91 } 92 93 94 bool 95 SBCommandInterpreter::CommandExists (const char *cmd) 96 { 97 if (cmd && m_opaque_ptr) 98 return m_opaque_ptr->CommandExists (cmd); 99 return false; 100 } 101 102 bool 103 SBCommandInterpreter::AliasExists (const char *cmd) 104 { 105 if (cmd && m_opaque_ptr) 106 return m_opaque_ptr->AliasExists (cmd); 107 return false; 108 } 109 110 lldb::ReturnStatus 111 SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history) 112 { 113 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 114 115 if (log) 116 log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p), add_to_history=%i)", 117 m_opaque_ptr, command_line, result.get(), add_to_history); 118 119 result.Clear(); 120 if (command_line && m_opaque_ptr) 121 { 122 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 123 Mutex::Locker api_locker; 124 if (target_sp) 125 api_locker.Lock(target_sp->GetAPIMutex()); 126 m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref()); 127 } 128 else 129 { 130 result->AppendError ("SBCommandInterpreter or the command line is not valid"); 131 result->SetStatus (eReturnStatusFailed); 132 } 133 134 // We need to get the value again, in case the command disabled the log! 135 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 136 if (log) 137 { 138 SBStream sstr; 139 result.GetDescription (sstr); 140 log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p): %s, add_to_history=%i) => %i", 141 m_opaque_ptr, command_line, result.get(), sstr.GetData(), add_to_history, result.GetStatus()); 142 } 143 144 return result.GetStatus(); 145 } 146 147 int 148 SBCommandInterpreter::HandleCompletion (const char *current_line, 149 const char *cursor, 150 const char *last_char, 151 int match_start_point, 152 int max_return_elements, 153 SBStringList &matches) 154 { 155 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 156 int num_completions = 0; 157 158 // Sanity check the arguments that are passed in: 159 // cursor & last_char have to be within the current_line. 160 if (current_line == NULL || cursor == NULL || last_char == NULL) 161 return 0; 162 163 if (cursor < current_line || last_char < current_line) 164 return 0; 165 166 size_t current_line_size = strlen (current_line); 167 if (cursor - current_line > current_line_size || last_char - current_line > current_line_size) 168 return 0; 169 170 if (log) 171 log->Printf ("SBCommandInterpreter(%p)::HandleCompletion (current_line=\"%s\", cursor at: %" PRId64 ", last char at: %" PRId64 ", match_start_point: %d, max_return_elements: %d)", 172 m_opaque_ptr, current_line, (uint64_t) (cursor - current_line), (uint64_t) (last_char - current_line), match_start_point, max_return_elements); 173 174 if (m_opaque_ptr) 175 { 176 lldb_private::StringList lldb_matches; 177 num_completions = m_opaque_ptr->HandleCompletion (current_line, cursor, last_char, match_start_point, 178 max_return_elements, lldb_matches); 179 180 SBStringList temp_list (&lldb_matches); 181 matches.AppendList (temp_list); 182 } 183 if (log) 184 log->Printf ("SBCommandInterpreter(%p)::HandleCompletion - Found %d completions.", m_opaque_ptr, num_completions); 185 186 return num_completions; 187 } 188 189 int 190 SBCommandInterpreter::HandleCompletion (const char *current_line, 191 uint32_t cursor_pos, 192 int match_start_point, 193 int max_return_elements, 194 lldb::SBStringList &matches) 195 { 196 const char *cursor = current_line + cursor_pos; 197 const char *last_char = current_line + strlen (current_line); 198 return HandleCompletion (current_line, cursor, last_char, match_start_point, max_return_elements, matches); 199 } 200 201 bool 202 SBCommandInterpreter::HasCommands () 203 { 204 if (m_opaque_ptr) 205 return m_opaque_ptr->HasCommands(); 206 return false; 207 } 208 209 bool 210 SBCommandInterpreter::HasAliases () 211 { 212 if (m_opaque_ptr) 213 return m_opaque_ptr->HasAliases(); 214 return false; 215 } 216 217 bool 218 SBCommandInterpreter::HasAliasOptions () 219 { 220 if (m_opaque_ptr) 221 return m_opaque_ptr->HasAliasOptions (); 222 return false; 223 } 224 225 SBProcess 226 SBCommandInterpreter::GetProcess () 227 { 228 SBProcess sb_process; 229 ProcessSP process_sp; 230 if (m_opaque_ptr) 231 { 232 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 233 if (target_sp) 234 { 235 Mutex::Locker api_locker(target_sp->GetAPIMutex()); 236 process_sp = target_sp->GetProcessSP(); 237 sb_process.SetSP(process_sp); 238 } 239 } 240 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 241 242 if (log) 243 log->Printf ("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)", 244 m_opaque_ptr, process_sp.get()); 245 246 247 return sb_process; 248 } 249 250 SBDebugger 251 SBCommandInterpreter::GetDebugger () 252 { 253 SBDebugger sb_debugger; 254 if (m_opaque_ptr) 255 sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this()); 256 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 257 258 if (log) 259 log->Printf ("SBCommandInterpreter(%p)::GetDebugger () => SBDebugger(%p)", 260 m_opaque_ptr, sb_debugger.get()); 261 262 263 return sb_debugger; 264 } 265 266 CommandInterpreter * 267 SBCommandInterpreter::get () 268 { 269 return m_opaque_ptr; 270 } 271 272 CommandInterpreter & 273 SBCommandInterpreter::ref () 274 { 275 assert (m_opaque_ptr); 276 return *m_opaque_ptr; 277 } 278 279 void 280 SBCommandInterpreter::reset (lldb_private::CommandInterpreter *interpreter) 281 { 282 m_opaque_ptr = interpreter; 283 } 284 285 void 286 SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &result) 287 { 288 result.Clear(); 289 if (m_opaque_ptr) 290 { 291 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 292 Mutex::Locker api_locker; 293 if (target_sp) 294 api_locker.Lock(target_sp->GetAPIMutex()); 295 m_opaque_ptr->SourceInitFile (false, result.ref()); 296 } 297 else 298 { 299 result->AppendError ("SBCommandInterpreter is not valid"); 300 result->SetStatus (eReturnStatusFailed); 301 } 302 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 303 304 if (log) 305 log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory (&SBCommandReturnObject(%p))", 306 m_opaque_ptr, result.get()); 307 308 } 309 310 void 311 SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnObject &result) 312 { 313 result.Clear(); 314 if (m_opaque_ptr) 315 { 316 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 317 Mutex::Locker api_locker; 318 if (target_sp) 319 api_locker.Lock(target_sp->GetAPIMutex()); 320 m_opaque_ptr->SourceInitFile (true, result.ref()); 321 } 322 else 323 { 324 result->AppendError ("SBCommandInterpreter is not valid"); 325 result->SetStatus (eReturnStatusFailed); 326 } 327 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 328 329 if (log) 330 log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory (&SBCommandReturnObject(%p))", 331 m_opaque_ptr, result.get()); 332 } 333 334 SBBroadcaster 335 SBCommandInterpreter::GetBroadcaster () 336 { 337 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 338 339 SBBroadcaster broadcaster (m_opaque_ptr, false); 340 341 if (log) 342 log->Printf ("SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)", 343 m_opaque_ptr, broadcaster.get()); 344 345 return broadcaster; 346 } 347 348 const char * 349 SBCommandInterpreter::GetBroadcasterClass () 350 { 351 return Communication::GetStaticBroadcasterClass().AsCString(); 352 } 353 354 const char * 355 SBCommandInterpreter::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type) 356 { 357 return CommandObject::GetArgumentTypeAsCString (arg_type); 358 } 359 360 const char * 361 SBCommandInterpreter::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type) 362 { 363 return CommandObject::GetArgumentDescriptionAsCString (arg_type); 364 } 365 366 bool 367 SBCommandInterpreter::SetCommandOverrideCallback (const char *command_name, 368 lldb::CommandOverrideCallback callback, 369 void *baton) 370 { 371 if (command_name && command_name[0] && m_opaque_ptr) 372 { 373 std::string command_name_str (command_name); 374 CommandObject *cmd_obj = m_opaque_ptr->GetCommandObjectForCommand(command_name_str); 375 if (cmd_obj) 376 { 377 assert(command_name_str.empty()); 378 cmd_obj->SetOverrideCallback (callback, baton); 379 return true; 380 } 381 } 382 return false; 383 } 384 385 #ifndef LLDB_DISABLE_PYTHON 386 387 // Defined in the SWIG source file 388 extern "C" void 389 init_lldb(void); 390 391 #else 392 393 extern "C" void init_lldb(void); 394 395 // Usually defined in the SWIG source file, but we have sripting disabled 396 extern "C" void 397 init_lldb(void) 398 { 399 } 400 401 #endif 402 403 void 404 SBCommandInterpreter::InitializeSWIG () 405 { 406 static bool g_initialized = false; 407 if (!g_initialized) 408 { 409 g_initialized = true; 410 #ifndef LLDB_DISABLE_PYTHON 411 ScriptInterpreter::InitializeInterpreter (init_lldb); 412 #endif 413 } 414 } 415 416 lldb::SBCommand 417 SBCommandInterpreter::AddMultiwordCommand (const char* name, const char* help) 418 { 419 CommandObjectMultiword *new_command = new CommandObjectMultiword(*m_opaque_ptr,name,help); 420 new_command->SetRemovable (true); 421 lldb::CommandObjectSP new_command_sp(new_command); 422 if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) 423 return lldb::SBCommand(new_command_sp); 424 return lldb::SBCommand(); 425 } 426 427 lldb::SBCommand 428 SBCommandInterpreter::AddCommand (const char* name, lldb::SBCommandPluginInterface* impl, const char* help) 429 { 430 lldb::CommandObjectSP new_command_sp; 431 new_command_sp.reset(new CommandPluginInterfaceImplementation(*m_opaque_ptr,name,impl,help)); 432 433 if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) 434 return lldb::SBCommand(new_command_sp); 435 return lldb::SBCommand(); 436 } 437 438 SBCommand::SBCommand () 439 {} 440 441 SBCommand::SBCommand (lldb::CommandObjectSP cmd_sp) : m_opaque_sp (cmd_sp) 442 {} 443 444 bool 445 SBCommand::IsValid () 446 { 447 return (bool)m_opaque_sp; 448 } 449 450 const char* 451 SBCommand::GetName () 452 { 453 if (IsValid ()) 454 return m_opaque_sp->GetCommandName (); 455 return NULL; 456 } 457 458 const char* 459 SBCommand::GetHelp () 460 { 461 if (IsValid ()) 462 return m_opaque_sp->GetHelp (); 463 return NULL; 464 } 465 466 lldb::SBCommand 467 SBCommand::AddMultiwordCommand (const char* name, const char* help) 468 { 469 if (!IsValid ()) 470 return lldb::SBCommand(); 471 if (m_opaque_sp->IsMultiwordObject() == false) 472 return lldb::SBCommand(); 473 CommandObjectMultiword *new_command = new CommandObjectMultiword(m_opaque_sp->GetCommandInterpreter(),name,help); 474 new_command->SetRemovable (true); 475 lldb::CommandObjectSP new_command_sp(new_command); 476 if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp)) 477 return lldb::SBCommand(new_command_sp); 478 return lldb::SBCommand(); 479 } 480 481 lldb::SBCommand 482 SBCommand::AddCommand (const char* name, lldb::SBCommandPluginInterface *impl, const char* help) 483 { 484 if (!IsValid ()) 485 return lldb::SBCommand(); 486 if (m_opaque_sp->IsMultiwordObject() == false) 487 return lldb::SBCommand(); 488 lldb::CommandObjectSP new_command_sp; 489 new_command_sp.reset(new CommandPluginInterfaceImplementation(m_opaque_sp->GetCommandInterpreter(),name,impl,help)); 490 if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp)) 491 return lldb::SBCommand(new_command_sp); 492 return lldb::SBCommand(); 493 } 494 495