Home | History | Annotate | Download | only in API
      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     Log *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     Log *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         m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref());
    123     }
    124     else
    125     {
    126         result->AppendError ("SBCommandInterpreter or the command line is not valid");
    127         result->SetStatus (eReturnStatusFailed);
    128     }
    129 
    130     // We need to get the value again, in case the command disabled the log!
    131     log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
    132     if (log)
    133     {
    134         SBStream sstr;
    135         result.GetDescription (sstr);
    136         log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p): %s, add_to_history=%i) => %i",
    137                      m_opaque_ptr, command_line, result.get(), sstr.GetData(), add_to_history, result.GetStatus());
    138     }
    139 
    140     return result.GetStatus();
    141 }
    142 
    143 int
    144 SBCommandInterpreter::HandleCompletion (const char *current_line,
    145                                         const char *cursor,
    146                                         const char *last_char,
    147                                         int match_start_point,
    148                                         int max_return_elements,
    149                                         SBStringList &matches)
    150 {
    151     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    152     int num_completions = 0;
    153 
    154     // Sanity check the arguments that are passed in:
    155     // cursor & last_char have to be within the current_line.
    156     if (current_line == NULL || cursor == NULL || last_char == NULL)
    157         return 0;
    158 
    159     if (cursor < current_line || last_char < current_line)
    160         return 0;
    161 
    162     size_t current_line_size = strlen (current_line);
    163     if (cursor - current_line > current_line_size || last_char - current_line > current_line_size)
    164         return 0;
    165 
    166     if (log)
    167         log->Printf ("SBCommandInterpreter(%p)::HandleCompletion (current_line=\"%s\", cursor at: %" PRId64 ", last char at: %" PRId64 ", match_start_point: %d, max_return_elements: %d)",
    168                      m_opaque_ptr, current_line, (uint64_t) (cursor - current_line), (uint64_t) (last_char - current_line), match_start_point, max_return_elements);
    169 
    170     if (m_opaque_ptr)
    171     {
    172         lldb_private::StringList lldb_matches;
    173         num_completions =  m_opaque_ptr->HandleCompletion (current_line, cursor, last_char, match_start_point,
    174                                                            max_return_elements, lldb_matches);
    175 
    176         SBStringList temp_list (&lldb_matches);
    177         matches.AppendList (temp_list);
    178     }
    179     if (log)
    180         log->Printf ("SBCommandInterpreter(%p)::HandleCompletion - Found %d completions.", m_opaque_ptr, num_completions);
    181 
    182     return num_completions;
    183 }
    184 
    185 int
    186 SBCommandInterpreter::HandleCompletion (const char *current_line,
    187                   uint32_t cursor_pos,
    188                   int match_start_point,
    189                   int max_return_elements,
    190                   lldb::SBStringList &matches)
    191 {
    192     const char *cursor = current_line + cursor_pos;
    193     const char *last_char = current_line + strlen (current_line);
    194     return HandleCompletion (current_line, cursor, last_char, match_start_point, max_return_elements, matches);
    195 }
    196 
    197 bool
    198 SBCommandInterpreter::HasCommands ()
    199 {
    200     if (m_opaque_ptr)
    201         return m_opaque_ptr->HasCommands();
    202     return false;
    203 }
    204 
    205 bool
    206 SBCommandInterpreter::HasAliases ()
    207 {
    208     if (m_opaque_ptr)
    209         return m_opaque_ptr->HasAliases();
    210     return false;
    211 }
    212 
    213 bool
    214 SBCommandInterpreter::HasAliasOptions ()
    215 {
    216     if (m_opaque_ptr)
    217         return m_opaque_ptr->HasAliasOptions ();
    218     return false;
    219 }
    220 
    221 SBProcess
    222 SBCommandInterpreter::GetProcess ()
    223 {
    224     SBProcess sb_process;
    225     ProcessSP process_sp;
    226     if (m_opaque_ptr)
    227     {
    228         TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
    229         if (target_sp)
    230         {
    231             Mutex::Locker api_locker(target_sp->GetAPIMutex());
    232             process_sp = target_sp->GetProcessSP();
    233             sb_process.SetSP(process_sp);
    234         }
    235     }
    236     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    237 
    238     if (log)
    239         log->Printf ("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)",
    240                      m_opaque_ptr, process_sp.get());
    241 
    242 
    243     return sb_process;
    244 }
    245 
    246 SBDebugger
    247 SBCommandInterpreter::GetDebugger ()
    248 {
    249     SBDebugger sb_debugger;
    250     if (m_opaque_ptr)
    251         sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this());
    252     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    253 
    254     if (log)
    255         log->Printf ("SBCommandInterpreter(%p)::GetDebugger () => SBDebugger(%p)",
    256                      m_opaque_ptr, sb_debugger.get());
    257 
    258 
    259     return sb_debugger;
    260 }
    261 
    262 CommandInterpreter *
    263 SBCommandInterpreter::get ()
    264 {
    265     return m_opaque_ptr;
    266 }
    267 
    268 CommandInterpreter &
    269 SBCommandInterpreter::ref ()
    270 {
    271     assert (m_opaque_ptr);
    272     return *m_opaque_ptr;
    273 }
    274 
    275 void
    276 SBCommandInterpreter::reset (lldb_private::CommandInterpreter *interpreter)
    277 {
    278     m_opaque_ptr = interpreter;
    279 }
    280 
    281 void
    282 SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &result)
    283 {
    284     result.Clear();
    285     if (m_opaque_ptr)
    286     {
    287         TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
    288         Mutex::Locker api_locker;
    289         if (target_sp)
    290             api_locker.Lock(target_sp->GetAPIMutex());
    291         m_opaque_ptr->SourceInitFile (false, result.ref());
    292     }
    293     else
    294     {
    295         result->AppendError ("SBCommandInterpreter is not valid");
    296         result->SetStatus (eReturnStatusFailed);
    297     }
    298     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    299 
    300     if (log)
    301         log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory (&SBCommandReturnObject(%p))",
    302                      m_opaque_ptr, result.get());
    303 
    304 }
    305 
    306 void
    307 SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnObject &result)
    308 {
    309     result.Clear();
    310     if (m_opaque_ptr)
    311     {
    312         TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
    313         Mutex::Locker api_locker;
    314         if (target_sp)
    315             api_locker.Lock(target_sp->GetAPIMutex());
    316         m_opaque_ptr->SourceInitFile (true, result.ref());
    317     }
    318     else
    319     {
    320         result->AppendError ("SBCommandInterpreter is not valid");
    321         result->SetStatus (eReturnStatusFailed);
    322     }
    323     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    324 
    325     if (log)
    326         log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory (&SBCommandReturnObject(%p))",
    327                      m_opaque_ptr, result.get());
    328 }
    329 
    330 SBBroadcaster
    331 SBCommandInterpreter::GetBroadcaster ()
    332 {
    333     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    334 
    335     SBBroadcaster broadcaster (m_opaque_ptr, false);
    336 
    337     if (log)
    338         log->Printf ("SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)",
    339                      m_opaque_ptr, broadcaster.get());
    340 
    341     return broadcaster;
    342 }
    343 
    344 const char *
    345 SBCommandInterpreter::GetBroadcasterClass ()
    346 {
    347     return Communication::GetStaticBroadcasterClass().AsCString();
    348 }
    349 
    350 const char *
    351 SBCommandInterpreter::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
    352 {
    353     return CommandObject::GetArgumentTypeAsCString (arg_type);
    354 }
    355 
    356 const char *
    357 SBCommandInterpreter::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
    358 {
    359     return CommandObject::GetArgumentDescriptionAsCString (arg_type);
    360 }
    361 
    362 bool
    363 SBCommandInterpreter::SetCommandOverrideCallback (const char *command_name,
    364                                                   lldb::CommandOverrideCallback callback,
    365                                                   void *baton)
    366 {
    367     if (command_name && command_name[0] && m_opaque_ptr)
    368     {
    369         std::string command_name_str (command_name);
    370         CommandObject *cmd_obj = m_opaque_ptr->GetCommandObjectForCommand(command_name_str);
    371         if (cmd_obj)
    372         {
    373             assert(command_name_str.empty());
    374             cmd_obj->SetOverrideCallback (callback, baton);
    375             return true;
    376         }
    377     }
    378     return false;
    379 }
    380 
    381 #ifndef LLDB_DISABLE_PYTHON
    382 
    383 // Defined in the SWIG source file
    384 extern "C" void
    385 init_lldb(void);
    386 
    387 #else
    388 
    389 extern "C" void init_lldb(void);
    390 
    391 // Usually defined in the SWIG source file, but we have sripting disabled
    392 extern "C" void
    393 init_lldb(void)
    394 {
    395 }
    396 
    397 #endif
    398 
    399 void
    400 SBCommandInterpreter::InitializeSWIG ()
    401 {
    402     static bool g_initialized = false;
    403     if (!g_initialized)
    404     {
    405         g_initialized = true;
    406 #ifndef LLDB_DISABLE_PYTHON
    407         ScriptInterpreter::InitializeInterpreter (init_lldb);
    408 #endif
    409     }
    410 }
    411 
    412 lldb::SBCommand
    413 SBCommandInterpreter::AddMultiwordCommand (const char* name, const char* help)
    414 {
    415     CommandObjectMultiword *new_command = new CommandObjectMultiword(*m_opaque_ptr,name,help);
    416     new_command->SetRemovable (true);
    417     lldb::CommandObjectSP new_command_sp(new_command);
    418     if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
    419         return lldb::SBCommand(new_command_sp);
    420     return lldb::SBCommand();
    421 }
    422 
    423 lldb::SBCommand
    424 SBCommandInterpreter::AddCommand (const char* name, lldb::SBCommandPluginInterface* impl, const char* help)
    425 {
    426     lldb::CommandObjectSP new_command_sp;
    427     new_command_sp.reset(new CommandPluginInterfaceImplementation(*m_opaque_ptr,name,impl,help));
    428 
    429     if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
    430         return lldb::SBCommand(new_command_sp);
    431     return lldb::SBCommand();
    432 }
    433 
    434 SBCommand::SBCommand ()
    435 {}
    436 
    437 SBCommand::SBCommand (lldb::CommandObjectSP cmd_sp) : m_opaque_sp (cmd_sp)
    438 {}
    439 
    440 bool
    441 SBCommand::IsValid ()
    442 {
    443     return (bool)m_opaque_sp;
    444 }
    445 
    446 const char*
    447 SBCommand::GetName ()
    448 {
    449     if (IsValid ())
    450         return m_opaque_sp->GetCommandName ();
    451     return NULL;
    452 }
    453 
    454 const char*
    455 SBCommand::GetHelp ()
    456 {
    457     if (IsValid ())
    458         return m_opaque_sp->GetHelp ();
    459     return NULL;
    460 }
    461 
    462 lldb::SBCommand
    463 SBCommand::AddMultiwordCommand (const char* name, const char* help)
    464 {
    465     if (!IsValid ())
    466         return lldb::SBCommand();
    467     if (m_opaque_sp->IsMultiwordObject() == false)
    468         return lldb::SBCommand();
    469     CommandObjectMultiword *new_command = new CommandObjectMultiword(m_opaque_sp->GetCommandInterpreter(),name,help);
    470     new_command->SetRemovable (true);
    471     lldb::CommandObjectSP new_command_sp(new_command);
    472     if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp))
    473         return lldb::SBCommand(new_command_sp);
    474     return lldb::SBCommand();
    475 }
    476 
    477 lldb::SBCommand
    478 SBCommand::AddCommand (const char* name, lldb::SBCommandPluginInterface *impl, const char* help)
    479 {
    480     if (!IsValid ())
    481         return lldb::SBCommand();
    482     if (m_opaque_sp->IsMultiwordObject() == false)
    483         return lldb::SBCommand();
    484     lldb::CommandObjectSP new_command_sp;
    485     new_command_sp.reset(new CommandPluginInterfaceImplementation(m_opaque_sp->GetCommandInterpreter(),name,impl,help));
    486     if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp))
    487         return lldb::SBCommand(new_command_sp);
    488     return lldb::SBCommand();
    489 }
    490 
    491