diff options
Diffstat (limited to 'source/Commands/CommandObjectCommands.cpp')
| -rw-r--r-- | source/Commands/CommandObjectCommands.cpp | 264 | 
1 files changed, 217 insertions, 47 deletions
diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp index f98eac055f24..5fd99cfdabf4 100644 --- a/source/Commands/CommandObjectCommands.cpp +++ b/source/Commands/CommandObjectCommands.cpp @@ -7,8 +7,6 @@  //  //===----------------------------------------------------------------------===// -#include "lldb/lldb-python.h" -  #include "CommandObjectCommands.h"  // C Includes @@ -29,7 +27,6 @@  #include "lldb/Interpreter/OptionValueUInt64.h"  #include "lldb/Interpreter/Options.h"  #include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Interpreter/ScriptInterpreterPython.h"  using namespace lldb;  using namespace lldb_private; @@ -85,7 +82,7 @@ protected:              switch (short_option)              {                  case 'c': -                    error = m_count.SetValueFromCString(option_arg,eVarSetOperationAssign); +                    error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);                      break;                  case 's':                      if (option_arg && strcmp("end", option_arg) == 0) @@ -94,10 +91,10 @@ protected:                          m_start_idx.SetOptionWasSet();                      }                      else -                        error = m_start_idx.SetValueFromCString(option_arg,eVarSetOperationAssign); +                        error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);                      break;                  case 'e': -                    error = m_stop_idx.SetValueFromCString(option_arg,eVarSetOperationAssign); +                    error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);                      break;                  case 'C':                      m_clear.SetCurrentValue(true); @@ -326,15 +323,15 @@ protected:              switch (short_option)              {                  case 'e': -                    error = m_stop_on_error.SetValueFromCString(option_arg); +                    error = m_stop_on_error.SetValueFromString(option_arg);                      break;                  case 'c': -                    error = m_stop_on_continue.SetValueFromCString(option_arg); +                    error = m_stop_on_continue.SetValueFromString(option_arg);                      break;                  case 's': -                    error = m_silent_run.SetValueFromCString(option_arg); +                    error = m_silent_run.SetValueFromString(option_arg);                      break;                  default: @@ -1430,6 +1427,130 @@ protected:  }; +class CommandObjectScriptingObject : public CommandObjectRaw +{ +private: +    StructuredData::GenericSP m_cmd_obj_sp; +    ScriptedCommandSynchronicity m_synchro; +    bool m_fetched_help_short:1; +    bool m_fetched_help_long:1; +     +public: +     +    CommandObjectScriptingObject (CommandInterpreter &interpreter, +                                  std::string name, +                                  StructuredData::GenericSP cmd_obj_sp, +                                  ScriptedCommandSynchronicity synch) : +    CommandObjectRaw (interpreter, +                      name.c_str(), +                      NULL, +                      NULL), +    m_cmd_obj_sp(cmd_obj_sp), +    m_synchro(synch), +    m_fetched_help_short(false), +    m_fetched_help_long(false) +    { +        StreamString stream; +        stream.Printf("For more information run 'help %s'",name.c_str()); +        SetHelp(stream.GetData()); +        if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter()) +            GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp)); +    } +     +    virtual +    ~CommandObjectScriptingObject () +    { +    } +     +    virtual bool +    IsRemovable () const +    { +        return true; +    } +     +    StructuredData::GenericSP +    GetImplementingObject () +    { +        return m_cmd_obj_sp; +    } +     +    ScriptedCommandSynchronicity +    GetSynchronicity () +    { +        return m_synchro; +    } + +    virtual const char * +    GetHelp () +    { +        if (!m_fetched_help_short) +        { +            ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); +            if (scripter) +            { +                std::string docstring; +                m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring); +                if (!docstring.empty()) +                    SetHelp(docstring); +            } +        } +        return CommandObjectRaw::GetHelp(); +    } +     +    virtual const char * +    GetHelpLong () +    { +        if (!m_fetched_help_long) +        { +            ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); +            if (scripter) +            { +                std::string docstring; +                m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring); +                if (!docstring.empty()) +                    SetHelpLong(docstring); +            } +        } +        return CommandObjectRaw::GetHelpLong(); +    } +     +protected: +    virtual bool +    DoExecute (const char *raw_command_line, CommandReturnObject &result) +    { +        ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); +         +        Error error; +         +        result.SetStatus(eReturnStatusInvalid); +         +        if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp, +                                                         raw_command_line, +                                                         m_synchro, +                                                         result, +                                                         error, +                                                         m_exe_ctx) == false) +        { +            result.AppendError(error.AsCString()); +            result.SetStatus(eReturnStatusFailed); +        } +        else +        { +            // Don't change the status if the command already set it... +            if (result.GetStatus() == eReturnStatusInvalid) +            { +                if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') +                    result.SetStatus(eReturnStatusSuccessFinishNoResult); +                else +                    result.SetStatus(eReturnStatusSuccessFinishResult); +            } +        } +         +        return result.Succeeded(); +    } +     +}; +  //-------------------------------------------------------------------------  // CommandObjectCommandsScriptImport  //------------------------------------------------------------------------- @@ -1449,7 +1570,7 @@ public:          // Define the first (and only) variant of this arg.          cmd_arg.arg_type = eArgTypeFilename; -        cmd_arg.arg_repetition = eArgRepeatPlain; +        cmd_arg.arg_repetition = eArgRepeatPlus;          // There is only one variant this argument could be; put it into the argument entry.          arg1.push_back (cmd_arg); @@ -1549,7 +1670,6 @@ protected:      bool      DoExecute (Args& command, CommandReturnObject &result)      { -                  if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)          {              result.AppendError ("only scripting language supported for module importing is currently Python"); @@ -1558,36 +1678,40 @@ protected:          }          size_t argc = command.GetArgumentCount(); -         -        if (argc != 1) +        if (0 == argc)          { -            result.AppendError ("'command script import' requires one argument"); +            result.AppendError("command script import needs one or more arguments");              result.SetStatus (eReturnStatusFailed);              return false;          } -        std::string path = command.GetArgumentAtIndex(0); -        Error error; -         -        const bool init_session = true; -        // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that -        // commands won't ever be recursively invoked, but it's actually possible to craft -        // a Python script that does other "command script imports" in __lldb_init_module -        // the real fix is to have recursive commands possible with a CommandInvocation object -        // separate from the CommandObject itself, so that recursive command invocations -        // won't stomp on each other (wrt to execution contents, options, and more) -        m_exe_ctx.Clear(); -        if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), -                                                                      m_options.m_allow_reload, -                                                                      init_session, -                                                                      error)) -        { -            result.SetStatus (eReturnStatusSuccessFinishNoResult); -        } -        else +        for (size_t i = 0; +             i < argc; +             i++)          { -            result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); -            result.SetStatus (eReturnStatusFailed); +            std::string path = command.GetArgumentAtIndex(i); +            Error error; +             +            const bool init_session = true; +            // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that +            // commands won't ever be recursively invoked, but it's actually possible to craft +            // a Python script that does other "command script imports" in __lldb_init_module +            // the real fix is to have recursive commands possible with a CommandInvocation object +            // separate from the CommandObject itself, so that recursive command invocations +            // won't stomp on each other (wrt to execution contents, options, and more) +            m_exe_ctx.Clear(); +            if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), +                                                                          m_options.m_allow_reload, +                                                                          init_session, +                                                                          error)) +            { +                result.SetStatus (eReturnStatusSuccessFinishNoResult); +            } +            else +            { +                result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); +                result.SetStatus (eReturnStatusFailed); +            }          }          return result.Succeeded(); @@ -1652,7 +1776,11 @@ protected:      public:          CommandOptions (CommandInterpreter &interpreter) : -            Options (interpreter) +            Options (interpreter), +            m_class_name(), +            m_funct_name(), +            m_short_help(), +            m_synchronicity(eScriptedCommandSynchronicitySynchronous)          {          } @@ -1671,6 +1799,10 @@ protected:                      if (option_arg)                          m_funct_name.assign(option_arg);                      break; +                case 'c': +                    if (option_arg) +                        m_class_name.assign(option_arg); +                    break;                  case 'h':                      if (option_arg)                          m_short_help.assign(option_arg); @@ -1691,6 +1823,7 @@ protected:          void          OptionParsingStarting ()          { +            m_class_name.clear();              m_funct_name.clear();              m_short_help.clear();              m_synchronicity = eScriptedCommandSynchronicitySynchronous; @@ -1708,6 +1841,7 @@ protected:          // Instance variables to hold the values for command options. +        std::string m_class_name;          std::string m_funct_name;          std::string m_short_help;          ScriptedCommandSynchronicity m_synchronicity; @@ -1812,20 +1946,55 @@ protected:          m_short_help.assign(m_options.m_short_help);          m_synchronicity = m_options.m_synchronicity; -        if (m_options.m_funct_name.empty()) +        if (m_options.m_class_name.empty())          { -            m_interpreter.GetPythonCommandsFromIOHandler ("     ",  // Prompt -                                                          *this,    // IOHandlerDelegate -                                                          true,     // Run IOHandler in async mode -                                                          NULL);    // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions +            if (m_options.m_funct_name.empty()) +            { +                m_interpreter.GetPythonCommandsFromIOHandler ("     ",  // Prompt +                                                              *this,    // IOHandlerDelegate +                                                              true,     // Run IOHandler in async mode +                                                              NULL);    // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions +            } +            else +            { +                CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, +                                                                        m_cmd_name, +                                                                        m_options.m_funct_name, +                                                                        m_options.m_short_help, +                                                                        m_synchronicity)); +                if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) +                { +                    result.SetStatus (eReturnStatusSuccessFinishNoResult); +                } +                else +                { +                    result.AppendError("cannot add command"); +                    result.SetStatus (eReturnStatusFailed); +                } +            }          }          else          { -            CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, -                                                                    m_cmd_name, -                                                                    m_options.m_funct_name, -                                                                    m_options.m_short_help, -                                                                    m_synchronicity)); +            ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter(); +            if (!interpreter) +            { +                result.AppendError("cannot find ScriptInterpreter"); +                result.SetStatus(eReturnStatusFailed); +                return false; +            } +             +            auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str()); +            if (!cmd_obj_sp) +            { +                result.AppendError("cannot create helper object"); +                result.SetStatus(eReturnStatusFailed); +                return false; +            } +             +            CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter, +                                                                     m_cmd_name, +                                                                     cmd_obj_sp, +                                                                     m_synchronicity));              if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))              {                  result.SetStatus (eReturnStatusSuccessFinishNoResult); @@ -1859,8 +2028,9 @@ OptionDefinition  CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =  {      { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction,        "Name of the Python function to bind to this command name."}, +    { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass,        "Name of the Python class to bind to this command name."},      { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."}, -    { LLDB_OPT_SET_1, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity,        "Set the synchronicity of this command's executions with regard to LLDB event system."}, +    { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity,        "Set the synchronicity of this command's executions with regard to LLDB event system."},      { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }  };  | 
