[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