Add support for custom commands to set flags on themselves
authorEnrico Granata <egranata@apple.com>
Wed, 27 May 2015 05:04:35 +0000 (05:04 +0000)
committerEnrico Granata <egranata@apple.com>
Wed, 27 May 2015 05:04:35 +0000 (05:04 +0000)
This works for Python commands defined via a class (implement get_flags on your class) and C++ plugin commands (which can call SBCommand::GetFlags()/SetFlags())

Flags allow features such as not letting the command run if there's no target, or if the process is not stopped, ...
Commands could always check for these things themselves, but having these accessible via flags makes custom commands more consistent with built-in ones

llvm-svn: 238286

26 files changed:
lldb/include/lldb/API/SBCommandInterpreter.h
lldb/include/lldb/Interpreter/CommandObject.h
lldb/include/lldb/Interpreter/ScriptInterpreter.h
lldb/include/lldb/Interpreter/ScriptInterpreterPython.h
lldb/include/lldb/lldb-enumerations.h
lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
lldb/source/API/SBCommandInterpreter.cpp
lldb/source/Commands/CommandObjectCommands.cpp
lldb/source/Commands/CommandObjectExpression.cpp
lldb/source/Commands/CommandObjectFrame.cpp
lldb/source/Commands/CommandObjectMemory.cpp
lldb/source/Commands/CommandObjectPlatform.cpp
lldb/source/Commands/CommandObjectProcess.cpp
lldb/source/Commands/CommandObjectRegister.cpp
lldb/source/Commands/CommandObjectSource.cpp
lldb/source/Commands/CommandObjectTarget.cpp
lldb/source/Commands/CommandObjectThread.cpp
lldb/source/Commands/CommandObjectType.cpp
lldb/source/Commands/CommandObjectWatchpoint.cpp
lldb/source/Interpreter/CommandObject.cpp
lldb/source/Interpreter/ScriptInterpreterPython.cpp
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
lldb/test/functionalities/command_script/TestCommandScript.py
lldb/test/functionalities/command_script/py_import
lldb/test/functionalities/command_script/welcome.py

index 352cfa5..235a2f3 100644 (file)
@@ -291,6 +291,12 @@ public:
     void
     SetHelpLong (const char*);
     
+    uint32_t
+    GetFlags ();
+    
+    void
+    SetFlags (uint32_t flags);
+    
     lldb::SBCommand
     AddMultiwordCommand (const char* name, const char* help = NULL);
     
index f743f2e..c0901d5 100644 (file)
@@ -220,89 +220,6 @@ public:
     
     bool
     IsPairType (ArgumentRepetitionType arg_repeat_type);
-    
-    enum
-    {
-        //----------------------------------------------------------------------
-        // eFlagRequiresTarget
-        //
-        // Ensures a valid target is contained in m_exe_ctx prior to executing
-        // the command. If a target doesn't exist or is invalid, the command
-        // will fail and CommandObject::GetInvalidTargetDescription() will be
-        // returned as the error. CommandObject subclasses can override the
-        // virtual function for GetInvalidTargetDescription() to provide custom
-        // strings when needed.
-        //----------------------------------------------------------------------
-        eFlagRequiresTarget         = (1u << 0),
-        //----------------------------------------------------------------------
-        // eFlagRequiresProcess
-        //
-        // Ensures a valid process is contained in m_exe_ctx prior to executing
-        // the command. If a process doesn't exist or is invalid, the command
-        // will fail and CommandObject::GetInvalidProcessDescription() will be
-        // returned as the error. CommandObject subclasses can override the
-        // virtual function for GetInvalidProcessDescription() to provide custom
-        // strings when needed.
-        //----------------------------------------------------------------------
-        eFlagRequiresProcess        = (1u << 1),
-        //----------------------------------------------------------------------
-        // eFlagRequiresThread
-        //
-        // Ensures a valid thread is contained in m_exe_ctx prior to executing
-        // the command. If a thread doesn't exist or is invalid, the command
-        // will fail and CommandObject::GetInvalidThreadDescription() will be
-        // returned as the error. CommandObject subclasses can override the
-        // virtual function for GetInvalidThreadDescription() to provide custom
-        // strings when needed.
-        //----------------------------------------------------------------------
-        eFlagRequiresThread         = (1u << 2),
-        //----------------------------------------------------------------------
-        // eFlagRequiresFrame
-        //
-        // Ensures a valid frame is contained in m_exe_ctx prior to executing
-        // the command. If a frame doesn't exist or is invalid, the command
-        // will fail and CommandObject::GetInvalidFrameDescription() will be
-        // returned as the error. CommandObject subclasses can override the
-        // virtual function for GetInvalidFrameDescription() to provide custom
-        // strings when needed.
-        //----------------------------------------------------------------------
-        eFlagRequiresFrame          = (1u << 3),
-        //----------------------------------------------------------------------
-        // eFlagRequiresRegContext
-        //
-        // Ensures a valid register context (from the selected frame if there
-        // is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
-        // is available from m_exe_ctx prior to executing the command. If a
-        // target doesn't exist or is invalid, the command will fail and
-        // CommandObject::GetInvalidRegContextDescription() will be returned as
-        // the error. CommandObject subclasses can override the virtual function
-        // for GetInvalidRegContextDescription() to provide custom strings when
-        // needed.
-        //----------------------------------------------------------------------
-        eFlagRequiresRegContext     = (1u << 4),
-        //----------------------------------------------------------------------
-        // eFlagTryTargetAPILock
-        //
-        // Attempts to acquire the target lock if a target is selected in the
-        // command interpreter. If the command object fails to acquire the API
-        // lock, the command will fail with an appropriate error message.
-        //----------------------------------------------------------------------
-        eFlagTryTargetAPILock       = (1u << 5),
-        //----------------------------------------------------------------------
-        // eFlagProcessMustBeLaunched
-        //
-        // Verifies that there is a launched process in m_exe_ctx, if there
-        // isn't, the command will fail with an appropriate error message.
-        //----------------------------------------------------------------------
-        eFlagProcessMustBeLaunched  = (1u << 6),
-        //----------------------------------------------------------------------
-        // eFlagProcessMustBePaused
-        //
-        // Verifies that there is a paused process in m_exe_ctx, if there
-        // isn't, the command will fail with an appropriate error message.
-        //----------------------------------------------------------------------
-        eFlagProcessMustBePaused    = (1u << 7)
-    };
 
     bool
     ParseOptions (Args& args, CommandReturnObject &result);
index fe27bb2..0f45dd8 100644 (file)
@@ -470,6 +470,12 @@ public:
         dest.clear();
         return false;
     }
+    
+    virtual uint32_t
+    GetFlagsForCommandObject (StructuredData::GenericSP cmd_obj_sp)
+    {
+        return 0;
+    }
 
     virtual bool
     GetLongHelpForCommandObject (StructuredData::GenericSP cmd_obj_sp,
index 28863a7..058058e 100644 (file)
@@ -271,6 +271,9 @@ public:
     bool
     GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string& dest) override;
     
+    uint32_t
+    GetFlagsForCommandObject (StructuredData::GenericSP cmd_obj_sp) override;
+    
     bool
     GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string& dest) override;
     
index 5436e21..df788dd 100644 (file)
@@ -950,6 +950,89 @@ namespace lldb {
         eTypeIsSigned           = (1u << 21)
     };
     
+    FLAGS_ENUM(CommandFlags)
+    {
+        //----------------------------------------------------------------------
+        // eCommandRequiresTarget
+        //
+        // Ensures a valid target is contained in m_exe_ctx prior to executing
+        // the command. If a target doesn't exist or is invalid, the command
+        // will fail and CommandObject::GetInvalidTargetDescription() will be
+        // returned as the error. CommandObject subclasses can override the
+        // virtual function for GetInvalidTargetDescription() to provide custom
+        // strings when needed.
+        //----------------------------------------------------------------------
+        eCommandRequiresTarget         = (1u << 0),
+        //----------------------------------------------------------------------
+        // eCommandRequiresProcess
+        //
+        // Ensures a valid process is contained in m_exe_ctx prior to executing
+        // the command. If a process doesn't exist or is invalid, the command
+        // will fail and CommandObject::GetInvalidProcessDescription() will be
+        // returned as the error. CommandObject subclasses can override the
+        // virtual function for GetInvalidProcessDescription() to provide custom
+        // strings when needed.
+        //----------------------------------------------------------------------
+        eCommandRequiresProcess        = (1u << 1),
+        //----------------------------------------------------------------------
+        // eCommandRequiresThread
+        //
+        // Ensures a valid thread is contained in m_exe_ctx prior to executing
+        // the command. If a thread doesn't exist or is invalid, the command
+        // will fail and CommandObject::GetInvalidThreadDescription() will be
+        // returned as the error. CommandObject subclasses can override the
+        // virtual function for GetInvalidThreadDescription() to provide custom
+        // strings when needed.
+        //----------------------------------------------------------------------
+        eCommandRequiresThread         = (1u << 2),
+        //----------------------------------------------------------------------
+        // eCommandRequiresFrame
+        //
+        // Ensures a valid frame is contained in m_exe_ctx prior to executing
+        // the command. If a frame doesn't exist or is invalid, the command
+        // will fail and CommandObject::GetInvalidFrameDescription() will be
+        // returned as the error. CommandObject subclasses can override the
+        // virtual function for GetInvalidFrameDescription() to provide custom
+        // strings when needed.
+        //----------------------------------------------------------------------
+        eCommandRequiresFrame          = (1u << 3),
+        //----------------------------------------------------------------------
+        // eCommandRequiresRegContext
+        //
+        // Ensures a valid register context (from the selected frame if there
+        // is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
+        // is available from m_exe_ctx prior to executing the command. If a
+        // target doesn't exist or is invalid, the command will fail and
+        // CommandObject::GetInvalidRegContextDescription() will be returned as
+        // the error. CommandObject subclasses can override the virtual function
+        // for GetInvalidRegContextDescription() to provide custom strings when
+        // needed.
+        //----------------------------------------------------------------------
+        eCommandRequiresRegContext     = (1u << 4),
+        //----------------------------------------------------------------------
+        // eCommandTryTargetAPILock
+        //
+        // Attempts to acquire the target lock if a target is selected in the
+        // command interpreter. If the command object fails to acquire the API
+        // lock, the command will fail with an appropriate error message.
+        //----------------------------------------------------------------------
+        eCommandTryTargetAPILock       = (1u << 5),
+        //----------------------------------------------------------------------
+        // eCommandProcessMustBeLaunched
+        //
+        // Verifies that there is a launched process in m_exe_ctx, if there
+        // isn't, the command will fail with an appropriate error message.
+        //----------------------------------------------------------------------
+        eCommandProcessMustBeLaunched  = (1u << 6),
+        //----------------------------------------------------------------------
+        // eCommandProcessMustBePaused
+        //
+        // Verifies that there is a paused process in m_exe_ctx, if there
+        // isn't, the command will fail with an appropriate error message.
+        //----------------------------------------------------------------------
+        eCommandProcessMustBePaused    = (1u << 7)
+    };
+    
     //----------------------------------------------------------------------
     // Whether a summary should cap how much data it returns to users or not
     //----------------------------------------------------------------------
index 6affe30..46d6229 100644 (file)
@@ -87,7 +87,7 @@
       launchStyle = "0"
       useCustomWorkingDirectory = "NO"
       customWorkingDirectory = "/Volumes/work/gclayton/Documents/devb/attach"
-      buildConfiguration = "Debug"
+      buildConfiguration = "DebugClang"
       ignoresPersistentStateOnLaunch = "YES"
       debugDocumentVersioning = "YES"
       debugServiceExtension = "internal"
index dfa66f8..c2a13c0 100644 (file)
@@ -704,3 +704,18 @@ SBCommand::AddCommand (const char* name, lldb::SBCommandPluginInterface *impl, c
         return lldb::SBCommand(new_command_sp);
     return lldb::SBCommand();
 }
+
+uint32_t
+SBCommand::GetFlags ()
+{
+    if (!IsValid())
+        return 0;
+    return m_opaque_sp->GetFlags().Get();
+}
+
+void
+SBCommand::SetFlags (uint32_t flags)
+{
+    if (IsValid())
+        m_opaque_sp->GetFlags().Set(flags);
+}
index 2946a0b..bab12c8 100644 (file)
@@ -1455,6 +1455,8 @@ public:
         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
index c07d9f3..1d385ea 100644 (file)
@@ -196,7 +196,7 @@ CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interprete
                       "expression",
                       "Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
                       NULL,
-                      eFlagProcessMustBePaused | eFlagTryTargetAPILock),
+                      eCommandProcessMustBePaused | eCommandTryTargetAPILock),
     IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
     m_option_group (interpreter),
     m_format_options (eFormatDefault),
index cd38216..19400ee 100644 (file)
@@ -65,10 +65,10 @@ public:
                              "frame info",
                              "List information about the currently selected frame in the current thread.",
                              "frame info",
-                             eFlagRequiresFrame         |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   )
+                             eCommandRequiresFrame         |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   )
     {
     }
 
@@ -156,10 +156,10 @@ public:
                              "frame select",
                              "Select a frame by index from within the current thread and make it the current frame.",
                              NULL,
-                             eFlagRequiresThread        |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   ),
+                             eCommandRequiresThread        |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   ),
         m_options (interpreter)
     {
         CommandArgumentEntry arg;
@@ -192,7 +192,7 @@ protected:
     bool
     DoExecute (Args& command, CommandReturnObject &result)
     {
-        // No need to check "thread" for validity as eFlagRequiresThread ensures it is valid
+        // No need to check "thread" for validity as eCommandRequiresThread ensures it is valid
         Thread *thread = m_exe_ctx.GetThreadPtr();
 
         uint32_t frame_idx = UINT32_MAX;
@@ -314,11 +314,11 @@ public:
                              "Children of aggregate variables can be specified such as "
                              "'var->child.x'.",
                              NULL,
-                             eFlagRequiresFrame |
-                             eFlagTryTargetAPILock |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused |
-                             eFlagRequiresProcess),
+                             eCommandRequiresFrame |
+                             eCommandTryTargetAPILock |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused |
+                             eCommandRequiresProcess),
         m_option_group (interpreter),
         m_option_variable(true), // Include the frame specific options by passing "true"
         m_option_format (eFormatDefault),
@@ -385,7 +385,7 @@ protected:
     virtual bool
     DoExecute (Args& command, CommandReturnObject &result)
     {
-        // No need to check "frame" for validity as eFlagRequiresFrame ensures it is valid
+        // No need to check "frame" for validity as eCommandRequiresFrame ensures it is valid
         StackFrame *frame = m_exe_ctx.GetFramePtr();
 
         Stream &s = result.GetOutputStream();
index 25029a6..efbde4d 100644 (file)
@@ -315,7 +315,7 @@ public:
                              "memory read",
                              "Read from the memory of the process being debugged.",
                              NULL,
-                             eFlagRequiresTarget | eFlagProcessMustBePaused),
+                             eCommandRequiresTarget | eCommandProcessMustBePaused),
         m_option_group (interpreter),
         m_format_options (eFormatBytesWithASCII, 1, 8),
         m_memory_options (),
@@ -388,7 +388,7 @@ protected:
     virtual bool
     DoExecute (Args& command, CommandReturnObject &result)
     {
-        // No need to check "target" for validity as eFlagRequiresTarget ensures it is valid
+        // No need to check "target" for validity as eCommandRequiresTarget ensures it is valid
         Target *target = m_exe_ctx.GetTargetPtr();
 
         const size_t argc = command.GetArgumentCount();
@@ -1034,7 +1034,7 @@ public:
                        "memory find",
                        "Find a value in the memory of the process being debugged.",
                        NULL,
-                       eFlagRequiresProcess | eFlagProcessMustBeLaunched),
+                       eCommandRequiresProcess | eCommandProcessMustBeLaunched),
   m_option_group (interpreter),
   m_memory_options ()
   {
@@ -1080,7 +1080,7 @@ protected:
   virtual bool
   DoExecute (Args& command, CommandReturnObject &result)
   {
-      // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
+      // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
       Process *process = m_exe_ctx.GetProcessPtr();
 
       const size_t argc = command.GetArgumentCount();
@@ -1335,7 +1335,7 @@ public:
                              "memory write",
                              "Write to the memory of the process being debugged.",
                              NULL,
-                             eFlagRequiresProcess | eFlagProcessMustBeLaunched),
+                             eCommandRequiresProcess | eCommandProcessMustBeLaunched),
         m_option_group (interpreter),
         m_format_options (eFormatBytes, 1, UINT64_MAX),
         m_memory_options ()
@@ -1412,7 +1412,7 @@ protected:
     virtual bool
     DoExecute (Args& command, CommandReturnObject &result)
     {
-        // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
+        // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
         Process *process = m_exe_ctx.GetProcessPtr();
 
         const size_t argc = command.GetArgumentCount();
@@ -1702,7 +1702,7 @@ public:
                          "memory history",
                          "Prints out the recorded stack traces for allocation/deallocation of a memory address.",
                          NULL,
-                         eFlagRequiresTarget | eFlagRequiresProcess | eFlagProcessMustBePaused | eFlagProcessMustBeLaunched)
+                         eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBePaused | eCommandProcessMustBeLaunched)
     {
         CommandArgumentEntry arg1;
         CommandArgumentData addr_arg;
index f62a002..16326e4 100644 (file)
@@ -1274,7 +1274,7 @@ public:
                              "platform process launch",
                              "Launch a new process on a remote platform.",
                              "platform process launch program",
-                             eFlagRequiresTarget | eFlagTryTargetAPILock),
+                             eCommandRequiresTarget | eCommandTryTargetAPILock),
         m_options (interpreter)
     {
     }
index a908c4b..14b7e2f 100644 (file)
@@ -125,7 +125,7 @@ public:
                                             "process launch",
                                             "Launch the executable in the debugger.",
                                             NULL,
-                                            eFlagRequiresTarget,
+                                            eCommandRequiresTarget,
                                             "restart"),
         m_options (interpreter)
     {
@@ -639,10 +639,10 @@ public:
                              "process continue",
                              "Continue execution of all threads in the current process.",
                              "process continue",
-                             eFlagRequiresProcess       |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   ),
+                             eCommandRequiresProcess       |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   ),
         m_options(interpreter)
     {
     }
@@ -900,9 +900,9 @@ public:
                              "process detach",
                              "Detach from the current process being debugged.",
                              "process detach",
-                             eFlagRequiresProcess      |
-                             eFlagTryTargetAPILock     |
-                             eFlagProcessMustBeLaunched),
+                             eCommandRequiresProcess      |
+                             eCommandTryTargetAPILock     |
+                             eCommandProcessMustBeLaunched),
         m_options(interpreter)
     {
     }
@@ -1181,10 +1181,10 @@ public:
                              "process load",
                              "Load a shared library into the current process.",
                              "process load <filename> [<filename> ...]",
-                             eFlagRequiresProcess       |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   )
+                             eCommandRequiresProcess       |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   )
     {
     }
 
@@ -1238,10 +1238,10 @@ public:
                              "process unload",
                              "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
                              "process unload <index>",
-                             eFlagRequiresProcess       |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   )
+                             eCommandRequiresProcess       |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   )
     {
     }
 
@@ -1302,7 +1302,7 @@ public:
                              "process signal",
                              "Send a UNIX signal to the current process being debugged.",
                              NULL,
-                             eFlagRequiresProcess | eFlagTryTargetAPILock)
+                             eCommandRequiresProcess | eCommandTryTargetAPILock)
     {
         CommandArgumentEntry arg;
         CommandArgumentData signal_arg;
@@ -1384,9 +1384,9 @@ public:
                              "process interrupt",
                              "Interrupt the current process being debugged.",
                              "process interrupt",
-                             eFlagRequiresProcess      |
-                             eFlagTryTargetAPILock     |
-                             eFlagProcessMustBeLaunched)
+                             eCommandRequiresProcess      |
+                             eCommandTryTargetAPILock     |
+                             eCommandProcessMustBeLaunched)
     {
     }
 
@@ -1446,9 +1446,9 @@ public:
                              "process kill",
                              "Terminate the current process being debugged.",
                              "process kill",
-                             eFlagRequiresProcess      |
-                             eFlagTryTargetAPILock     |
-                             eFlagProcessMustBeLaunched)
+                             eCommandRequiresProcess      |
+                             eCommandTryTargetAPILock     |
+                             eCommandProcessMustBeLaunched)
     {
     }
 
@@ -1507,9 +1507,9 @@ public:
                          "process save-core",
                          "Save the current process as a core file using an appropriate file type.",
                          "process save-core FILE",
-                         eFlagRequiresProcess      |
-                         eFlagTryTargetAPILock     |
-                         eFlagProcessMustBeLaunched)
+                         eCommandRequiresProcess      |
+                         eCommandTryTargetAPILock     |
+                         eCommandProcessMustBeLaunched)
     {
     }
     
@@ -1571,7 +1571,7 @@ public:
                              "process status",
                              "Show the current status and location of executing process.",
                              "process status",
-                             eFlagRequiresProcess | eFlagTryTargetAPILock)
+                             eCommandRequiresProcess | eCommandTryTargetAPILock)
     {
     }
 
@@ -1585,7 +1585,7 @@ public:
     {
         Stream &strm = result.GetOutputStream();
         result.SetStatus (eReturnStatusSuccessFinishNoResult);
-        // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid        
+        // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid        
         Process *process = m_exe_ctx.GetProcessPtr();
         const bool only_threads_with_stop_reason = true;
         const uint32_t start_frame = 0;
index 6181802..0940897 100644 (file)
@@ -48,10 +48,10 @@ public:
                              "register read",
                              "Dump the contents of one or more register values from the current frame.  If no register is specified, dumps them all.",
                              NULL,
-                             eFlagRequiresFrame         |
-                             eFlagRequiresRegContext    |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   ),
+                             eCommandRequiresFrame         |
+                             eCommandRequiresRegContext    |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   ),
         m_option_group (interpreter),
         m_format_options (eFormatDefault),
         m_command_options ()
@@ -377,10 +377,10 @@ public:
                              "register write",
                              "Modify a single register value.",
                              NULL,
-                             eFlagRequiresFrame         |
-                             eFlagRequiresRegContext    |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused)
+                             eCommandRequiresFrame         |
+                             eCommandRequiresRegContext    |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused)
     {
         CommandArgumentEntry arg1;
         CommandArgumentEntry arg2;
index 23fb52b..3d0c739 100644 (file)
@@ -253,7 +253,7 @@ public:
                              "source list",
                              "Display source code (as specified) based on the current executable's debug info.",
                              NULL,
-                             eFlagRequiresTarget), 
+                             eCommandRequiresTarget), 
         m_options (interpreter)
     {
     }
index e9ab673..661215d 100644 (file)
@@ -740,7 +740,7 @@ public:
                              "target variable",
                              "Read global variable(s) prior to, or while running your binary.",
                              NULL,
-                             eFlagRequiresTarget),
+                             eCommandRequiresTarget),
         m_option_group (interpreter),
         m_option_variable (false), // Don't include frame options
         m_option_format (eFormatDefault),
@@ -2561,7 +2561,7 @@ public:
                                                       "target modules dump line-table",
                                                       "Dump the line table for one or more compilation units.",
                                                       NULL,
-                                                      eFlagRequiresTarget)
+                                                      eCommandRequiresTarget)
     {
     }
 
@@ -3651,10 +3651,10 @@ public:
                              "target modules show-unwind",
                              "Show synthesized unwind instructions for a function.",
                              NULL,
-                             eFlagRequiresTarget        |
-                             eFlagRequiresProcess       |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   ),
+                             eCommandRequiresTarget        |
+                             eCommandRequiresProcess       |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   ),
         m_options (interpreter)
     {
     }
@@ -4011,7 +4011,7 @@ public:
                              "target modules lookup",
                              "Look up information within executable and dependent shared library images.",
                              NULL,
-                             eFlagRequiresTarget),
+                             eCommandRequiresTarget),
         m_options (interpreter)
     {
         CommandArgumentEntry arg;
@@ -4391,7 +4391,7 @@ public:
         CommandObjectParsed (interpreter,
                              "target symbols add",
                              "Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for.",
-                             "target symbols add [<symfile>]", eFlagRequiresTarget),
+                             "target symbols add [<symfile>]", eCommandRequiresTarget),
         m_option_group (interpreter),
         m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
         m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
index d0c82b4..78271f2 100644 (file)
@@ -241,11 +241,11 @@ public:
                              "thread backtrace",
                              "Show the stack for one or more threads.  If no threads are specified, show the currently selected thread.  Use the thread-index \"all\" to see all threads.",
                              NULL,
-                             eFlagRequiresProcess       |
-                             eFlagRequiresThread        |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   ),
+                             eCommandRequiresProcess       |
+                             eCommandRequiresThread        |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   ),
         m_options(interpreter)
     {
     }
@@ -472,11 +472,11 @@ public:
                                              StepType step_type,
                                              StepScope step_scope) :
         CommandObjectParsed (interpreter, name, help, syntax,
-                             eFlagRequiresProcess       |
-                             eFlagRequiresThread        |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   ),
+                             eCommandRequiresProcess       |
+                             eCommandRequiresThread        |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   ),
         m_step_type (step_type),
         m_step_scope (step_scope),
         m_options (interpreter)
@@ -760,10 +760,10 @@ public:
                              "thread continue",
                              "Continue execution of one or more threads in an active process.",
                              NULL,
-                             eFlagRequiresThread        |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused)
+                             eCommandRequiresThread        |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused)
     {
         CommandArgumentEntry arg;
         CommandArgumentData thread_idx_arg;
@@ -1072,10 +1072,10 @@ public:
                              "thread until",
                              "Run the current or specified thread until it reaches a given line number or address or leaves the current function.",
                              NULL,
-                             eFlagRequiresThread        |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   ),
+                             eCommandRequiresThread        |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   ),
         m_options (interpreter)
     {
         CommandArgumentEntry arg;
@@ -1351,10 +1351,10 @@ public:
                              "thread select",
                              "Select a thread as the currently active thread.",
                              NULL,
-                             eFlagRequiresProcess       |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   )
+                             eCommandRequiresProcess       |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   )
     {
         CommandArgumentEntry arg;
         CommandArgumentData thread_idx_arg;
@@ -1427,10 +1427,10 @@ public:
                              "thread list",
                              "Show a summary of all current threads in a process.",
                              "thread list",
-                             eFlagRequiresProcess       |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   )
+                             eCommandRequiresProcess       |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   )
     {
     }
 
@@ -1472,10 +1472,10 @@ public:
                                          "thread info",
                                          "Show an extended summary of information about thread(s) in a process.",
                                          "thread info",
-                                         eFlagRequiresProcess       |
-                                         eFlagTryTargetAPILock      |
-                                         eFlagProcessMustBeLaunched |
-                                         eFlagProcessMustBePaused),
+                                         eCommandRequiresProcess       |
+                                         eCommandTryTargetAPILock      |
+                                         eCommandProcessMustBeLaunched |
+                                         eCommandProcessMustBePaused),
         m_options (interpreter)
     {
         m_add_return = false;
@@ -1664,10 +1664,10 @@ public:
                           "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
                           " or with the -x option from the innermost function evaluation.",
                           "thread return",
-                          eFlagRequiresFrame         |
-                          eFlagTryTargetAPILock      |
-                          eFlagProcessMustBeLaunched |
-                          eFlagProcessMustBePaused   ),
+                          eCommandRequiresFrame         |
+                          eCommandTryTargetAPILock      |
+                          eCommandProcessMustBeLaunched |
+                          eCommandProcessMustBePaused   ),
         m_options (interpreter)
     {
         CommandArgumentEntry arg;
@@ -1892,10 +1892,10 @@ public:
                           "thread jump",
                           "Sets the program counter to a new address.",
                           "thread jump",
-                          eFlagRequiresFrame         |
-                          eFlagTryTargetAPILock      |
-                          eFlagProcessMustBeLaunched |
-                          eFlagProcessMustBePaused   ),
+                          eCommandRequiresFrame         |
+                          eCommandTryTargetAPILock      |
+                          eCommandProcessMustBeLaunched |
+                          eCommandProcessMustBePaused   ),
         m_options (interpreter)
     {
     }
@@ -2076,11 +2076,11 @@ public:
                                          "Show thread plans for one or more threads.  If no threads are specified, show the "
                                          "currently selected thread.  Use the thread-index \"all\" to see all threads.",
                                          NULL,
-                                         eFlagRequiresProcess       |
-                                         eFlagRequiresThread        |
-                                         eFlagTryTargetAPILock      |
-                                         eFlagProcessMustBeLaunched |
-                                         eFlagProcessMustBePaused   ),
+                                         eCommandRequiresProcess       |
+                                         eCommandRequiresThread        |
+                                         eCommandTryTargetAPILock      |
+                                         eCommandProcessMustBeLaunched |
+                                         eCommandProcessMustBePaused   ),
         m_options(interpreter)
     {
     }
@@ -2128,11 +2128,11 @@ public:
                              "Only user visible plans can be discarded, use the index from \"thread plan list\""
                              " without the \"-i\" argument.",
                              NULL,
-                             eFlagRequiresProcess       |
-                             eFlagRequiresThread        |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   )
+                             eCommandRequiresProcess       |
+                             eCommandRequiresThread        |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   )
     {
         CommandArgumentEntry arg;
         CommandArgumentData plan_index_arg;
index 3a4c60c..f89b41a 100644 (file)
@@ -4249,7 +4249,7 @@ public:
                      nullptr,
                      nullptr,
                      nullptr,
-                     eFlagRequiresFrame),
+                     eCommandRequiresFrame),
     m_formatter_name(formatter_name ? formatter_name : ""),
     m_discovery_function(discovery_func)
     {
index b42e74c..51b3670 100644 (file)
@@ -925,10 +925,10 @@ public:
                              "If watchpoint setting fails, consider disable/delete existing ones "
                              "to free up resources.",
                              NULL,
-                             eFlagRequiresFrame         |
-                             eFlagTryTargetAPILock      |
-                             eFlagProcessMustBeLaunched |
-                             eFlagProcessMustBePaused   ),
+                             eCommandRequiresFrame         |
+                             eCommandTryTargetAPILock      |
+                             eCommandProcessMustBeLaunched |
+                             eCommandProcessMustBePaused   ),
         m_option_group (interpreter),
         m_option_watchpoint ()
     {
@@ -1132,10 +1132,10 @@ public:
                           "If watchpoint setting fails, consider disable/delete existing ones "
                           "to free up resources.",
                           NULL,
-                          eFlagRequiresFrame         |
-                          eFlagTryTargetAPILock      |
-                          eFlagProcessMustBeLaunched |
-                          eFlagProcessMustBePaused   ),
+                          eCommandRequiresFrame         |
+                          eCommandTryTargetAPILock      |
+                          eCommandProcessMustBeLaunched |
+                          eCommandProcessMustBePaused   ),
         m_option_group (interpreter),
         m_option_watchpoint ()
     {
index f6e5bca..29e4744 100644 (file)
@@ -228,20 +228,20 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
     m_exe_ctx = m_interpreter.GetExecutionContext();
 
     const uint32_t flags = GetFlags().Get();
-    if (flags & (eFlagRequiresTarget   |
-                 eFlagRequiresProcess  |
-                 eFlagRequiresThread   |
-                 eFlagRequiresFrame    |
-                 eFlagTryTargetAPILock ))
+    if (flags & (eCommandRequiresTarget   |
+                 eCommandRequiresProcess  |
+                 eCommandRequiresThread   |
+                 eCommandRequiresFrame    |
+                 eCommandTryTargetAPILock ))
     {
 
-        if ((flags & eFlagRequiresTarget) && !m_exe_ctx.HasTargetScope())
+        if ((flags & eCommandRequiresTarget) && !m_exe_ctx.HasTargetScope())
         {
             result.AppendError (GetInvalidTargetDescription());
             return false;
         }
 
-        if ((flags & eFlagRequiresProcess) && !m_exe_ctx.HasProcessScope())
+        if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope())
         {
             if (!m_exe_ctx.HasTargetScope())
                 result.AppendError (GetInvalidTargetDescription());
@@ -250,7 +250,7 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
             return false;
         }
         
-        if ((flags & eFlagRequiresThread) && !m_exe_ctx.HasThreadScope())
+        if ((flags & eCommandRequiresThread) && !m_exe_ctx.HasThreadScope())
         {
             if (!m_exe_ctx.HasTargetScope())
                 result.AppendError (GetInvalidTargetDescription());
@@ -261,7 +261,7 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
             return false;
         }
         
-        if ((flags & eFlagRequiresFrame) && !m_exe_ctx.HasFrameScope())
+        if ((flags & eCommandRequiresFrame) && !m_exe_ctx.HasFrameScope())
         {
             if (!m_exe_ctx.HasTargetScope())
                 result.AppendError (GetInvalidTargetDescription());
@@ -274,13 +274,13 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
             return false;
         }
         
-        if ((flags & eFlagRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr))
+        if ((flags & eCommandRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr))
         {
             result.AppendError (GetInvalidRegContextDescription());
             return false;
         }
 
-        if (flags & eFlagTryTargetAPILock)
+        if (flags & eCommandTryTargetAPILock)
         {
             Target *target = m_exe_ctx.GetTargetPtr();
             if (target)
@@ -288,13 +288,13 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
         }
     }
 
-    if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
+    if (GetFlags().AnySet (eCommandProcessMustBeLaunched | eCommandProcessMustBePaused))
     {
         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
         if (process == nullptr)
         {
             // A process that is not running is considered paused.
-            if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
+            if (GetFlags().Test(eCommandProcessMustBeLaunched))
             {
                 result.AppendError ("Process must exist.");
                 result.SetStatus (eReturnStatusFailed);
@@ -318,7 +318,7 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
             case eStateDetached:
             case eStateExited:
             case eStateUnloaded:
-                if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
+                if (GetFlags().Test(eCommandProcessMustBeLaunched))
                 {
                     result.AppendError ("Process must be launched.");
                     result.SetStatus (eReturnStatusFailed);
@@ -328,7 +328,7 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
 
             case eStateRunning:
             case eStateStepping:
-                if (GetFlags().Test(CommandObject::eFlagProcessMustBePaused))
+                if (GetFlags().Test(eCommandProcessMustBePaused))
                 {
                     result.AppendError ("Process is running.  Use 'process interrupt' to pause execution.");
                     result.SetStatus (eReturnStatusFailed);
index 1baf484..1e16fd3 100644 (file)
@@ -2878,6 +2878,78 @@ ScriptInterpreterPython::GetShortHelpForCommandObject (StructuredData::GenericSP
     return got_string;
 }
 
+uint32_t
+ScriptInterpreterPython::GetFlagsForCommandObject (StructuredData::GenericSP cmd_obj_sp)
+{
+    uint32_t result = 0;
+    
+    Locker py_lock (this,
+                    Locker::AcquireLock | Locker::NoSTDIN,
+                    Locker::FreeLock);
+    
+    static char callee_name[] = "get_flags";
+    
+    if (!cmd_obj_sp)
+        return result;
+    
+    PyObject* implementor = (PyObject*)cmd_obj_sp->GetValue();
+    
+    if (implementor == nullptr || implementor == Py_None)
+        return result;
+    
+    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    if (pmeth == nullptr || pmeth == Py_None)
+    {
+        Py_XDECREF(pmeth);
+        return result;
+    }
+    
+    if (PyCallable_Check(pmeth) == 0)
+    {
+        if (PyErr_Occurred())
+        {
+            PyErr_Clear();
+        }
+        
+        Py_XDECREF(pmeth);
+        return result;
+    }
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    Py_XDECREF(pmeth);
+    
+    // right now we know this function exists and is callable..
+    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
+    
+    // if it fails, print the error but otherwise go on
+    if (PyErr_Occurred())
+    {
+        PyErr_Print();
+        PyErr_Clear();
+    }
+    
+    if (py_return != nullptr && py_return != Py_None)
+    {
+        if (PyInt_Check(py_return))
+            result = (uint32_t)PyInt_AsLong(py_return);
+        else if (PyLong_Check(py_return))
+            result = (uint32_t)PyLong_AsLong(py_return);
+    }
+    Py_XDECREF(py_return);
+    
+    return result;
+}
+
 bool
 ScriptInterpreterPython::GetLongHelpForCommandObject (StructuredData::GenericSP cmd_obj_sp,
                                                       std::string& dest)
index 7c71df2..eba16a0 100644 (file)
@@ -458,9 +458,9 @@ public:
                          "dump",
                          "Dump information on Objective-C classes known to the current process.",
                          "language objc class-table dump",
-                         eFlagRequiresProcess       |
-                         eFlagProcessMustBeLaunched |
-                         eFlagProcessMustBePaused   )
+                         eCommandRequiresProcess       |
+                         eCommandProcessMustBeLaunched |
+                         eCommandProcessMustBePaused   )
     {
     }
     
@@ -518,9 +518,9 @@ public:
                          "info",
                          "Dump information on a tagged pointer.",
                          "language objc tagged-pointer info",
-                         eFlagRequiresProcess       |
-                         eFlagProcessMustBeLaunched |
-                         eFlagProcessMustBePaused   )
+                         eCommandRequiresProcess       |
+                         eCommandProcessMustBeLaunched |
+                         eCommandProcessMustBePaused   )
     {
         CommandArgumentEntry arg;
         CommandArgumentData index_arg;
index 6514494..d95c302 100644 (file)
@@ -330,7 +330,7 @@ class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
         : CommandObjectParsed(interpreter, "renderscript module probe",
                               "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
                               "renderscript module probe",
-                              eFlagRequiresTarget | eFlagRequiresProcess | eFlagProcessMustBeLaunched)
+                              eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
     {
     }
 
@@ -368,7 +368,7 @@ class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
     CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
         : CommandObjectParsed(interpreter, "renderscript module dump",
                               "Dumps renderscript specific information for all modules.", "renderscript module dump",
-                              eFlagRequiresProcess | eFlagProcessMustBeLaunched)
+                              eCommandRequiresProcess | eCommandProcessMustBeLaunched)
     {
     }
 
index fab1cb2..d4210b4 100644 (file)
@@ -23,11 +23,17 @@ class CmdPythonTestCase(TestBase):
         self.pycmd_tests ()
 
     def pycmd_tests (self):
+        self.runCmd("command source py_import")
+
+        self.expect('targetname',
+            substrs = ['a.out'], matching=False, error=True)
+
         exe = os.path.join (os.getcwd(), "a.out")
         self.expect("file " + exe,
                     patterns = [ "Current executable set to .*a.out" ])
 
-        self.runCmd("command source py_import")
+        self.expect('targetname',
+            substrs = ['a.out'], matching=True, error=False)
 
         # This is the function to remove the custom commands in order to have a
         # clean slate for the next test case.
@@ -75,9 +81,6 @@ class CmdPythonTestCase(TestBase):
         self.expect('welcome Enrico', matching=False, error=True,
                 substrs = ['Hello Enrico, welcome to LLDB']);
 
-        self.expect('targetname',
-            substrs = ['a.out'])
-
         self.expect('targetname fail', error=True,
                     substrs = ['a test for error in command'])
 
@@ -122,7 +125,7 @@ class CmdPythonTestCase(TestBase):
         self.runCmd('command script add my_command --class welcome.WelcomeCommand')
         self.expect('my_command Blah', substrs = ['Hello Blah, welcome to LLDB'])
 
-        self.runCmd('command script add my_command --function welcome.target_name_impl')
+        self.runCmd('command script add my_command --class welcome.TargetnameCommand')
         self.expect('my_command', substrs = ['a.out'])
 
         self.runCmd("command script clear")
index 6150e02..169daac 100644 (file)
@@ -3,7 +3,7 @@ script sys.path.append(os.path.join(os.getcwd(), os.pardir))
 script import welcome
 script import bug11569
 command script add welcome --class welcome.WelcomeCommand
-command script add targetname --function welcome.target_name_impl
+command script add targetname --class welcome.TargetnameCommand
 command script add longwait --function welcome.print_wait_impl
 command script import mysto.py --allow-reload
 command script add tell_sync --function welcome.check_for_synchro --synchronicity sync
index 90bd0b8..c6d4ddc 100644 (file)
@@ -1,4 +1,4 @@
-import sys
+import lldb, sys
 
 class WelcomeCommand(object):
     def __init__(self, debugger, session_dict):
@@ -11,12 +11,19 @@ class WelcomeCommand(object):
         print >>result,  ('Hello ' + args + ', welcome to LLDB');
         return None;
 
-def target_name_impl(debugger, args, result, dict):
-    target = debugger.GetSelectedTarget()
-    file = target.GetExecutable()
-    print >>result,  ('Current target ' + file.GetFilename())
-    if args == 'fail':
-        result.SetError('a test for error in command')
+class TargetnameCommand(object):
+    def __init__(self, debugger, session_dict):
+        pass
+
+    def __call__(self, debugger, args, exe_ctx, result):
+        target = debugger.GetSelectedTarget()
+        file = target.GetExecutable()
+        print >>result,  ('Current target ' + file.GetFilename())
+        if args == 'fail':
+            result.SetError('a test for error in command')
+    
+    def get_flags(self):
+        return lldb.eCommandRequiresTarget
 
 def print_wait_impl(debugger, args, result, dict):
     result.SetImmediateOutputFile(sys.stdout)