aboutsummaryrefslogtreecommitdiffstats
path: root/source/Commands
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2014-02-18 16:23:10 +0000
committerEd Maste <emaste@FreeBSD.org>2014-02-18 16:23:10 +0000
commit866dcdacfe59f5f448e008fe2c4cb9dfcf72b2ec (patch)
tree95cb16075f0af1b3a05b9b84eb18dda8e6c903e9 /source/Commands
parentde889deb2c386f2a7831befaf226e5c86685fa53 (diff)
downloadsrc-866dcdacfe59f5f448e008fe2c4cb9dfcf72b2ec.tar.gz
src-866dcdacfe59f5f448e008fe2c4cb9dfcf72b2ec.zip
Import lldb as of SVN r201577 (git 2bdc2f6)vendor/lldb/lldb-r201577
(A number of files not required for the FreeBSD build have been removed.) Sponsored by: DARPA, AFRL
Notes
Notes: svn path=/vendor/lldb/dist/; revision=262182 svn path=/vendor/lldb/lldb-r201577/; revision=262183; tag=vendor/lldb/lldb-r201577
Diffstat (limited to 'source/Commands')
-rw-r--r--source/Commands/CommandObjectBreakpointCommand.cpp156
-rw-r--r--source/Commands/CommandObjectBreakpointCommand.h1
-rw-r--r--source/Commands/CommandObjectCommands.cpp517
-rw-r--r--source/Commands/CommandObjectDisassemble.cpp1
-rw-r--r--source/Commands/CommandObjectExpression.cpp163
-rw-r--r--source/Commands/CommandObjectExpression.h25
-rw-r--r--source/Commands/CommandObjectGUI.cpp61
-rw-r--r--source/Commands/CommandObjectGUI.h43
-rw-r--r--source/Commands/CommandObjectMultiword.cpp9
-rw-r--r--source/Commands/CommandObjectProcess.cpp184
-rw-r--r--source/Commands/CommandObjectQuit.cpp3
-rw-r--r--source/Commands/CommandObjectRegister.cpp1
-rw-r--r--source/Commands/CommandObjectSource.cpp1
-rw-r--r--source/Commands/CommandObjectTarget.cpp160
-rw-r--r--source/Commands/CommandObjectType.cpp877
-rw-r--r--source/Commands/CommandObjectWatchpointCommand.cpp158
-rw-r--r--source/Commands/CommandObjectWatchpointCommand.h3
17 files changed, 1018 insertions, 1345 deletions
diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp
index e540461dadae..532d6cedc83e 100644
--- a/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -16,6 +16,7 @@
#include "CommandObjectBreakpointCommand.h"
#include "CommandObjectBreakpoint.h"
+#include "lldb/Core/IOHandler.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Target.h"
@@ -34,7 +35,9 @@ using namespace lldb_private;
//-------------------------------------------------------------------------
-class CommandObjectBreakpointCommandAdd : public CommandObjectParsed
+class CommandObjectBreakpointCommandAdd :
+ public CommandObjectParsed,
+ public IOHandlerDelegateMultiline
{
public:
@@ -43,6 +46,7 @@ public:
"add",
"Add a set of commands to a breakpoint, to be executed whenever the breakpoint is hit.",
NULL),
+ IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
m_options (interpreter)
{
SetHelpLong (
@@ -207,42 +211,47 @@ one command per line.\n" );
return &m_options;
}
- void
- CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
- CommandReturnObject &result)
+ virtual void
+ IOHandlerActivated (IOHandler &io_handler)
{
- InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
- std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
- if (reader_sp && data_ap.get())
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp)
{
- BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
- bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp);
-
- Error err (reader_sp->Initialize (CommandObjectBreakpointCommandAdd::GenerateBreakpointCommandCallback,
- bp_options, // 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);
- }
+ output_sp->PutCString(g_reader_instructions);
+ output_sp->Flush();
}
- else
+ }
+
+
+ virtual void
+ IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
+ {
+ io_handler.SetIsDone(true);
+
+ BreakpointOptions *bp_options = (BreakpointOptions *) io_handler.GetUserData();
+ if (bp_options)
{
- result.AppendError("out of memory");
- result.SetStatus (eReturnStatusFailed);
+ std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
+ if (data_ap.get())
+ {
+ data_ap->user_source.SplitIntoLines (line.c_str(), line.size());
+ BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
+ bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp);
+ }
}
}
+ void
+ CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
+ CommandReturnObject &result)
+ {
+ m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ bp_options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
+ }
+
/// Set a one-liner as the callback for the breakpoint.
void
SetBreakpointCommandCallback (BreakpointOptions *bp_options,
@@ -262,93 +271,6 @@ one command per line.\n" );
return;
}
-
- static size_t
- GenerateBreakpointCommandCallback (void *baton,
- InputReader &reader,
- lldb::InputReaderAction notification,
- const char *bytes,
- size_t bytes_len)
- {
- StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
- bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
-
- switch (notification)
- {
- case eInputReaderActivate:
- if (!batch_mode)
- {
- out_stream->Printf ("%s\n", g_reader_instructions);
- if (reader.GetPrompt())
- out_stream->Printf ("%s", reader.GetPrompt());
- out_stream->Flush();
- }
- break;
-
- case eInputReaderDeactivate:
- break;
-
- case eInputReaderReactivate:
- if (reader.GetPrompt() && !batch_mode)
- {
- out_stream->Printf ("%s", reader.GetPrompt());
- out_stream->Flush();
- }
- break;
-
- case eInputReaderAsynchronousOutputWritten:
- break;
-
- case eInputReaderGotToken:
- if (bytes && bytes_len && baton)
- {
- BreakpointOptions *bp_options = (BreakpointOptions *) baton;
- if (bp_options)
- {
- Baton *bp_options_baton = bp_options->GetBaton();
- if (bp_options_baton)
- ((BreakpointOptions::CommandData *)bp_options_baton->m_data)->user_source.AppendString (bytes, bytes_len);
- }
- }
- if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
- {
- out_stream->Printf ("%s", reader.GetPrompt());
- out_stream->Flush();
- }
- break;
-
- case eInputReaderInterrupt:
- {
- // Finish, and cancel the breakpoint command.
- reader.SetIsDone (true);
- BreakpointOptions *bp_options = (BreakpointOptions *) baton;
- if (bp_options)
- {
- Baton *bp_options_baton = bp_options->GetBaton ();
- if (bp_options_baton)
- {
- ((BreakpointOptions::CommandData *) bp_options_baton->m_data)->user_source.Clear();
- ((BreakpointOptions::CommandData *) bp_options_baton->m_data)->script_source.clear();
- }
- }
- if (!batch_mode)
- {
- out_stream->Printf ("Warning: No command attached to breakpoint.\n");
- out_stream->Flush();
- }
- }
- break;
-
- case eInputReaderEndOfFile:
- reader.SetIsDone (true);
- break;
-
- case eInputReaderDone:
- break;
- }
-
- return bytes_len;
- }
static bool
BreakpointOptionsCallbackFunction (void *baton,
@@ -623,7 +545,7 @@ private:
};
const char *
-CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.";
+CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.\n";
// FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting
// language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper.
diff --git a/source/Commands/CommandObjectBreakpointCommand.h b/source/Commands/CommandObjectBreakpointCommand.h
index afedb7602cdd..e91790779510 100644
--- a/source/Commands/CommandObjectBreakpointCommand.h
+++ b/source/Commands/CommandObjectBreakpointCommand.h
@@ -19,7 +19,6 @@
#include "lldb/lldb-types.h"
#include "lldb/Interpreter/Options.h"
-#include "lldb/Core/InputReader.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp
index 6824ead0d9e0..7bfdec094d6c 100644
--- a/source/Commands/CommandObjectCommands.cpp
+++ b/source/Commands/CommandObjectCommands.cpp
@@ -18,8 +18,7 @@
// Project includes
#include "lldb/Core/Debugger.h"
-#include "lldb/Core/InputReader.h"
-#include "lldb/Core/InputReaderEZ.h"
+#include "lldb/Core/IOHandler.h"
#include "lldb/Core/StringList.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandHistory.h"
@@ -309,7 +308,9 @@ protected:
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
- m_stop_on_error (true)
+ m_stop_on_error (true),
+ m_silent_run (false),
+ m_stop_on_continue (true)
{
}
@@ -321,23 +322,21 @@ protected:
{
Error error;
const int short_option = m_getopt_table[option_idx].val;
- bool success;
switch (short_option)
{
case 'e':
error = m_stop_on_error.SetValueFromCString(option_arg);
break;
+
case 'c':
- m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg);
+ error = m_stop_on_continue.SetValueFromCString(option_arg);
break;
+
case 's':
- m_silent_run = Args::StringToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid value for silent-run: %s", option_arg);
+ error = m_silent_run.SetValueFromCString(option_arg);
break;
+
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -350,8 +349,8 @@ protected:
OptionParsingStarting ()
{
m_stop_on_error.Clear();
- m_silent_run = false;
- m_stop_on_continue = true;
+ m_silent_run.Clear();
+ m_stop_on_continue.Clear();
}
const OptionDefinition*
@@ -367,8 +366,8 @@ protected:
// Instance variables to hold the values for command options.
OptionValueBoolean m_stop_on_error;
- bool m_silent_run;
- bool m_stop_on_continue;
+ OptionValueBoolean m_silent_run;
+ OptionValueBoolean m_stop_on_continue;
};
bool
@@ -379,22 +378,40 @@ protected:
{
const char *filename = command.GetArgumentAtIndex(0);
- result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
-
FileSpec cmd_file (filename, true);
ExecutionContext *exe_ctx = NULL; // Just use the default context.
- bool echo_commands = !m_options.m_silent_run;
- bool print_results = true;
- bool stop_on_error = m_options.m_stop_on_error.OptionWasSet() ? (bool)m_options.m_stop_on_error : m_interpreter.GetStopCmdSourceOnError();
-
- m_interpreter.HandleCommandsFromFile (cmd_file,
- exe_ctx,
- m_options.m_stop_on_continue,
- stop_on_error,
- echo_commands,
- print_results,
- eLazyBoolCalculate,
- result);
+
+ // If any options were set, then use them
+ if (m_options.m_stop_on_error.OptionWasSet() ||
+ m_options.m_silent_run.OptionWasSet() ||
+ m_options.m_stop_on_continue.OptionWasSet())
+ {
+ // Use user set settings
+ LazyBool print_command = m_options.m_silent_run.GetCurrentValue() ? eLazyBoolNo : eLazyBoolYes;
+ m_interpreter.HandleCommandsFromFile (cmd_file,
+ exe_ctx,
+ m_options.m_stop_on_continue.GetCurrentValue() ? eLazyBoolYes : eLazyBoolNo, // Stop on continue
+ m_options.m_stop_on_error.GetCurrentValue() ? eLazyBoolYes : eLazyBoolNo, // Stop on error
+ print_command, // Echo command
+ print_command, // Print command output
+ eLazyBoolCalculate, // Add to history
+ result);
+
+ }
+ else
+ {
+ // No options were set, inherit any settings from nested "command source" commands,
+ // or set to sane default settings...
+ m_interpreter.HandleCommandsFromFile (cmd_file,
+ exe_ctx,
+ eLazyBoolCalculate, // Stop on continue
+ eLazyBoolCalculate, // Stop on error
+ eLazyBoolCalculate, // Echo command
+ eLazyBoolCalculate, // Print command output
+ eLazyBoolCalculate, // Add to history
+ result);
+
+ }
}
else
{
@@ -423,7 +440,7 @@ CommandObjectCommandsSource::CommandOptions::g_option_table[] =
static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
"You must define a Python function with this signature:\n"
- "def my_command_impl(debugger, args, result, internal_dict):";
+ "def my_command_impl(debugger, args, result, internal_dict):\n";
class CommandObjectCommandsAlias : public CommandObjectRaw
@@ -856,7 +873,9 @@ protected:
//-------------------------------------------------------------------------
#pragma mark CommandObjectCommandsAddRegex
-class CommandObjectCommandsAddRegex : public CommandObjectParsed
+class CommandObjectCommandsAddRegex :
+ public CommandObjectParsed,
+ public IOHandlerDelegate
{
public:
CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
@@ -864,6 +883,7 @@ public:
"command regex",
"Allow the user to create a regular expression command.",
"command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
+ IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand),
m_options (interpreter)
{
SetHelpLong(
@@ -899,6 +919,97 @@ public:
protected:
+
+ virtual void
+ IOHandlerActivated (IOHandler &io_handler)
+ {
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp)
+ {
+ output_sp->PutCString("Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\nTerminate the substitution list with an empty line.\n");
+ output_sp->Flush();
+ }
+ }
+
+ virtual void
+ IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
+ {
+ io_handler.SetIsDone(true);
+ if (m_regex_cmd_ap.get())
+ {
+ StringList lines;
+ if (lines.SplitIntoLines (data))
+ {
+ const size_t num_lines = lines.GetSize();
+ bool check_only = false;
+ for (size_t i=0; i<num_lines; ++i)
+ {
+ printf ("regex[%zu] = %s\n", i, lines[i].c_str());
+ llvm::StringRef bytes_strref (lines[i]);
+ Error error = AppendRegexSubstitution (bytes_strref, check_only);
+ if (error.Fail())
+ {
+ if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
+ {
+ StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
+ out_stream->Printf("error: %s\n", error.AsCString());
+ }
+ }
+ }
+ }
+ if (m_regex_cmd_ap->HasRegexEntries())
+ {
+ CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
+ m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
+ }
+ }
+ }
+
+ virtual LineStatus
+ IOHandlerLinesUpdated (IOHandler &io_handler,
+ StringList &lines,
+ uint32_t line_idx,
+ Error &error)
+ {
+ if (line_idx == UINT32_MAX)
+ {
+ // Return true to indicate we are done getting lines (this
+ // is a "fake" line - the real terminating blank line was
+ // removed during a previous call with the code below)
+ error.Clear();
+ return LineStatus::Done;
+ }
+ else
+ {
+ const size_t num_lines = lines.GetSize();
+ if (line_idx + 1 == num_lines)
+ {
+ // The last line was edited, if this line is empty, then we are done
+ // getting our multiple lines.
+ if (lines[line_idx].empty())
+ {
+ // Remove the last empty line from "lines" so it doesn't appear
+ // in our final expression and return true to indicate we are done
+ // getting lines
+ lines.PopBack();
+ return LineStatus::Done;
+ }
+ }
+ // Check the current line to make sure it is formatted correctly
+ bool check_only = true;
+ llvm::StringRef regex_sed(lines[line_idx]);
+ error = AppendRegexSubstitution (regex_sed, check_only);
+ if (error.Fail())
+ {
+ return LineStatus::Error;
+ }
+ else
+ {
+ return LineStatus::Success;
+ }
+ }
+ }
+
bool
DoExecute (Args& command, CommandReturnObject &result)
{
@@ -920,21 +1031,18 @@ protected:
if (argc == 1)
{
- InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
- if (reader_sp)
+ Debugger &debugger = m_interpreter.GetDebugger();
+ const bool multiple_lines = true; // Get multiple lines
+ IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
+ "lldb", // Name of input reader for history
+ "\033[K> ", // Prompt and clear line
+ multiple_lines,
+ *this));
+
+ if (io_handler_sp)
{
- error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
- this, // baton
- eInputReaderGranularityLine, // token size, to pass to callback function
- NULL, // end token
- "> ", // prompt
- true); // echo input
- if (error.Success())
- {
- m_interpreter.GetDebugger().PushInputReader (reader_sp);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- return true;
- }
+ debugger.PushIOHandler(io_handler_sp);
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
}
else
@@ -942,7 +1050,8 @@ protected:
for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
{
llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
- error = AppendRegexSubstitution (arg_strref);
+ bool check_only = false;
+ error = AppendRegexSubstitution (arg_strref, check_only);
if (error.Fail())
break;
}
@@ -963,7 +1072,7 @@ protected:
}
Error
- AppendRegexSubstitution (const llvm::StringRef &regex_sed)
+ AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
{
Error error;
@@ -1053,10 +1162,14 @@ protected:
regex_sed.data());
return error;
}
- 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));
- m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
- subst.c_str());
+
+ if (check_only == false)
+ {
+ 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));
+ m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
+ subst.c_str());
+ }
return error;
}
@@ -1073,89 +1186,6 @@ protected:
}
}
- void
- InputReaderDidCancel()
- {
- m_regex_cmd_ap.reset();
- }
-
- static size_t
- InputReaderCallback (void *baton,
- InputReader &reader,
- lldb::InputReaderAction notification,
- const char *bytes,
- size_t bytes_len)
- {
- CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
- bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
-
- switch (notification)
- {
- case eInputReaderActivate:
- if (!batch_mode)
- {
- StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
- out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
- out_stream->Flush();
- }
- break;
- case eInputReaderReactivate:
- break;
-
- case eInputReaderDeactivate:
- break;
-
- case eInputReaderAsynchronousOutputWritten:
- break;
-
- case eInputReaderGotToken:
- while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
- --bytes_len;
- if (bytes_len == 0)
- reader.SetIsDone(true);
- else if (bytes)
- {
- llvm::StringRef bytes_strref (bytes, bytes_len);
- Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
- if (error.Fail())
- {
- if (!batch_mode)
- {
- StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
- out_stream->Printf("error: %s\n", error.AsCString());
- out_stream->Flush();
- }
- add_regex_cmd->InputReaderDidCancel ();
- reader.SetIsDone (true);
- }
- }
- break;
-
- case eInputReaderInterrupt:
- {
- reader.SetIsDone (true);
- if (!batch_mode)
- {
- StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
- out_stream->PutCString("Regular expression command creations was cancelled.\n");
- out_stream->Flush();
- }
- add_regex_cmd->InputReaderDidCancel ();
- }
- break;
-
- case eInputReaderEndOfFile:
- reader.SetIsDone (true);
- break;
-
- case eInputReaderDone:
- add_regex_cmd->AddRegexCommandToInterpreter();
- break;
- }
-
- return bytes_len;
- }
-
private:
std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
@@ -1526,7 +1556,9 @@ CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
// CommandObjectCommandsScriptAdd
//-------------------------------------------------------------------------
-class CommandObjectCommandsScriptAdd : public CommandObjectParsed
+class CommandObjectCommandsScriptAdd :
+ public CommandObjectParsed,
+ public IOHandlerDelegateMultiline
{
public:
CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
@@ -1534,6 +1566,7 @@ public:
"command script add",
"Add a scripted function as an LLDB command.",
NULL),
+ IOHandlerDelegateMultiline ("DONE"),
m_options (interpreter)
{
CommandArgumentEntry arg1;
@@ -1567,7 +1600,7 @@ protected:
public:
CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
+ Options (interpreter)
{
}
@@ -1586,7 +1619,7 @@ protected:
m_funct_name = std::string(option_arg);
break;
case 's':
- m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
+ m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
if (!error.Success())
error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
break;
@@ -1602,7 +1635,7 @@ protected:
OptionParsingStarting ()
{
m_funct_name = "";
- m_synchronous = eScriptedCommandSynchronicitySynchronous;
+ m_synchronicity = eScriptedCommandSynchronicitySynchronous;
}
const OptionDefinition*
@@ -1618,128 +1651,81 @@ protected:
// Instance variables to hold the values for command options.
std::string m_funct_name;
- ScriptedCommandSynchronicity m_synchronous;
+ ScriptedCommandSynchronicity m_synchronicity;
};
-private:
- class PythonAliasReader : public InputReaderEZ
+ virtual void
+ IOHandlerActivated (IOHandler &io_handler)
{
- private:
- CommandInterpreter& m_interpreter;
- std::string m_cmd_name;
- ScriptedCommandSynchronicity m_synchronous;
- StringList m_user_input;
- DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
- public:
- PythonAliasReader(Debugger& debugger,
- CommandInterpreter& interpreter,
- std::string cmd_name,
- ScriptedCommandSynchronicity synch) :
- InputReaderEZ(debugger),
- m_interpreter(interpreter),
- m_cmd_name(cmd_name),
- m_synchronous(synch),
- m_user_input()
- {}
-
- virtual
- ~PythonAliasReader()
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp)
{
+ output_sp->PutCString(g_python_command_instructions);
+ output_sp->Flush();
}
+ }
+
+
+ virtual void
+ IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
+ {
+ StreamFileSP error_sp = io_handler.GetErrorStreamFile();
- virtual void ActivateHandler(HandlerData& data)
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (interpreter)
{
- StreamSP out_stream = data.GetOutStream();
- bool batch_mode = data.GetBatchMode();
- if (!batch_mode)
- {
- out_stream->Printf ("%s\n", g_python_command_instructions);
- if (data.reader.GetPrompt())
- out_stream->Printf ("%s", data.reader.GetPrompt());
- out_stream->Flush();
- }
- }
- virtual void ReactivateHandler(HandlerData& data)
- {
- StreamSP out_stream = data.GetOutStream();
- bool batch_mode = data.GetBatchMode();
- if (data.reader.GetPrompt() && !batch_mode)
+ StringList lines;
+ lines.SplitIntoLines(data);
+ if (lines.GetSize() > 0)
{
- out_stream->Printf ("%s", data.reader.GetPrompt());
- out_stream->Flush();
- }
- }
- virtual void GotTokenHandler(HandlerData& data)
- {
- StreamSP out_stream = data.GetOutStream();
- bool batch_mode = data.GetBatchMode();
- if (data.bytes && data.bytes_len)
- {
- m_user_input.AppendString(data.bytes, data.bytes_len);
- }
- if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
- {
- out_stream->Printf ("%s", data.reader.GetPrompt());
- out_stream->Flush();
+ std::string funct_name_str;
+ if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
+ {
+ if (funct_name_str.empty())
+ {
+ error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
+ error_sp->Flush();
+ }
+ else
+ {
+ // everything should be fine now, let's add this alias
+
+ CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
+ m_cmd_name,
+ funct_name_str.c_str(),
+ m_synchronicity));
+
+ if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
+ {
+ error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
+ error_sp->Flush();
+ }
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: unable to create function, didn't add python command.\n");
+ error_sp->Flush();
+ }
}
- }
- virtual void InterruptHandler(HandlerData& data)
- {
- StreamSP out_stream = data.GetOutStream();
- bool batch_mode = data.GetBatchMode();
- data.reader.SetIsDone (true);
- if (!batch_mode)
+ else
{
- out_stream->Printf ("Warning: No script attached.\n");
- out_stream->Flush();
+ error_sp->Printf ("error: empty function, didn't add python command.\n");
+ error_sp->Flush();
}
}
- virtual void EOFHandler(HandlerData& data)
+ else
{
- data.reader.SetIsDone (true);
+ error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
+ error_sp->Flush();
}
- virtual void DoneHandler(HandlerData& data)
- {
- StreamSP out_stream = data.GetOutStream();
-
- ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- if (!interpreter)
- {
- out_stream->Printf ("Script interpreter missing: no script attached.\n");
- out_stream->Flush();
- return;
- }
- std::string funct_name_str;
- if (!interpreter->GenerateScriptAliasFunction (m_user_input,
- funct_name_str))
- {
- out_stream->Printf ("Unable to create function: no script attached.\n");
- out_stream->Flush();
- return;
- }
- if (funct_name_str.empty())
- {
- out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
- out_stream->Flush();
- return;
- }
- // everything should be fine now, let's add this alias
-
- CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
- m_cmd_name,
- funct_name_str.c_str(),
- m_synchronous));
-
- if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
- {
- out_stream->Printf ("Unable to add selected command: no script attached.\n");
- out_stream->Flush();
- return;
- }
- }
- };
-
+
+ io_handler.SetIsDone(true);
+
+
+ }
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result)
@@ -1761,45 +1747,24 @@ protected:
return false;
}
- std::string cmd_name = command.GetArgumentAtIndex(0);
+ // Store the command name and synchronicity in case we get multi-line input
+ m_cmd_name = command.GetArgumentAtIndex(0);
+ m_synchronicity = m_options.m_synchronicity;
if (m_options.m_funct_name.empty())
{
- InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
- m_interpreter,
- cmd_name,
- m_options.m_synchronous));
-
- if (reader_sp)
- {
-
- InputReaderEZ::InitializationParameters ipr;
-
- Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" ")));
- if (err.Success())
- {
- m_interpreter.GetDebugger().PushInputReader (reader_sp);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError (err.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError("out of memory");
- result.SetStatus (eReturnStatusFailed);
- }
+ m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
}
else
{
CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
- cmd_name,
+ m_cmd_name,
m_options.m_funct_name,
- m_options.m_synchronous));
- if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
+ m_synchronicity));
+ if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
{
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
@@ -1815,6 +1780,8 @@ protected:
}
CommandOptions m_options;
+ std::string m_cmd_name;
+ ScriptedCommandSynchronicity m_synchronicity;
};
static OptionEnumValueElement g_script_synchro_type[] =
diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp
index fc148b1899f6..f9c683b364ce 100644
--- a/source/Commands/CommandObjectDisassemble.cpp
+++ b/source/Commands/CommandObjectDisassemble.cpp
@@ -27,6 +27,7 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index 5ca44ff920d6..c772a2e58912 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -17,7 +17,6 @@
// Project includes
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Value.h"
-#include "lldb/Core/InputReader.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Expression/ClangExpressionVariable.h"
@@ -197,6 +196,7 @@ CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interprete
"Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
NULL,
eFlagProcessMustBePaused | eFlagTryTargetAPILock),
+ IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
m_option_group (interpreter),
m_format_options (eFormatDefault),
m_command_options (),
@@ -254,87 +254,6 @@ CommandObjectExpression::GetOptions ()
return &m_option_group;
}
-size_t
-CommandObjectExpression::MultiLineExpressionCallback
-(
- void *baton,
- InputReader &reader,
- lldb::InputReaderAction notification,
- const char *bytes,
- size_t bytes_len
-)
-{
- CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
- bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
-
- switch (notification)
- {
- case eInputReaderActivate:
- if (!batch_mode)
- {
- StreamSP async_strm_sp(reader.GetDebugger().GetAsyncOutputStream());
- if (async_strm_sp)
- {
- async_strm_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
- async_strm_sp->Flush();
- }
- }
- // Fall through
- case eInputReaderReactivate:
- break;
-
- case eInputReaderDeactivate:
- break;
-
- case eInputReaderAsynchronousOutputWritten:
- break;
-
- case eInputReaderGotToken:
- ++cmd_object_expr->m_expr_line_count;
- if (bytes && bytes_len)
- {
- cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
- }
-
- if (bytes_len == 0)
- reader.SetIsDone(true);
- break;
-
- case eInputReaderInterrupt:
- cmd_object_expr->m_expr_lines.clear();
- reader.SetIsDone (true);
- if (!batch_mode)
- {
- StreamSP async_strm_sp (reader.GetDebugger().GetAsyncOutputStream());
- if (async_strm_sp)
- {
- async_strm_sp->PutCString("Expression evaluation cancelled.\n");
- async_strm_sp->Flush();
- }
- }
- break;
-
- case eInputReaderEndOfFile:
- reader.SetIsDone (true);
- break;
-
- case eInputReaderDone:
- if (cmd_object_expr->m_expr_lines.size() > 0)
- {
- StreamSP output_stream = reader.GetDebugger().GetAsyncOutputStream();
- StreamSP error_stream = reader.GetDebugger().GetAsyncErrorStream();
- cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
- output_stream.get(),
- error_stream.get());
- output_stream->Flush();
- error_stream->Flush();
- }
- break;
- }
-
- return bytes_len;
-}
-
bool
CommandObjectExpression::EvaluateExpression
(
@@ -373,6 +292,8 @@ CommandObjectExpression::EvaluateExpression
if (m_command_options.timeout > 0)
options.SetTimeoutUsec(m_command_options.timeout);
+ else
+ options.SetTimeoutUsec(0);
exe_results = target->EvaluateExpression (expr,
exe_ctx.GetFramePtr(),
@@ -443,6 +364,48 @@ CommandObjectExpression::EvaluateExpression
return true;
}
+void
+CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
+{
+ io_handler.SetIsDone(true);
+// StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
+// StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP error_sp(io_handler.GetErrorStreamFile());
+
+ EvaluateExpression (line.c_str(),
+ output_sp.get(),
+ error_sp.get());
+ if (output_sp)
+ output_sp->Flush();
+ if (error_sp)
+ error_sp->Flush();
+}
+
+LineStatus
+CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
+ StringList &lines,
+ uint32_t line_idx,
+ Error &error)
+{
+ if (line_idx == UINT32_MAX)
+ {
+ // Remove the last line from "lines" so it doesn't appear
+ // in our final expression
+ lines.PopBack();
+ error.Clear();
+ return LineStatus::Done;
+ }
+ else if (line_idx + 1 == lines.GetSize())
+ {
+ // The last line was edited, if this line is empty, then we are done
+ // getting our multiple lines.
+ if (lines[line_idx].empty())
+ return LineStatus::Done;
+ }
+ return LineStatus::Success;
+}
+
bool
CommandObjectExpression::DoExecute
(
@@ -459,31 +422,21 @@ CommandObjectExpression::DoExecute
m_expr_lines.clear();
m_expr_line_count = 0;
- InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
- if (reader_sp)
- {
- Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
- this, // baton
- eInputReaderGranularityLine, // token size, to pass to callback function
- NULL, // end token
- NULL, // 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
+ Debugger &debugger = GetCommandInterpreter().GetDebugger();
+ const bool multiple_lines = true; // Get multiple lines
+ IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
+ "lldb-expr", // Name of input reader for history
+ NULL, // No prompt
+ multiple_lines,
+ *this));
+
+ StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
+ if (output_sp)
{
- result.AppendError("out of memory");
- result.SetStatus (eReturnStatusFailed);
+ output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
+ output_sp->Flush();
}
+ debugger.PushIOHandler(io_handler_sp);
return result.Succeeded();
}
diff --git a/source/Commands/CommandObjectExpression.h b/source/Commands/CommandObjectExpression.h
index e0703a22a4cc..c943f0e8023d 100644
--- a/source/Commands/CommandObjectExpression.h
+++ b/source/Commands/CommandObjectExpression.h
@@ -14,6 +14,7 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Core/IOHandler.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
@@ -21,7 +22,9 @@
namespace lldb_private {
-class CommandObjectExpression : public CommandObjectRaw
+class CommandObjectExpression :
+ public CommandObjectRaw,
+ public IOHandlerDelegate
{
public:
@@ -71,17 +74,23 @@ public:
GetOptions ();
protected:
+
+ //------------------------------------------------------------------
+ // IOHandler::Delegate functions
+ //------------------------------------------------------------------
+ virtual void
+ IOHandlerInputComplete (IOHandler &io_handler,
+ std::string &line);
+
+ virtual LineStatus
+ IOHandlerLinesUpdated (IOHandler &io_handler,
+ StringList &lines,
+ uint32_t line_idx,
+ Error &error);
virtual bool
DoExecute (const char *command,
CommandReturnObject &result);
- static size_t
- MultiLineExpressionCallback (void *baton,
- InputReader &reader,
- lldb::InputReaderAction notification,
- const char *bytes,
- size_t bytes_len);
-
bool
EvaluateExpression (const char *expr,
Stream *output_stream,
diff --git a/source/Commands/CommandObjectGUI.cpp b/source/Commands/CommandObjectGUI.cpp
new file mode 100644
index 000000000000..3d05335e92e4
--- /dev/null
+++ b/source/Commands/CommandObjectGUI.cpp
@@ -0,0 +1,61 @@
+//===-- CommandObjectGUI.cpp ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "CommandObjectGUI.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//-------------------------------------------------------------------------
+// CommandObjectGUI
+//-------------------------------------------------------------------------
+
+CommandObjectGUI::CommandObjectGUI (CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter, "gui", "Switch into the curses based GUI mode.", "gui")
+{
+}
+
+CommandObjectGUI::~CommandObjectGUI ()
+{
+}
+
+bool
+CommandObjectGUI::DoExecute (Args& args, CommandReturnObject &result)
+{
+#ifndef LLDB_DISABLE_CURSES
+ if (args.GetArgumentCount() == 0)
+ {
+ Debugger &debugger = m_interpreter.GetDebugger();
+ IOHandlerSP io_handler_sp (new IOHandlerCursesGUI (debugger));
+ if (io_handler_sp)
+ debugger.PushIOHandler(io_handler_sp);
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ result.AppendError("the gui command takes no arguments.");
+ result.SetStatus (eReturnStatusFailed);
+ }
+ return true;
+#else
+ result.AppendError("lldb was not build with gui support");
+ return false;
+#endif
+}
+
diff --git a/source/Commands/CommandObjectGUI.h b/source/Commands/CommandObjectGUI.h
new file mode 100644
index 000000000000..72ddb961c266
--- /dev/null
+++ b/source/Commands/CommandObjectGUI.h
@@ -0,0 +1,43 @@
+//===-- CommandObjectGUI.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CommandObjectGUI_h_
+#define liblldb_CommandObjectGUI_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/CommandObject.h"
+
+namespace lldb_private {
+
+//-------------------------------------------------------------------------
+// CommandObjectGUI
+//-------------------------------------------------------------------------
+
+class CommandObjectGUI : public CommandObjectParsed
+{
+public:
+
+ CommandObjectGUI (CommandInterpreter &interpreter);
+
+ virtual
+ ~CommandObjectGUI ();
+
+protected:
+ virtual bool
+ DoExecute (Args& args,
+ CommandReturnObject &result);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_CommandObjectGUI_h_
diff --git a/source/Commands/CommandObjectMultiword.cpp b/source/Commands/CommandObjectMultiword.cpp
index f84b401f3aa6..69b178da46ba 100644
--- a/source/Commands/CommandObjectMultiword.cpp
+++ b/source/Commands/CommandObjectMultiword.cpp
@@ -235,18 +235,19 @@ CommandObjectMultiword::HandleCompletion
// completers will override this.
word_complete = true;
+ const char *arg0 = input.GetArgumentAtIndex(0);
if (cursor_index == 0)
{
CommandObject::AddNamesMatchingPartialString (m_subcommand_dict,
- input.GetArgumentAtIndex(0),
+ arg0,
matches);
if (matches.GetSize() == 1
&& matches.GetStringAtIndex(0) != NULL
- && strcmp (input.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0)
+ && strcmp (arg0, matches.GetStringAtIndex(0)) == 0)
{
StringList temp_matches;
- CommandObject *cmd_obj = GetSubcommandObject (input.GetArgumentAtIndex(0),
+ CommandObject *cmd_obj = GetSubcommandObject (arg0,
&temp_matches);
if (cmd_obj != NULL)
{
@@ -270,7 +271,7 @@ CommandObjectMultiword::HandleCompletion
}
else
{
- CommandObject *sub_command_object = GetSubcommandObject (input.GetArgumentAtIndex(0),
+ CommandObject *sub_command_object = GetSubcommandObject (arg0,
&matches);
if (sub_command_object == NULL)
{
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index 2933c78ca908..49a392286c6a 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -49,7 +49,7 @@ public:
virtual ~CommandObjectProcessLaunchOrAttach () {}
protected:
bool
- StopProcessIfNecessary (Process *&process, StateType &state, CommandReturnObject &result)
+ StopProcessIfNecessary (Process *process, StateType &state, CommandReturnObject &result)
{
state = eStateInvalid;
if (process)
@@ -187,12 +187,10 @@ protected:
{
Debugger &debugger = m_interpreter.GetDebugger();
Target *target = debugger.GetSelectedTarget().get();
- Error error;
// If our listener is NULL, users aren't allows to launch
- char filename[PATH_MAX];
- const Module *exe_module = target->GetExecutableModulePointer();
+ ModuleSP exe_module_sp = target->GetExecutableModule();
- if (exe_module == NULL)
+ if (exe_module_sp == NULL)
{
result.AppendError ("no file in target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -200,23 +198,31 @@ protected:
}
StateType state = eStateInvalid;
- Process *process = m_exe_ctx.GetProcessPtr();
- if (!StopProcessIfNecessary(process, state, result))
+ if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
return false;
const char *target_settings_argv0 = target->GetArg0();
- exe_module->GetFileSpec().GetPath (filename, sizeof(filename));
+ if (target->GetDisableASLR())
+ m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
+
+ if (target->GetDisableSTDIO())
+ m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
+ Args environment;
+ target->GetEnvironmentAsArgs (environment);
+ if (environment.GetArgumentCount() > 0)
+ m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
+
if (target_settings_argv0)
{
m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
- m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), false);
+ m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), false);
}
else
{
- m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
+ m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), true);
}
if (launch_args.GetArgumentCount() == 0)
@@ -228,122 +234,33 @@ protected:
else
{
m_options.launch_info.GetArguments().AppendArguments (launch_args);
-
// Save the arguments for subsequent runs in the current target.
target->SetRunArguments (launch_args);
}
- if (target->GetDisableASLR())
- m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
-
- if (target->GetDisableSTDIO())
- m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
-
- m_options.launch_info.GetFlags().Set (eLaunchFlagDebug);
-
- Args environment;
- target->GetEnvironmentAsArgs (environment);
- if (environment.GetArgumentCount() > 0)
- m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
-
- // Get the value of synchronous execution here. If you wait till after you have started to
- // run, then you could have hit a breakpoint, whose command might switch the value, and
- // then you'll pick up that incorrect value.
- bool synchronous_execution = m_interpreter.GetSynchronous ();
-
- PlatformSP platform_sp (target->GetPlatform());
-
- // Finalize the file actions, and if none were given, default to opening
- // up a pseudo terminal
- const bool default_to_use_pty = platform_sp ? platform_sp->IsHost() : false;
- m_options.launch_info.FinalizeFileActions (target, default_to_use_pty);
-
- if (state == eStateConnected)
- {
- if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
- {
- result.AppendWarning("can't launch in tty when launching through a remote connection");
- m_options.launch_info.GetFlags().Clear (eLaunchFlagLaunchInTTY);
- }
- }
-
- if (!m_options.launch_info.GetArchitecture().IsValid())
- m_options.launch_info.GetArchitecture() = target->GetArchitecture();
+ Error error = target->Launch(debugger.GetListener(), m_options.launch_info);
- if (platform_sp && platform_sp->CanDebugProcess ())
- {
- process = target->GetPlatform()->DebugProcess (m_options.launch_info,
- debugger,
- target,
- debugger.GetListener(),
- error).get();
- }
- else
- {
- const char *plugin_name = m_options.launch_info.GetProcessPluginName();
- process = target->CreateProcess (debugger.GetListener(), plugin_name, NULL).get();
- if (process)
- error = process->Launch (m_options.launch_info);
- }
-
- if (process == NULL)
- {
- result.SetError (error, "failed to launch or debug process");
- return false;
- }
-
-
if (error.Success())
{
- const char *archname = exe_module->GetArchitecture().GetArchitectureName();
-
- result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process->GetID(), filename, archname);
- result.SetDidChangeProcessState (true);
- if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
+ const char *archname = exe_module_sp->GetArchitecture().GetArchitectureName();
+ ProcessSP process_sp (target->GetProcessSP());
+ if (process_sp)
{
- result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- StateType state = process->WaitForProcessToStop (NULL, NULL, false);
-
- if (state == eStateStopped)
- {
- error = process->Resume();
- if (error.Success())
- {
- if (synchronous_execution)
- {
- state = process->WaitForProcessToStop (NULL);
- const bool must_be_alive = true;
- if (!StateIsStoppedState(state, must_be_alive))
- {
- result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state));
- }
- result.SetDidChangeProcessState (true);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("process resume at entry point failed: %s", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
- result.SetStatus (eReturnStatusFailed);
- }
+ result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ result.SetDidChangeProcessState (true);
+ }
+ else
+ {
+ result.AppendError("no error returned from Target::Launch, and target has no process");
+ result.SetStatus (eReturnStatusFailed);
}
}
else
{
- result.AppendErrorWithFormat ("process launch failed: %s", error.AsCString());
+ result.AppendError(error.AsCString());
result.SetStatus (eReturnStatusFailed);
}
-
return result.Succeeded();
}
@@ -615,37 +532,36 @@ protected:
if (error.Success())
{
+ ListenerSP listener_sp (new Listener("lldb.CommandObjectProcessAttach.DoExecute.attach.hijack"));
+ m_options.attach_info.SetHijackListener(listener_sp);
+ process->HijackProcessEvents(listener_sp.get());
error = process->Attach (m_options.attach_info);
if (error.Success())
{
result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- }
- else
- {
- result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- // If we're synchronous, wait for the stopped event and report that.
- // Otherwise just return.
- // FIXME: in the async case it will now be possible to get to the command
- // interpreter with a state eStateAttaching. Make sure we handle that correctly.
- StateType state = process->WaitForProcessToStop (NULL);
-
- result.SetDidChangeProcessState (true);
+ StateType state = process->WaitForProcessToStop (NULL, NULL, false, listener_sp.get());
- if (state == eStateStopped)
- {
- result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ process->RestoreProcessEvents();
+
+ result.SetDidChangeProcessState (true);
+
+ if (state == eStateStopped)
+ {
+ result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
+ else
+ {
+ result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
+ process->Destroy();
+ result.SetStatus (eReturnStatusFailed);
+ }
}
else
{
- result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
- process->Destroy();
+ result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
result.SetStatus (eReturnStatusFailed);
- return false;
}
}
}
@@ -1170,7 +1086,7 @@ protected:
if (process)
{
- error = process->ConnectRemote (&process->GetTarget().GetDebugger().GetOutputStream(), remote_url);
+ error = process->ConnectRemote (process->GetTarget().GetDebugger().GetOutputFile().get(), remote_url);
if (error.Fail())
{
diff --git a/source/Commands/CommandObjectQuit.cpp b/source/Commands/CommandObjectQuit.cpp
index d04ecdd9885c..ffe2a9240726 100644
--- a/source/Commands/CommandObjectQuit.cpp
+++ b/source/Commands/CommandObjectQuit.cpp
@@ -92,7 +92,8 @@ CommandObjectQuit::DoExecute (Args& command, CommandReturnObject &result)
return false;
}
}
- m_interpreter.BroadcastEvent (CommandInterpreter::eBroadcastBitQuitCommandReceived);
+ const uint32_t event_type = CommandInterpreter::eBroadcastBitQuitCommandReceived;
+ m_interpreter.BroadcastEvent (event_type);
result.SetStatus (eReturnStatusQuit);
return true;
}
diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp
index 7cbfaa5d60fc..deaf2ab3793e 100644
--- a/source/Commands/CommandObjectRegister.cpp
+++ b/source/Commands/CommandObjectRegister.cpp
@@ -29,6 +29,7 @@
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp
index 1f6873611a22..bf2a42e0bea0 100644
--- a/source/Commands/CommandObjectSource.cpp
+++ b/source/Commands/CommandObjectSource.cpp
@@ -28,6 +28,7 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/Options.h"
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index 8e7e68aad39a..308b72f355d3 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -19,7 +19,7 @@
// Project includes
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Debugger.h"
-#include "lldb/Core/InputReader.h"
+#include "lldb/Core/IOHandler.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/Section.h"
@@ -49,6 +49,7 @@
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
@@ -2893,7 +2894,8 @@ protected:
if (m_slide_option.GetOptionValue().OptionWasSet())
{
const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
- module->SetLoadAddress (*target, slide, changed);
+ const bool slide_is_offset = true;
+ module->SetLoadAddress (*target, slide, slide_is_offset, changed);
}
else
{
@@ -4758,7 +4760,9 @@ private:
// CommandObjectTargetStopHookAdd
//-------------------------------------------------------------------------
-class CommandObjectTargetStopHookAdd : public CommandObjectParsed
+class CommandObjectTargetStopHookAdd :
+ public CommandObjectParsed,
+ public IOHandlerDelegateMultiline
{
public:
@@ -4925,9 +4929,10 @@ public:
CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
- "target stop-hook add ",
+ "target stop-hook add",
"Add a hook to be executed when the target stops.",
"target stop-hook add"),
+ IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
m_options (interpreter)
{
}
@@ -4936,102 +4941,61 @@ public:
{
}
- static size_t
- ReadCommandsCallbackFunction (void *baton,
- InputReader &reader,
- lldb::InputReaderAction notification,
- const char *bytes,
- size_t bytes_len)
+protected:
+
+ virtual void
+ IOHandlerActivated (IOHandler &io_handler)
{
- StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
- Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
- static bool got_interrupted;
- bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
-
- switch (notification)
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp)
{
- case eInputReaderActivate:
- if (!batch_mode)
- {
- out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
- if (reader.GetPrompt())
- out_stream->Printf ("%s", reader.GetPrompt());
- out_stream->Flush();
- }
- got_interrupted = false;
- break;
-
- case eInputReaderDeactivate:
- break;
-
- case eInputReaderReactivate:
- if (reader.GetPrompt() && !batch_mode)
- {
- out_stream->Printf ("%s", reader.GetPrompt());
- out_stream->Flush();
- }
- got_interrupted = false;
- break;
-
- case eInputReaderAsynchronousOutputWritten:
- break;
-
- case eInputReaderGotToken:
- if (bytes && bytes_len && baton)
+ output_sp->PutCString("Enter your stop hook command(s). Type 'DONE' to end.\n");
+ output_sp->Flush();
+ }
+ }
+
+
+ virtual void
+ IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
+ {
+ if (m_stop_hook_sp)
+ {
+ if (line.empty())
{
- StringList *commands = new_stop_hook->GetCommandPointer();
- if (commands)
+ StreamFileSP error_sp(io_handler.GetErrorStreamFile());
+ if (error_sp)
{
- commands->AppendString (bytes, bytes_len);
+ error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID());
+ error_sp->Flush();
}
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target)
+ target->RemoveStopHookByID(m_stop_hook_sp->GetID());
}
- if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
- {
- out_stream->Printf ("%s", reader.GetPrompt());
- out_stream->Flush();
- }
- break;
-
- case eInputReaderInterrupt:
+ else
{
- // Finish, and cancel the stop hook.
- new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
- if (!batch_mode)
+ m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp)
{
- out_stream->Printf ("Stop hook cancelled.\n");
- out_stream->Flush();
+ output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID());
+ output_sp->Flush();
}
-
- reader.SetIsDone (true);
}
- got_interrupted = true;
- break;
-
- case eInputReaderEndOfFile:
- reader.SetIsDone (true);
- break;
-
- case eInputReaderDone:
- if (!got_interrupted && !batch_mode)
- {
- out_stream->Printf ("Stop hook #%" PRIu64 " added.\n", new_stop_hook->GetID());
- out_stream->Flush();
- }
- break;
+ m_stop_hook_sp.reset();
}
-
- return bytes_len;
+ io_handler.SetIsDone(true);
}
-
-protected:
+
bool
DoExecute (Args& command, CommandReturnObject &result)
{
+ m_stop_hook_sp.reset();
+
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
if (target)
{
- Target::StopHookSP new_hook_sp;
- target->AddStopHook (new_hook_sp);
+ Target::StopHookSP new_hook_sp = target->CreateStopHook();
// First step, make the specifier.
std::unique_ptr<SymbolContextSpecifier> specifier_ap;
@@ -5104,31 +5068,12 @@ protected:
}
else
{
- // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
- // the new stop hook's command string.
- InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
- if (!reader_sp)
- {
- result.AppendError("out of memory\n");
- result.SetStatus (eReturnStatusFailed);
- target->RemoveStopHookByID (new_hook_sp->GetID());
- return false;
- }
-
- Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
- new_hook_sp.get(), // baton
- eInputReaderGranularityLine, // token size, to pass to callback function
- "DONE", // end token
- "> ", // prompt
- true)); // echo input
- if (!err.Success())
- {
- result.AppendError (err.AsCString());
- result.SetStatus (eReturnStatusFailed);
- target->RemoveStopHookByID (new_hook_sp->GetID());
- return false;
- }
- m_interpreter.GetDebugger().PushInputReader (reader_sp);
+ m_stop_hook_sp = new_hook_sp;
+ m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
+
}
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
@@ -5142,6 +5087,7 @@ protected:
}
private:
CommandOptions m_options;
+ Target::StopHookSP m_stop_hook_sp;
};
OptionDefinition
diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp
index 1c695b37c566..f1b1d2c1900c 100644
--- a/source/Commands/CommandObjectType.cpp
+++ b/source/Commands/CommandObjectType.cpp
@@ -19,7 +19,7 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Debugger.h"
-#include "lldb/Core/InputReaderEZ.h"
+#include "lldb/Core/IOHandler.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StringList.h"
@@ -42,7 +42,6 @@ public:
TypeSummaryImpl::Flags m_flags;
StringList m_target_types;
- StringList m_user_source;
bool m_regex;
@@ -74,7 +73,6 @@ public:
bool m_skip_references;
bool m_cascade;
bool m_regex;
- StringList m_user_source;
StringList m_target_types;
std::string m_category;
@@ -88,7 +86,6 @@ public:
m_skip_references(sref),
m_cascade(casc),
m_regex(regx),
- m_user_source(),
m_target_types(),
m_category(catg)
{
@@ -98,9 +95,36 @@ public:
};
+static bool
+WarnOnPotentialUnquotedUnsignedType (Args& command, CommandReturnObject &result)
+{
+ for (int idx = 0; idx < command.GetArgumentCount(); idx++)
+ {
+ const char* arg = command.GetArgumentAtIndex(idx);
+ if (idx+1 < command.GetArgumentCount())
+ {
+ if (arg && 0 == strcmp(arg,"unsigned"))
+ {
+ const char* next = command.GetArgumentAtIndex(idx+1);
+ if (next &&
+ (0 == strcmp(next, "int") ||
+ 0 == strcmp(next, "short") ||
+ 0 == strcmp(next, "char") ||
+ 0 == strcmp(next, "long")))
+ {
+ result.AppendWarningWithFormat("%s %s being treated as two types. if you meant the combined type name use quotes, as in \"%s %s\"\n",
+ arg,next,arg,next);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
-
-class CommandObjectTypeSummaryAdd : public CommandObjectParsed
+class CommandObjectTypeSummaryAdd :
+ public CommandObjectParsed,
+ public IOHandlerDelegateMultiline
{
private:
@@ -153,10 +177,6 @@ private:
return &m_options;
}
- void
- CollectPythonScript(ScriptAddOptions *options,
- CommandReturnObject &result);
-
bool
Execute_ScriptSummary (Args& command, CommandReturnObject &result);
@@ -178,6 +198,147 @@ public:
{
}
+ virtual void
+ IOHandlerActivated (IOHandler &io_handler)
+ {
+ static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
+ "def function (valobj,internal_dict):\n"
+ " \"\"\"valobj: an SBValue which you want to provide a summary for\n"
+ " internal_dict: an LLDB support object not to be used\"\"\"";
+
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp)
+ {
+ output_sp->PutCString(g_summary_addreader_instructions);
+ output_sp->Flush();
+ }
+ }
+
+
+ virtual void
+ IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
+ {
+ StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+
+#ifndef LLDB_DISABLE_PYTHON
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (interpreter)
+ {
+ StringList lines;
+ lines.SplitIntoLines(data);
+ if (lines.GetSize() > 0)
+ {
+ ScriptAddOptions *options_ptr = ((ScriptAddOptions*)io_handler.GetUserData());
+ if (options_ptr)
+ {
+ ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
+
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (interpreter)
+ {
+ std::string funct_name_str;
+ if (interpreter->GenerateTypeScriptFunction (lines, funct_name_str))
+ {
+ if (funct_name_str.empty())
+ {
+ error_sp->Printf ("unable to obtain a valid function name from the script interpreter.\n");
+ error_sp->Flush();
+ }
+ else
+ {
+ // now I have a valid function name, let's add this as script for every type in the list
+
+ TypeSummaryImplSP script_format;
+ script_format.reset(new ScriptSummaryFormat(options->m_flags,
+ funct_name_str.c_str(),
+ lines.CopyList(" ").c_str()));
+
+ Error error;
+
+ for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
+ {
+ const char *type_name = options->m_target_types.GetStringAtIndex(i);
+ CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
+ script_format,
+ (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
+ options->m_category,
+ &error);
+ if (error.Fail())
+ {
+ error_sp->Printf ("error: %s", error.AsCString());
+ error_sp->Flush();
+ }
+ }
+
+ if (options->m_name)
+ {
+ CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
+ script_format,
+ CommandObjectTypeSummaryAdd::eNamedSummary,
+ options->m_category,
+ &error);
+ if (error.Fail())
+ {
+ CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
+ script_format,
+ CommandObjectTypeSummaryAdd::eNamedSummary,
+ options->m_category,
+ &error);
+ if (error.Fail())
+ {
+ error_sp->Printf ("error: %s", error.AsCString());
+ error_sp->Flush();
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: %s", error.AsCString());
+ error_sp->Flush();
+ }
+ }
+ else
+ {
+ if (error.AsCString())
+ {
+ error_sp->Printf ("error: %s", error.AsCString());
+ error_sp->Flush();
+ }
+ }
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: unable to generate a function.\n");
+ error_sp->Flush();
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: no script interpreter.\n");
+ error_sp->Flush();
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: internal synchronization information missing or invalid.\n");
+ error_sp->Flush();
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: empty function, didn't add python command.\n");
+ error_sp->Flush();
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
+ error_sp->Flush();
+ }
+#endif // #ifndef LLDB_DISABLE_PYTHON
+ io_handler.SetIsDone(true);
+ }
+
static bool
AddSummary(ConstString type_name,
lldb::TypeSummaryImplSP entry,
@@ -190,7 +351,19 @@ protected:
};
-class CommandObjectTypeSynthAdd : public CommandObjectParsed
+static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
+"You must define a Python class with these methods:\n"
+" def __init__(self, valobj, dict):\n"
+" def num_children(self):\n"
+" def get_child_at_index(self, index):\n"
+" def get_child_index(self, name):\n"
+" def update(self):\n"
+" '''Optional'''\n"
+"class synthProvider:\n";
+
+class CommandObjectTypeSynthAdd :
+ public CommandObjectParsed,
+ public IOHandlerDelegateMultiline
{
private:
@@ -200,7 +373,7 @@ private:
public:
CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
+ Options (interpreter)
{
}
@@ -296,9 +469,6 @@ private:
return &m_options;
}
- void
- CollectPythonScript (SynthAddOptions *options,
- CommandReturnObject &result);
bool
Execute_HandwritePython (Args& command, CommandReturnObject &result);
@@ -307,8 +477,139 @@ private:
protected:
bool
- DoExecute (Args& command, CommandReturnObject &result);
+ DoExecute (Args& command, CommandReturnObject &result)
+ {
+ WarnOnPotentialUnquotedUnsignedType(command, result);
+
+ if (m_options.handwrite_python)
+ return Execute_HandwritePython(command, result);
+ else if (m_options.is_class_based)
+ return Execute_PythonClass(command, result);
+ else
+ {
+ result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ virtual void
+ IOHandlerActivated (IOHandler &io_handler)
+ {
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp)
+ {
+ output_sp->PutCString(g_synth_addreader_instructions);
+ output_sp->Flush();
+ }
+ }
+
+ virtual void
+ IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
+ {
+ StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+
+#ifndef LLDB_DISABLE_PYTHON
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (interpreter)
+ {
+ StringList lines;
+ lines.SplitIntoLines(data);
+ if (lines.GetSize() > 0)
+ {
+ SynthAddOptions *options_ptr = ((SynthAddOptions*)io_handler.GetUserData());
+ if (options_ptr)
+ {
+ SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
+
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (interpreter)
+ {
+ std::string class_name_str;
+ if (interpreter->GenerateTypeSynthClass (lines, class_name_str))
+ {
+ if (class_name_str.empty())
+ {
+ error_sp->Printf ("error: unable to obtain a proper name for the class.\n");
+ error_sp->Flush();
+ }
+ else
+ {
+ // everything should be fine now, let's add the synth provider class
+
+ SyntheticChildrenSP synth_provider;
+ synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade).
+ SetSkipPointers(options->m_skip_pointers).
+ SetSkipReferences(options->m_skip_references),
+ class_name_str.c_str()));
+
+
+ lldb::TypeCategoryImplSP category;
+ DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category);
+
+ Error error;
+
+ for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
+ {
+ const char *type_name = options->m_target_types.GetStringAtIndex(i);
+ ConstString const_type_name(type_name);
+ if (const_type_name)
+ {
+ if (!CommandObjectTypeSynthAdd::AddSynth(const_type_name,
+ synth_provider,
+ options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth,
+ options->m_category,
+ &error))
+ {
+ error_sp->Printf("error: %s\n", error.AsCString());
+ error_sp->Flush();
+ break;
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: invalid type name.\n");
+ error_sp->Flush();
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: unable to generate a class.\n");
+ error_sp->Flush();
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: no script interpreter.\n");
+ error_sp->Flush();
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: internal synchronization data missing.\n");
+ error_sp->Flush();
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: empty function, didn't add python command.\n");
+ error_sp->Flush();
+ }
+ }
+ else
+ {
+ error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
+ error_sp->Flush();
+ }
+
+#endif // #ifndef LLDB_DISABLE_PYTHON
+ io_handler.SetIsDone(true);
+ }
+
public:
enum SynthFormatType
@@ -371,6 +672,7 @@ private:
m_skip_references = false;
m_regex = false;
m_category.assign("default");
+ m_custom_type_name.clear();
}
virtual Error
SetOptionValue (CommandInterpreter &interpreter,
@@ -400,6 +702,9 @@ private:
case 'x':
m_regex = true;
break;
+ case 't':
+ m_custom_type_name.assign(option_value);
+ break;
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -419,6 +724,7 @@ private:
bool m_skip_pointers;
bool m_regex;
std::string m_category;
+ std::string m_custom_type_name;
};
OptionGroupOptions m_option_group;
@@ -480,7 +786,7 @@ public:
);
// Add the "--format" to all options groups
- m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_ALL);
+ m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
m_option_group.Append (&m_command_options);
m_option_group.Finalize();
@@ -504,7 +810,7 @@ protected:
}
const Format format = m_format_options.GetFormat();
- if (format == eFormatInvalid)
+ if (format == eFormatInvalid && m_command_options.m_custom_type_name.empty())
{
result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
@@ -513,10 +819,16 @@ protected:
TypeFormatImplSP entry;
- entry.reset(new TypeFormatImpl(format,
- TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
- SetSkipPointers(m_command_options.m_skip_pointers).
- SetSkipReferences(m_command_options.m_skip_references)));
+ if (m_command_options.m_custom_type_name.empty())
+ entry.reset(new TypeFormatImpl_Format(format,
+ TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
+ SetSkipPointers(m_command_options.m_skip_pointers).
+ SetSkipReferences(m_command_options.m_skip_references)));
+ else
+ entry.reset(new TypeFormatImpl_EnumType(ConstString(m_command_options.m_custom_type_name.c_str()),
+ TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
+ SetSkipPointers(m_command_options.m_skip_pointers).
+ SetSkipReferences(m_command_options.m_skip_references)));
// now I have a valid format, let's add it to every type
@@ -525,6 +837,8 @@ protected:
if (!category_sp)
return false;
+ WarnOnPotentialUnquotedUnsignedType(command, result);
+
for (size_t i = 0; i < argc; i++)
{
const char* typeA = command.GetArgumentAtIndex(i);
@@ -540,11 +854,11 @@ protected:
result.SetStatus(eReturnStatusFailed);
return false;
}
- category_sp->GetRegexSummaryNavigator()->Delete(typeCS);
- category_sp->GetRegexValueNavigator()->Add(typeRX, entry);
+ category_sp->GetRegexTypeSummariesContainer()->Delete(typeCS);
+ category_sp->GetRegexTypeFormatsContainer()->Add(typeRX, entry);
}
else
- category_sp->GetValueNavigator()->Add(typeCS, entry);
+ category_sp->GetTypeFormatsContainer()->Add(typeCS, entry);
}
else
{
@@ -562,11 +876,12 @@ protected:
OptionDefinition
CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
- { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
+ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
+ { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Format variables as if they were of this type."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
@@ -817,8 +1132,8 @@ private:
PerCategoryCallback(void* param,
const lldb::TypeCategoryImplSP& cate)
{
- cate->GetValueNavigator()->Clear();
- cate->GetRegexValueNavigator()->Clear();
+ cate->GetTypeFormatsContainer()->Clear();
+ cate->GetRegexTypeFormatsContainer()->Clear();
return true;
}
@@ -996,6 +1311,7 @@ protected:
param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,NULL,cate_regex);
DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
+ delete param;
if (cate_regex)
delete cate_regex;
@@ -1029,12 +1345,12 @@ private:
cate_name,
(cate->IsEnabled() ? "enabled" : "disabled"));
- cate->GetValueNavigator()->LoopThrough(CommandObjectTypeFormatList_LoopCallback, param_vp);
+ cate->GetTypeFormatsContainer()->LoopThrough(CommandObjectTypeFormatList_LoopCallback, param_vp);
- if (cate->GetRegexSummaryNavigator()->GetCount() > 0)
+ if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0)
{
result->GetOutputStream().Printf("Regex-based summaries (slower):\n");
- cate->GetRegexValueNavigator()->LoopThrough(CommandObjectTypeRXFormatList_LoopCallback, param_vp);
+ cate->GetRegexTypeFormatsContainer()->LoopThrough(CommandObjectTypeRXFormatList_LoopCallback, param_vp);
}
return true;
}
@@ -1089,176 +1405,6 @@ CommandObjectTypeFormatList::CommandOptions::g_option_table[] =
// CommandObjectTypeSummaryAdd
//-------------------------------------------------------------------------
-static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
- "def function (valobj,internal_dict):\n"
- " \"\"\"valobj: an SBValue which you want to provide a summary for\n"
- " internal_dict: an LLDB support object not to be used\"\"\"";
-
-class TypeScriptAddInputReader : public InputReaderEZ
-{
-private:
- DISALLOW_COPY_AND_ASSIGN (TypeScriptAddInputReader);
-public:
- TypeScriptAddInputReader(Debugger& debugger) :
- InputReaderEZ(debugger)
- {}
-
- virtual
- ~TypeScriptAddInputReader()
- {
- }
-
- virtual void ActivateHandler(HandlerData& data)
- {
- StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
- bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
- if (!batch_mode)
- {
- out_stream->Printf ("%s\n", g_summary_addreader_instructions);
- if (data.reader.GetPrompt())
- out_stream->Printf ("%s", data.reader.GetPrompt());
- out_stream->Flush();
- }
- }
-
- virtual void ReactivateHandler(HandlerData& data)
- {
- StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
- bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
- if (data.reader.GetPrompt() && !batch_mode)
- {
- out_stream->Printf ("%s", data.reader.GetPrompt());
- out_stream->Flush();
- }
- }
- virtual void GotTokenHandler(HandlerData& data)
- {
- StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
- bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
- if (data.bytes && data.bytes_len && data.baton)
- {
- ((ScriptAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len);
- }
- if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
- {
- out_stream->Printf ("%s", data.reader.GetPrompt());
- out_stream->Flush();
- }
- }
- virtual void InterruptHandler(HandlerData& data)
- {
- StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
- bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
- data.reader.SetIsDone (true);
- if (!batch_mode)
- {
- out_stream->Printf ("Warning: No command attached to breakpoint.\n");
- out_stream->Flush();
- }
- }
- virtual void EOFHandler(HandlerData& data)
- {
- data.reader.SetIsDone (true);
- }
- virtual void DoneHandler(HandlerData& data)
- {
- StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
- ScriptAddOptions *options_ptr = ((ScriptAddOptions*)data.baton);
- if (!options_ptr)
- {
- out_stream->Printf ("internal synchronization information missing or invalid.\n");
- out_stream->Flush();
- return;
- }
-
- ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
-
- ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- if (!interpreter)
- {
- out_stream->Printf ("no script interpreter.\n");
- out_stream->Flush();
- return;
- }
- std::string funct_name_str;
- if (!interpreter->GenerateTypeScriptFunction (options->m_user_source,
- funct_name_str))
- {
- out_stream->Printf ("unable to generate a function.\n");
- out_stream->Flush();
- return;
- }
- if (funct_name_str.empty())
- {
- out_stream->Printf ("unable to obtain a valid function name from the script interpreter.\n");
- out_stream->Flush();
- return;
- }
- // now I have a valid function name, let's add this as script for every type in the list
-
- TypeSummaryImplSP script_format;
- script_format.reset(new ScriptSummaryFormat(options->m_flags,
- funct_name_str.c_str(),
- options->m_user_source.CopyList(" ").c_str()));
-
- Error error;
-
- for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
- {
- const char *type_name = options->m_target_types.GetStringAtIndex(i);
- CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
- script_format,
- (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
- options->m_category,
- &error);
- if (error.Fail())
- {
- out_stream->Printf ("%s", error.AsCString());
- out_stream->Flush();
- return;
- }
- }
-
- if (options->m_name)
- {
- CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
- script_format,
- CommandObjectTypeSummaryAdd::eNamedSummary,
- options->m_category,
- &error);
- if (error.Fail())
- {
- CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
- script_format,
- CommandObjectTypeSummaryAdd::eNamedSummary,
- options->m_category,
- &error);
- if (error.Fail())
- {
- out_stream->Printf ("%s", error.AsCString());
- out_stream->Flush();
- return;
- }
- }
- else
- {
- out_stream->Printf ("%s", error.AsCString());
- out_stream->Flush();
- return;
- }
- }
- else
- {
- if (error.AsCString())
- {
- out_stream->PutCString (error.AsCString());
- out_stream->Flush();
- }
- return;
- }
- }
-};
-
#endif // #ifndef LLDB_DISABLE_PYTHON
Error
@@ -1339,35 +1485,9 @@ CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting ()
m_category = "default";
}
+
+
#ifndef LLDB_DISABLE_PYTHON
-void
-CommandObjectTypeSummaryAdd::CollectPythonScript (ScriptAddOptions *options,
- CommandReturnObject &result)
-{
- InputReaderSP reader_sp (new TypeScriptAddInputReader(m_interpreter.GetDebugger()));
- if (reader_sp && options)
- {
-
- InputReaderEZ::InitializationParameters ipr;
-
- Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt(" ")));
- if (err.Success())
- {
- m_interpreter.GetDebugger().PushInputReader (reader_sp);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError (err.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError("out of memory");
- result.SetStatus (eReturnStatusFailed);
- }
-}
bool
CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result)
@@ -1393,7 +1513,7 @@ CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturn
return false;
}
- std::string code = (" " + m_options.m_python_function + "(valobj,internal_dict)");
+ std::string code = (" " + m_options.m_python_function + "(valobj,internal_dict)");
script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
funct_name,
@@ -1432,14 +1552,15 @@ CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturn
return false;
}
- std::string code = " " + m_options.m_python_script;
+ std::string code = " " + m_options.m_python_script;
script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
funct_name_str.c_str(),
code.c_str()));
}
- else // use an InputReader to grab Python code from the user
- {
+ else
+ {
+ // Use an IOHandler to grab Python code from the user
ScriptAddOptions *options = new ScriptAddOptions(m_options.m_flags,
m_options.m_regex,
m_options.m_name,
@@ -1458,7 +1579,12 @@ CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturn
}
}
- CollectPythonScript(options,result);
+ m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+
return result.Succeeded();
}
@@ -1590,6 +1716,7 @@ CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &in
"type summary add",
"Add a new summary style for a type.",
NULL),
+ IOHandlerDelegateMultiline ("DONE"),
m_options (interpreter)
{
CommandArgumentEntry type_arg;
@@ -1671,6 +1798,8 @@ CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &in
bool
CommandObjectTypeSummaryAdd::DoExecute (Args& command, CommandReturnObject &result)
{
+ WarnOnPotentialUnquotedUnsignedType(command, result);
+
if (m_options.m_is_add_script)
{
#ifndef LLDB_DISABLE_PYTHON
@@ -1720,8 +1849,8 @@ CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
return false;
}
- category->GetRegexSummaryNavigator()->Delete(type_name);
- category->GetRegexSummaryNavigator()->Add(typeRX, entry);
+ category->GetRegexTypeSummariesContainer()->Delete(type_name);
+ category->GetRegexTypeSummariesContainer()->Add(typeRX, entry);
return true;
}
@@ -1733,7 +1862,7 @@ CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
}
else
{
- category->GetSummaryNavigator()->Add(type_name, entry);
+ category->GetTypeSummariesContainer()->Add(type_name, entry);
return true;
}
}
@@ -1994,8 +2123,8 @@ private:
PerCategoryCallback(void* param,
const lldb::TypeCategoryImplSP& cate)
{
- cate->GetSummaryNavigator()->Clear();
- cate->GetRegexSummaryNavigator()->Clear();
+ cate->GetTypeSummariesContainer()->Clear();
+ cate->GetRegexTypeSummariesContainer()->Clear();
return true;
}
@@ -2178,7 +2307,8 @@ protected:
param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,NULL,cate_regex);
DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
-
+ delete param;
+
if (DataVisualization::NamedSummaryFormats::GetCount() > 0)
{
result.GetOutputStream().Printf("Named summaries:\n");
@@ -2226,12 +2356,12 @@ private:
cate_name,
(cate->IsEnabled() ? "enabled" : "disabled"));
- cate->GetSummaryNavigator()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param_vp);
+ cate->GetTypeSummariesContainer()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param_vp);
- if (cate->GetRegexSummaryNavigator()->GetCount() > 0)
+ if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0)
{
result->GetOutputStream().Printf("Regex-based summaries (slower):\n");
- cate->GetRegexSummaryNavigator()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param_vp);
+ cate->GetRegexTypeSummariesContainer()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param_vp);
}
return true;
}
@@ -2741,6 +2871,7 @@ protected:
param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex);
DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
+ delete param;
if (cate_regex)
delete cate_regex;
@@ -2774,12 +2905,12 @@ private:
cate_name,
(cate->IsEnabled() ? "enabled" : "disabled"));
- cate->GetFilterNavigator()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp);
+ cate->GetTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp);
- if (cate->GetRegexFilterNavigator()->GetCount() > 0)
+ if (cate->GetRegexTypeFiltersContainer()->GetCount() > 0)
{
result->GetOutputStream().Printf("Regex-based filters (slower):\n");
- cate->GetRegexFilterNavigator()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp);
+ cate->GetRegexTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp);
}
return true;
@@ -2955,7 +3086,8 @@ protected:
param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex);
DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
-
+ delete param;
+
if (cate_regex)
delete cate_regex;
@@ -2988,12 +3120,12 @@ private:
cate_name,
(cate->IsEnabled() ? "enabled" : "disabled"));
- cate->GetSyntheticNavigator()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp);
+ cate->GetTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp);
- if (cate->GetRegexSyntheticNavigator()->GetCount() > 0)
+ if (cate->GetRegexTypeSyntheticsContainer()->GetCount() > 0)
{
result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n");
- cate->GetRegexSyntheticNavigator()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp);
+ cate->GetRegexTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp);
}
return true;
@@ -3179,8 +3311,8 @@ protected:
lldb::TypeCategoryImplSP category;
DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
- bool delete_category = category->GetFilterNavigator()->Delete(typeCS);
- delete_category = category->GetRegexFilterNavigator()->Delete(typeCS) || delete_category;
+ bool delete_category = category->GetTypeFiltersContainer()->Delete(typeCS);
+ delete_category = category->GetRegexTypeFiltersContainer()->Delete(typeCS) || delete_category;
if (delete_category)
{
@@ -3345,8 +3477,8 @@ protected:
lldb::TypeCategoryImplSP category;
DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
- bool delete_category = category->GetSyntheticNavigator()->Delete(typeCS);
- delete_category = category->GetRegexSyntheticNavigator()->Delete(typeCS) || delete_category;
+ bool delete_category = category->GetTypeSyntheticsContainer()->Delete(typeCS);
+ delete_category = category->GetRegexTypeSyntheticsContainer()->Delete(typeCS) || delete_category;
if (delete_category)
{
@@ -3484,8 +3616,8 @@ protected:
}
else
DataVisualization::Categories::GetCategory(ConstString(NULL), category);
- category->GetFilterNavigator()->Clear();
- category->GetRegexFilterNavigator()->Clear();
+ category->GetTypeFiltersContainer()->Clear();
+ category->GetRegexTypeFiltersContainer()->Clear();
}
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -3613,8 +3745,8 @@ protected:
}
else
DataVisualization::Categories::GetCategory(ConstString(NULL), category);
- category->GetSyntheticNavigator()->Clear();
- category->GetRegexSyntheticNavigator()->Clear();
+ category->GetTypeSyntheticsContainer()->Clear();
+ category->GetRegexTypeSyntheticsContainer()->Clear();
}
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -3631,193 +3763,6 @@ CommandObjectTypeSynthClear::CommandOptions::g_option_table[] =
};
-//-------------------------------------------------------------------------
-// TypeSynthAddInputReader
-//-------------------------------------------------------------------------
-
-static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
- "You must define a Python class with these methods:\n"
- " def __init__(self, valobj, dict):\n"
- " def num_children(self):\n"
- " def get_child_at_index(self, index):\n"
- " def get_child_index(self, name):\n"
- "Optionally, you can also define a method:\n"
- " def update(self):\n"
- "if your synthetic provider is holding on to any per-object state variables (currently, this is not implemented because of the way LLDB handles instances of SBValue and you should not rely on object persistence and per-object state)\n"
- "class synthProvider:";
-
-class TypeSynthAddInputReader : public InputReaderEZ
-{
-public:
- TypeSynthAddInputReader(Debugger& debugger) :
- InputReaderEZ(debugger)
- {}
-
- virtual
- ~TypeSynthAddInputReader()
- {
- }
-
- virtual void ActivateHandler(HandlerData& data)
- {
- StreamSP out_stream = data.GetOutStream();
- bool batch_mode = data.GetBatchMode();
- if (!batch_mode)
- {
- out_stream->Printf ("%s\n", g_synth_addreader_instructions);
- if (data.reader.GetPrompt())
- out_stream->Printf ("%s", data.reader.GetPrompt());
- out_stream->Flush();
- }
- }
-
- virtual void ReactivateHandler(HandlerData& data)
- {
- StreamSP out_stream = data.GetOutStream();
- bool batch_mode = data.GetBatchMode();
- if (data.reader.GetPrompt() && !batch_mode)
- {
- out_stream->Printf ("%s", data.reader.GetPrompt());
- out_stream->Flush();
- }
- }
- virtual void GotTokenHandler(HandlerData& data)
- {
- StreamSP out_stream = data.GetOutStream();
- bool batch_mode = data.GetBatchMode();
- if (data.bytes && data.bytes_len && data.baton)
- {
- ((SynthAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len);
- }
- if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
- {
- out_stream->Printf ("%s", data.reader.GetPrompt());
- out_stream->Flush();
- }
- }
- virtual void InterruptHandler(HandlerData& data)
- {
- StreamSP out_stream = data.GetOutStream();
- bool batch_mode = data.GetBatchMode();
- data.reader.SetIsDone (true);
- if (!batch_mode)
- {
- out_stream->Printf ("Warning: No command attached to breakpoint.\n");
- out_stream->Flush();
- }
- }
- virtual void EOFHandler(HandlerData& data)
- {
- data.reader.SetIsDone (true);
- }
- virtual void DoneHandler(HandlerData& data)
- {
- StreamSP out_stream = data.GetOutStream();
- SynthAddOptions *options_ptr = ((SynthAddOptions*)data.baton);
- if (!options_ptr)
- {
- out_stream->Printf ("internal synchronization data missing.\n");
- out_stream->Flush();
- return;
- }
-
- SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
-
- ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- if (!interpreter)
- {
- out_stream->Printf ("no script interpreter.\n");
- out_stream->Flush();
- return;
- }
- std::string class_name_str;
- if (!interpreter->GenerateTypeSynthClass (options->m_user_source,
- class_name_str))
- {
- out_stream->Printf ("unable to generate a class.\n");
- out_stream->Flush();
- return;
- }
- if (class_name_str.empty())
- {
- out_stream->Printf ("unable to obtain a proper name for the class.\n");
- out_stream->Flush();
- return;
- }
-
- // everything should be fine now, let's add the synth provider class
-
- SyntheticChildrenSP synth_provider;
- synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade).
- SetSkipPointers(options->m_skip_pointers).
- SetSkipReferences(options->m_skip_references),
- class_name_str.c_str()));
-
-
- lldb::TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category);
-
- Error error;
-
- for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
- {
- const char *type_name = options->m_target_types.GetStringAtIndex(i);
- ConstString typeCS(type_name);
- if (typeCS)
- {
- if (!CommandObjectTypeSynthAdd::AddSynth(typeCS,
- synth_provider,
- options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth,
- options->m_category,
- &error))
- {
- out_stream->Printf("%s\n", error.AsCString());
- out_stream->Flush();
- return;
- }
- }
- else
- {
- out_stream->Printf ("invalid type name.\n");
- out_stream->Flush();
- return;
- }
- }
- }
-
-private:
- DISALLOW_COPY_AND_ASSIGN (TypeSynthAddInputReader);
-};
-
-void
-CommandObjectTypeSynthAdd::CollectPythonScript (SynthAddOptions *options,
- CommandReturnObject &result)
-{
- InputReaderSP reader_sp (new TypeSynthAddInputReader(m_interpreter.GetDebugger()));
- if (reader_sp && options)
- {
-
- InputReaderEZ::InitializationParameters ipr;
-
- Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt(" ")));
- if (err.Success())
- {
- m_interpreter.GetDebugger().PushInputReader (reader_sp);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError (err.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError("out of memory");
- result.SetStatus (eReturnStatusFailed);
- }
-}
-
bool
CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result)
{
@@ -3842,7 +3787,11 @@ CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturn
}
}
- CollectPythonScript(options,result);
+ m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
}
@@ -3921,6 +3870,7 @@ CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interp
"type synthetic add",
"Add a new synthetic provider for a type.",
NULL),
+ IOHandlerDelegateMultiline ("DONE"),
m_options (interpreter)
{
CommandArgumentEntry type_arg;
@@ -3979,32 +3929,17 @@ CommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
return false;
}
- category->GetRegexSyntheticNavigator()->Delete(type_name);
- category->GetRegexSyntheticNavigator()->Add(typeRX, entry);
+ category->GetRegexTypeSyntheticsContainer()->Delete(type_name);
+ category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry);
return true;
}
else
{
- category->GetSyntheticNavigator()->Add(type_name, entry);
+ category->GetTypeSyntheticsContainer()->Add(type_name, entry);
return true;
}
}
-
-bool
-CommandObjectTypeSynthAdd::DoExecute (Args& command, CommandReturnObject &result)
-{
- if (m_options.handwrite_python)
- return Execute_HandwritePython(command, result);
- else if (m_options.is_class_based)
- return Execute_PythonClass(command, result);
- else
- {
- result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-}
OptionDefinition
CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
@@ -4173,14 +4108,14 @@ private:
return false;
}
- category->GetRegexFilterNavigator()->Delete(type_name);
- category->GetRegexFilterNavigator()->Add(typeRX, entry);
+ category->GetRegexTypeFiltersContainer()->Delete(type_name);
+ category->GetRegexTypeFiltersContainer()->Add(typeRX, entry);
return true;
}
else
{
- category->GetFilterNavigator()->Add(type_name, entry);
+ category->GetTypeFiltersContainer()->Add(type_name, entry);
return true;
}
}
@@ -4279,6 +4214,8 @@ protected:
Error error;
+ WarnOnPotentialUnquotedUnsignedType(command, result);
+
for (size_t i = 0; i < argc; i++)
{
const char* typeA = command.GetArgumentAtIndex(i);
diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp
index e19216d74fce..0083ff140e5a 100644
--- a/source/Commands/CommandObjectWatchpointCommand.cpp
+++ b/source/Commands/CommandObjectWatchpointCommand.cpp
@@ -16,6 +16,7 @@
#include "CommandObjectWatchpointCommand.h"
#include "CommandObjectWatchpoint.h"
+#include "lldb/Core/IOHandler.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Target.h"
@@ -34,7 +35,9 @@ using namespace lldb_private;
//-------------------------------------------------------------------------
-class CommandObjectWatchpointCommandAdd : public CommandObjectParsed
+class CommandObjectWatchpointCommandAdd :
+ public CommandObjectParsed,
+ public IOHandlerDelegateMultiline
{
public:
@@ -43,6 +46,7 @@ public:
"add",
"Add a set of commands to a watchpoint, to be executed whenever the watchpoint is hit.",
NULL),
+ IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand),
m_options (interpreter)
{
SetHelpLong (
@@ -185,40 +189,45 @@ but do NOT enter more than one command per line. \n" );
return &m_options;
}
- void
- CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
- CommandReturnObject &result)
+ virtual void
+ IOHandlerActivated (IOHandler &io_handler)
{
- InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
- std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
- if (reader_sp && data_ap.get())
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp)
{
- BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
- wp_options->SetCallback (WatchpointOptionsCallbackFunction, baton_sp);
-
- Error err (reader_sp->Initialize (CommandObjectWatchpointCommandAdd::GenerateWatchpointCommandCallback,
- wp_options, // callback_data
- 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);
- }
+ output_sp->PutCString("Enter your debugger command(s). Type 'DONE' to end.\n");
+ output_sp->Flush();
}
- else
+ }
+
+
+ virtual void
+ IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
+ {
+ io_handler.SetIsDone(true);
+
+ // The WatchpointOptions object is owned by the watchpoint or watchpoint location
+ WatchpointOptions *wp_options = (WatchpointOptions *) io_handler.GetUserData();
+ if (wp_options)
{
- result.AppendError("out of memory");
- result.SetStatus (eReturnStatusFailed);
+ std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
+ if (data_ap.get())
+ {
+ data_ap->user_source.SplitIntoLines(line);
+ BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
+ wp_options->SetCallback (WatchpointOptionsCallbackFunction, baton_sp);
+ }
}
+ }
+ void
+ CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
+ CommandReturnObject &result)
+ {
+ m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ wp_options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
}
/// Set a one-liner as the callback for the watchpoint.
@@ -240,93 +249,6 @@ but do NOT enter more than one command per line. \n" );
return;
}
-
- static size_t
- GenerateWatchpointCommandCallback (void *callback_data,
- InputReader &reader,
- lldb::InputReaderAction notification,
- const char *bytes,
- size_t bytes_len)
- {
- StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
- bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
-
- switch (notification)
- {
- case eInputReaderActivate:
- if (!batch_mode)
- {
- out_stream->Printf ("%s\n", g_reader_instructions);
- if (reader.GetPrompt())
- out_stream->Printf ("%s", reader.GetPrompt());
- out_stream->Flush();
- }
- break;
-
- case eInputReaderDeactivate:
- break;
-
- case eInputReaderReactivate:
- if (reader.GetPrompt() && !batch_mode)
- {
- out_stream->Printf ("%s", reader.GetPrompt());
- out_stream->Flush();
- }
- break;
-
- case eInputReaderAsynchronousOutputWritten:
- break;
-
- case eInputReaderGotToken:
- if (bytes && bytes_len && callback_data)
- {
- WatchpointOptions *wp_options = (WatchpointOptions *) callback_data;
- if (wp_options)
- {
- Baton *wp_options_baton = wp_options->GetBaton();
- if (wp_options_baton)
- ((WatchpointOptions::CommandData *)wp_options_baton->m_data)->user_source.AppendString (bytes, bytes_len);
- }
- }
- if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
- {
- out_stream->Printf ("%s", reader.GetPrompt());
- out_stream->Flush();
- }
- break;
-
- case eInputReaderInterrupt:
- {
- // Finish, and cancel the watchpoint command.
- reader.SetIsDone (true);
- WatchpointOptions *wp_options = (WatchpointOptions *) callback_data;
- if (wp_options)
- {
- Baton *wp_options_baton = wp_options->GetBaton ();
- if (wp_options_baton)
- {
- ((WatchpointOptions::CommandData *) wp_options_baton->m_data)->user_source.Clear();
- ((WatchpointOptions::CommandData *) wp_options_baton->m_data)->script_source.clear();
- }
- }
- if (!batch_mode)
- {
- out_stream->Printf ("Warning: No command attached to watchpoint.\n");
- out_stream->Flush();
- }
- }
- break;
-
- case eInputReaderEndOfFile:
- reader.SetIsDone (true);
- break;
-
- case eInputReaderDone:
- break;
- }
-
- return bytes_len;
- }
static bool
WatchpointOptionsCallbackFunction (void *baton,
@@ -579,12 +501,8 @@ protected:
private:
CommandOptions m_options;
- static const char *g_reader_instructions;
-
};
-const char *
-CommandObjectWatchpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.";
// FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting
// language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper.
diff --git a/source/Commands/CommandObjectWatchpointCommand.h b/source/Commands/CommandObjectWatchpointCommand.h
index c2faf7187db9..3bc9b3537db7 100644
--- a/source/Commands/CommandObjectWatchpointCommand.h
+++ b/source/Commands/CommandObjectWatchpointCommand.h
@@ -19,9 +19,6 @@
#include "lldb/lldb-types.h"
#include "lldb/Interpreter/Options.h"
-#include "lldb/Core/InputReader.h"
-#include "lldb/Interpreter/CommandObject.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"