[Lldb-commits] [lldb] r129855 - in /lldb/trunk: include/lldb/Interpreter/CommandInterpreter.h include/lldb/Interpreter/CommandObjectRegexCommand.h include/lldb/Interpreter/NamedOptionValue.h source/Commands/CommandObjectCommands.cpp source/Interpreter/CommandInterpreter.cpp source/Interpreter/NamedOptionValue.cpp

Greg Clayton gclayton at apple.com
Wed Apr 20 09:37:46 PDT 2011


Author: gclayton
Date: Wed Apr 20 11:37:46 2011
New Revision: 129855

URL: http://llvm.org/viewvc/llvm-project?rev=129855&view=rev
Log:
Added the ability for users to create new regex commands.
To do this currently, it must be done in multi-line mode:

(lldb) commands regex --help "Help text for command" --syntax "syntax for command" <cmd-name>

Any example that would use "f" for "finish" when there are no arguments,
and "f <num>" to do a "frame select <num>" would be:
(lldb) commands regex f
Enter multiple regular expressions in the form s/find/replace/ then terminate with an empty line:
s/^$/finish/
s/([0-9]+)/frame select %1/

(lldb) f 11
frame select 12
...
(lldb) f
finish
...

Also added the string version of the OptionValue as OptionValueString.


Modified:
    lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
    lldb/trunk/include/lldb/Interpreter/CommandObjectRegexCommand.h
    lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h
    lldb/trunk/source/Commands/CommandObjectCommands.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp
    lldb/trunk/source/Interpreter/NamedOptionValue.cpp

Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=129855&r1=129854&r2=129855&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Wed Apr 20 11:37:46 2011
@@ -49,6 +49,11 @@
     virtual
     ~CommandInterpreter ();
 
+    bool
+    AddCommand (const char *name, 
+                const lldb::CommandObjectSP &cmd_sp,
+                bool can_replace);
+    
     lldb::CommandObjectSP
     GetCommandSPExact (const char *cmd, 
                        bool include_aliases);

Modified: lldb/trunk/include/lldb/Interpreter/CommandObjectRegexCommand.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandObjectRegexCommand.h?rev=129855&r1=129854&r2=129855&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandObjectRegexCommand.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandObjectRegexCommand.h Wed Apr 20 11:37:46 2011
@@ -16,8 +16,8 @@
 
 // Other libraries and framework includes
 // Project includes
-#include "lldb/Interpreter/CommandObject.h"
 #include "lldb/Core/RegularExpression.h"
+#include "lldb/Interpreter/CommandObject.h"
 
 namespace lldb_private {
 
@@ -53,6 +53,12 @@
     bool
     AddRegexCommand (const char *re_cstr, const char *command_cstr);
 
+    bool
+    HasRegexEntries () const
+    {
+        return !m_entries.empty();
+    }
+
 protected:
     struct Entry
     {

Modified: lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h?rev=129855&r1=129854&r2=129855&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h (original)
+++ lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h Wed Apr 20 11:37:46 2011
@@ -282,6 +282,89 @@
     };
 
     //---------------------------------------------------------------------
+    // OptionValueString
+    //---------------------------------------------------------------------
+    class OptionValueString : public OptionValue
+    {
+        OptionValueString (const char *current_value, 
+                           const char *default_value) :
+            m_current_value (),
+            m_default_value ()
+        {
+            if  (current_value && current_value[0])
+                m_current_value.assign (current_value);
+            if  (default_value && default_value[0])
+                m_default_value.assign (default_value);
+        }
+        
+        virtual 
+        ~OptionValueString()
+        {
+        }
+        
+        //---------------------------------------------------------------------
+        // Virtual subclass pure virtual overrides
+        //---------------------------------------------------------------------
+        
+        virtual OptionValue::Type
+        GetType ()
+        {
+            return eTypeString;
+        }
+        
+        virtual void
+        DumpValue (Stream &strm);
+        
+        virtual bool
+        SetValueFromCString (const char *value);
+
+        virtual bool
+        ResetValueToDefault ()
+        {
+            m_current_value = m_default_value;
+            return true;
+        }
+        
+        //---------------------------------------------------------------------
+        // Subclass specific functions
+        //---------------------------------------------------------------------
+        
+        const char *
+        GetCurrentValue() const
+        {
+            return m_current_value.c_str();
+        }
+        
+        const char *
+        GetDefaultValue() const
+        {
+            return m_default_value.c_str();
+        }
+        
+        void
+        SetCurrentValue (const char *value)
+        {
+            if (value && value[0])
+                m_current_value.assign (value);
+            else
+                m_current_value.clear();
+        }
+        
+        void
+        SetDefaultValue (const char *value)
+        {
+            if (value && value[0])
+                m_default_value.assign (value);
+            else
+                m_default_value.clear();
+        }
+        
+    protected:
+        std::string m_current_value;
+        std::string m_default_value;
+    };
+
+    //---------------------------------------------------------------------
     // OptionValueFileSpec
     //---------------------------------------------------------------------
     class OptionValueFileSpec : public OptionValue
@@ -626,6 +709,9 @@
         OptionValueUInt64 *
         GetUInt64Value ();        
 
+        OptionValueString *
+        GetStringValue ();
+
         OptionValueFileSpec *
         GetFileSpecValue() ;
 

Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=129855&r1=129854&r2=129855&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Wed Apr 20 11:37:46 2011
@@ -13,9 +13,11 @@
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
-#include "lldb/Interpreter/Args.h"
 #include "lldb/Core/Debugger.h"
+#include "lldb/Core/InputReader.h"
+#include "lldb/Interpreter/Args.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObjectRegexCommand.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/Options.h"
 
@@ -92,10 +94,6 @@
         bool m_stop_on_continue;
     };
     
-    // Options table: Required for subclasses of Options.
-
-    static OptionDefinition g_option_table[];
-
     CommandOptions m_options;
     
     virtual Options *
@@ -640,6 +638,275 @@
     }
 };
 
+#pragma mark CommandObjectCommandsAddRegex
+//-------------------------------------------------------------------------
+// CommandObjectCommandsAddRegex
+//-------------------------------------------------------------------------
+
+class CommandObjectCommandsAddRegex : public CommandObject
+{
+public:
+    CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
+        CommandObject (interpreter,
+                       "commands regex",
+                       "Allow the user to create a regular expression command.",
+                       NULL),
+        m_options (interpreter)
+    {
+    }
+    
+    ~CommandObjectCommandsAddRegex()
+    {
+    }
+    
+    
+    bool
+    Execute (Args& args, CommandReturnObject &result)
+    {
+        if (args.GetArgumentCount() == 1)
+        {
+            const char *name = args.GetArgumentAtIndex(0);
+            InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
+            m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter, 
+                                                                 name, 
+                                                                 m_options.GetHelp (),
+                                                                 m_options.GetSyntax (),
+                                                                 10));
+            if (reader_sp)
+            {
+                Error err (reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
+                                                  this,                         // baton
+                                                  eInputReaderGranularityLine,  // token size, to pass to callback function
+                                                  "DONE",                       // end token
+                                                  "> ",                         // prompt
+                                                  true));                       // echo input
+                if (err.Success())
+                {
+                    m_interpreter.GetDebugger().PushInputReader (reader_sp);
+                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
+                }
+                else
+                {
+                    result.AppendError (err.AsCString());
+                    result.SetStatus (eReturnStatusFailed);
+                }
+            }
+        }
+        else
+        {
+            result.AppendError ("invalid arguments.\n");
+            result.SetStatus (eReturnStatusFailed);
+        }
+        return result.Succeeded();
+    }
+    
+    bool
+    AppendRegexAndSubstitution (const char *regex, const char *subst)
+    {
+        if (m_regex_cmd_ap.get())
+        {
+            m_regex_cmd_ap->AddRegexCommand (regex, subst);
+            return true;
+        }
+        return false;
+    }
+    
+    void
+    InputReaderIsDone()
+    {
+        if (m_regex_cmd_ap.get())
+        {
+            if (m_regex_cmd_ap->HasRegexEntries())
+            {
+                CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
+                m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
+            }
+        }
+    }
+
+    static size_t
+    InputReaderCallback (void *baton, 
+                         InputReader &reader, 
+                         lldb::InputReaderAction notification,
+                         const char *bytes, 
+                         size_t bytes_len);
+private:
+    std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;    
+
+     class CommandOptions : public Options
+     {
+     public:
+         
+         CommandOptions (CommandInterpreter &interpreter) :
+            Options (interpreter)
+         {
+         }
+         
+         virtual
+         ~CommandOptions (){}
+         
+         virtual Error
+         SetOptionValue (uint32_t option_idx, const char *option_arg)
+         {
+             Error error;
+             char short_option = (char) m_getopt_table[option_idx].val;
+             
+             switch (short_option)
+             {
+                 case 'h':
+                     m_help.assign (option_arg);
+                     break;
+                 case 's':
+                     m_syntax.assign (option_arg);
+                     break;
+
+                 default:
+                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+                     break;
+             }
+             
+             return error;
+         }
+         
+         void
+         OptionParsingStarting ()
+         {
+             m_help.clear();
+             m_syntax.clear();
+         }
+         
+         const OptionDefinition*
+         GetDefinitions ()
+         {
+             return g_option_table;
+         }
+         
+         // Options table: Required for subclasses of Options.
+         
+         static OptionDefinition g_option_table[];
+         
+         const char *
+         GetHelp ()
+         {
+             if (m_help.empty())
+                 return NULL;
+             return m_help.c_str();
+         }
+         const char *
+         GetSyntax ()
+         {
+             if (m_syntax.empty())
+                 return NULL;
+             return m_syntax.c_str();
+         }
+         // Instance variables to hold the values for command options.
+     protected:
+         std::string m_help;
+         std::string m_syntax;
+     };
+     
+     CommandOptions m_options;
+     
+     virtual Options *
+     GetOptions ()
+     {
+         return &m_options;
+     }
+
+};
+
+size_t
+CommandObjectCommandsAddRegex::InputReaderCallback (void *baton, 
+                                                    InputReader &reader, 
+                                                    lldb::InputReaderAction notification,
+                                                    const char *bytes, 
+                                                    size_t bytes_len)
+{
+    CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
+    
+    switch (notification)
+    {
+        case eInputReaderActivate:
+            reader.GetDebugger().GetOutputStream().Printf("%s\n", "Enter multiple regular expressions in the form s/find/replace/ then terminate with an empty line:");
+            break;
+        case eInputReaderReactivate:
+            break;
+            
+        case eInputReaderDeactivate:
+            break;
+            
+        case eInputReaderGotToken:
+            if (bytes_len == 0)
+                reader.SetIsDone(true);
+            else if (bytes)
+            {
+                std::string regex_sed (bytes, bytes_len);
+                bool success = regex_sed.size() > 3 && regex_sed[0] == 's';
+                if (success)
+                {
+                    const size_t first_separator_char_pos = 1;
+                    const char separator_char = regex_sed[first_separator_char_pos];
+                    const size_t third_separator_char_pos = regex_sed.rfind (separator_char);
+
+                    if (third_separator_char_pos != regex_sed.size() - 1)
+                        success = false;    // Didn't end with regex separator char
+                    else
+                    {
+                        const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
+                        if (second_separator_char_pos == std::string::npos)
+                            success = false;    // Didn't find second regex separator char
+                        else 
+                        {
+                            if (second_separator_char_pos <= 3)
+                                success = false;    // Empty regex is invalid ("s///")
+                            else
+                            {
+                                std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
+                                std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
+                                if (regex.empty() || subst.empty())
+                                    success= false;
+                                else
+                                {
+                                    add_regex_cmd->AppendRegexAndSubstitution(regex.c_str(), subst.c_str());
+                                }
+                            }
+                        }
+                    }
+                }
+                if (!success)
+                {
+                    reader.GetDebugger().GetOutputStream().PutCString("Regular expressions should be in the form s/<regex>/<subst>/.\n");
+                }
+            }
+            break;
+            
+        case eInputReaderInterrupt:
+            reader.SetIsDone (true);
+            reader.GetDebugger().GetOutputStream().PutCString("Regular expression command creations was cancelled.\n");
+            break;
+            
+        case eInputReaderEndOfFile:
+            reader.SetIsDone (true);
+            break;
+            
+        case eInputReaderDone:
+            add_regex_cmd->InputReaderIsDone();
+            break;
+    }
+    
+    return bytes_len;
+}
+
+                                                                 
+OptionDefinition
+CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_1, false, "help", 'h', required_argument, NULL, 0, eArgTypeNone,    "The help text to display for this command."},
+{ LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
+{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
+
 #pragma mark CommandObjectMultiwordCommands
 
 //-------------------------------------------------------------------------
@@ -655,6 +922,7 @@
     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
+    LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
 }
 
 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=129855&r1=129854&r2=129855&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Wed Apr 20 11:37:46 2011
@@ -356,6 +356,24 @@
     return ret_val;
 }
 
+bool
+CommandInterpreter::AddCommand (const char *name, const lldb::CommandObjectSP &cmd_sp, bool can_replace)
+{
+    if (name && name[0])
+    {
+        std::string name_sstr(name);
+        if (!can_replace)
+        {
+            if (m_command_dict.find (name_sstr) != m_command_dict.end())
+                return false;
+        }
+        m_command_dict[name_sstr] = cmd_sp;
+        return true;
+    }
+    return false;
+}
+
+
 CommandObjectSP
 CommandInterpreter::GetCommandSPExact (const char *cmd_cstr, bool include_aliases)
 {

Modified: lldb/trunk/source/Interpreter/NamedOptionValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/NamedOptionValue.cpp?rev=129855&r1=129854&r2=129855&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/NamedOptionValue.cpp (original)
+++ lldb/trunk/source/Interpreter/NamedOptionValue.cpp Wed Apr 20 11:37:46 2011
@@ -94,6 +94,13 @@
     return NULL;
 }
 
+OptionValueString *
+NamedOptionValue::GetStringValue ()
+{
+    if (GetValueType() == OptionValue::eTypeString)
+        return static_cast<OptionValueString *>(m_value_sp.get());
+    return NULL;
+}
 
 OptionValueFileSpec *
 NamedOptionValue::GetFileSpecValue ()
@@ -186,6 +193,24 @@
 }
 
 //-------------------------------------------------------------------------
+// OptionValueDictionary
+//-------------------------------------------------------------------------
+void
+OptionValueString::DumpValue (Stream &strm)
+{
+    strm.Printf ("\"%s\"", m_current_value.c_str());
+}
+
+bool
+OptionValueString::SetValueFromCString (const char *value_cstr)
+{
+    SetCurrentValue (value_cstr);
+    return true;
+}
+
+
+
+//-------------------------------------------------------------------------
 // OptionValueFileSpec
 //-------------------------------------------------------------------------
 void





More information about the lldb-commits mailing list