summaryrefslogtreecommitdiffstats
path: root/lldb/source/Commands
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2011-02-18 00:54:25 +0000
committerJim Ingham <jingham@apple.com>2011-02-18 00:54:25 +0000
commite16c50a11a4cc49b0b4a88c481642f72003aac89 (patch)
treed86a18f84f4a736f5d10a240b3d576d03bc73754 /lldb/source/Commands
parentd12b480e29e3891c308b0380d591cdca4e8e9a63 (diff)
downloadbcm5719-llvm-e16c50a11a4cc49b0b4a88c481642f72003aac89.tar.gz
bcm5719-llvm-e16c50a11a4cc49b0b4a88c481642f72003aac89.zip
Factor all the code that does "Execute a list of lldb command interpreter commands" into a single function in the Interpreter, and then use that in all the places that used to do this by hand.
llvm-svn: 125807
Diffstat (limited to 'lldb/source/Commands')
-rw-r--r--lldb/source/Commands/CommandObjectBreakpointCommand.cpp154
-rw-r--r--lldb/source/Commands/CommandObjectBreakpointCommand.h1
-rw-r--r--lldb/source/Commands/CommandObjectCommands.cpp154
-rw-r--r--lldb/source/Commands/CommandObjectImage.cpp2
4 files changed, 176 insertions, 135 deletions
diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
index 0024e6d2e80..edca869e48a 100644
--- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -45,20 +45,29 @@ CommandObjectBreakpointCommandAdd::CommandOptions::~CommandOptions ()
{
}
+// 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.
+
+static lldb::OptionEnumValueElement
+g_script_option_enumeration[4] =
+{
+ { eScriptLanguageNone, "command", "Commands are in the lldb command interpreter language"},
+ { eScriptLanguagePython, "python", "Commands are in the Python language."},
+ { eSortOrderByName, "default-script", "Commands are in the default scripting language."},
+ { 0, NULL, NULL }
+};
+
lldb::OptionDefinition
CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner,
"Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
- { LLDB_OPT_SET_1, true, "script", 's', no_argument, NULL, NULL, eArgTypeNone,
- "Write the breakpoint command script in the default scripting language."},
+ { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, NULL, eArgTypeBoolean,
+ "Specify whether breakpoint command execution should terminate on error." },
- { LLDB_OPT_SET_2, true, "python", 'p', no_argument, NULL, NULL, eArgTypeNone,
- "Write the breakpoint command script in the Python scripting language."},
-
- { LLDB_OPT_SET_3, true, "commands", 'c', no_argument, NULL, NULL, eArgTypeNone,
- "Write the breakpoint command script using standard debugger commands."},
+ { LLDB_OPT_SET_ALL, false, "script-type", 's', required_argument, g_script_option_enumeration, NULL, eArgTypeNone,
+ "Specify the language for the commands - if none is specified, the lldb command interpreter will be used."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
@@ -83,26 +92,42 @@ CommandObjectBreakpointCommandAdd::CommandOptions::SetOptionValue
switch (short_option)
{
case 'o':
- m_use_one_liner = true;
- m_one_liner = option_arg;
- break;
+ m_use_one_liner = true;
+ m_one_liner = option_arg;
+ break;
+ break;
case 's':
- m_use_commands = false;
- m_use_script_language = true;
- m_script_language = eScriptLanguageDefault;
- break;
- case 'p':
- m_use_commands = false;
- m_use_script_language = true;
- m_script_language = eScriptLanguagePython;
- break;
- case 'c':
- m_use_commands = true;
- m_use_script_language = false;
- m_script_language = eScriptLanguageNone;
- break;
+ {
+ bool found_one = false;
+ m_script_language = (lldb::ScriptLanguage) Args::StringToOptionEnum (option_arg,
+ g_option_table[option_idx].enum_values,
+ eScriptLanguageNone,
+ &found_one);
+ if (!found_one)
+ error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n",
+ option_arg,
+ short_option);
+
+ if (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault)
+ {
+ m_use_commands = false;
+ m_use_script_language = true;
+ }
+ else
+ {
+ m_use_commands = true;
+ m_use_script_language = false;
+ }
+ }
+ break;
+ case 'e':
+ bool success_ptr;
+ m_stop_on_error = Args::StringToBoolean(option_arg, false, &success_ptr);
+ if (!success_ptr)
+ error.SetErrorStringWithFormat("Invalid value for stop-on-error: \"%s\".\n", option_arg);
+ break;
default:
- break;
+ break;
}
return error;
}
@@ -112,11 +137,12 @@ CommandObjectBreakpointCommandAdd::CommandOptions::ResetOptionValues ()
{
Options::ResetOptionValues();
- m_use_commands = false;
+ m_use_commands = true;
m_use_script_language = false;
m_script_language = eScriptLanguageNone;
m_use_one_liner = false;
+ m_stop_on_error = true;
m_one_liner.clear();
}
@@ -173,13 +199,13 @@ breakpoint commands. \n\
\n\
Example Python one-line breakpoint command: \n\
\n\
-(lldb) breakpoint command add -p 1 \n\
+(lldb) breakpoint command add -s python 1 \n\
Enter your Python command(s). Type 'DONE' to end. \n\
> print \"Hit this breakpoint!\" \n\
> DONE \n\
\n\
As a convenience, this also works for a short Python one-liner: \n\
-(lldb) breakpoint command add -p 1 -o \"import time; print time.asctime()\" \n\
+(lldb) breakpoint command add -s python 1 -o \"import time; print time.asctime()\" \n\
(lldb) run \n\
Launching '.../a.out' (x86_64) \n\
(lldb) Fri Sep 10 12:17:45 2010 \n\
@@ -196,7 +222,7 @@ Process 21778 Stopped \n\
\n\
Example multiple line Python breakpoint command, using function definition: \n\
\n\
-(lldb) breakpoint command add -p 1 \n\
+(lldb) breakpoint command add -s python 1 \n\
Enter your Python command(s). Type 'DONE' to end. \n\
> def breakpoint_output (bp_no): \n\
> out_string = \"Hit breakpoint number \" + repr (bp_no) \n\
@@ -208,7 +234,7 @@ Enter your Python command(s). Type 'DONE' to end. \n\
\n\
Example multiple line Python breakpoint command, using 'loose' Python: \n\
\n\
-(lldb) breakpoint command add -p 1 \n\
+(lldb) breakpoint command add -s p 1 \n\
Enter your Python command(s). Type 'DONE' to end. \n\
> global bp_count \n\
> bp_count = bp_count + 1 \n\
@@ -309,7 +335,7 @@ CommandObjectBreakpointCommandAdd::Execute
bp_options = bp_loc_sp->GetLocationOptions();
}
- // Skip this breakpoiont if bp_options is not good.
+ // Skip this breakpoint if bp_options is not good.
if (bp_options == NULL) continue;
// If we are using script language, get the script interpreter
@@ -401,6 +427,7 @@ CommandObjectBreakpointCommandAdd::SetBreakpointCommandCallback (BreakpointOptio
// while the latter is used for Python to interpret during the actual callback.
data_ap->user_source.AppendString (oneliner);
data_ap->script_source.AppendString (oneliner);
+ data_ap->stop_on_error = m_options.m_stop_on_error;
BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
bp_options->SetCallback (CommandObjectBreakpointCommand::BreakpointOptionsCallbackFunction, baton_sp);
@@ -686,7 +713,9 @@ CommandObjectBreakpointCommandList::Execute
if (bp_options)
{
StreamString id_str;
- BreakpointID::GetCanonicalReference (&id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID());
+ BreakpointID::GetCanonicalReference (&id_str,
+ cur_bp_id.GetBreakpointID(),
+ cur_bp_id.GetLocationID());
const Baton *baton = bp_options->GetBaton();
if (baton)
{
@@ -697,7 +726,8 @@ CommandObjectBreakpointCommandList::Execute
}
else
{
- result.AppendMessageWithFormat ("Breakpoint %s does not have an associated command.\n", id_str.GetData());
+ result.AppendMessageWithFormat ("Breakpoint %s does not have an associated command.\n",
+ id_str.GetData());
}
}
result.SetStatus (eReturnStatusSuccessFinishResult);
@@ -763,55 +793,31 @@ CommandObjectBreakpointCommand::BreakpointOptionsCallbackFunction
if (commands.GetSize() > 0)
{
- uint32_t num_commands = commands.GetSize();
CommandReturnObject result;
if (context->exe_ctx.target)
{
Debugger &debugger = context->exe_ctx.target->GetDebugger();
- CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
-
- File &out_file = debugger.GetOutputFile();
- File &err_file = debugger.GetErrorFile();
-
- uint32_t i;
- for (i = 0; i < num_commands; ++i)
+
+ bool stop_on_continue = true;
+ bool echo_commands = false;
+ bool print_results = true;
+
+ debugger.GetCommandInterpreter().HandleCommands (commands,
+ &(context->exe_ctx),
+ stop_on_continue,
+ data->stop_on_error,
+ echo_commands,
+ print_results,
+ result);
+ // Now dump the commands to the debugger's output:
+ if (!result.Succeeded())
{
-
- // First time through we use the context from the stoppoint, after that we use whatever
- // has been set by the previous command.
-
- if (!interpreter.HandleCommand (commands.GetStringAtIndex(i), false, result, &context->exe_ctx))
- break;
-
- // FIXME: This isn't really the right way to do this. We should be able to peek at the public
- // to see if there is any new events, but that is racey, since the internal process thread has to run and
- // deliver the event to the public queue before a run will show up. So for now we check
- // the internal thread state.
-
- lldb::StateType internal_state = context->exe_ctx.process->GetPrivateState();
- if (internal_state != eStateStopped)
- {
- if (i < num_commands - 1)
- {
- out_file.Printf ("Short-circuiting command execution because target state changed to %s."
- " last command: \"%s\"\n", StateAsCString(internal_state),
- commands.GetStringAtIndex(i));
- }
- break;
- }
-
- out_file.Printf ("%s", result.GetErrorStream().GetData());
- err_file.Printf ("%s", result.GetOutputStream().GetData());
- result.Clear();
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ debugger.GetErrorFile().Printf ("%s", result.GetErrorStream().GetData());
}
+
+ debugger.GetOutputFile().Printf ("%s", result.GetOutputStream().GetData());
- if (!result.Succeeded() && i < num_commands)
- err_file.Printf ("Attempt to execute '%s' failed.\n", commands.GetStringAtIndex(i));
-
- out_file.Printf ("%s", result.GetErrorStream().GetData());
- err_file.Printf ("%s", result.GetOutputStream().GetData());
}
}
return ret_value;
diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.h b/lldb/source/Commands/CommandObjectBreakpointCommand.h
index 034a0e80727..51131d2ee04 100644
--- a/lldb/source/Commands/CommandObjectBreakpointCommand.h
+++ b/lldb/source/Commands/CommandObjectBreakpointCommand.h
@@ -122,6 +122,7 @@ public:
// Instance variables to hold the values for one_liner options.
bool m_use_one_liner;
std::string m_one_liner;
+ bool m_stop_on_error;
};
private:
diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp
index e2358bda661..9230aea8ba1 100644
--- a/lldb/source/Commands/CommandObjectCommands.cpp
+++ b/lldb/source/Commands/CommandObjectCommands.cpp
@@ -22,14 +22,87 @@
using namespace lldb;
using namespace lldb_private;
-const char *k_space_characters = "\t\n\v\f\r ";
-
//-------------------------------------------------------------------------
// CommandObjectCommandsSource
//-------------------------------------------------------------------------
class CommandObjectCommandsSource : public CommandObject
{
+private:
+
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (){}
+
+ virtual
+ ~CommandOptions (){}
+
+ virtual Error
+ SetOptionValue (int option_idx, const char *option_arg)
+ {
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+ bool success;
+
+ switch (short_option)
+ {
+ case 'e':
+ m_stop_on_error = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("Invalid value for stop-on-error: %s.\n", 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.\n", option_arg);
+ break;
+ default:
+ error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ ResetOptionValues ()
+ {
+ Options::ResetOptionValues();
+
+ m_stop_on_error = true;
+ m_stop_on_continue = true;
+ }
+
+ const lldb::OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static lldb::OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+
+ bool m_stop_on_error;
+ bool m_stop_on_continue;
+ };
+
+ // Options table: Required for subclasses of Options.
+
+ static lldb::OptionDefinition g_option_table[];
+
+ CommandOptions m_options;
+
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
public:
CommandObjectCommandsSource(CommandInterpreter &interpreter) :
CommandObject (interpreter,
@@ -66,68 +139,21 @@ public:
if (argc == 1)
{
const char *filename = args.GetArgumentAtIndex(0);
- bool success = true;
result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
FileSpec cmd_file (filename, true);
- if (cmd_file.Exists())
- {
- STLStringArray commands;
- success = cmd_file.ReadFileLines (commands);
-
- STLStringArray::iterator pos = commands.begin();
-
- // Trim out any empty lines or lines that start with the comment
- // char '#'
- while (pos != commands.end())
- {
- size_t non_space = pos->find_first_not_of (k_space_characters);
- // Check for empty line or comment line (lines whose first
- // non-space character is a '#')
- if (non_space == std::string::npos || (*pos)[non_space] == '#')
- pos = commands.erase(pos);
- else
- ++pos;
- }
-
- if (commands.size() > 0)
- {
- const size_t num_commands = commands.size();
- size_t i;
- for (i = 0; i<num_commands; ++i)
- {
- result.GetOutputStream().Printf ("%s %s\n",
- m_interpreter.GetPrompt(),
- commands[i].c_str());
- if (!m_interpreter.HandleCommand(commands[i].c_str(), false, result))
- break;
- }
-
- if (i < num_commands)
- {
- result.AppendErrorWithFormat("Aborting source of '%s' after command '%s' failed.\n",
- filename, commands[i].c_str());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- success = true;
- result.SetStatus (eReturnStatusFailed);
- }
- }
- }
- else
- {
- result.AppendErrorWithFormat ("File '%s' does not exist.\n", filename);
- result.SetStatus (eReturnStatusFailed);
- success = false;
- }
-
- if (success)
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
+ ExecutionContext *exe_ctx = NULL; // Just use the default context.
+ bool echo_commands = true;
+ bool print_results = true;
+
+ m_interpreter.HandleCommandsFromFile (cmd_file,
+ exe_ctx,
+ m_options.m_stop_on_continue,
+ m_options.m_stop_on_error,
+ echo_commands,
+ print_results,
+ result);
}
else
{
@@ -139,6 +165,14 @@ public:
}
};
+lldb::OptionDefinition
+CommandObjectCommandsSource::CommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
+{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
+{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
#pragma mark CommandObjectCommandsAlias
//-------------------------------------------------------------------------
// CommandObjectCommandsAlias
diff --git a/lldb/source/Commands/CommandObjectImage.cpp b/lldb/source/Commands/CommandObjectImage.cpp
index 6b4a89a9c33..771562a8f2c 100644
--- a/lldb/source/Commands/CommandObjectImage.cpp
+++ b/lldb/source/Commands/CommandObjectImage.cpp
@@ -784,7 +784,7 @@ protected:
CommandOptions m_options;
};
-lldb::OptionEnumValueElement
+static lldb::OptionEnumValueElement
g_sort_option_enumeration[4] =
{
{ eSortOrderNone, "none", "No sorting, use the original symbol table order."},
OpenPOWER on IntegriCloud