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